applied platformio structure

This commit is contained in:
2026-03-13 17:03:22 +00:00
parent c5233cf15c
commit db7d90e736
3510 changed files with 691878 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
set( WEBPACK_DIR webapp/webpack/dist )
# for the forgetful, REQUIRES cannot use CONFIG_XXX due to parsing order
if(IDF_TARGET STREQUAL "esp32")
set(target_requires "driver_bt")
endif()
idf_component_register( SRC_DIRS . webapp UML-State-Machine-in-C/src
INCLUDE_DIRS . webapp UML-State-Machine-in-C/src
REQUIRES squeezelite-ota json mdns
PRIV_REQUIRES tools services platform_config esp_common json newlib freertos spi_flash nvs_flash mdns pthread wpa_supplicant platform_console esp_http_server console ${target_requires}
)
include(webapp/webapp.cmake)
+121
View File
@@ -0,0 +1,121 @@
menu "Network Manager Configuration"
menu "WiFi Options"
config WIFI_MANAGER_TASK_PRIORITY
int "RTOS Task Priority for the wifi_manager"
default 1
help
Tasks spawn by the manager will have a priority of WIFI_MANAGER_TASK_PRIORITY-1. For this particular reason, minimum recommended task priority is 2.
config WIFI_MANAGER_MAX_RETRY
int "Max Retry on failed connection"
default 2
help
Defines when a connection is lost/attempt to connect is made, how many retries should be made before giving up.
config DEFAULT_AP_SSID
string "Access Point SSID"
default "esp32"
help
SSID (network name) the the esp32 will broadcast.
config DEFAULT_AP_PASSWORD
string "Access Point Password"
default "esp32pwd"
help
Password used for the Access Point. Leave empty and set AUTH MODE to WIFI_AUTH_OPEN for no password.
config DEFAULT_AP_CHANNEL
int "Access Point WiFi Channel"
default 1
help
Be careful you might not see the access point if you use a channel not allowed in your country.
config DEFAULT_AP_IP
string "Access Point IP Address"
default "10.10.0.1"
help
This is used for the redirection to the captive portal. It is recommended to leave unchanged.
config DEFAULT_AP_GATEWAY
string "Access Point IP Gateway"
default "10.10.0.1"
help
This is used for the redirection to the captive portal. It is recommended to leave unchanged.
config DEFAULT_AP_NETMASK
string "Access Point Netmask"
default "255.255.255.0"
help
This is used for the redirection to the captive portal. It is recommended to leave unchanged.
config DEFAULT_AP_MAX_CONNECTIONS
int "Access Point Max Connections"
default 4
help
Max is 4.
config DEFAULT_AP_BEACON_INTERVAL
int "Access Point Beacon Interval (ms)"
default 100
help
100ms is the recommended default.
endmenu
menu "Ethernet Options"
visible if BASIC_I2C_BT && (ETH_USE_ESP32_EMAC || ETH_USE_SPI_ETHERNET)
choice
prompt "Ethernet Chipset"
default ETH_NODRIVER
config ETH_NODRIVER
bool "Defined in NVS"
config ETH_LAN8720
bool "Microchip LAN8720 (RMII)"
config ETH_DM9051
bool "Davicom 9051 (SPI)"
config ETH_W5500
bool "WIZnet 5500 (SPI)"
endchoice
comment "LAN8720 is an RMII interface and most of the required GPIOs aren't user selectable. They are defined as follow tx_en=21, tx0=19, tx1=22, rx0=25, rx1=26, crs_dv=27"
depends on ETH_LAN8720
config ETH_PHY_RST_IO
int "PHY Reset GPIO number" if !ETH_NODRIVER
default -1
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config ETH_MDC_IO
int "SMI MDC GPIO number" if ETH_LAN8720
default -1
help
Set the GPIO number used by SMI MDC.
config ETH_MDIO_IO
int "SMI MDIO GPIO number" if ETH_LAN8720
default -1
help
Set the GPIO number used by SMI MDIO.
config ETH_SPI_HOST
int "SPI host number (-1,1 or 2)" if ETH_DM9051 || ETH_W5500
default -1
help
Set to -1 to use system's SPI config (see Various I/O)
Set to 2 or 3 to use a dedicated bus
config ETH_SPI_INTR_IO
int "interrupt" if ETH_DM9051 || ETH_W5500
default -1
config ETH_SPI_CS_IO
int "Chip Select" if ETH_DM9051 || ETH_W5500
default -1
config ETH_SPI_CLK_IO
int "SPI clock" if ETH_SPI_HOST != -1 && (ETH_DM9051 || ETH_W5500)
default -1
config ETH_SPI_MOSI_IO
int "Data Out" if ETH_SPI_HOST != -1 && (ETH_DM9051 || ETH_W5500)
default -1
config ETH_SPI_MISO_IO
int "Data In" if ETH_SPI_HOST != -1 && (ETH_DM9051 || ETH_W5500)
default -1
config ETH_SPI_SPEED
int "SPI speed (Hz)" if ETH_SPI_HOST != -1 && (ETH_DM9051 || ETH_W5500)
default 20000000
endmenu
endmenu
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2017-2019 Tony Pottier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+14
View File
@@ -0,0 +1,14 @@
#
# Component Makefile
#
# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default,
# this will take the sources in the src/ directory, compile them and link them into
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
# please read the SDK documents if you need to do this.
#
COMPONENT_EMBED_FILES := style.css code.js index.html bootstrap.min.css.gz jquery.min.js.gz popper.min.js.gz bootstrap.min.js.gz favicon.ico
COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp_http_server/src $(IDF_PATH)/components/esp_http_server/src/port/esp32 $(IDF_PATH)/components/esp_http_server/src/util $(IDF_PATH)/components/esp_http_server/src/
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_INFO
+185
View File
@@ -0,0 +1,185 @@
/*
Copyright (c) 2019 Tony Pottier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@file dns_server.c
@author Tony Pottier
@brief Defines an extremely basic DNS server for captive portal functionality.
It's basically a DNS hijack that replies to the esp's address no matter which
request is sent to it.
Contains the freeRTOS task for the DNS server that processes the requests.
@see https://idyl.io
@see https://github.com/tonyp7/esp32-wifi-manager
*/
#include "dns_server.h"
#include <lwip/sockets.h>
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_err.h>
#include <nvs_flash.h>
#include <lwip/err.h>
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/netdb.h>
#include <lwip/dns.h>
#include <byteswap.h>
#include "squeezelite-ota.h"
#include "network_manager.h"
static const char TAG[] = "dns_server";
static TaskHandle_t task_dns_server = NULL;
int socket_fd;
void dns_server_start(esp_netif_t * netif) {
xTaskCreate(&dns_server, "dns_server", 3072, (void *)netif, WIFI_MANAGER_TASK_PRIORITY-1, &task_dns_server);
}
void dns_server_stop(){
if(task_dns_server){
vTaskDelete(task_dns_server);
close(socket_fd);
task_dns_server = NULL;
}
}
void dns_server(void *pvParameters) {
struct sockaddr_in sa, ra;
esp_err_t esp_err = ESP_OK;
esp_netif_t * netif = (esp_netif_t * )pvParameters;
/* Set redirection DNS hijack to the access point IP */
ip4_addr_t ip_resolved;
inet_pton(AF_INET, DEFAULT_AP_IP, &ip_resolved);
/* Create UDP socket */
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0){
ESP_LOGE(TAG, "Failed to create socket");
exit(0);
}
memset(&sa, 0, sizeof(struct sockaddr_in));
/* Bind to port 53 (typical DNS Server port) */
esp_netif_ip_info_t ip_info;
esp_err = esp_netif_get_ip_info(netif,&ip_info);
if(esp_err!=ESP_OK) {
ESP_LOGE(TAG, "Failed to get adapter info for udp: %s", esp_err_to_name(esp_err));
exit(1);
}
ra.sin_family = AF_INET;
ra.sin_addr.s_addr = ip_info.ip.addr;
ra.sin_port = htons(53);
if (bind(socket_fd, (struct sockaddr *)&ra, sizeof(struct sockaddr_in)) == -1) {
ESP_LOGE(TAG, "Failed to bind to 53/udp");
close(socket_fd);
exit(1);
}
struct sockaddr_in client;
socklen_t client_len;
client_len = sizeof(client);
int length;
uint8_t data[DNS_QUERY_MAX_SIZE]; /* dns query buffer */
uint8_t response[DNS_ANSWER_MAX_SIZE]; /* dns response buffer */
char ip_address[INET_ADDRSTRLEN]; /* buffer to store IPs as text. This is only used for debug and serves no other purpose */
char *domain; /* This is only used for debug and serves no other purpose */
int err;
ESP_LOGI(TAG, "DNS Server listening on 53/udp");
/* Start loop to process DNS requests */
for(;;) {
memset(data, 0x00, sizeof(data)); /* reset buffer */
length = recvfrom(socket_fd, data, sizeof(data), 0, (struct sockaddr *)&client, &client_len); /* read udp request */
/*if the query is bigger than the buffer size we simply ignore it. This case should only happen in case of multiple
* queries within the same DNS packet and is not supported by this simple DNS hijack. */
if ( length > 0 && ((length + sizeof(dns_answer_t)-1) < DNS_ANSWER_MAX_SIZE) ) {
data[length] = '\0'; /*in case there's a bogus domain name that isn't null terminated */
/* Generate header message */
memcpy(response, data, sizeof(dns_header_t));
dns_header_t *dns_header = (dns_header_t*)response;
dns_header->QR = 1; /*response bit */
dns_header->OPCode = DNS_OPCODE_QUERY; /* no support for other type of response */
dns_header->AA = 1; /*authoritative answer */
dns_header->RCode = DNS_REPLY_CODE_NO_ERROR; /* no error */
dns_header->TC = 0; /*no truncation */
dns_header->RD = 0; /*no recursion */
dns_header->ANCount = dns_header->QDCount; /* set answer count = question count -- duhh! */
dns_header->NSCount = 0x0000; /* name server resource records = 0 */
dns_header->ARCount = 0x0000; /* resource records = 0 */
/* copy the rest of the query in the response */
memcpy(response + sizeof(dns_header_t), data + sizeof(dns_header_t), length - sizeof(dns_header_t));
/* extract domain name and request IP for debug */
inet_ntop(AF_INET, &(client.sin_addr), ip_address, INET_ADDRSTRLEN);
domain = (char*) &data[sizeof(dns_header_t) + 1];
for(char* c=domain; *c != '\0'; c++){
if(*c < ' ' || *c > 'z') *c = '.'; /* technically we should test if the first two bits are 00 (e.g. if( (*c & 0xC0) == 0x00) *c = '.') but this makes the code a lot more readable */
}
ESP_LOGD(TAG, "Replying to DNS request for %s from %s", domain, ip_address);
/* create DNS answer at the end of the query*/
dns_answer_t *dns_answer = (dns_answer_t*)&response[length];
dns_answer->NAME = __bswap_16(0xC00C); /* This is a pointer to the beginning of the question. As per DNS standard, first two bits must be set to 11 for some odd reason hence 0xC0 */
dns_answer->TYPE = __bswap_16(DNS_ANSWER_TYPE_A);
dns_answer->CLASS = __bswap_16(DNS_ANSWER_CLASS_IN);
dns_answer->TTL = (uint32_t)0x00000000; /* no caching. Avoids DNS poisoning since this is a DNS hijack */
dns_answer->RDLENGTH = __bswap_16(0x0004); /* 4 byte => size of an ipv4 address */
dns_answer->RDATA = ip_resolved.addr;
err = sendto(socket_fd, response, length+sizeof(dns_answer_t), 0, (struct sockaddr *)&client, client_len);
if (err < 0) {
ESP_LOGE(TAG, "UDP sendto failed: %d", err);
}
}
taskYIELD(); /* allows the freeRTOS scheduler to take over if needed. DNS daemon should not be taxing on the system */
}
close(socket_fd);
vTaskDelete ( NULL );
}
+142
View File
@@ -0,0 +1,142 @@
/*
Copyright (c) 2019 Tony Pottier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@file dns_server.h
@author Tony Pottier
@brief Defines an extremly basic DNS server for captive portal functionality.
Contains the freeRTOS task for the DNS server that processes the requests.
@see https://idyl.io
@see https://github.com/tonyp7/esp32-wifi-manager
@see http://www.zytrax.com/books/dns/ch15
*/
#ifndef MAIN_DNS_SERVER_H_
#define MAIN_DNS_SERVER_H_
#include <esp_system.h>
#include <stdbool.h>
#include "squeezelite-ota.h"
#include "esp_netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/** 12 byte header, 64 byte domain name, 4 byte qtype/qclass. This NOT compliant with the RFC, but it's good enough for a captive portal
* if a DNS query is too big it just wont be processed. */
#define DNS_QUERY_MAX_SIZE 80
/** Query + 2 byte ptr, 2 byte type, 2 byte class, 4 byte TTL, 2 byte len, 4 byte data */
#define DNS_ANSWER_MAX_SIZE (DNS_QUERY_MAX_SIZE+16)
/**
* @brief RCODE values used in a DNS header message
*/
typedef enum dns_reply_code_t {
DNS_REPLY_CODE_NO_ERROR = 0,
DNS_REPLY_CODE_FORM_ERROR = 1,
DNS_REPLY_CODE_SERVER_FAILURE = 2,
DNS_REPLY_CODE_NON_EXISTANT_DOMAIN = 3,
DNS_REPLY_CODE_NOT_IMPLEMENTED = 4,
DNS_REPLY_CODE_REFUSED = 5,
DNS_REPLY_CODE_YXDOMAIN = 6,
DNS_REPLY_CODE_YXRRSET = 7,
DNS_REPLY_CODE_NXRRSET = 8
}dns_reply_code_t;
/**
* @brief OPCODE values used in a DNS header message
*/
typedef enum dns_opcode_code_t {
DNS_OPCODE_QUERY = 0,
DNS_OPCODE_IQUERY = 1,
DNS_OPCODE_STATUS = 2
}dns_opcode_code_t;
/**
* @brief Represents a 12 byte DNS header.
* __packed__ is needed to prevent potential unwanted memory alignments
*/
typedef struct __attribute__((__packed__)) dns_header_t{
uint16_t ID; // identification number
uint8_t RD : 1; // recursion desired
uint8_t TC : 1; // truncated message
uint8_t AA : 1; // authoritive answer
uint8_t OPCode : 4; // message_type
uint8_t QR : 1; // query/response flag
uint8_t RCode : 4; // response code
uint8_t Z : 3; // its z! reserved
uint8_t RA : 1; // recursion available
uint16_t QDCount; // number of question entries
uint16_t ANCount; // number of answer entries
uint16_t NSCount; // number of authority entries
uint16_t ARCount; // number of resource entries
}dns_header_t;
typedef enum dns_answer_type_t {
DNS_ANSWER_TYPE_A = 1,
DNS_ANSWER_TYPE_NS = 2,
DNS_ANSWER_TYPE_CNAME = 5,
DNS_ANSWER_TYPE_SOA = 6,
DNS_ANSWER_TYPE_WKS = 11,
DNS_ANSWER_TYPE_PTR = 12,
DNS_ANSWER_TYPE_MX = 15,
DNS_ANSWER_TYPE_SRV = 33,
DNS_ANSWER_TYPE_AAAA = 28
}dns_answer_type_t;
typedef enum dns_answer_class_t {
DNS_ANSWER_CLASS_IN = 1
}dns_answer_class_t;
typedef struct __attribute__((__packed__)) dns_answer_t{
uint16_t NAME; /* for the sake of simplicity only 16 bit pointers are supported */
uint16_t TYPE; /* Unsigned 16 bit value. The resource record types - determines the content of the RDATA field. */
uint16_t CLASS; /* Class of response. */
uint32_t TTL; /* The time in seconds that the record may be cached. A value of 0 indicates the record should not be cached. */
uint16_t RDLENGTH; /* Unsigned 16-bit value that defines the length in bytes of the RDATA record. */
uint32_t RDATA; /* For the sake of simplicity only ipv4 is supported, and as such it's a unsigned 32 bit */
}dns_answer_t;
void dns_server(void *pvParameters);
void dns_server_start(esp_netif_t * netif);
void dns_server_stop();
#ifdef __cplusplus
}
#endif
#endif /* MAIN_DNS_SERVER_H_ */
File diff suppressed because it is too large Load Diff
+115
View File
@@ -0,0 +1,115 @@
/*
Copyright (c) 2017-2021 Sebastien L
*/
#ifndef HTTP_SERVER_H_INCLUDED
#define HTTP_SERVER_H_INCLUDED
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "esp_http_server.h"
#include "network_manager.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include <esp_event.h>
#include "nvs_flash.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "mdns.h"
#include "lwip/api.h"
#include "lwip/err.h"
#include "lwip/netdb.h"
#include "lwip/opt.h"
#include "lwip/memp.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/priv/api_msg.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/priv/tcpip_priv.h"
#include "esp_vfs.h"
#include "esp_console.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_LOGE_LOC(t,str, ...) ESP_LOGE(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define ESP_LOGI_LOC(t,str, ...) ESP_LOGI(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define ESP_LOGD_LOC(t,str, ...) ESP_LOGD(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define ESP_LOGW_LOC(t,str, ...) ESP_LOGW(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define ESP_LOGV_LOC(t,str, ...) ESP_LOGV(t, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__)
esp_err_t root_get_handler(httpd_req_t *req);
esp_err_t resource_filehandler(httpd_req_t *req);
esp_err_t ap_get_handler(httpd_req_t *req);
esp_err_t config_get_handler(httpd_req_t *req);
esp_err_t config_post_handler(httpd_req_t *req);
esp_err_t connect_post_handler(httpd_req_t *req);
esp_err_t connect_delete_handler(httpd_req_t *req);
esp_err_t reboot_ota_post_handler(httpd_req_t *req);
esp_err_t reboot_post_handler(httpd_req_t *req);
esp_err_t recovery_post_handler(httpd_req_t *req);
esp_err_t flash_post_handler(httpd_req_t *req);
esp_err_t status_get_handler(httpd_req_t *req);
esp_err_t messages_get_handler(httpd_req_t *req);
esp_err_t console_cmd_get_handler(httpd_req_t *req);
esp_err_t console_cmd_post_handler(httpd_req_t *req);
esp_err_t ap_scan_handler(httpd_req_t *req);
esp_err_t redirect_ev_handler(httpd_req_t *req);
esp_err_t redirect_200_ev_handler(httpd_req_t *req);
esp_err_t err_handler(httpd_req_t *req, httpd_err_code_t error);
#define SCRATCH_BUFSIZE (10240)
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
typedef struct rest_server_context {
char base_path[ESP_VFS_PATH_MAX + 1];
char scratch[SCRATCH_BUFSIZE];
} rest_server_context_t;
/**
* @brief RTOS task for the HTTP server. Do not start manually.
* @see void http_server_start()
*/
void http_server(void *pvParameters);
/* @brief helper function that processes one HTTP request at a time */
void http_server_netconn_serve(struct netconn *conn);
/* @brief create the task for the http server */
esp_err_t http_server_start();
/**
* @brief gets a char* pointer to the first occurence of header_name withing the complete http request request.
*
* For optimization purposes, no local copy is made. memcpy can then be used in coordination with len to extract the
* data.
*
* @param request the full HTTP raw request.
* @param header_name the header that is being searched.
* @param len the size of the header value if found.
* @return pointer to the beginning of the header value.
*/
char* http_server_get_header(char *request, char *header_name, int *len);
void strreplace(char *src, char *str, char *rep);
/* @brief lock the json config object */
bool http_server_lock_json_object(TickType_t xTicksToWait);
/* @brief unlock the json config object */
void http_server_unlock_json_object();
httpd_handle_t http_get_server(int *port);
#define PROTECTED_JSON_CALL(a) if(http_server_lock_json_object( portMAX_DELAY )){ \ a; http_server_unlocklock_json_object(); } else{ ESP_LOGE(TAG, "could not get access to json mutex in wifi_scan"); }
#ifdef __cplusplus
}
#endif
#endif
+22
View File
@@ -0,0 +1,22 @@
{
"name": "wifi-manager",
"version": "1.0.0",
"description": "WiFi management component for ESP32",
"keywords": "wifi, esp32, network",
"repository": {
"type": "git",
"url": "https://github.com/squeezelite-esp32/squeezelite-esp32"
},
"authors": [
{
"name": "SqueezeESP32 Contributors",
"maintainer": true
}
],
"license": "MIT",
"frameworks": ["espidf"],
"platforms": ["espressif32"],
"build": {
"flags": ["-DCORE_DEBUG_LEVEL=3"]
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

+56
View File
@@ -0,0 +1,56 @@
#include "esp_eth.h"
#include "network_ethernet.h"
static EXT_RAM_ATTR network_ethernet_driver_t DM9051;
static EXT_RAM_ATTR spi_device_interface_config_t devcfg;
static EXT_RAM_ATTR esp_netif_config_t cfg_spi;
static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config;
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_dm9051_config_t eth_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
// we assume that isr has been installed already
eth_config.int_gpio_num = ethernet_config->intr;
phy_config.phy_addr = -1;
phy_config.reset_gpio_num = ethernet_config->rst;
esp_eth_mac_t* mac = esp_eth_mac_new_dm9051(&eth_config, &mac_config);
esp_eth_phy_t* phy = esp_eth_phy_new_dm9051(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
return esp_eth_driver_install(&config, &DM9051.handle);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
static void init_config(eth_config_t* ethernet_config) {
esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
devcfg.command_bits = 1;
devcfg.address_bits = 7;
devcfg.mode = 0;
devcfg.clock_speed_hz = ethernet_config->speed > 0 ? ethernet_config->speed : SPI_MASTER_FREQ_20M; // default speed
devcfg.queue_size = 20;
devcfg.spics_io_num = ethernet_config->cs;
memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config));
cfg_spi.base = &esp_netif_config,
cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
DM9051.cfg_netif = &cfg_spi;
DM9051.devcfg = &devcfg;
DM9051.start = start;
}
network_ethernet_driver_t* DM9051_Detect(char* Driver) {
if (!strcasestr(Driver, "DM9051"))
return NULL;
DM9051.rmii = false;
DM9051.spi = true;
#ifdef CONFIG_ETH_SPI_ETHERNET_DM9051
DM9051.valid = true;
#else
DM9051.valid = false;
#endif
DM9051.init_config = init_config;
return &DM9051;
}
+50
View File
@@ -0,0 +1,50 @@
#include "esp_eth.h"
#include "network_ethernet.h"
static EXT_RAM_ATTR network_ethernet_driver_t LAN8720;
static EXT_RAM_ATTR esp_netif_config_t cfg_rmii;
static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config;
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
mac_config.smi_mdc_gpio_num = ethernet_config->mdc;
mac_config.smi_mdio_gpio_num = ethernet_config->mdio;
phy_config.phy_addr = 1;
phy_config.reset_gpio_num = ethernet_config->rst;
esp_eth_mac_t* mac = esp_eth_mac_new_esp32(&mac_config);
esp_eth_phy_t* phy = esp_eth_phy_new_lan8720(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
return esp_eth_driver_install(&config, &LAN8720.handle);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
static void init_config(eth_config_t* ethernet_config) {
esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config));
cfg_rmii.base = &esp_netif_config,
cfg_rmii.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
LAN8720.cfg_netif = &cfg_rmii;
LAN8720.start = start;
}
network_ethernet_driver_t* LAN8720_Detect(char* Driver) {
if (!strcasestr(Driver, "LAN8720"))
return NULL;
#ifdef CONFIG_ETH_PHY_INTERFACE_RMII
LAN8720.valid = true;
#else
LAN8720.valid = false;
#endif
LAN8720.rmii = true;
LAN8720.spi = false;
LAN8720.init_config = init_config;
return &LAN8720;
}
+58
View File
@@ -0,0 +1,58 @@
#include "esp_eth.h"
#include "network_ethernet.h"
static EXT_RAM_ATTR network_ethernet_driver_t W5500;
static EXT_RAM_ATTR spi_device_interface_config_t devcfg;
static EXT_RAM_ATTR esp_netif_config_t cfg_spi;
static EXT_RAM_ATTR esp_netif_inherent_config_t esp_netif_config;
static esp_err_t start(spi_device_handle_t spi_handle, eth_config_t* ethernet_config) {
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
eth_w5500_config_t eth_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
eth_config.int_gpio_num = ethernet_config->intr;
phy_config.phy_addr = -1; // let the system automatically find out the phy address
phy_config.reset_gpio_num = ethernet_config->rst;
esp_eth_mac_t* mac = esp_eth_mac_new_w5500(&eth_config, &mac_config);
esp_eth_phy_t* phy = esp_eth_phy_new_w5500(&phy_config);
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
return esp_eth_driver_install(&config, &W5500.handle);
#else
return ESP_ERR_NOT_SUPPORTED;
#endif
}
static void init_config(eth_config_t* ethernet_config) {
// This function is called when the network interface is started
// and performs any initialization that requires a valid ethernet
// configuration .
esp_netif_inherent_config_t loc_esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
devcfg.command_bits = 16; // Actually it's the address phase in W5500 SPI frame
devcfg.address_bits = 8; // Actually it's the control phase in W5500 SPI frame
devcfg.mode = 0;
devcfg.clock_speed_hz = ethernet_config->speed > 0 ? ethernet_config->speed : SPI_MASTER_FREQ_20M; // default speed
devcfg.queue_size = 20;
devcfg.spics_io_num = ethernet_config->cs;
memcpy(&esp_netif_config, &loc_esp_netif_config, sizeof(loc_esp_netif_config));
cfg_spi.base = &esp_netif_config,
cfg_spi.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
W5500.cfg_netif = &cfg_spi;
W5500.devcfg = &devcfg;
W5500.start = start;
}
network_ethernet_driver_t* W5500_Detect(char* Driver, network_ethernet_driver_t* Device) {
if (!strcasestr(Driver, "W5500"))
return NULL;
W5500.init_config = init_config;
W5500.spi = true;
W5500.rmii = false;
#ifdef CONFIG_ETH_SPI_ETHERNET_W5500
W5500.valid = true;
#else
W5500.valid = false;
#endif
return &W5500;
}
+194
View File
@@ -0,0 +1,194 @@
#ifdef NETWORK_ETHERNET_LOG_LEVEL
#define LOG_LOCAL_LEVEL NETWORK_ETHERNET_LOG_LEVEL
#endif
#include "network_ethernet.h"
#include "freertos/timers.h"
#include "messaging.h"
#include "network_status.h"
#include "platform_config.h"
#include "tools.h"
#include "accessors.h"
#include "esp_log.h"
#include "globdefs.h"
static char TAG[] = "network_ethernet";
TimerHandle_t ETH_timer;
esp_netif_t* eth_netif = NULL;
EventGroupHandle_t ethernet_event_group;
const int LINK_UP_BIT = BIT0;
static const char* known_drivers[] = {"DM9051", "W5500", "LAN8720", NULL};
static network_ethernet_driver_t* network_driver = NULL;
extern network_ethernet_detect_func_t DM9051_Detect, W5500_Detect, LAN8720_Detect;
static network_ethernet_detect_func_t* drivers[] = {DM9051_Detect, W5500_Detect, LAN8720_Detect, NULL};
#define ETH_TIMEOUT_MS (30 * 1000)
/****************************************************************************************
*
*/
const char* network_ethernet_conf_get_driver_name(const char* driver) {
for (uint8_t i = 0; known_drivers[i] != NULL && strlen(known_drivers[i]) > 0; i++) {
if (strcasestr(driver, known_drivers[i])) {
return known_drivers[i];
}
}
return NULL;
}
/****************************************************************************************
*
*/
bool network_ethernet_is_valid_driver(const char* driver) {
return network_ethernet_conf_get_driver_name(driver) != NULL;
}
network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver) {
if (!Driver)
return NULL;
for (int i = 0; drivers[i]; i++) {
network_ethernet_driver_t* found_driver = drivers[i](Driver);
if (found_driver) {
ESP_LOGI(TAG, "Detected driver %s ", Driver);
network_driver = found_driver;
return found_driver;
}
}
return NULL;
}
static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
esp_netif_t *network_ethernet_get_interface(){
return eth_netif;
}
bool network_ethernet_is_up() {
return (xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0;
}
bool network_ethernet_enabled() {
return network_driver !=NULL && network_driver->handle != NULL;
}
bool network_ethernet_wait_for_link(uint16_t max_wait_ms){
if(!network_ethernet_enabled()) return false;
bool link_up=(xEventGroupGetBits(ethernet_event_group) & LINK_UP_BIT)!=0;
if(!link_up){
ESP_LOGD(TAG,"Waiting for Ethernet link to be established...");
link_up = (xEventGroupWaitBits(ethernet_event_group, LINK_UP_BIT,pdFALSE, pdTRUE, max_wait_ms / portTICK_PERIOD_MS)& LINK_UP_BIT)!=0;
if(!link_up){
ESP_LOGW(TAG,"Ethernet Link timeout.");
}
else
{
ESP_LOGI(TAG,"Ethernet Link Up!");
}
}
return link_up;
}
static void ETH_Timeout(void* timer_id);
void destroy_network_ethernet() {
}
static void network_ethernet_print_config(const eth_config_t* eth_config) {
ESP_LOGI(TAG,"Ethernet config => model: %s, valid: %s, type: %s, mdc:%d, mdio:%d, rst:%d, intr:%d, cs:%d, speed:%d, host:%d",
eth_config->model, eth_config->valid ? "YES" : "NO", eth_config->spi ? "SPI" : "RMII",
eth_config->mdc, eth_config->mdio,
eth_config->rst, eth_config->intr, eth_config->cs, eth_config->speed, eth_config->host);
}
void init_network_ethernet() {
esp_err_t err = ESP_OK;
eth_config_t eth;
ESP_LOGI(TAG, "Attempting to initialize Ethernet");
config_eth_init(&eth);
if(!eth.valid){
ESP_LOGI(TAG,"No Ethernet configuration, or configuration invalid");
return;
}
network_driver->init_config(&eth);
network_ethernet_print_config(&eth);
eth_netif = esp_netif_new(network_driver->cfg_netif);
esp_eth_set_default_handlers(eth_netif);
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL);
ethernet_event_group = xEventGroupCreate();
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
spi_device_handle_t spi_handle = NULL;
if (network_driver->spi) {
err = spi_bus_add_device(eth.host, network_driver->devcfg, &spi_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "SPI host failed : %s", esp_err_to_name(err));
}
}
if (err == ESP_OK) {
err = network_driver->start(spi_handle,&eth);
}
if(err == ESP_OK){
uint8_t mac_address[6];
esp_read_mac(mac_address,ESP_MAC_ETH);
char * mac_string=network_manager_alloc_get_mac_string(mac_address);
ESP_LOGD(TAG,"Assigning mac address %s to ethernet interface", STR_OR_BLANK(mac_string));
FREE_AND_NULL(mac_string);
esp_eth_ioctl(network_driver->handle, ETH_CMD_S_MAC_ADDR, mac_address);
}
if (err == ESP_OK) {
ESP_LOGD(TAG, "Attaching ethernet to network interface");
err = esp_netif_attach(eth_netif, esp_eth_new_netif_glue(network_driver->handle));
}
if (err == ESP_OK) {
ESP_LOGI(TAG, "Starting ethernet network");
err = esp_eth_start(network_driver->handle);
}
if (err != ESP_OK) {
messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Configuring Ethernet failed: %s", esp_err_to_name(err));
if(spi_handle) {
spi_bus_remove_device(spi_handle);
}
network_driver->handle = NULL;
}
}
void network_ethernet_start_timer() {
ETH_timer = xTimerCreate("ETH check", pdMS_TO_TICKS(ETH_TIMEOUT_MS), pdFALSE, NULL, ETH_Timeout);
}
/** Event handler for Ethernet events */
static void eth_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
uint8_t mac_addr[6] = {0};
/* we can get the ethernet driver handle from event data */
if (event_base == ETH_EVENT) {
esp_eth_handle_t eth_handle = *(esp_eth_handle_t*)event_data;
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
xEventGroupSetBits(ethernet_event_group, LINK_UP_BIT);
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "Ethernet Link Up, HW Addr %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
network_async_link_up();
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
xEventGroupClearBits(ethernet_event_group, LINK_UP_BIT);
network_async_link_down();
break;
case ETHERNET_EVENT_START:
ESP_LOGI(TAG, "Ethernet Started. Setting host name");
network_set_hostname(eth_netif);
network_async_success();
break;
case ETHERNET_EVENT_STOP:
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}
}
static void ETH_Timeout(void* timer_id) {
network_async_fail();
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "network_manager.h"
#include "accessors.h"
#include <string.h>
#include "esp_netif_defaults.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
bool valid;
bool rmii;
bool spi;
esp_eth_handle_t handle;
esp_netif_config_t * cfg_netif;
spi_device_interface_config_t * devcfg;
// This function is called when the network interface is started
// and performs any initialization that requires a valid ethernet
// configuration .
void (*init_config)(eth_config_t * eth_config);
esp_err_t (*start)(spi_device_handle_t spi_handle,eth_config_t *ethernet_config);
} network_ethernet_driver_t;
typedef network_ethernet_driver_t* network_ethernet_detect_func_t(const char* Driver);
network_ethernet_driver_t* network_ethernet_driver_autodetect(const char* Driver);
void destroy_network_ethernet();
void init_network_ethernet();
bool network_ethernet_wait_for_link(uint16_t max_wait_ms);
void network_ethernet_start_timer();
bool network_ethernet_is_up();
bool network_ethernet_enabled();
esp_netif_t *network_ethernet_get_interface();
#ifdef __cplusplus
}
#endif
+750
View File
@@ -0,0 +1,750 @@
/*
Copyright (c) 2017-2021 Sebastien L
*/
#ifdef NETWORK_MANAGER_LOG_LEVEL
#define LOG_LOCAL_LEVEL NETWORK_MANAGER_LOG_LEVEL
#endif
#include "network_manager.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "network_ethernet.h"
#include "network_status.h"
#include "network_wifi.h"
#include "dns_server.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "platform_esp32.h"
#include "esp_netif.h"
#include "freertos/task.h"
#include "cJSON.h"
#include "cmd_system.h"
#include "esp_app_format.h"
#include "esp_event.h"
#include "esp_ota_ops.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "lwip/api.h"
#include "lwip/err.h"
#include "lwip/ip4_addr.h"
#include "lwip/netdb.h"
#include "mdns.h"
#include "messaging.h"
#include "platform_config.h"
#include "tools.h"
#include "trace.h"
#include "accessors.h"
#include "esp_err.h"
#include "http_server_handlers.h"
#include "network_manager.h"
QueueHandle_t network_queue;
BaseType_t network_task_handle;
static const char TAG[] = "network";
static TaskHandle_t task_network_manager = NULL;
RTC_NOINIT_ATTR static bool s_wifi_prioritized;
extern esp_reset_reason_t xReason;
typedef struct network_callback {
network_status_reached_cb cb;
nm_state_t state;
int sub_state;
const char* from;
SLIST_ENTRY(network_callback)
next; //!< next callback
} network_callback_t;
/** linked list of command structures */
static SLIST_HEAD(cb_list, network_callback) s_cb_list;
network_t NM;
//! Create and initialize the array of state machines.
state_machine_t* const SM[] = {(state_machine_t*)&NM};
static void network_timer_cb(void* timer_id);
int get_root_id(const state_t * state);
const state_t* get_root( const state_t* const state);
static void network_task(void* pvParameters);
void network_start_stop_dhcp_client(esp_netif_t* netif, bool start) {
tcpip_adapter_dhcp_status_t status;
esp_err_t err = ESP_OK;
ESP_LOGD(TAG, "Checking if DHCP client for STA interface is running");
if (!netif) {
ESP_LOGE(TAG, "Invalid adapter. Cannot start/stop dhcp. ");
return;
}
if((err=esp_netif_dhcpc_get_status(netif, &status))!=ESP_OK){
ESP_LOGE(TAG,"Error retrieving dhcp status : %s", esp_err_to_name(err));
return;
}
switch (status)
{
case ESP_NETIF_DHCP_STARTED:
if(start){
ESP_LOGD(TAG, "DHCP client already started");
}
else {
ESP_LOGI(TAG, "Stopping DHCP client");
err = esp_netif_dhcpc_stop(netif);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Error stopping DHCP Client : %s",esp_err_to_name(err));
}
}
break;
case ESP_NETIF_DHCP_STOPPED:
if(start){
ESP_LOGI(TAG, "Starting DHCP client");
err = esp_netif_dhcpc_start(netif);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Error stopping DHCP Client : %s",esp_err_to_name(err));
}
}
else {
ESP_LOGI(TAG, "DHCP client already started");
}
break;
case ESP_NETIF_DHCP_INIT:
if(start){
ESP_LOGI(TAG, "Starting DHCP client");
err = esp_netif_dhcpc_start(netif);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Error stopping DHCP Client : %s",esp_err_to_name(err));
}
}
else {
ESP_LOGI(TAG, "Stopping DHCP client");
err = esp_netif_dhcpc_stop(netif);
if(err!=ESP_OK){
ESP_LOGE(TAG,"Error stopping DHCP Client : %s",esp_err_to_name(err));
}
}
break;
default:
ESP_LOGW(TAG,"Unknown DHCP status");
break;
}
}
void network_start_stop_dhcps(esp_netif_t* netif, bool start) {
tcpip_adapter_dhcp_status_t status;
esp_err_t err = ESP_OK;
ESP_LOGD(TAG, "Checking if DHCP server is running");
if (!netif) {
ESP_LOGE(TAG, "Invalid adapter. Cannot start/stop dhcp server. ");
return;
}
if((err=esp_netif_dhcps_get_status(netif, &status))!=ESP_OK){
ESP_LOGE(TAG,"Error retrieving dhcp server status : %s", esp_err_to_name(err));
return;
}
switch (status)
{
case ESP_NETIF_DHCP_STARTED:
if(start){
ESP_LOGD(TAG, "DHCP server already started");
}
else {
ESP_LOGI(TAG, "Stopping DHCP server");
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif));
}
break;
case ESP_NETIF_DHCP_STOPPED:
if(start){
ESP_LOGI(TAG, "Starting DHCP server");
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(netif));
}
else {
ESP_LOGI(TAG, "DHCP server already stopped");
}
break;
case ESP_NETIF_DHCP_INIT:
if(start){
ESP_LOGI(TAG, "Starting DHCP server");
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(netif));
}
else {
ESP_LOGI(TAG, "Stopping DHCP server");
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif));
}
break;
default:
ESP_LOGW(TAG,"Unknown DHCP status");
break;
}
}
/*********************************************************************************************
* String conversion routines
*/
#define ADD_ROOT(name,...) CASE_TO_STR(name);
#define ADD_ROOT_LEAF(name,...) CASE_TO_STR(name);
#define ADD_LEAF(name,...) CASE_TO_STR(name);
#define ADD_EVENT(name) CASE_TO_STR(name);
#define ADD_FIRST_EVENT(name) CASE_TO_STR(name);
static const char* state_to_string(const state_t * state) {
if(!state) {
return "";
}
switch (state->Parent?state->Parent->Id:state->Id) {
ALL_NM_STATE
default:
break;
}
return "Unknown";
}
static const char* wifi_state_to_string(mn_wifi_active_state_t state) {
switch (state) {
ALL_WIFI_STATE(,)
default:
break;
}
return "Unknown";
}
static const char* eth_state_to_string(mn_eth_active_state_t state) {
switch (state) {
ALL_ETH_STATE(,)
default:
break;
}
return "Unknown";
}
static const char* wifi_configuring_state_to_string(mn_wifi_configuring_state_t state) {
switch (state) {
ALL_WIFI_CONFIGURING_STATE(,)
default:
break;
}
return "Unknown";
}
static const char* sub_state_to_string(const state_t * state) {
if(!state) {
return "N/A";
}
int root_id = get_root_id(state);
switch (root_id)
{
case NETWORK_ETH_ACTIVE_STATE:
return eth_state_to_string(state->Id);
break;
case NETWORK_WIFI_ACTIVE_STATE:
return wifi_state_to_string(state->Id);
case NETWORK_WIFI_CONFIGURING_ACTIVE_STATE:
return wifi_configuring_state_to_string(state->Id);
default:
break;
}
return "*";
}
static const char* event_to_string(network_event_t state) {
switch (state) {
ALL_NM_EVENTS
default:
break;
}
return "Unknown";
}
#undef ADD_EVENT
#undef ADD_FIRST_EVENT
#undef ADD_ROOT
#undef ADD_ROOT_LEAF
#undef ADD_LEAF
typedef struct {
int parent_state;
int sub_state_last ;
} max_sub_states_t;
static const max_sub_states_t state_max[] = {
{ .parent_state = NETWORK_INSTANTIATED_STATE, .sub_state_last = 0 },
{.parent_state = NETWORK_ETH_ACTIVE_STATE, .sub_state_last = TOTAL_ETH_ACTIVE_STATE-1 },
{.parent_state = NETWORK_WIFI_ACTIVE_STATE, .sub_state_last = TOTAL_WIFI_ACTIVE_STATE-1 },
{.parent_state = WIFI_CONFIGURING_STATE, .sub_state_last = TOTAL_WIFI_CONFIGURING_STATE-1 },
{.parent_state = WIFI_CONFIGURING_STATE, .sub_state_last = TOTAL_WIFI_CONFIGURING_STATE-1 },
{.parent_state =-1}
};
void network_start() {
if(cold_boot){
ESP_LOGI(TAG, "Setting wifi priotitized flag to false");
s_wifi_prioritized = false;
}
ESP_LOGD(TAG, " Creating message queue");
network_queue = xQueueCreate(3, sizeof(queue_message));
ESP_LOGD(TAG, " Creating network manager task");
network_task_handle = xTaskCreate(&network_task, "network", 4096, NULL, WIFI_MANAGER_TASK_PRIORITY, &task_network_manager);
}
static void event_logger(uint32_t state_machine, uint32_t state, uint32_t event) {
ESP_LOGD(TAG, "Handling network manager event state Id %d->[%s]", state, event_to_string(event));
}
static const char * get_state_machine_result_string(state_machine_result_t result) {
switch(result) {
case EVENT_HANDLED:
return "EVENT_HANDLED";
case EVENT_UN_HANDLED:
return "EVENT_UN_HANDLED";
case TRIGGERED_TO_SELF:
return "TRIGGERED_TO_SELF";
}
return "Unknown";
}
static void result_logger(uint32_t state, state_machine_result_t result) {
ESP_LOGD(TAG, "Network Manager Result: %s, New State id: %d", get_state_machine_result_string(result) , state);
}
static void network_task(void* pvParameters) {
queue_message msg;
BaseType_t xStatus;
initialize_network_handlers((state_machine_t*)&NM);
network_async(EN_START);
/* main processing loop */
for (;;) {
xStatus = xQueueReceive(network_queue, &msg, portMAX_DELAY);
if (xStatus == pdPASS) {
// pass the event to the sync processor
NM.event_parameters = &msg;
NM.Machine.Event = msg.trigger;
if (dispatch_event(SM, 1, event_logger, result_logger) == EVENT_UN_HANDLED) {
network_manager_format_from_to_states(ESP_LOG_ERROR,"Unhandled Event",NULL,NM.Machine.State,msg.trigger,false,"network manager");
}
} /* end of if status=pdPASS */
} /* end of for loop */
vTaskDelete(NULL);
}
int get_max_substate(nm_state_t state){
for(int i=0;state_max[i].parent_state!=-1;i++){
if(state_max[i].parent_state == state){
return state_max[i].sub_state_last;
}
}
return -1;
}
esp_err_t network_register_state_callback(nm_state_t state,int sub_state, const char* from, network_status_reached_cb cb) {
network_callback_t* item = NULL;
if (!cb) {
return ESP_ERR_INVALID_ARG;
}
item = calloc(1, sizeof(*item));
if (item == NULL) {
return ESP_ERR_NO_MEM;
}
if(sub_state != -1 && sub_state>get_max_substate(state)){
// sub state has to be valid
return ESP_ERR_INVALID_ARG;
}
item->state = state;
item->cb = cb;
item->from = from;
item->sub_state=sub_state;
network_callback_t* last = SLIST_FIRST(&s_cb_list);
if (last == NULL) {
SLIST_INSERT_HEAD(&s_cb_list, item, next);
} else {
network_callback_t* it;
while ((it = SLIST_NEXT(last, next)) != NULL) {
last = it;
}
SLIST_INSERT_AFTER(last, item, next);
}
return ESP_OK;
}
const state_t* get_root( const state_t* const state){
if(!state) return NULL;
return state->Parent==NULL?state: get_root(state->Parent);
}
int get_root_id(const state_t * state){
if(!state) return -1;
return state->Parent==NULL?state->Id: get_root_id(state->Parent);
}
static bool is_root_state(const state_t * state){
return state->Parent==NULL;
}
static bool is_current_state(const state_t* state, nm_state_t state_id, int sub_state_id){
return get_root(state)->Id == state_id && (sub_state_id==-1 || (!is_root_state(state) && state->Id == sub_state_id) );
}
void network_execute_cb(state_machine_t* const state_machine, const char * caller) {
network_callback_t* it;
SLIST_FOREACH(it, &s_cb_list, next) {
if (is_current_state(state_machine->State,it->state, it->sub_state)) {
char * cb_prefix= messaging_alloc_format_string("BEGIN Executing Callback %s", it->from) ;
NETWORK_DEBUG_STATE_MACHINE(true,STR_OR_BLANK(cb_prefix),state_machine,false, STR_OR_BLANK(caller));
FREE_AND_NULL(cb_prefix);
it->cb((nm_state_t)get_root(state_machine->State)->Id, is_root_state(state_machine->State)?-1:state_machine->State->Id);
cb_prefix= messaging_alloc_format_string("END Executing Callback %s", it->from) ;
NETWORK_DEBUG_STATE_MACHINE(false,STR_OR_BLANK(cb_prefix),state_machine,false, STR_OR_BLANK(caller));
FREE_AND_NULL(cb_prefix);
}
}
}
bool network_is_wifi_prioritized() {
eth_config_t eth_config;
config_eth_init(&eth_config);
// char* prioritize = (char*)config_alloc_get_default(NVS_TYPE_STR, "prio_wifi", "N", 0);
// bool result = strcasecmp("N", prioritize);
bool result = s_wifi_prioritized;
if(result){
result = network_wifi_get_known_count()>0 || !eth_config.valid;
ESP_LOGD(TAG,"Wifi is prioritized with %d known access points.%s %s",network_wifi_get_known_count(),eth_config.valid?" And a valid ethernet adapter":"",result?"Wifi prioritized":"Ethernet prioritized");
}
return result;
}
void network_prioritize_wifi(bool activate) {
if(s_wifi_prioritized == activate) return;
s_wifi_prioritized = activate;
ESP_LOGI(TAG,"Wifi is %s prioritized",activate?"":"not");
// if (network_is_wifi_prioritized() != activate) {
// ESP_LOGW(TAG, "Wifi will %s be prioritized on next boot", activate ? "" : "NOT");
// config_set_value(NVS_TYPE_STR, "prio_wifi", activate ? "Y" : "N");
// }
}
void network_manager_format_state_machine(esp_log_level_t level, const char* prefix, state_machine_t* state_machine, bool show_source, const char * caller) {
state_t const* source_state = NULL;
state_t const* current_state = NULL;
network_event_t event = -1;
MEMTRACE_PRINT_DELTA();
if (state_machine) {
source_state = ((network_t *)state_machine)->source_state;
current_state = state_machine->State;
event = state_machine->Event;
network_manager_format_from_to_states(level, prefix, source_state, current_state, event, show_source,caller);
}
else {
ESP_LOG_LEVEL(level, TAG, "%s - %s -> [%s]",
STR_OR_BLANK(caller),
prefix,
event_to_string(event));
}
}
void network_manager_format_from_to_states(esp_log_level_t level, const char* prefix, const state_t * from_state,const state_t * current_state, network_event_t event,bool show_source, const char * caller) {
const char* source_state = "";
const char* source_sub_state = "";
const char* state = "N/A";
const char* sub_state = "N/A";
if (current_state) {
state = state_to_string(current_state);
sub_state = sub_state_to_string(current_state);
}
if (!from_state) {
source_state = "N/A";
} else {
source_state = state_to_string(from_state);
source_sub_state = sub_state_to_string(from_state);
}
if (show_source) {
ESP_LOG_LEVEL(level, TAG, "%s %s %s(%s)->%s(%s) [%s]",
STR_OR_BLANK(caller),
prefix,
source_state,
source_sub_state,
state,
sub_state,
event_to_string(event));
} else {
ESP_LOG_LEVEL(level, TAG, "%s %s %s(%s) [%s]",
STR_OR_BLANK(caller),
prefix,
state,
sub_state,
event_to_string(event));
}
}
void network_async(network_event_t trigger) {
queue_message msg;
memset(&msg,0x00,sizeof(msg));
msg.trigger = trigger;
ESP_LOGD(TAG, "Posting event %s directly", event_to_string(trigger));
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
}
void network_async_fail() {
network_async(EN_FAIL);
}
void network_async_success() {
network_async(EN_SUCCESS);
}
void network_async_connected(){
network_async(EN_CONNECTED);
}
void network_async_link_up() {
network_async(EN_LINK_UP);
}
void network_async_link_down() {
network_async(EN_LINK_DOWN);
}
void network_async_configure() {
network_async(EN_CONFIGURE);
}
void network_async_got_ip() {
network_async(EN_GOT_IP);
}
void network_async_eth_got_ip() {
network_async(EN_ETH_GOT_IP);
}
void network_async_timer() {
network_async(EN_TIMER);
}
void network_async_start() {
network_async(EN_START);
}
void network_async_scan() {
network_async(EN_SCAN);
}
void network_async_update_status() {
network_async(EN_UPDATE_STATUS);
}
void network_async_delete() {
network_async(EN_DELETE);
}
void network_async_scan_done() {
network_async(EN_SCAN_DONE);
}
void network_async_connect(const char * ssid, const char * password) {
queue_message msg;
memset(&msg,0x00,sizeof(msg));
msg.trigger = EN_CONNECT_NEW;
msg.ssid = strdup_psram(ssid);
if(password && strlen(password) >0){
msg.password = strdup_psram(password);
}
ESP_LOGD(TAG, "Posting event %s", event_to_string(msg.trigger));
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
}
void network_async_lost_connection(wifi_event_sta_disconnected_t* disconnected_event) {
queue_message msg;
memset(&msg,0x00,sizeof(msg));
msg.trigger = EN_LOST_CONNECTION;
ESP_LOGD(TAG, "Posting event %s", event_to_string(msg.trigger));
msg.disconnected_event = clone_obj_psram(disconnected_event,sizeof(wifi_event_sta_disconnected_t));
if(msg.disconnected_event){
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
}
else {
ESP_LOGE(TAG,"Unable to post lost connection event.");
}
}
void network_async_reboot(reboot_type_t rtype) {
queue_message msg;
memset(&msg,0x00,sizeof(msg));
msg.trigger = EN_REBOOT;
msg.rtype = rtype;
ESP_LOGD(TAG, "Posting event %s - type %d", event_to_string(msg.trigger),rtype);
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
}
void network_reboot_ota(char* url) {
queue_message msg;
memset(&msg,0x00,sizeof(msg));
if (url == NULL) {
msg.trigger = EN_REBOOT;
msg.rtype = OTA;
ESP_LOGD(TAG, "Posting event %s - type %d", event_to_string(msg.trigger),msg.rtype);
} else {
msg.trigger = EN_REBOOT_URL;
ESP_LOGD(TAG, "Posting event %s - type reboot URL", event_to_string(msg.trigger));
msg.strval = strdup_psram(url);
}
xQueueSendToBack(network_queue, &msg, portMAX_DELAY);
}
network_t* network_get_state_machine() {
return &NM;
}
static void network_timer_cb(void* timer_id) {
network_async_timer();
}
esp_netif_t* network_get_active_interface() {
if (NM.wifi_ap_netif && (network_wifi_is_ap_mode() || network_wifi_is_ap_sta_mode())) {
return NM.wifi_ap_netif;
} else if (NM.wifi_netif && network_wifi_is_sta_mode()) {
return NM.wifi_netif;
}
return NM.eth_netif;
}
bool network_is_interface_connected(esp_netif_t* interface) {
esp_err_t err = ESP_OK;
tcpip_adapter_ip_info_t ipInfo;
if(!interface){
return false;
}
err = network_get_ip_info_for_netif(interface, &ipInfo);
if(err != ESP_OK){
ESP_LOGD(TAG,"network_get_ip_info_for_netif returned %s", esp_err_to_name(err));
}
return ((err == ESP_OK) && (ipInfo.ip.addr != IPADDR_ANY));
}
static esp_netif_t* get_connected_interface() {
esp_netif_t* interface = NULL;
for (int i = 0; i < 4; i++) {
switch (i) {
case 0:
// try the active interface
interface = network_get_active_interface();
break;
case 1:
interface = NM.wifi_ap_netif;
break;
case 2:
interface = NM.wifi_netif;
break;
case 3:
interface = NM.eth_netif;
break;
default:
break;
}
if (interface && network_is_interface_connected(interface)) {
ESP_LOGD(TAG,"Found connected interface in iteration #%d",i);
return interface;
}
}
ESP_LOGD(TAG,"No connected interface found");
return NULL;
}
esp_err_t network_get_ip_info_for_netif(esp_netif_t* netif, tcpip_adapter_ip_info_t* ipInfo) {
esp_netif_ip_info_t loc_ip_info;
if (!ipInfo ) {
ESP_LOGE(TAG, "Invalid pointer for ipInfo");
return ESP_ERR_INVALID_ARG;
}
if (!netif) {
ESP_LOGE(TAG, "Invalid pointer for netif");
return ESP_ERR_INVALID_ARG;
}
memset(ipInfo,0x00,sizeof(tcpip_adapter_ip_info_t));
esp_err_t err= esp_netif_get_ip_info(netif, &loc_ip_info);
if(err==ESP_OK){
ip4_addr_set(&(ipInfo->ip),&loc_ip_info.ip);
ip4_addr_set(&(ipInfo->gw),&loc_ip_info.gw);
ip4_addr_set(&(ipInfo->netmask),&loc_ip_info.netmask);
}
return err;
}
esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo) {
esp_netif_t* netif= get_connected_interface();
if(netif){
return network_get_ip_info_for_netif(netif,ipInfo);
}
return ESP_FAIL;
}
esp_err_t network_get_hostname(const char** hostname) {
return esp_netif_get_hostname(get_connected_interface(), hostname);
}
void network_set_timer(uint16_t duration, const char * tag) {
if (duration > 0) {
if(tag){
ESP_LOGD(TAG, "Setting timer tag to %s", tag);
NM.timer_tag = strdup_psram(tag);
}
if (!NM.state_timer) {
ESP_LOGD(TAG, "Starting %s timer with period of %u ms.", STR_OR_ALT(NM.timer_tag,"anonymous"), duration);
NM.state_timer = xTimerCreate("background STA", pdMS_TO_TICKS(duration), pdFALSE, NULL, network_timer_cb);
} else {
ESP_LOGD(TAG, "Changing %s timer period to %u ms.", STR_OR_ALT(NM.timer_tag,"anonymous"),duration);
xTimerChangePeriod(NM.state_timer, pdMS_TO_TICKS(duration), portMAX_DELAY);
}
xTimerStart(NM.state_timer, portMAX_DELAY);
} else if (NM.state_timer) {
ESP_LOGD(TAG,"Stopping timer %s",STR_OR_ALT(NM.timer_tag,"anonymous"));
xTimerStop(NM.state_timer, portMAX_DELAY);
FREE_AND_NULL(NM.timer_tag);
}
}
void network_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
ip_event_got_ip_t* s = NULL;
esp_netif_ip_info_t* ip_info = NULL;
if (event_base != IP_EVENT)
return;
switch (event_id) {
case IP_EVENT_ETH_GOT_IP:
case IP_EVENT_STA_GOT_IP:
s = (ip_event_got_ip_t*)event_data;
ip_info = &s->ip_info;
ESP_LOGI(TAG, "Got an IP address from interface %s. IP=" IPSTR ", Gateway=" IPSTR ", NetMask=" IPSTR ", %s",
event_id == IP_EVENT_ETH_GOT_IP ? "Eth" : event_id == IP_EVENT_STA_GOT_IP ? "Wifi"
: "Unknown",
IP2STR(&ip_info->ip),
IP2STR(&ip_info->gw),
IP2STR(&ip_info->netmask),
s->ip_changed ? "Address was changed" : "Address unchanged");
network_async(event_id == IP_EVENT_ETH_GOT_IP ? EN_ETH_GOT_IP : EN_GOT_IP);
break;
case IP_EVENT_STA_LOST_IP:
ESP_LOGD(TAG, "IP_EVENT_STA_LOST_IP");
break;
case IP_EVENT_AP_STAIPASSIGNED:
ESP_LOGD(TAG, "IP_EVENT_AP_STAIPASSIGNED");
break;
case IP_EVENT_GOT_IP6:
ESP_LOGD(TAG, "IP_EVENT_GOT_IP6");
break;
default:
break;
}
}
void network_set_hostname(esp_netif_t* interface) {
esp_err_t err;
ESP_LOGD(TAG, "Retrieving host name from nvs");
char* host_name = (char*)config_alloc_get(NVS_TYPE_STR, "host_name");
if (host_name == NULL) {
ESP_LOGE(TAG, "Could not retrieve host name from nvs");
} else {
ESP_LOGD(TAG, "Setting host name to : %s", host_name);
if ((err = esp_netif_set_hostname(interface, host_name)) != ESP_OK) {
ESP_LOGE(TAG, "Unable to set host name. Error: %s", esp_err_to_name(err));
}
free(host_name);
}
}
#define LOCAL_MAC_SIZE 20
char* network_manager_alloc_get_mac_string(uint8_t mac[6]) {
char* macStr = malloc_init_external(LOCAL_MAC_SIZE);
if(macStr){
snprintf(macStr, LOCAL_MAC_SIZE, MACSTR, MAC2STR(mac));
}
return macStr;
}
+364
View File
@@ -0,0 +1,364 @@
#pragma once
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "squeezelite-ota.h"
#include "cJSON.h"
#include "esp_eth.h"
#include "freertos/event_groups.h"
#include "hsm.h"
#include "esp_log.h"
#include "network_services.h"
#ifdef __cplusplus
extern "C" {
#endif
//! List of oven events
#define ALL_NM_EVENTS \
ADD_FIRST_EVENT(EN_LINK_UP) \
ADD_EVENT(EN_LINK_DOWN)\
ADD_EVENT(EN_CONFIGURE)\
ADD_EVENT(EN_GOT_IP)\
ADD_EVENT(EN_ETH_GOT_IP)\
ADD_EVENT(EN_DELETE)\
ADD_EVENT(EN_TIMER)\
ADD_EVENT(EN_START)\
ADD_EVENT(EN_SCAN)\
ADD_EVENT(EN_FAIL)\
ADD_EVENT(EN_SUCCESS)\
ADD_EVENT(EN_SCAN_DONE)\
ADD_EVENT(EN_CONNECT)\
ADD_EVENT(EN_CONNECT_NEW)\
ADD_EVENT(EN_REBOOT)\
ADD_EVENT(EN_REBOOT_URL)\
ADD_EVENT(EN_LOST_CONNECTION)\
ADD_EVENT(EN_ETHERNET_FALLBACK)\
ADD_EVENT(EN_UPDATE_STATUS)\
ADD_EVENT(EN_CONNECTED)
#define ADD_EVENT(name) name,
#define ADD_FIRST_EVENT(name) name=1,
typedef enum {
ALL_NM_EVENTS
} network_event_t;
#undef ADD_EVENT
#undef ADD_FIRST_EVENT
typedef enum {
OTA,
RECOVERY,
RESTART,
} reboot_type_t;
typedef struct {
network_event_t trigger;
char * ssid;
char * password;
reboot_type_t rtype;
char* strval;
wifi_event_sta_disconnected_t* disconnected_event;
esp_netif_t *netif;
} queue_message;
typedef struct
{
state_machine_t Machine; //!< Abstract state machine
const state_t* source_state;
bool ethernet_connected;
TimerHandle_t state_timer;
uint32_t STA_duration;
int32_t total_connected_time;
int64_t last_connected;
uint16_t num_disconnect;
uint16_t retries;
bool wifi_connected;
esp_netif_t *wifi_netif;
esp_netif_t *eth_netif;
esp_netif_t *wifi_ap_netif;
uint16_t sta_polling_min_ms;
uint16_t sta_polling_max_ms;
uint16_t ap_duration_ms;
uint16_t eth_link_down_reboot_ms;
uint16_t dhcp_timeout;
uint16_t wifi_dhcp_fail_ms;
queue_message * event_parameters;
char * timer_tag;
} network_t;
/*
* --------------------- External function prototype ---------------------
*/
void network_start();
network_t * network_get_state_machine();
void network_event_simple(network_event_t trigger);
void network_event(network_event_t trigger, void* param);
void network_async_event(network_event_t trigger, void* param);
void network_async(network_event_t trigger);
void network_async_fail();
void network_async_success();
void network_async_link_up();
void network_async_link_down();
void network_async_configure();
void network_async_got_ip();
void network_async_timer();
void network_async_start();
void network_async_scan();
void network_async_scan_done();
void network_async_connect(const char * ssid, const char * password);
void network_async_lost_connection(wifi_event_sta_disconnected_t * disconnected_event);
void network_async_reboot(reboot_type_t rtype);
void network_reboot_ota(char* url);
void network_async_delete();
void network_async_update_status();
void network_async_eth_got_ip();
void network_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
bool network_is_interface_connected(esp_netif_t * interface);
/*
* --------------------- Inline functions ---------------------
*/
/**
* @brief Defines the maximum size of a SSID name. 32 is IEEE standard.
* @warning limit is also hard coded in wifi_config_t. Never extend this value.
*/
#define MAX_SSID_SIZE 32
/**
* @brief Defines the maximum size of a WPA2 passkey. 64 is IEEE standard.
* @warning limit is also hard coded in wifi_config_t. Never extend this value.
*/
#define MAX_PASSWORD_SIZE 64
#define MAX_COMMAND_LINE_SIZE 201
/**
* @brief Defines the maximum number of access points that can be scanned.
*
* To save memory and avoid nasty out of memory errors,
* we can limit the number of APs detected in a wifi scan.
*/
#define MAX_AP_NUM 15
/**
* @brief Defines when a connection is lost/attempt to connect is made, how many retries should be made before giving up.
* Setting it to 2 for instance means there will be 3 attempts in total (original request + 2 retries)
*/
#define WIFI_MANAGER_MAX_RETRY CONFIG_WIFI_MANAGER_MAX_RETRY
/** @brief Defines the task priority of the wifi_manager.
*
* Tasks spawn by the manager will have a priority of WIFI_MANAGER_TASK_PRIORITY-1.
* For this particular reason, minimum task priority is 1. It it highly not recommended to set
* it to 1 though as the sub-tasks will now have a priority of 0 which is the priority
* of freeRTOS' idle task.
*/
#define WIFI_MANAGER_TASK_PRIORITY CONFIG_WIFI_MANAGER_TASK_PRIORITY
/** @brief Defines the auth mode as an access point
* Value must be of type wifi_auth_mode_t
* @see esp_wifi_types.h
* @warning if set to WIFI_AUTH_OPEN, passowrd me be empty. See DEFAULT_AP_PASSWORD.
*/
#define AP_AUTHMODE WIFI_AUTH_WPA2_PSK
/** @brief Defines visibility of the access point. 0: visible AP. 1: hidden */
#define DEFAULT_AP_SSID_HIDDEN 0
/** @brief Defines access point's name. Default value: esp32. Run 'make menuconfig' to setup your own value or replace here by a string */
#define DEFAULT_AP_SSID CONFIG_DEFAULT_AP_SSID
/** @brief Defines access point's password.
* @warning In the case of an open access point, the password must be a null string "" or "\0" if you want to be verbose but waste one byte.
* In addition, the AP_AUTHMODE must be WIFI_AUTH_OPEN
*/
#define DEFAULT_AP_PASSWORD CONFIG_DEFAULT_AP_PASSWORD
/** @brief Defines access point's bandwidth.
* Value: WIFI_BW_HT20 for 20 MHz or WIFI_BW_HT40 for 40 MHz
* 20 MHz minimize channel interference but is not suitable for
* applications with high data speeds
*/
#define DEFAULT_AP_BANDWIDTH WIFI_BW_HT20
/** @brief Defines access point's channel.
* Channel selection is only effective when not connected to another AP.
* Good practice for minimal channel interference to use
* For 20 MHz: 1, 6 or 11 in USA and 1, 5, 9 or 13 in most parts of the world
* For 40 MHz: 3 in USA and 3 or 11 in most parts of the world
*/
#define DEFAULT_AP_CHANNEL CONFIG_DEFAULT_AP_CHANNEL
/** @brief Defines the access point's default IP address. Default: "10.10.0.1 */
#define DEFAULT_AP_IP CONFIG_DEFAULT_AP_IP
/** @brief Defines the access point's gateway. This should be the same as your IP. Default: "10.10.0.1" */
#define DEFAULT_AP_GATEWAY CONFIG_DEFAULT_AP_GATEWAY
/** @brief Defines the access point's netmask. Default: "255.255.255.0" */
#define DEFAULT_AP_NETMASK CONFIG_DEFAULT_AP_NETMASK
/** @brief Defines access point's maximum number of clients. Default: 4 */
#define DEFAULT_AP_MAX_CONNECTIONS CONFIG_DEFAULT_AP_MAX_CONNECTIONS
/** @brief Defines access point's beacon interval. 100ms is the recommended default. */
#define DEFAULT_AP_BEACON_INTERVAL CONFIG_DEFAULT_AP_BEACON_INTERVAL
/** @brief Defines if esp32 shall run both AP + STA when connected to another AP.
* Value: 0 will have the own AP always on (APSTA mode)
* Value: 1 will turn off own AP when connected to another AP (STA only mode when connected)
* Turning off own AP when connected to another AP minimize channel interference and increase throughput
*/
#define DEFAULT_STA_ONLY 1
/** @brief Defines if wifi power save shall be enabled.
* Value: WIFI_PS_NONE for full power (wifi modem always on)
* Value: WIFI_PS_MODEM for power save (wifi modem sleep periodically)
* Note: Power save is only effective when in STA only mode
*/
#define DEFAULT_STA_POWER_SAVE WIFI_PS_MIN_MODEM
void network_reboot_ota(char * url);
/**
* @brief simplified reason codes for a lost connection.
*
* esp-idf maintains a big list of reason codes which in practice are useless for most typical application.
* UPDATE_CONNECTION_OK - Web UI expects this when attempting to connect to a new access point succeeds
* UPDATE_FAILED_ATTEMPT - Web UI expects this when attempting to connect to a new access point fails
* UPDATE_USER_DISCONNECT = 2,
* UPDATE_LOST_CONNECTION = 3,
* UPDATE_FAILED_ATTEMPT_AND_RESTORE - Web UI expects this when attempting to connect to a new access point fails and previous connection is restored
* UPDATE_ETHERNET_CONNECTED = 5
*/
typedef enum update_reason_code_t {
UPDATE_CONNECTION_OK = 0, // expected when
UPDATE_FAILED_ATTEMPT = 1,
UPDATE_USER_DISCONNECT = 2,
UPDATE_LOST_CONNECTION = 3,
UPDATE_FAILED_ATTEMPT_AND_RESTORE = 4,
UPDATE_ETHERNET_CONNECTED = 5
}update_reason_code_t;
/**
* Frees up all memory allocated by the wifi_manager and kill the task.
*/
void network_destroy();
/**
* Filters the AP scan list to unique SSIDs
*/
void filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num);
char* network_status_alloc_get_ap_list_json();
cJSON * network_manager_clear_ap_list_json(cJSON **old);
/**
* @brief A standard wifi event handler as recommended by Espressif
*/
esp_err_t network_manager_event_handler(void *ctx, system_event_t *event);
/**
* @brief Clears the connection status json.
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
*/
cJSON * network_status_clear_ip_info_json(cJSON **old);
cJSON * network_status_get_new_json(cJSON **old);
/**
* @brief Start the mDNS service
*/
void network_manager_initialise_mdns();
/**
* @brief Register a callback to a custom function when specific network manager states are reached.
*/
bool network_is_wifi_prioritized();
void network_set_timer(uint16_t duration, const char * tag);
void network_set_hostname(esp_netif_t * netif);
esp_err_t network_get_ip_info_for_netif(esp_netif_t* netif, tcpip_adapter_ip_info_t* ipInfo);
void network_start_stop_dhcp_client(esp_netif_t* netif, bool start);
void network_start_stop_dhcps(esp_netif_t* netif, bool start);
void network_prioritize_wifi(bool activate);
#define ADD_ROOT_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
#define ADD_ROOT_LEAF_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
#define ADD_LEAF_FORWARD_DECLARATION(name, ...) ADD_STATE_FORWARD_DECLARATION_(name)
#define ADD_STATE_FORWARD_DECLARATION_(name) \
static state_machine_result_t name##_handler(state_machine_t* const State_Machine); \
static state_machine_result_t name##_entry_handler(state_machine_t* const State_Machine); \
static state_machine_result_t name##_exit_handler(state_machine_t* const State_Machine);
void initialize_network_handlers(state_machine_t* state_machine);
void network_manager_format_from_to_states(esp_log_level_t level, const char* prefix, state_t const * from_state, state_t const* current_state, network_event_t event,bool show_source, const char * caller );
void network_manager_format_state_machine(esp_log_level_t level, const char* prefix, state_machine_t * state_machine, bool show_source, const char * caller) ;
char* network_manager_alloc_get_mac_string(uint8_t mac[6]);
#if defined(LOG_LOCAL_LEVEL)
#if LOG_LOCAL_LEVEL >=5
#define NETWORK_PRINT_TRANSITION(begin, prefix, source,target, event, print_source,caller ) network_manager_format_from_to_states(ESP_LOG_VERBOSE, prefix, source,target, event, print_source,caller )
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller) network_manager_format_state_machine(ESP_LOG_DEBUG,cb_prefix,state_machine,print_from,caller)
#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,__FUNCTION__);
#define network_handler_entry_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"ENTRY START":"ENTRY END",State_Machine,false,__FUNCTION__)
#define network_exit_handler_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"EXIT START":"END END",State_Machine,false,__FUNCTION__)
#define network_handler_print(State_Machine, begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"HANDLER START":"HANDLER END",State_Machine,false,__FUNCTION__)
#elif LOG_LOCAL_LEVEL >= 4
#define network_handler_entry_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"BEGIN ENTRY":"END ENTRY",State_Machine,false,"")
#define network_exit_handler_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"BEGIN EXIT":"END EXIT",State_Machine,false,"")
#define network_handler_print(State_Machine, begin) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,begin?"HANDLER START":"HANDLER END",State_Machine,false,"")
#define NETWORK_PRINT_TRANSITION(begin, prefix, source,target, event, print_source,caller ) if(begin) network_manager_format_from_to_states(ESP_LOG_DEBUG, prefix, source,target, event, print_source,caller )#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,__FUNCTION__);
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller) if(begin) network_manager_format_state_machine(ESP_LOG_DEBUG,cb_prefix,state_machine,print_from,caller)
#endif
#endif
#ifndef NETWORK_PRINT_TRANSITION
#define network_exit_handler_print(nm, begin)
#define network_handler_entry_print(State_Machine, begin)
#define network_handler_print(State_Machine, begin)
#define NETWORK_EXECUTE_CB(mch) network_execute_cb(mch,NULL)
#define NETWORK_PRINT_TRANSITION(begin, prefix, source,target, event, print_source,caller )
#define NETWORK_DEBUG_STATE_MACHINE(begin, cb_prefix,state_machine,print_from,caller)
#endif
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
#pragma once
#include "esp_netif.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ADD_ROOT(name, ...) name,
#define ADD_ROOT_LEAF(name, ...) name,
#define ADD_LEAF(name, ...) name,
#define ALL_NM_STATE \
ADD_ROOT_LEAF(NETWORK_INSTANTIATED_STATE)\
ADD_ROOT_LEAF(NETWORK_INITIALIZING_STATE)\
ADD_ROOT(NETWORK_ETH_ACTIVE_STATE, Eth_Active_State)\
ADD_ROOT(NETWORK_WIFI_ACTIVE_STATE, Wifi_Active_State)\
ADD_ROOT(NETWORK_WIFI_CONFIGURING_ACTIVE_STATE, Wifi_Configuring_State)
#define ALL_ETH_STATE(PARENT, LEVEL)\
ADD_LEAF(ETH_STARTING_STATE,PARENT,LEVEL)\
ADD_LEAF(ETH_ACTIVE_LINKUP_STATE,PARENT,LEVEL)\
ADD_LEAF(ETH_ACTIVE_LINKDOWN_STATE,PARENT,LEVEL)\
ADD_LEAF(ETH_ACTIVE_CONNECTED_STATE,PARENT,LEVEL)\
ADD_LEAF(ETH_CONNECTING_NEW_STATE,PARENT,LEVEL)
#define ALL_WIFI_STATE(PARENT, LEVEL)\
ADD_LEAF(WIFI_INITIALIZING_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONNECTING_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONNECTING_NEW_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONNECTING_NEW_FAILED_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONNECTED_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_USER_DISCONNECTED_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_LOST_CONNECTION_STATE,PARENT,LEVEL)
#define ALL_WIFI_CONFIGURING_STATE(PARENT, LEVEL)\
ADD_LEAF(WIFI_CONFIGURING_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONFIGURING_CONNECT_STATE,PARENT,LEVEL)\
ADD_LEAF(WIFI_CONFIGURING_CONNECT_SUCCESS_STATE,PARENT,LEVEL)
typedef enum {
ALL_NM_STATE
TOTAL_NM_STATE
} nm_state_t;
typedef enum {
ALL_WIFI_STATE(,)
TOTAL_WIFI_ACTIVE_STATE
} mn_wifi_active_state_t;
typedef enum {
ALL_ETH_STATE(,)
TOTAL_ETH_ACTIVE_STATE
} mn_eth_active_state_t;
typedef enum {
ALL_WIFI_CONFIGURING_STATE(,)
TOTAL_WIFI_CONFIGURING_STATE
} mn_wifi_configuring_state_t;
#undef ADD_STATE
#undef ADD_ROOT
#undef ADD_ROOT_LEAF
#undef ADD_LEAF
typedef void (*network_status_reached_cb)(nm_state_t state_id, int sub_state);
esp_err_t network_register_state_callback(nm_state_t state, int sub_state, const char* from, network_status_reached_cb cb);
esp_netif_t * network_get_active_interface();
esp_err_t network_get_hostname(const char **hostname);
esp_err_t network_get_ip_info(tcpip_adapter_ip_info_t* ipInfo);
#ifdef __cplusplus
}
#endif
+349
View File
@@ -0,0 +1,349 @@
#ifdef NETWORK_STATUS_LOG_LEVEL
#define LOG_LOCAL_LEVEL NETWORK_STATUS_LOG_LEVEL
#endif
#include "network_status.h"
#include <string.h>
#ifdef CONFIG_BT_ENABLED
#include "bt_app_core.h"
#endif
#include "esp_log.h"
#include "lwip/inet.h"
#include "monitor.h"
#include "network_ethernet.h"
#include "network_wifi.h"
#include "platform_config.h"
#include "platform_esp32.h"
#include "tools.h"
#include "trace.h"
#ifndef CONFIG_SQUEEZELITE_ESP32_RELEASE_URL
#pragma message "Defaulting release url"
#define CONFIG_SQUEEZELITE_ESP32_RELEASE_URL "https://github.com/sle118/squeezelite-esp32/releases"
#endif
static const char TAG[] = "network_status";
SemaphoreHandle_t network_status_json_mutex = NULL;
static TaskHandle_t network_json_locked_task = NULL;
SemaphoreHandle_t network_status_ip_address_mutex = NULL;
static TaskHandle_t network_status_ip_address_locked_task = NULL;
char* release_url = NULL;
char* network_status_ip_address = NULL;
char* ip_info_json = NULL;
cJSON* ip_info_cjson = NULL;
static char lms_server_ip[IP4ADDR_STRLEN_MAX] = {0};
static uint16_t lms_server_port = 0;
static uint16_t lms_server_cport = 0;
static void (*chained_notify)(in_addr_t, u16_t, u16_t);
static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport);
#define STA_IP_LEN sizeof(char) * IP4ADDR_STRLEN_MAX
void init_network_status() {
chained_notify = server_notify;
server_notify = connect_notify;
ESP_LOGD(TAG, "init_network_status. Creating mutexes");
network_status_json_mutex = xSemaphoreCreateMutex();
network_status_ip_address_mutex = xSemaphoreCreateMutex();
ip_info_json = NULL;
ESP_LOGD(TAG, "init_network_status. Creating status json structure");
ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson);
ESP_LOGD(TAG, "Getting release url ");
char* release_url = (char*)config_alloc_get_default(NVS_TYPE_STR, "release_url", QUOTE(CONFIG_SQUEEZELITE_ESP32_RELEASE_URL), 0);
if (release_url == NULL) {
ESP_LOGE(TAG, "Unable to retrieve the release url from nvs");
} else {
ESP_LOGD(TAG, "Found release url %s", release_url);
}
ESP_LOGD(TAG, "About to set the STA IP String to 0.0.0.0");
network_status_ip_address = (char*)malloc_init_external(STA_IP_LEN);
network_status_safe_update_sta_ip_string(NULL);
}
void destroy_network_status() {
FREE_AND_NULL(release_url);
FREE_AND_NULL(ip_info_json);
FREE_AND_NULL(network_status_ip_address);
cJSON_Delete(ip_info_cjson);
vSemaphoreDelete(network_status_json_mutex);
network_status_json_mutex = NULL;
vSemaphoreDelete(network_status_ip_address_mutex);
network_status_ip_address_mutex = NULL;
ip_info_cjson = NULL;
}
cJSON* network_status_get_new_json(cJSON** old) {
ESP_LOGV(TAG, "network_status_get_new_json called");
cJSON* root = *old;
if (root != NULL) {
cJSON_Delete(root);
*old = NULL;
}
ESP_LOGV(TAG, "network_status_get_new_json done");
return cJSON_CreateObject();
}
cJSON* network_status_clear_ip_info_json(cJSON** old) {
ESP_LOGV(TAG, "network_status_clear_ip_info_json called");
cJSON* root = network_status_get_basic_info(old);
cJSON_DeleteItemFromObjectCaseSensitive(root, "ip");
cJSON_DeleteItemFromObjectCaseSensitive(root, "netmask");
cJSON_DeleteItemFromObjectCaseSensitive(root, "gw");
cJSON_DeleteItemFromObjectCaseSensitive(root, "rssi");
cJSON_DeleteItemFromObjectCaseSensitive(root, "ssid");
cJSON_DeleteItemFromObjectCaseSensitive(root, "eth");
ESP_LOGV(TAG, "network_status_clear_ip_info_json done");
return root;
}
void network_status_clear_ip() {
if (network_status_lock_json_buffer(portMAX_DELAY)) {
ip_info_cjson = network_status_clear_ip_info_json(&ip_info_cjson);
network_status_unlock_json_buffer();
}
}
char* network_status_alloc_get_ip_info_json() {
return cJSON_PrintUnformatted(ip_info_cjson);
}
void network_status_unlock_json_buffer() {
ESP_LOGV(TAG, "Unlocking json buffer!");
network_json_locked_task = NULL;
xSemaphoreGive(network_status_json_mutex);
}
bool network_status_lock_json_buffer(TickType_t xTicksToWait) {
ESP_LOGV(TAG, "Locking json buffer");
TaskHandle_t calling_task = xTaskGetCurrentTaskHandle();
if (calling_task == network_json_locked_task) {
ESP_LOGV(TAG, "json buffer already locked to current task");
return true;
}
if (network_status_json_mutex) {
if (xSemaphoreTake(network_status_json_mutex, xTicksToWait) == pdTRUE) {
ESP_LOGV(TAG, "Json buffer locked!");
network_json_locked_task = calling_task;
return true;
} else {
ESP_LOGE(TAG, "Semaphore take failed. Unable to lock json buffer mutex");
return false;
}
} else {
ESP_LOGV(TAG, "Unable to lock json buffer mutex");
return false;
}
}
bool network_status_lock_sta_ip_string(TickType_t xTicksToWait) {
TaskHandle_t calling_task = xTaskGetCurrentTaskHandle();
if (calling_task == network_status_ip_address_locked_task) {
ESP_LOGD(TAG, "json buffer already locked to current task ");
return true;
}
if (network_status_ip_address_mutex) {
if (xSemaphoreTake(network_status_ip_address_mutex, xTicksToWait) == pdTRUE) {
network_status_ip_address_locked_task = calling_task;
return true;
} else {
return false;
}
} else {
return false;
}
}
void network_status_unlock_sta_ip_string() {
network_status_ip_address_locked_task = NULL;
xSemaphoreGive(network_status_ip_address_mutex);
}
void network_status_safe_update_sta_ip_string(esp_ip4_addr_t* ip4) {
if (network_status_lock_sta_ip_string(portMAX_DELAY)) {
strcpy(network_status_ip_address, ip4 != NULL ? ip4addr_ntoa((ip4_addr_t*)ip4) : "0.0.0.0");
ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address);
network_status_unlock_sta_ip_string();
}
}
void network_status_safe_reset_sta_ip_string() {
if (network_status_lock_sta_ip_string(portMAX_DELAY)) {
strcpy(network_status_ip_address, "0.0.0.0");
ESP_LOGD(TAG, "Set STA IP String to: %s", network_status_ip_address);
network_status_unlock_sta_ip_string();
}
}
char* network_status_get_sta_ip_string() {
return network_status_ip_address;
}
void set_lms_server_details(in_addr_t ip, u16_t hport, u16_t cport) {
strncpy(lms_server_ip, inet_ntoa(ip), sizeof(lms_server_ip));
lms_server_ip[sizeof(lms_server_ip) - 1] = '\0';
ESP_LOGI(TAG, "LMS IP: %s, hport: %d, cport: %d", lms_server_ip, hport, cport);
lms_server_port = hport;
lms_server_cport = cport;
}
static void connect_notify(in_addr_t ip, u16_t hport, u16_t cport) {
set_lms_server_details(ip, hport, cport);
if (chained_notify)
(*chained_notify)(ip, hport, cport);
network_async_update_status();
}
void network_status_update_basic_info() {
// locking happens below this level
network_status_get_basic_info(&ip_info_cjson);
}
cJSON* network_status_update_float(cJSON** root, const char* key, float value) {
if (network_status_lock_json_buffer(portMAX_DELAY)) {
if (*root == NULL) {
*root = cJSON_CreateObject();
}
if (key && strlen(key) != 0) {
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
if (cjsonvalue) {
cJSON_SetNumberValue(cjsonvalue, value);
} else {
cJSON_AddNumberToObject(*root, key, value);
}
}
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
return *root;
}
cJSON* network_status_update_bool(cJSON** root, const char* key, bool value) {
if (network_status_lock_json_buffer(portMAX_DELAY)) {
if (*root == NULL) {
*root = cJSON_CreateObject();
}
if (key && strlen(key) != 0) {
cJSON* cjsonvalue = cJSON_GetObjectItemCaseSensitive(*root, key);
if (cjsonvalue) {
cjsonvalue->type = value ? cJSON_True : cJSON_False;
} else {
cJSON_AddBoolToObject(*root, key, value);
}
}
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
return *root;
}
cJSON * network_update_cjson_string(cJSON** root, const char* key, const char* value){
if (network_status_lock_json_buffer(portMAX_DELAY)) {
cjson_update_string(root, key, value);
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
return *root;
}
cJSON * network_update_cjson_number(cJSON** root, const char* key, int value){
if (network_status_lock_json_buffer(portMAX_DELAY)) {
cjson_update_number(root, key, value);
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
return *root;
}
cJSON* network_status_get_basic_info(cJSON** old) {
if (network_status_lock_json_buffer(portMAX_DELAY)) {
network_t* nm = network_get_state_machine();
monitor_gpio_t* mgpio = get_jack_insertion_gpio();
const esp_app_desc_t* desc = esp_ota_get_app_description();
*old = network_update_cjson_string(old, "project_name", desc->project_name);
#ifdef CONFIG_FW_PLATFORM_NAME
*old = network_update_cjson_string(old, "platform_name", CONFIG_FW_PLATFORM_NAME);
#endif
*old = network_update_cjson_string(old, "version", desc->version);
if (release_url != NULL)
*old = network_update_cjson_string(old, "release_url", release_url);
*old = network_update_cjson_number(old, "recovery", is_recovery_running ? 1 : 0);
*old = network_status_update_bool(old, "Jack", mgpio->gpio >= 0 && jack_inserted_svc());
*old = network_status_update_float(old, "Voltage", battery_value_svc());
*old = network_update_cjson_number(old, "disconnect_count", nm->num_disconnect);
*old = network_status_update_float(old, "avg_conn_time", nm->num_disconnect > 0 ? (nm->total_connected_time / nm->num_disconnect) : 0);
#ifdef CONFIG_BT_ENABLED
*old = network_update_cjson_number(old, "bt_status", bt_app_source_get_a2d_state());
*old = network_update_cjson_number(old, "bt_sub_status", bt_app_source_get_media_state());
#endif
#if DEPTH == 16
*old = network_update_cjson_number(old, "depth", 16);
#elif DEPTH == 32
*old = network_update_cjson_number(old, "depth", 32);
#endif
#if CONFIG_I2C_LOCKED
*old = network_status_update_bool(old, "is_i2c_locked", true);
#else
*old = network_status_update_bool(old, "is_i2c_locked", false);
#endif
if (network_ethernet_enabled()) {
*old = network_status_update_bool(old, "eth_up", network_ethernet_is_up());
}
if (lms_server_cport > 0) {
*old = network_update_cjson_number(old, "lms_cport", lms_server_cport);
}
if (lms_server_port > 0) {
*old = network_update_cjson_number(old, "lms_port", lms_server_port);
}
if (strlen(lms_server_ip) > 0) {
*old = network_update_cjson_string(old, "lms_ip", lms_server_ip);
}
ESP_LOGV(TAG, "network_status_get_basic_info done");
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
return *old;
}
void network_status_update_address(cJSON* root, esp_netif_ip_info_t* ip_info) {
if (!root || !ip_info) {
ESP_LOGE(TAG, "Cannor update IP address. JSON structure or ip_info is null");
return;
}
network_update_cjson_string(&root, "ip", ip4addr_ntoa((ip4_addr_t*)&ip_info->ip));
network_update_cjson_string(&root, "netmask", ip4addr_ntoa((ip4_addr_t*)&ip_info->netmask));
network_update_cjson_string(&root, "gw", ip4addr_ntoa((ip4_addr_t*)&ip_info->gw));
}
void network_status_update_ip_info(update_reason_code_t update_reason_code) {
ESP_LOGV(TAG, "network_status_update_ip_info called");
esp_netif_ip_info_t ip_info;
if (network_status_lock_json_buffer(portMAX_DELAY)) {
/* generate the connection info with success */
ip_info_cjson = network_status_get_basic_info(&ip_info_cjson);
ip_info_cjson = network_update_cjson_number(&ip_info_cjson, "urc", (int)update_reason_code);
ESP_LOGD(TAG,"Updating ip info with reason code %d. Checking if Wifi interface is connected",update_reason_code);
if (network_is_interface_connected(network_wifi_get_interface()) || update_reason_code == UPDATE_FAILED_ATTEMPT ) {
network_update_cjson_string(&ip_info_cjson, "if", "wifi");
esp_netif_get_ip_info(network_wifi_get_interface(), &ip_info);
network_status_update_address(ip_info_cjson, &ip_info);
if (!network_wifi_is_ap_mode()) {
/* wifi is active, and associated to an AP */
wifi_ap_record_t ap;
esp_wifi_sta_get_ap_info(&ap);
network_update_cjson_string(&ip_info_cjson, "ssid", ((char*)ap.ssid));
network_update_cjson_number(&ip_info_cjson, "rssi", ap.rssi);
}
} else {
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "rssi");
cJSON_DeleteItemFromObjectCaseSensitive(ip_info_cjson, "ssid");
}
ESP_LOGD(TAG,"Checking if ethernet interface is connected");
if (network_is_interface_connected(network_ethernet_get_interface())) {
network_update_cjson_string(&ip_info_cjson, "if", "eth");
esp_netif_get_ip_info(network_ethernet_get_interface(), &ip_info);
network_status_update_address(ip_info_cjson, &ip_info);
}
network_status_unlock_json_buffer();
} else {
ESP_LOGW(TAG, "Unable to lock status json buffer. ");
}
ESP_LOGV(TAG, "wifi_status_generate_ip_info_json done");
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include "network_manager.h"
#include "cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif
char* network_status_alloc_get_ip_info_json();
/**
* @brief Tries to get access to json buffer mutex.
*
* The HTTP server can try to access the json to serve clients while the wifi manager thread can try
* to update it. These two tasks are synchronized through a mutex.
*
* The mutex is used by both the access point list json and the connection status json.\n
* These two resources should technically have their own mutex but we lose some flexibility to save
* on memory.
*
* This is a simple wrapper around freeRTOS function xSemaphoreTake.
*
* @param xTicksToWait The time in ticks to wait for the semaphore to become available.
* @return true in success, false otherwise.
*/
bool network_status_lock_json_buffer(TickType_t xTicksToWait);
/**
* @brief Releases the json buffer mutex.
*/
void network_status_unlock_json_buffer();
bool network_status_lock_sta_ip_string(TickType_t xTicksToWait);
void network_status_unlock_sta_ip_string();
/**
* @brief gets the string representation of the STA IP address, e.g.: "192.168.1.69"
*/
char* network_status_get_sta_ip_string();
/**
* @brief thread safe char representation of the STA IP update
*/
void network_status_safe_update_sta_ip_string(esp_ip4_addr_t * ip4);
/**
* @brief Generates the connection status json: ssid and IP addresses.
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
*/
void network_status_update_ip_info(update_reason_code_t update_reason_code);
void init_network_status();
void destroy_network_status();
cJSON* network_status_get_basic_info(cJSON** old);
void network_status_update_basic_info();
void network_status_clear_ip();
void network_status_safe_reset_sta_ip_string();
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
#pragma once
#include "network_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
esp_netif_t * network_wifi_start();
void destroy_network_wifi();
/**
* @brief saves the current STA wifi config to flash ram storage.
*/
esp_err_t network_wifi_save_sta_config();
/**
* @brief fetch a previously STA wifi config in the flash ram storage.
* @return true if a previously saved config was found, false otherwise.
*/
bool network_wifi_load_wifi_sta_config();
/**
* @brief Registers handler for wifi and ip events
*/
void network_wifi_register_handlers();
/**
* @brief Generates the list of access points after a wifi scan.
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
*/
void network_wifi_generate_access_points_json(cJSON ** ap_list);
/**
* @brief Clear the list of access points.
* @note This is not thread-safe and should be called only if network_status_lock_json_buffer call is successful.
*/
void network_wifi_clear_access_points_json();
esp_netif_t * network_wifi_config_ap();
void network_wifi_filter_unique( wifi_ap_record_t * aplist, uint16_t * aps);
esp_err_t wifi_scan_done();
esp_err_t network_wifi_start_scan();
esp_err_t network_wifi_load_restore(queue_message *msg);
esp_err_t network_wifi_order_connect(queue_message *msg);
esp_err_t network_wifi_disconnected(queue_message *msg);
esp_err_t network_wifi_start_ap(queue_message *msg);
bool network_wifi_get_config_for_ssid(wifi_config_t* config, const char * ssid);
esp_err_t network_wifi_handle_event(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
bool is_wifi_up();
wifi_config_t* network_wifi_set_wifi_sta_config(const char * ssid, const char * password) ;
void network_wifi_clear_config();
esp_netif_t *network_wifi_get_interface();
esp_netif_t *network_wifi_get_ap_interface();
bool network_wifi_is_ap_sta_mode();
bool network_wifi_is_sta_mode();
bool network_wifi_is_ap_mode();
bool network_wifi_sta_config_changed();
void network_wifi_global_init();
bool network_wifi_is_known_ap(const char * ssid);
esp_err_t network_wifi_connect(const char * ssid, const char * password);
esp_err_t network_wifi_erase_legacy();
esp_err_t network_wifi_connect_ssid(const char * ssid);
esp_err_t network_wifi_connect_active_ssid();
esp_err_t network_wifi_erase_known_ap();
esp_err_t network_wifi_set_sta_mode();
size_t network_wifi_get_known_count();
size_t network_wifi_get_known_count_in_range();
esp_err_t network_wifi_built_known_ap_list();
esp_err_t network_wifi_connect_next_in_range();
const wifi_sta_config_t* network_wifi_load_active_config();
#ifdef __cplusplus
}
#endif
+13
View File
@@ -0,0 +1,13 @@
{
"presets": [
"@babel/preset-env",
"@babel/typescript"
],
"env": {
"production": {
"presets": [
"minify"
]
}
}
}
File diff suppressed because one or more lines are too long
+27
View File
@@ -0,0 +1,27 @@
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2020,
"ecmaFeatures": {
"modules": true
}
},
"env": {
"browser": true,
"es6": true,
"jquery": true
} ,
"rules": {
"no-tabs": "off",
"semi": 0,
"comma-dangle": 0,
"require-jsdoc": ["off", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": false,
"ClassDeclaration": false
}
}]
}
}
@@ -0,0 +1,18 @@
{
"env": {
"browser": true,
"es6": true,
"jquery": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
}
}
+4
View File
@@ -0,0 +1,4 @@
node_modules
.DS_Store
.idea
package-lock.json
+12
View File
@@ -0,0 +1,12 @@
{
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Debug",
"preLaunchTask": "webpack: dev server",
"sourceMaps": true,
"trace": true
}
]
}
+92
View File
@@ -0,0 +1,92 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"label": "webpack: dev server",
"script": "dev",
"promptOnClose": true,
"isBackground": true,
"problemMatcher": {
"owner": "webpack",
"severity": "error",
"fileLocation": "absolute",
"pattern": [
{
"regexp": "ERROR in (.*)",
"file": 1
},
{
"regexp": "\\((\\d+),(\\d+)\\):(.*)",
"line": 1,
"column": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling\\.\\.\\.",
"endsPattern": "Compiled successfully\\."
}
}
},
{
"type": "npm",
"label": "webpack: prod server",
"script": "prod",
"promptOnClose": true,
"isBackground": true,
"problemMatcher": {
"owner": "webpack",
"severity": "error",
"fileLocation": "absolute",
"pattern": [
{
"regexp": "ERROR in (.*)",
"file": 1
},
{
"regexp": "\\((\\d+),(\\d+)\\):(.*)",
"line": 1,
"column": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling\\.\\.\\.",
"endsPattern": "Compiled successfully\\."
}
}
},
{
"type": "npm",
"label": "webpack: build",
"script": "build",
"promptOnClose": true,
"isBackground": true,
"problemMatcher": {
"owner": "webpack",
"severity": "error",
"fileLocation": "absolute",
"pattern": [
{
"regexp": "ERROR in (.*)",
"file": 1
},
{
"regexp": "\\((\\d+),(\\d+)\\):(.*)",
"line": 1,
"column": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling\\.\\.\\.",
"endsPattern": "Compiled successfully\\."
}
}
}
]
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 AndyKorek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+204
View File
@@ -0,0 +1,204 @@
<h2 align="center">Boilerplate - Bootstrap v4 - SASS - JQuery - WebPack</h2>
<p align="center">
<a href="https://webpack.js.org/"><img alt="Webpack" src="https://img.shields.io/badge/Webpack-4.41.6-%238DD6F9.svg"></a>
<a href="https://babeljs.io/"><img alt="Webpack" src="https://img.shields.io/badge/Babel%2FCore-7.8.4-%23f5da55.svg"></a>
<a href="https://www.npmjs.com/package/gulp-sass"><img alt="node-sass" src="https://img.shields.io/badge/node--sass-v4.13.1-ff69b4.svg"></a>
<a href="https://jquery.com/"><img src="https://img.shields.io/badge/jQuery-3.3.1-blue.svg" alt="jquery"></a>
<a href="https://lodash.com/"><img src="https://img.shields.io/badge/lodash-4.17.15-blue.svg" alt="jquery"></a>
<a href="https://popper.js.org/"><img src="https://img.shields.io/badge/popper.js-2.0.6-blue.svg" alt="popper.js"></a>
<a href="https://eslint.org/"><img src="https://img.shields.io/badge/es--lint-5.15.1-%23463fd4.svg" alt="eslint"></a>
<a href="https://fontawesome.com/"><img alt="Font Awesome" src="https://img.shields.io/badge/Font--Awesome-5.12.1-blue.svg"></a>
<a href="https://icons8.com/line-awesome"><img alt="Line Awesome" src="https://img.shields.io/badge/Line%20Awesome-1.3.0-green"></a>
</p>
![webpack logo](https://abload.de/img/webpack1tkeb.png)
![bootstrap logo](https://abload.de/img/bootstrap-logo-vector78khf.png)
![babel logo](https://abload.de/img/2000px-babel_logo.svgrzkxw.png)
![sass logo](https://abload.de/img/1280px-sass_logo_colo0bjb4.png)
<p align="center">
<em>
SASS
· Babel
· Bootstrap
· JQuery
· PopperJS
· Font Awesome
</em>
</p>
This Webpack4-Sass Boilerplate contains the following features:
- Webpack4 & Dev-Server
- TypeScript 3.7.5
- Babel ES6 Compiler
- Bootstrap v4 - with Theme Support
- Font Awesome v5.7
- Animate.css Library v3.7.2
- JQuery v3.3.1
- PopperJS v2
- _lodash
- concentrate and minify JavaScript.
- Compile, minify, Autoprefix SASS.
- Optimize and Cache Images
- Preconfigured BootsWatch Template (YETI & Slate)
- Linting for your TS, JS and SASS
## Features
### Webpack Loaders & Plugins
This project contains the following loaders & plugins:
- `node-sass` for compiling sass (SCSS)
- `babel-loader` for compiling ES6 code
- `babel-eslint && eslint-loader` for Linting your .js
- `tslint` for Linting your .ts
- `lodash-webpack-plugin` create smaller Lodash builds by replacing feature sets of modules with noop, identity, or simpler alternatives.
- `webpack-dev-server` for serving & Hot-Reloading
- `css-loader` for compressing css
- `sass-loader` for compressing and loading scss & sass
- `url- & file-loader` for loading and optimizing images
- `xml and csv loader` for loading data files
- `html-loader` for loading & optimizing html files
- `clean-webpack-plugin` for keeping your dist folder clean
- `favicons-webpack-plugin` generate favicons form your "logo.png"
## Getting Started
### Dependencies
Make sure these are installed first.
- [Node.js](http://nodejs.org)
- [Webpack](https://webpack.js.org/guides/installation/)
`npm install --g webpack`
<hr/>
### Quick Start
1. Clone the repo :
`git clone https://github.com/AndyKorek/webpack-boilerplate-sass-ts-bootstrap4-fontawesome.git`
2. In bash/terminal/command line, `cd ` into project directory.
3. Run `npm i` to install required dependencies.
4. Run the Dev Server with (with Hot Reloading) `npm run dev`
<hr/>
### Build the Production Folder
`npm run build`
This will:
- Bundle and Minify SASS(scss) to css & Hash and Cash it
- generate GZip and Brodli Compressed Assets
- Bundle and Minify JS
- Optimize Images
- Optimize HTML
- generate Favicons
<hr/>
## Documentation
### Workflow structure
`src` - > source directory
`dist` -> build directory
```
├── src
│ ├── assets
│ │ └── images
│ ├── fonts
│ ├── sass
│ │ ├── layout
| | | └── _features.scss
│ │ ├── setup
| | | └── _normalize.scss
│ │ ├── themes
| | | ├── _slate.scss
| | | └── _yeti.scss
│ │ ├── utils
| | | ├── _mixins.scss
| | | └── _variables.scss
│ │ ├── _globals.scss
│ │ ├── _headings.scss
│ │ ├── _typography.scss
│ │ ├── _vendor.scss
│ │ └── main.scss
│ ├── ts
│ │ ├── custom.ts
│ │ ├── line-awesome.ts
│ │ ├── vendor.ts
│ |── .htaccess
│ |── 404.html
│ |── index.html
│ └── index.ts
├── dist
│ ├── assets
│ │ ├── images
│ │ └──
│ ├── css
│ │ ├── vendors.[contenthash].css
│ │ └── main.contenthash].css
│ ├── js
│ │ ├── main.[contenthash].js
│ │ ├── runtime.[contenthash].js
│ │ └── vendors.[contenthash].js
│ │
│ └── index.html
```
### Loading the Features you need
in `src/js/vendor/_boostrap.js` uncomment all Features you need
put your custom js to `src/js/_custom.js`
<hr/>
### Instructions
- Add `sass`(.scss) files to `src/_scss` folder.
- Make sure you import the scss file in `main.scss`
```
@import "filename";
```
- Add your assets to `src/assets/`
- Add `images` to `src/assets/images`
## TODO list
- [x] Bootstrap 4
- [x] Webpack 4
- [x] Jquery
- [x] PopperJS v2
- [x] Include ES-Lint
- [x] Font-Awesome
- [x] Assets Loader
- [x] Separated location for Bundled Files
- [x] Adding EsLint
- [ ] Code Optimising
- [x] Uglify and Minify JS with Terser
## Licence
Code released under the [MIT License](https://github.com/AndyKorek/webpack4_boilerplate/blob/master/LICENSE).
*</> with* :heart: *from Germany*
@@ -0,0 +1,24 @@
{
"extends": "stylelint-config-standard",
"rules": {
"no-duplicate-selectors": true,
"indentation": null,
"color-hex-case": "lower",
"color-hex-length": "long",
"selector-combinator-space-after": "never",
"declaration-block-trailing-semicolon": "always",
"declaration-colon-space-before": "never",
"declaration-colon-newline-after": null,
"comment-whitespace-inside": "always",
"comment-empty-line-before": null,
"selector-pseudo-class-parentheses-space-inside": "always",
"selector-list-comma-newline-after": null,
"media-feature-range-operator-space-before": "always",
"media-feature-range-operator-space-after": "always",
"media-feature-parentheses-space-inside": "always",
"media-feature-colon-space-before": "always",
"media-feature-colon-space-after": "always",
"no-eol-whitespace": null,
"no-missing-end-of-source-newline": null,
"number-leading-zero": "never" }
}
+3
View File
@@ -0,0 +1,3 @@
[1211/165128.604:ERROR:directory_reader_win.cc(43)] FindFirstFile: Le chemin daccès spécifié est introuvable. (0x3)
[1212/063417.746:ERROR:directory_reader_win.cc(43)] FindFirstFile: Le chemin daccès spécifié est introuvable. (0x3)
[1213/063413.475:ERROR:directory_reader_win.cc(43)] FindFirstFile: Le chemin daccès spécifié est introuvable. (0x3)
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
export {};
File diff suppressed because one or more lines are too long
+4
View File
@@ -0,0 +1,4 @@
import 'bootstrap';
import './sass/main.scss';
import './assets/images/favicon-32x32.png';
import './js/custom.js';
+1
View File
@@ -0,0 +1 @@
export {};
+252
View File
@@ -0,0 +1,252 @@
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare let sd: {};
declare let rf: boolean;
declare function refreshStatus(): void;
+3
View File
@@ -0,0 +1,3 @@
import 'bootstrap';
import './sass/main.scss';
import './js/test.js';
+1
View File
@@ -0,0 +1 @@
export {};
+1
View File
@@ -0,0 +1 @@
export {};
+2
View File
@@ -0,0 +1,2 @@
declare function _exports(env: any, options: any): {};
export = _exports;
@@ -0,0 +1,8 @@
export class BuildEventsHook {
constructor(name: any, fn: any, stage?: string);
name: any;
stage: string;
function: any;
apply(compiler: any): void;
}
export function createBuildEventsHook(options: any): BuildEventsHook;
View File
@@ -0,0 +1,6 @@
export const parser: string;
export const plugins: {
'postcss-import': {};
'postcss-cssnext': {};
cssnano: {};
};
+37
View File
@@ -0,0 +1,37 @@
declare const PORT: 5000;
import HtmlWebPackPlugin = require("html-webpack-plugin");
export namespace entry {
const test: string;
}
export namespace devServer {
export namespace _static {
const directory: string;
const staticOptions: {};
const publicPath: string;
const serveIndex: boolean;
const watch: boolean;
}
export { _static as static };
export namespace devMiddleware {
const publicPath_1: string;
export { publicPath_1 as publicPath };
}
export const open: boolean;
export const compress: boolean;
export { PORT as port };
export const host: string;
export const allowedHosts: string;
export const headers: {
'Access-Control-Allow-Origin': string;
'Accept-Encoding': string;
};
export namespace client {
const logging: string;
const overlay: boolean;
const progress: boolean;
}
export function onListening(devServer: any): void;
export function onBeforeSetupMiddleware(devServer: any): void;
}
export const plugins: HtmlWebPackPlugin[];
export {};
+13
View File
@@ -0,0 +1,13 @@
[
{"ssid":"Pantum-AP-A6D49F","chan":11,"rssi":-55,"auth":4, "known":false},
{"ssid":"a0308","chan":1,"rssi":-56,"auth":3, "known":false},
{"ssid":"dlink-D9D8","chan":11,"rssi":-82,"auth":4, "known":false},
{"ssid":"Linksys06730","chan":7,"rssi":-85,"auth":0, "known":false},
{"ssid":"SINGTEL-5171","chan":9,"rssi":-88,"auth":4, "known":false},
{"ssid":"1126-1","chan":11,"rssi":-89,"auth":4, "known":false},
{"ssid":"The Shah 5GHz-2","chan":1,"rssi":-90,"auth":0, "known":false},
{"ssid":"SINGTEL-1D28 (2G)","chan":11,"rssi":-91,"auth":3, "known":false},
{"ssid":"dlink-F864","chan":1,"rssi":-92,"auth":4, "known":false},
{"ssid":"dlink-74F0","chan":1,"rssi":-93,"auth":4, "known":false},
{"ssid":"MyTestSSID","chan":2,"rssi":-53,"auth":4, "known":true}
]
+783
View File
@@ -0,0 +1,783 @@
{
"commands": [{
"help": "Get the current size of free heap memory",
"hascb": false,
"name": "free"
}, {
"help": "Services",
"hascb": true,
"argtable": [{
"glossary": "Spotify (cspot)",
"longopts": "cspot",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Bluetooth Speaker",
"longopts": "BT_Speaker",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "AirPlay",
"longopts": "AirPlay",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "Disabled|Telnet Only|Telnet and Serial",
"glossary": "Telnet server. Use only for troubleshooting",
"longopts": "telnet",
"shortopts": "t",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "System Statistics. Use only for troubleshooting",
"longopts": "stats",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " [--cspot] [--BT_Speaker] [--AirPlay] [-t Disabled|Telnet Only|Telnet and Serial] [--stats]",
"name": "cfg-syst-services"
}, {
"help": "Get minimum size of free heap memory found during execution",
"hascb": false,
"name": "heap"
}, {
"help": "Device Name",
"hascb": true,
"argtable": [{
"datatype": "squeezelite-1fe714",
"glossary": "New Name",
"longopts": "new_name",
"shortopts": "n",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}],
"hint": " [-n squeezelite-1fe714]",
"name": "cfg-syst-name"
}, {
"help": "Get version of chip and SDK",
"hascb": false,
"name": "version"
}, {
"help": "Reboot system",
"hascb": false,
"name": "restart"
}, {
"help": "Reboot system to Recovery",
"hascb": false,
"name": "recovery"
}, {
"help": "Reboot system to Squeezelite",
"hascb": false,
"name": "restart_ota"
}, {
"help": "Preset Options",
"hascb": true,
"argtable": [{
"datatype": "SqueezeAMP|T-WATCH2020 by LilyGo",
"glossary": "Known Board Name.\nFor known boards, several systems parameters will be updated",
"longopts": "model_config",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}],
"hint": " --model_config=SqueezeAMP|T-WATCH2020 by LilyGo",
"name": "cfg-hw-preset"
}, {
"help": "General Audio Options",
"hascb": true,
"argtable": [{
"datatype": "Headphones|Subwoofer",
"glossary": "On supported DAC, determines the audio jack behavior. Selecting headphones will cause the external amp to be muted on insert, while selecting Subwoofer will keep the amp active all the time.",
"longopts": "jack_behavior",
"shortopts": "j",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}],
"hint": " [-j Headphones|Subwoofer]",
"name": "cfg-audio-general"
}, {
"help": "Bluetooth Audio Output Options",
"hascb": true,
"argtable": [{
"datatype": "name",
"glossary": "Bluetooth audio device name. This applies when output mode is Bluetooth",
"longopts": "sink_name",
"shortopts": "n",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "pin",
"glossary": "Bluetooth security/pin code. Usually 0000. This applies when output mode is Bluetooth",
"longopts": "pin_code",
"shortopts": "p",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}],
"hint": " -n name -p pin",
"name": "cfg-audio-bt_source"
}, {
"help": "DAC Options",
"hascb": true,
"argtable": [{
"datatype": "TAS57xx|TAS5713|AC101|WM8978|ES8388|",
"glossary": "DAC Model Name",
"longopts": "model_name",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Clock GPIO. e.g. 33",
"longopts": "clock",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Word Select GPIO. e.g. 25",
"longopts": "wordselect",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Data GPIO. e.g. 32",
"longopts": "data",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Mute GPIO. e.g. 14",
"longopts": "mute_gpio",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Mute GPIO level. Checked=HIGH, Unchecked=LOW",
"longopts": "mute_level",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SDA GPIO. e.g. 27",
"longopts": "dac_sda",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SCL GPIO. e.g. 26",
"longopts": "dac_scl",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "I2C device address. e.g. 106",
"longopts": "dac_i2c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Clear configuration",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " --model_name=TAS57xx|TAS5713|AC101|WM8978|ES8388| [--clock=<n>] [--wordselect=<n>] [--data=<n>] [--mute_gpio=<n>] [--mute_level] [--dac_sda=<n>] [--dac_scl=<n>] [--dac_i2c=<n>] [--clear]",
"name": "cfg-hw-dac"
}, {
"help": "SPDIF Options",
"hascb": true,
"argtable": [{
"datatype": "<n>",
"glossary": "Clock GPIO. e.g. 33",
"longopts": "clock",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Word Select GPIO. e.g. 25",
"longopts": "wordselect",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Data GPIO. e.g. 32",
"longopts": "data",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"glossary": "Clear configuration",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " --clock=<n> --wordselect=<n> --data=<n> [--clear]",
"name": "cfg-hw-spdif"
}, {
"help": "Rotary Control",
"hascb": true,
"argtable": [{
"datatype": "remark",
"glossary": "One rotary encoder is supported, quadrature shift with press. Such encoders usually have 2 pins for encoders (A and B), and common C that must be set to ground and an optional SW pin for press. A, B and SW must be pulled up, so automatic pull-up is provided by ESP32, but you can add your own resistors. A bit of filtering on A and B (~470nF) helps for debouncing which is not made by software.\r\nEncoder is normally hard-coded to respectively knob left, right and push on LMS and to volume down/up/play toggle on BT and AirPlay.",
"checkbox": false,
"remark": true,
"hasvalue": false,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "gpio",
"glossary": "A/DT gpio",
"longopts": "A",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "gpio",
"glossary": "B/CLK gpio",
"longopts": "B",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "gpio",
"glossary": "Switch gpio",
"longopts": "SW",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Force Volume down/up/play toggle all the time (even in LMS). ",
"longopts": "volume_lock",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Enable alternate mode mode on long-press. In that mode, left is previous, right is next and press is toggle. Every long press on SW alternates between modes (the main mode actual behavior depends on 'volume').",
"longopts": "longpress",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Single knob full navigation. Left, Right and Press is navigation, with Press always going to lower submenu item. Longpress is 'Play', Double press is 'Back', a quick left-right movement on the encoder is 'Pause'",
"longopts": "knobonly",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "ms",
"glossary": "The speed of double click (or left-right) when knob only option is enabled. Be aware that the longer you set double click speed, the less responsive the interface will be. ",
"longopts": "timer",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Clear configuration",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Send button events as raw values to LMS. No remapping is possible when this is enabled",
"longopts": "raw_mode",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " remark --A=gpio --B=gpio [--SW=gpio] [--volume_lock] [--longpress] [--knobonly] [--timer=ms] [--clear] [--raw_mode]",
"name": "cfg-hw-rotary"
}, {
"help": "I2C Bus Parameters",
"hascb": true,
"argtable": [{
"datatype": "0|1",
"glossary": "Port",
"longopts": "port",
"shortopts": "p",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "int",
"glossary": "Frequency (Hz) e.g. 100000",
"longopts": "speed",
"shortopts": "f",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SDA GPIO. e.g. 19",
"longopts": "sda",
"shortopts": "d",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SCL GPIO. e.g. 18",
"longopts": "scl",
"shortopts": "c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Clear configuration",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " [-p 0|1] [-f int] [-d <n>] [-c <n>] [--clear]",
"name": "cfg-hw-i2c"
}, {
"help": "SPI Bus Parameters",
"hascb": true,
"argtable": [{
"datatype": "<n>",
"glossary": "Data OUT GPIO",
"longopts": "data",
"shortopts": "d",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Data IN GPIO",
"longopts": "miso",
"shortopts": "d",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Clock GPIO",
"longopts": "clk",
"shortopts": "k",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "DC GPIO",
"longopts": "dc",
"shortopts": "c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "1|2",
"glossary": "SPI Host Number",
"longopts": "host",
"shortopts": "h",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Clear configuration",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " [-d <n>] [-d <n>] [-k <n>] [-c <n>] [-h 1|2] [--clear]",
"name": "cfg-hw-spi"
}, {
"help": "Scan I2C bus for devices",
"hascb": false,
"name": "i2cdetect"
}, {
"help": "Read registers visible through the I2C bus",
"hascb": false,
"argtable": [{
"datatype": "<chip_addr>",
"glossary": "Specify the address of the chip on that bus",
"longopts": "chip",
"shortopts": "c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<register_addr>",
"glossary": "Specify the address on that chip to read from",
"longopts": "register",
"shortopts": "r",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<length>",
"glossary": "Specify the length to read from that data address",
"longopts": "length",
"shortopts": "l",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}],
"hint": " -c <chip_addr> [-r <register_addr>] [-l <length>]",
"name": "i2cget"
}, {
"help": "Set registers visible through the I2C bus",
"hascb": false,
"argtable": [{
"datatype": "<chip_addr>",
"glossary": "Specify the address of the chip on that bus",
"longopts": "chip",
"shortopts": "c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Specify the i2c port (0|2)",
"longopts": "port",
"shortopts": "p",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<register_addr>",
"glossary": "Specify the address on that chip to read from",
"longopts": "register",
"shortopts": "r",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<data>",
"glossary": "Specify the data to write to that data address",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 256
}],
"hint": " -c <chip_addr> [-p <n>] [-r <register_addr>] [<data>]...",
"name": "i2cset"
}, {
"help": "Examine registers visible through the I2C bus",
"hascb": false,
"argtable": [{
"datatype": "<chip_addr>",
"glossary": "Specify the address of the chip on that bus",
"longopts": "chip",
"shortopts": "c",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<size>",
"glossary": "Specify the size of each read",
"longopts": "size",
"shortopts": "s",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}],
"hint": " -c <chip_addr> [-s <size>]",
"name": "i2cdump"
}, {
"help": "Display",
"hascb": true,
"argtable": [{
"datatype": "<I2C|SPI>",
"glossary": "Interface (default I2C)",
"longopts": "type",
"shortopts": "t",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<SH1106|SSD1306|SSD1322|SSD1326|SSD1327|SSD1675|SSD1351|ST7735|ST7789|ILI9341|>",
"glossary": "Driver",
"longopts": "driver",
"shortopts": "d",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "-1|1|4",
"glossary": "Bit Depth (only for SSD1326 displays)",
"longopts": "depth",
"shortopts": "p",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "I2C address (default 60)",
"longopts": "address",
"shortopts": "a",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Width",
"longopts": "width",
"shortopts": "w",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Height",
"longopts": "height",
"shortopts": "h",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 1,
"maxcount": 1
}, {
"glossary": "Rotate 180 degrees",
"longopts": "rotate",
"shortopts": "r",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Flip horizontally",
"longopts": "hf",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "Flip vertically",
"longopts": "vf",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SPI Only. Bus Speed (Default 8000000). SPI interface can work up to 26MHz~40MHz",
"longopts": "speed",
"shortopts": "s",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "SPI Only. CS GPIO (for SPI displays)",
"longopts": "cs",
"shortopts": "b",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Backlight GPIO (if applicable)",
"longopts": "back",
"shortopts": "b",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"datatype": "<n>",
"glossary": "Reset GPIO",
"longopts": "reset",
"checkbox": false,
"remark": false,
"hasvalue": true,
"mincount": 0,
"maxcount": 1
}, {
"glossary": "clear configuration and return",
"longopts": "clear",
"checkbox": true,
"remark": false,
"hasvalue": false,
"mincount": 0,
"maxcount": 1
}],
"hint": " [-r] [-t <I2C|SPI>] [-d <SH1106|SSD1306|SSD1322|SSD1326|SSD1327|SSD1675|SSD1351|ST7735|ST7789|ILI9341|>] [-p -1|1|4] [-a <n>] -w <n> -h <n> [--hf] [--vf] [-s <n>] [-b <n>] [-b <n>] [--reset=<n>] [--clear]",
"name": "cfg-hw-display"
}],
"values": {
"cfg-syst-services": {
"BT_Speaker": true,
"AirPlay": true,
"cspot": true,
"stats": false,
"telnet": "Telnet and Serial"
},
"cfg-syst-name": {
"new_name": "squeezelite-1fe714"
},
"cfg-hw-preset": {
"model_config": "previous config value"
},
"cfg-audio-general": {
"jack_behavior": "Subwoofer"
},
"cfg-audio-bt_source": {
"sink_name": "SMSL BT4.2",
"pin_code": "0000"
},
"cfg-hw-dac": {
"dac_sda": 33,
"dac_scl": 32,
"model_name": "AC101"
},
"cfg-hw-spdif": {
},
"cfg-hw-rotary": {
},
"cfg-hw-i2c": {
"speed": 400000
},
"cfg-hw-spi": {
"data": 13,
"clk": 14,
"host": 1
},
"cfg-hw-display": {
"rotate": false,
"hf": false,
"vf": false
}
}
}
+349
View File
@@ -0,0 +1,349 @@
{
"gpio": [
{
"gpio": 33,
"name": "bck",
"group": "spdif",
"fixed": false
},
{
"gpio": 25,
"name": "ws",
"group": "spdif",
"fixed": false
},
{
"gpio": 15,
"name": "do",
"group": "spdif",
"fixed": false
},
{
"gpio": -1,
"name": "bck",
"group": "dac",
"fixed": false
},
{
"gpio": -1,
"name": "ws",
"group": "dac",
"fixed": false
},
{
"gpio": -1,
"name": "do",
"group": "dac",
"fixed": false
},
{
"gpio": -1,
"name": "sda",
"group": "dac",
"fixed": false
},
{
"gpio": -1,
"name": "scl",
"group": "dac",
"fixed": false
},
{
"gpio": -1,
"name": "mute",
"group": "dac",
"fixed": false
},
{
"gpio": 17,
"name": "clk",
"group": "psram",
"fixed": true
},
{
"gpio": 16,
"name": "cs",
"group": "psram",
"fixed": true
},
{
"gpio": 7,
"name": "spiq_sd0_io",
"group": "psram",
"fixed": true
},
{
"gpio": 8,
"name": "spid_sd1_io",
"group": "psram",
"fixed": true
},
{
"gpio": 10,
"name": "spiwp_sd3_io",
"group": "psram",
"fixed": true
},
{
"gpio": 9,
"name": "spihd_sd2_io",
"group": "psram",
"fixed": true
},
{
"gpio": 6,
"name": "clk",
"group": "flash",
"fixed": true
},
{
"gpio": 11,
"name": "cs",
"group": "flash",
"fixed": true
}
],
"config": {
"a2dp_sink_name": {
"type": 33,
"value": "SMSL BT4.2",
"chg": false
},
"a2dp_ctmt": {
"type": 33,
"value": "1000",
"chg": false
},
"a2dp_ctrld": {
"type": 33,
"value": "500",
"chg": false
},
"bt_sink_pin": {
"type": 33,
"value": "1234",
"chg": false
},
"release_url": {
"type": 33,
"value": "https://github.com/sle118/squeezelite-esp32/releases",
"chg": false
},
"ap_ip_address": {
"type": 33,
"value": "192.168.4.1",
"chg": false
},
"ap_ip_gateway": {
"type": 33,
"value": "192.168.4.1",
"chg": false
},
"ap_ip_netmask": {
"type": 33,
"value": "255.255.255.0",
"chg": false
},
"ap_channel": {
"type": 33,
"value": "1",
"chg": false
},
"ap_pwd": {
"type": 33,
"value": "squeezelite",
"chg": false
},
"airplay_port": {
"type": 33,
"value": "5000",
"chg": false
},
"bypass_wm": {
"type": 33,
"value": "0",
"chg": false
},
"actrls_config": {
"type": 33,
"value": "",
"chg": false
},
"lms_ctrls_raw": {
"type": 33,
"value": "n",
"chg": false
},
"rotary_config": {
"type": 33,
"value": "",
"chg": false
},
"ota_erase_blk": {
"type": 33,
"value": "249856",
"chg": false
},
"ota_stack": {
"type": 33,
"value": "10240",
"chg": false
},
"ota_prio": {
"type": 33,
"value": "6",
"chg": false
},
"display_config": {
"type": 33,
"value": "",
"chg": false
},
"i2c_config": {
"type": 33,
"value": "",
"chg": false
},
"spi_config": {
"type": 33,
"value": "",
"chg": false
},
"set_GPIO": {
"type": 33,
"value": "",
"chg": false
},
"led_brightness": {
"type": 33,
"value": "",
"chg": false
},
"dac_config": {
"type": 33,
"value": "",
"chg": false
},
"dac_controlset": {
"type": 33,
"value": "",
"chg": false
},
"jack_mutes_amp": {
"type": 33,
"value": "n",
"chg": false
},
"bat_config": {
"type": 33,
"value": "",
"chg": false
},
"metadata_config": {
"type": 33,
"value": "",
"chg": false
},
"telnet_buffer": {
"type": 33,
"value": "40000",
"chg": false
},
"telnet_block": {
"type": 33,
"value": "500",
"chg": false
},
"spdif_config": {
"type": 33,
"value": "bck=33,ws=25,do=15",
"chg": false
},
"enable_bt_sink": {
"type": 33,
"value": "N",
"chg": false
},
"enable_airplay": {
"type": 33,
"value": "N",
"chg": false
},
"disable_ps": {
"type": 33,
"value": "n",
"chg": false
},
"stats": {
"type": 33,
"value": "Y",
"chg": false
},
"autoexec": {
"type": 33,
"value": "1",
"chg": false
},
"autoexec1_spdif": {
"type": 33,
"value": "squeezelite -b 500:2000 -d all=info -C 30 -W -n \"squeezelite-test3\" -o SPDIF -Z 192000",
"chg": false
},
"autoexec1_i2s": {
"type": 33,
"value": "squeezelite -b 500:2000 -d all=info -C 30 -W -n \"squeezelite-test3\" -o I2S",
"chg": false
},
"autoexec1_bt": {
"type": 33,
"value": "squeezelite -b 500:2000 -d all=info -C 30 -W -n \"squeezelite-test3\" -o \"BT -n 'test'\" -Z 192000",
"chg": false
},
"autoexec1": {
"type": 33,
"value": "squeezelite -b 500:2000 -d all=info -C 30 -W -n \"squeezelite-test3\" -o \"BT -n 'test'\" -Z 192000",
"chg": false
},
"bt_name": {
"type": 33,
"value": "squeezelite-test3",
"chg": false
},
"host_name": {
"type": 33,
"value": "squeezelite-test3",
"chg": false
},
"airplay_name": {
"type": 33,
"value": "squeezelite-test3",
"chg": false
},
"ap_ssid": {
"type": 33,
"value": "squeezelite-test3",
"chg": false
},
"a2dp_dev_name": {
"type": 33,
"value": "squeezelite-test3",
"chg": false
},
"telnet_enable": {
"type": 33,
"value": "D",
"chg": false
},
"rel_api": {
"type": 33,
"value": "https://api.github.com/repos/sle118/squeezelite-esp32/releases",
"chg": false
},
"enable_cspot": {
"type": 33,
"value": "Y",
"chg": false
}
}
}
@@ -0,0 +1,85 @@
[{
"message": "{\"free_iram\":190232,\"min_free_iram\":184520,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":3468,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":2,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 61257,
"current_time": 147316
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":3468,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 71255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 81256,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 91255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 101255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":98,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 111255,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 121256,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183872,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 131255,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183872,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 141256,
"current_time": 147319
},
{
"message": "Network connected",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_SYSTEM",
"sent_time": 141256,
"current_time": 147319
},
{
"message": "[{\n\t\t\"name\":\t\"SMSL BT4.2\",\n\t\t\"rssi\":\t-64\n\t}]",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_BT",
"sent_time": 6245,
"current_time": 6364
}, {
"message": "[{\n\t\t\"name\":\t\"BOSE BT\",\n\t\t\"rssi\":\t-129\n\t}]",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_BT",
"sent_time": 6259,
"current_time": 6364
}
, {
"message": "[{\n\t\t\"name\":\t\"BOSE2 BT\",\n\t\t\"rssi\":\t-50\n\t}]",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_BT",
"sent_time": 6259,
"current_time": 6364
}
]
@@ -0,0 +1,123 @@
[
{
"message": "Save Success",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_SYSTEM",
"sent_time": 14084,
"current_time": 16958
}, {
"message": "{\"ota_dsc\":\"Initializing...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 14110,
"current_time": 16958
}, {
"message": "{\"ota_dsc\":\"Starting OTA...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 14146,
"current_time": 16958
}, {
"message": "{\"ota_dsc\":\"Downloading firmware\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 15208,
"current_time": 16958
},
{
"message": "{\"ota_dsc\":\"Download success\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 18825,
"current_time": 22219
}, {
"message": "{\"ota_dsc\":\"New version is : mock version \",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 18849,
"current_time": 22220
}, {
"message": "{\"ota_dsc\":\"Formatting OTA partition\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 18850,
"current_time": 22220
}, {
"message": "{\"ota_dsc\":\"Erasing flash (1/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 22217,
"current_time": 22220
},
{
"message": "{\"ota_dsc\":\"Erasing flash (5/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 29896,
"current_time": 29902
},
{
"message": "{\"ota_dsc\":\"Erasing flash (7/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 33395,
"current_time": 33408
},
{
"message": "{\"ota_dsc\":\"Erasing flash (9/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 36843,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Erasing flash complete.\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 39463,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":5}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 41862,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":10}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 44003,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":40}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 56678,
"current_time": 65185
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":70}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 69407,
"current_time": 77858
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":95}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 80010,
"current_time": 82592
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":100}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 82084,
"current_time": 82592
},
{
"message": "{\"ota_dsc\":\"Success!\",\"ota_pct\":100}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 119255,
"current_time": 121838
}
]
@@ -0,0 +1,21 @@
[{
"message": "{\"ota_dsc\":\"Initializing...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 119203,
"current_time": 121837
}, {
"message": "{\"ota_dsc\":\"Starting OTA...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 119255,
"current_time": 121838
},
{
"message": "{\"ota_dsc\":\"Error: Failed to execute HTTP download. ERROR\",\"ota_pct\":0}",
"type": "MESSAGING_ERROR",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 121954,
"current_time": 124911
}
]
@@ -0,0 +1,117 @@
[
{
"message": "{\"ota_dsc\":\"Initializing...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 14110,
"current_time": 16958
}, {
"message": "{\"ota_dsc\":\"Starting OTA...\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 14146,
"current_time": 16958
}, {
"message": "{\"ota_dsc\":\"New version is : mock version \",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 18849,
"current_time": 22220
}, {
"message": "{\"ota_dsc\":\"Formatting OTA partition\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 18850,
"current_time": 22220
}, {
"message": "{\"ota_dsc\":\"Erasing flash (1/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 22217,
"current_time": 22220
},
{
"message": "{\"ota_dsc\":\"Erasing flash (5/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 29896,
"current_time": 29902
},
{
"message": "{\"ota_dsc\":\"Erasing flash (7/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 33395,
"current_time": 33408
},
{
"message": "{\"ota_dsc\":\"Erasing flash (9/11)\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 36843,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Erasing flash complete.\",\"ota_pct\":0}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 39463,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":5}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 41862,
"current_time": 54597
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":25}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 50307,
"current_time": 54598
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":30}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 52455,
"current_time": 54598
},
{
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":35}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 54603,
"current_time": 65184
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":55}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 63042,
"current_time": 65185
},
{
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":60}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 65190,
"current_time": 77858
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":95}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 80010,
"current_time": 82592
}, {
"message": "{\"ota_dsc\":\"Writing binary file\",\"ota_pct\":100}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 82084,
"current_time": 82592
},
{
"message": "{\"ota_dsc\":\"Success!\",\"ota_pct\":100}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_OTA",
"sent_time": 119255,
"current_time": 121838
}
]
@@ -0,0 +1,90 @@
[{
"message": "{\"free_iram\":190232,\"min_free_iram\":184520,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":3468,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":2,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 61257,
"current_time": 147316
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":3468,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 71255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 81256,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 91255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 101255,
"current_time": 147317
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":98,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 111255,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183992,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 121256,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183872,\"free_spiram\":4048488,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 131255,
"current_time": 147318
}, {
"message": "{\"free_iram\":190232,\"min_free_iram\":183872,\"free_spiram\":4048492,\"min_free_spiram\":4026220,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":400,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":97,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":1580,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":0,\"minstk\":708,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":3436,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 141256,
"current_time": 147319
},
{
"message": "Info Message",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_SYSTEM",
"sent_time": 3519,
"current_time": 24674
},
{
"message": "Warning Message",
"type": "MESSAGING_WARNING",
"class": "MESSAGING_CLASS_SYSTEM",
"sent_time": 3519,
"current_time": 24674
},
{
"message": "Warning Message",
"type": "MESSAGING_ERROR",
"class": "MESSAGING_CLASS_SYSTEM",
"sent_time": 3519,
"current_time": 24674
},
{
"message": "{\"free_iram\":194144,\"min_free_iram\":185048,\"free_spiram\":4061372,\"min_free_spiram\":4050012,\"ntasks\":13,\"tasks\":[]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 11201,
"current_time": 24674
}, {
"message": "{\"free_iram\":193848,\"min_free_iram\":185048,\"free_spiram\":4049576,\"min_free_spiram\":4049576,\"ntasks\":13,\"tasks\":[{\"cpu\":0,\"minstk\":480,\"bprio\":1,\"cprio\":1,\"nme\":\"Tmr Svc\",\"st\":1,\"num\":8},{\"cpu\":99,\"minstk\":1000,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE1\",\"st\":1,\"num\":7},{\"cpu\":98,\"minstk\":992,\"bprio\":0,\"cprio\":0,\"nme\":\"IDLE0\",\"st\":1,\"num\":6},{\"cpu\":0,\"minstk\":2184,\"bprio\":18,\"cprio\":18,\"nme\":\"tiT\",\"st\":2,\"num\":12},{\"cpu\":0,\"minstk\":1948,\"bprio\":5,\"cprio\":5,\"nme\":\"console\",\"st\":2,\"num\":18},{\"cpu\":0,\"minstk\":528,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc0\",\"st\":2,\"num\":2},{\"cpu\":0,\"minstk\":676,\"bprio\":20,\"cprio\":20,\"nme\":\"sys_evt\",\"st\":2,\"num\":13},{\"cpu\":0,\"minstk\":2096,\"bprio\":5,\"cprio\":5,\"nme\":\"wifi_manager\",\"st\":2,\"num\":15},{\"cpu\":0,\"minstk\":3468,\"bprio\":22,\"cprio\":22,\"nme\":\"esp_timer\",\"st\":2,\"num\":1},{\"cpu\":0,\"minstk\":2524,\"bprio\":5,\"cprio\":5,\"nme\":\"httpd\",\"st\":2,\"num\":16},{\"cpu\":1,\"minstk\":868,\"bprio\":23,\"cprio\":23,\"nme\":\"wifi\",\"st\":2,\"num\":14},{\"cpu\":0,\"minstk\":536,\"bprio\":24,\"cprio\":24,\"nme\":\"ipc1\",\"st\":2,\"num\":3},{\"cpu\":0,\"minstk\":7244,\"bprio\":1,\"cprio\":1,\"nme\":\"telnet\",\"st\":2,\"num\":17}]}",
"type": "MESSAGING_INFO",
"class": "MESSAGING_CLASS_STATS",
"sent_time": 21267,
"current_time": 24674
}
]
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1,16 @@
{
"project_name": "recovery",
"version": "custom.build",
"recovery": 1,
"Jack": "1",
"Voltage": 0,
"disconnect_count": 0,
"avg_conn_time": 0,
"is_i2c_locked": false,
"urc": 0,
"bt_status": 0,
"ssid": "MyTestSSID",
"ip": "192.168.10.225",
"netmask": "255.255.255.0",
"gw": "192.168.10.1"
}
+28
View File
@@ -0,0 +1,28 @@
{
"project_name": "SqueezeAMP",
"version": "local.500.cmake-master",
"recovery": 1,
"Jack": "1",
"Voltage": 0,
"disconnect_count": 0,
"avg_conn_time": 0,
"is_i2c_locked": false,
"urc": 0,
"bt_status": 0,
"bt_sub_status": 0,
"rssi": -59,
"ssid": "MyTestSSID",
"ip": "192.168.10.225",
"netmask": "255.255.255.0",
"gw": "192.168.10.1",
"lms_cport": 9090,
"lms_port": 9100,
"lms_ip": "127.0.0.1",
"if": "eth",
"platform_name": "SqueezeAmp",
"mock_plugin_has_proxy": "x",
"mock_fail_fw_update":"",
"mock_fail_recovery":"",
"mock_old_recovery":"",
"depth": 16
}
@@ -0,0 +1,26 @@
{
"urc": {
"Wifi Connection OK": 0,
"Wifi Failed Connect Attempt": 1,
"WiFi User Disconnect": 2,
"WiFi Lost Connection": 3,
"Wifi update failed attempt and restore" : 4,
"Ethernet Connected": 5
},
"bt_status": {
"Idle": 0,
"Discovering": 1,
"Discovered": 2,
"Unconnected": 3,
"Connecting": 4,
"Connected": 5,
"Disconnecting": 6
},
"bt_sub_status": {
"Default": 0,
"Connected - Starting": 1,
"Connected - Started": 2,
"Connected - Pause": 3,
"Connected - Stop": 4
}
}
+98
View File
@@ -0,0 +1,98 @@
{
"name": "squeezelite-esp32",
"version": "0.5.0",
"main": "src/index.html",
"repository": "git@github.com:sle118/squeezelite-esp32.git",
"author": "Sebastien L",
"license": "MIT",
"scripts": {
"prod": "webpack serve --open --mode=production",
"build": "webpack --mode=production ",
"stats": "webpack --env ANALYZE_SIZE=1 --mode=production ",
"watch": "webpack --progress --watch --mode=development ",
"dev": "webpack serve --open --mode=development"
},
"devDependencies": {
"@babel/core": "^7.16.12",
"@babel/plugin-transform-runtime": "^7.16.10",
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@squoosh/lib": "^0.4.0",
"autoprefixer": "^10.4.2",
"babel": "^6.23.0",
"babel-loader": "^8.2.3",
"babel-runtime": "^6.26.0",
"clean-webpack-plugin": "^4.0.0",
"commander": "^8.3.0",
"compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^10.2.1",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"ejs-loader": "^0.5.0",
"es6-promise": "^4.2.8",
"file-loader": "^6.2.0",
"glob": "^7.2.0",
"glob-all": "^3.2.1",
"google-fonts-webpack-plugin": "^0.4.4",
"html-loader": "^3.1.0",
"html-minimizer-webpack-plugin": "^3.5.0",
"html-webpack-plugin": "^5.5.0",
"image-minimizer-webpack-plugin": "^3.2.3",
"imagemin": "^8.0.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-mozjpeg": "^10.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-pngquant": "^9.0.2",
"imagemin-svgo": "^10.0.1",
"js-cookie": "^3.0.1",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-webpack-plugin": "^0.11.6",
"mini-css-extract-plugin": "^2.5.2",
"node-sass": "^7.0.1",
"open": "^9.1.0",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
"purgecss-webpack-plugin": "^4.1.3",
"purgecss-whitelister": "^2.4.0",
"purify-css": "^1.2.5",
"purifycss-webpack": "^0.7.0",
"remixicon": "^2.5.0",
"sass-loader": "^12.4.0",
"string-argv": "^0.3.1",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.0",
"ts-loader": "^9.2.6",
"typescript": "^4.5.5",
"webpack": "^5.67.0",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.7.3"
},
"dependencies": {
"@babel/runtime": "^7.16.7",
"async-mutex": "^0.3.2",
"bootstrap": "^5.1.3",
"bootswatch": "^5.3.2",
"jquery": "^3.6.0",
"npm": "^10.1.0",
"optipng-bin": "^9.0.0",
"popper.js": "^1.16.1",
"webpack-visualizer-plugin": "^0.1.11",
"webpack-visualizer-plugin2": "^1.0.0"
},
"keywords": [
"webppack4",
"sass",
"bootstrap4",
"jquery",
"popperjs",
"livereload",
"dev-server",
"font-awesome",
"es-lint",
"typescript",
"line-awesome"
]
}
+141
View File
@@ -0,0 +1,141 @@
{
"name": "squeezelite-esp32",
"version": "0.5.0",
"main": "src/index.html",
"repository": "git@github.com:sle118/squeezelite-esp32.git",
"author": "Andy K., Sebastien",
"license": "MIT",
"scripts": {
"dev": "webpack-dev-server --open --config webpack/webpack.dev.js",
"build": "webpack --config webpack/webpack.prod.js",
"prod": "webpack-dev-server --open --config webpack/webpack.prod.js"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"dependencies": {
"@popperjs/core": "^2.11.2",
"@types/bootstrap": "^5.1.8",
"animate.css": "^4.1.1",
"bootstrap": "^5.1.3",
"bootswatch": "^5.1.3",
"commander": "^8.3.0",
"expose-loader": "^3.1.0",
"hamburgers": "^1.1.3",
"jquery": "^3.6.0",
"line-awesome": "^1.3.0",
"lodash": "^4.17.21",
"perfect-scrollbar": "^1.5.3",
"popper": "^1.0.1",
"react": "^17.0.2",
"remixicon": "^2.5.0",
"string-argv": "^0.3.1",
"stylelint-config-standard": "^24.0.0",
"svgo": "^2.8.0",
"underscore": "^1.13.2",
"webpack-icons-installer": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.16.7",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
"@babel/plugin-transform-runtime": "^7.16.8",
"@babel/preset-env": "^7.16.8",
"@babel/preset-typescript": "^7.16.7",
"@fullhuman/postcss-purgecss": "^4.1.3",
"@types/lodash": "^4.14.178",
"autoprefixer": "^10.4.2",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.2.3",
"babel-preset-minify": "^0.5.1",
"body-parser": "^1.19.1",
"browser-sync": "^2.27.7",
"browser-sync-webpack-plugin": "^2.3.0",
"browserlist": "^1.0.1",
"compression-webpack-plugin": "^9.2.0",
"cross-env": "^7.0.3",
"css-loader": "^6.5.1",
"cssnano": "^5.0.15",
"eslint": "^8.6.0",
"eslint-config-google": "^0.14.0",
"eslint-webpack-plugin": "^3.1.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"favicons-webpack-plugin": "5.0.2",
"file-loader": "^6.2.0",
"glob": "^7.2.0",
"glob-all": "^3.2.1",
"hook-shell-script-webpack-plugin": "^0.1.4",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"image-minimizer-webpack-plugin": "^3.2.2",
"image-webpack-loader": "^8.1.0",
"imagemin": "^8.0.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-mozjpeg": "^10.0.0",
"imagemin-pngquant": "^9.0.2",
"imagemin-svgo": "^10.0.1",
"imagemin-webpack-plugin": "^2.4.2",
"img-loader": "^4.0.0",
"install": "^0.13.0",
"less": "^4.1.2",
"lodash-webpack-plugin": "^0.11.6",
"mini-css-extract-plugin": "^2.4.6",
"miragejs": "^0.1.43",
"node-sass": "^7.0.1",
"offline-plugin": "^5.0.7",
"on-build-webpack": "^0.1.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss-loader": "^6.2.1",
"preload-webpack-plugin": "^2.3.0",
"promise": "^8.1.0",
"purgecss-webpack-plugin": "^4.1.3",
"purify-css": "^1.2.5",
"purifycss-webpack": "^0.7.0",
"raw-loader": "^4.0.2",
"resolve-url-loader": "^4.0.0",
"sass-loader": "^12.4.0",
"script-ext-html-webpack-plugin": "^2.1.5",
"source-map-loader": "^3.0.1",
"style-loader": "^3.3.1",
"stylelint": "^14.2.0",
"stylelint-config-recommended": "^6.0.0",
"stylelint-webpack-plugin": "^3.1.0",
"svg-sprite-loader": "^6.0.11",
"svg-transform-loader": "^2.0.13",
"svgo-loader": "^3.0.0",
"terser-webpack-plugin": "^5.3.0",
"ts-loader": "^9.2.6",
"tslint": "^5.20.1",
"tslint-webpack-plugin": "^2.1.1",
"typescript": "^4.5.4",
"url-loader": "^4.1.1",
"webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.7.3",
"webpack-merge": "^5.8.0",
"xml-loader": "^1.2.1"
},
"keywords": [
"webppack4",
"sass",
"bootstrap4",
"jquery",
"popperjs",
"livereload",
"dev-server",
"font-awesome",
"es-lint",
"typescript",
"line-awesome"
]
}
@@ -0,0 +1,3 @@
module.exports = {
};
+37
View File
@@ -0,0 +1,37 @@
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 days"
ExpiresByType text/html "access plus 5 minutes"
ExpiresByType text/xml "access plus 6 hours"
ExpiresByType text/css "access plus 1 weeks"
ExpiresByType text/javascript "access plus 1 weeks"
ExpiresByType application/javascript "access plus 1 weeks"
ExpiresByType application/x-javascript "access plus 1 weeks"
ExpiresByType text/ecmascript "access plus 1 weeks"
ExpiresByType image/gif "access plus 1 years"
ExpiresByType image/png "access plus 1 years"
ExpiresByType image/jpeg "access plus 1 years"
ExpiresByType image/ico "access plus 1 years"
ExpiresByType image/icon "access plus 1 years"
ExpiresByType image/x-icon "access plus 1 years"
ExpiresByType video/x-flv "access plus 1 years"
ExpiresByType video/quicktime "access plus 1 years"
ExpiresByType application/x-shockwave-flash "access plus 1 years"
ExpiresByType application/pdf "access plus 1 years"
</IfModule>
# gzip Compression if availiable
AddEncoding gzip .gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-shockwave-flash
</IfModule>
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

+590
View File
@@ -0,0 +1,590 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<meta name="apple-mobile-web-app-capable" content="yes" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<title></title>
</head>
<body class="d-flex flex-column">
<header class="navbar navbar-expand-sm navbar-dark bg-primary sticky-top border-bottom border-dark" id="mainnav">
<a class="navbar-brand" id="navtitle" href="#"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav navbar-nav mr-auto" role="tablist">
<li class="nav-item"><a class="nav-link active" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-wifi">WiFi</a></li>
<li class="nav-item omsg"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-syslog">Status<span class="badge badge-pill badge-success" id="msgcnt"></span></a>
</li>
<li class="nav-item orec"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-cfg-audio">Audio</a></li>
<li class="nav-item orec"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-cfg-syst">System</a></li>
<li class="nav-item orec"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-cfg-hw">Hardware</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-cfg-fw">Updates</a></li>
<div class="dropdown-divider"></div>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-nvs">NVS Editor</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-commands">Advanced</a></li>
<li class="nav-item"><a class="nav-link" data-bs-toggle="tab" aria-controls="profile" role="tab"
href="#tab-credits">Credits</a></li>
</ul>
</div>
<div class="info navbar-right" style="display: inline-flex;">
<span class="recovery_element material-icons " style="color:orange; display: none"
aria-label="🛑">system_update_alt</span>
<span id="battery" class="material-icons" style="fill:white; display: none"
aria-label="🔋">battery_full</span>
<span id="o_jack" class="material-icons" style="fill:white; display: none" aria-label="🎧">headphones</span>
<span id="s_airplay" class="material-icons" style="fill:white; display: none" aria-label="🍎">airplay</span>
<em id="s_cspot" class="fab fa-spotify" style="fill:white; display: inline"></em>
<span data-bs-toggle="tooltip" id="o_type" data-bs-placement="top" title="">
<span id="o_bt" class="material-icons" style="fill:white; display: none" aria-label="">bluetooth</span>
<span id="o_spdif" class="material-icons" style="fill:white; display: none"
aria-label="">graphic_eq</span>
<span id="o_i2s" class="material-icons" style="fill:white; display: none" aria-label="🔈">speaker</span>
</span>
<span id="ethernet" class="material-icons if_eth" style="fill:white; display: none"
aria-label="ETH">cable</span>
<span id="wifiStsIcon" class="material-icons if_wifi" style="fill:white; display: none"
aria-label=""></span>
</div>
</header>
<main role="main" class="flex-grow mt-1 mb-12" style="margin-bottom: 7rem;" id="content">
<!-- Button trigger modal -->
<!-- Modal -->
<div class="modal" id="otadiv" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="fwProgressLabel">Upgrade Progress</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<span id="flash-status"></span>
<div class="progress" id="progress">
<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100"
style="width:0%">
0%
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade" id="tab-cfg-hw"> </div>
<div class="tab-pane fade" id="tab-cfg-syst"></div>
<div class="tab-pane fade" id="tab-cfg-gen"></div>
<div class="tab-pane fade" id="tab-cfg-fw">
<div class="card mb-3">
<div class="card-header">Software Updates</div>
<div class="card-body">
<table class="table table-hover table-striped table-dark">
<thead>
<tr>
<th class="border-bottom-0 pb-0" scope="col">Version</th>
<th class="border-bottom-0 pb-0" scope="col">Date/Time</th>
<th class="border-bottom-0 pb-0" scope="col">Platform</th>
<th class="border-bottom-0 pb-0" scope="col">Branch</th>
<th class="border-bottom-0 pb-0" scope="col">Bit Depth</th>
</tr>
<tr>
<th class="border-top-0 pt-0" scope="col"><input class="form-control-sm upSrch"
id="svrs" type="text" placeholder="search releases"></th>
<th class="border-top-0 pt-0" scope="col"></th>
<th class="border-top-0 pt-0" scope="col"><input class="form-control-sm upSrch"
id="splf" type="text" placeholder="search platform"></th>
<th class="border-top-0 pt-0" scope="col"><select class="form-control-sm upSrch"
id="fwbranch">
<option selected="">Choose FW branch</option>
</select>
<th class="border-top-0 pt-0" scope="col"><input class="form-control-sm upSrch"
id="bits" type="text" placeholder="search bit depth"></th>
</th>
</tr>
</thead>
<tbody id="rTable"></tbody>
</table>
<div class="form-group row">
<div class="col-auto">
<button type="button" id="chkUpdates" class="btn btn-info btn-sm">Check for
updates</button>
</div>
<label class="col-auto col-form-label" for="fw-url-input">Firmware URL</label>
<div class="col">
<input type="text" class="form-control"
placeholder="select entry from list or enter known url" id="fw-url-input">
</div>
<div class="col-auto">
<button type="button" id='start-flash' data-bs-toggle="modal" data-bs-target="#uCnfrm"
class="btn btn-warning btn-sm flact" style="display: none;">Flash Firmware</button>
</div>
<div class="col-auto">
<button id="btn_reboot_recovery" class="btn-warning ota_element"
type="submit">Recovery</button>
</div>
</div>
</div>
</div>
<div class="modal" id="uCnfrm">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Firmware Flash</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Flash URL <span id="selectedFWURL" class="text-break"></span> to device?</p>
</div>
<div class="modal-footer ">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button id="btn_flash" type="button" class="btn btn-warning"
data-bs-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header">Local Firmware Upload</div>
<div class="card-body">
<div id="uploaddiv" class="form-group row ">
<label for="flashfilename" class="col-auto col-form-label">Local File</label>
<div class="col">
<input type="file" class="form-control-file" id="flashfilename"
aria-describedby="fileHelp">
</div>
<div class="col-auto">
<div class="buttons">
<button type="button" class="btn btn-danger flact" id="fwUpload">Upload!</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="tab-nvs">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Key</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody id="nvsTable">
</tbody>
</table>
<div class="buttons">
<button button id="btn_reboot" class="btn btn-primary" style="float:right"
type="submit">Reboot</button>
<input id="save-nvs" type="button" class="btn btn-success" value="Commit">
<input id="save-as-nvs" type="button" class="btn btn-success" value="Download config">
<input id="load-nvs" type="button" class="btn btn-success" value="Load File">
<input aria-describedby="fileHelp" id="nvsfilename" type="file" style="display:none">
</div>
</div>
<div class="tab-pane fade" id="tab-cfg-audio">
<div class="card mb-3">
<div class="card-header">Usage Templates</div>
<div class="card-body">
<fieldset class="form-group" id="output-tmpl">
<label>Output</label><br>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="output-tmpl" id="i2s">
I2S Dac
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="output-tmpl" id="spdif">
SPDIF
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="output-tmpl" id="bt">
Bluetooth
</label>
</div>
</fieldset>
<fieldset>
<div id="options">
<div class="form-group"><label for="cmd_opt_n">Set the player name</label><input
type="text" class="form-control sqcmd" placeholder="name" id="cmd_opt_n"></div>
<div class="form-group"><label for="cmd_opt_s">Server</label><input type="text"
class="form-control sqcmd" placeholder="server[:port]" id="cmd_opt_s"></div>
<div class="form-group"><label for="cmd_opt_b">Stream and Output buffer sizes (in
Kbytes)</label><input type="text" class="form-control sqcmd"
placeholder="stream:output" id="cmd_opt_b"></div>
<div class="form-group"><label for="cmd_opt_c">Restrict codecs </label><input
type="text" class="form-control sqcmd" placeholder="codec1,codec2"
id="cmd_opt_c"><small class="form-text text-muted">Supported: flac,pcm,mp3,ogg
(mad,mpg for specific mp3 codec)</small></div>
<div class="form-group"><label for="cmd_opt_C">Ouput device close timeout</label><input
type="text" class="form-control sqcmd" placeholder="timeout"
id="cmd_opt_C"><small class="form-text text-muted">Close output device after
timeout seconds, default
is to keep it open while player is 'on'</small></div>
<div class="form-group"><label for="cmd_opt_d">Set logging level</label><input
type="text" class="form-control sqcmd" placeholder="log=level"
id="cmd_opt_d"><small class="form-text text-muted">Logs:
all|slimproto|stream|decode|output, level:
info|debug|sdebug</small></div>
<div class="form-group"><label for="cmd_opt_e">Explicitly exclude native support of one
or more codecs</label><input type="text" class="form-control sqcmd"
placeholder="codec1,codec2" id="cmd_opt_e"><small
class="form-text text-muted">Supported: flac,pcm,mp3,ogg (mad,mpg for specific
mp3 codec)</small></div>
<div class="form-group"><label for="cmd_opt_m">Set mac address</label><input type="text"
class="form-control sqcmd" placeholder="mac addr" id="cmd_opt_m"><small
class="form-text text-muted">Format: ab:cd:ef:12:34:56</small></div>
<div class="form-group"><label for="cmd_opt_r">Sample rates supported, allows output to
be off when squeezelite is started</label><input type="text"
class="form-control sqcmd" placeholder="rates" id="cmd_opt_r"><small
class="form-text text-muted">&lt;maxrate&gt;|&lt;minrate&gt;&lt;maxrate&gt;&lt;rate1&gt;&lt;rate2&gt;&lt;rate3&gt;</small>
</div>
<div class="form-group hide" id="cmd_opt_R">
<label>Resample</label><br>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="resample" id="resample_none"
suffix="" checked aint="false">
<label class="form-check-label" for="resampleNone">No resampling</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="resample" id="resample"
suffix=' -R' aint="false">
<label class="form-check-label" for="resampleNone">Default</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="resample" id="resample_b"
suffix=' -R -u b' aint="true">
<label class="form-check-label" for="resampleBasic">Basic linear
interpolation</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="resample" id="resample_l"
suffix=' -R -u l' aint="true">
<label class="form-check-label" for="resample13Taps">13 taps</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="resample" id="resample_m"
suffix=' -R -u m' aint="true">
<label class="form-check-label" for="resample21Taps">21 taps</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="interpolate"
id="resample_i" suffix=":i">
<label class="form-check-label" for="interpolate">Interpolate filter
coefficients</label>
</div>
</div>
<div class="form-group"><label for="cmd_opt_Z">Report rate to server in helo as the
maximum sample rate we can support</label><input type="text"
class="form-control" placeholder="rate" id="cmd_opt_Z"></div>
<div class="form-group">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" id="cmd_opt_W" value=""
checked="">
Read wave and aiff format from header, ignore server parameters
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" id="disable-squeezelite" value="" >
Disable Squeezelite
</label>
</div>
</div>
<div style="margin-top: 16px;">
<div class="toast hide" role="alert" aria-live="assertive" aria-atomic="true"
id="toast_cfg-audio-tmpl">
<div class="toast-header"><strong class="mr-auto">Result</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast"
aria-label="Close"></button>
</div>
<div class="toast-body" id="msg_cfg-audio-tmpl"></div>
</div>
</div>
<button id="save-autoexec1" type="submit" class="btn btn-info"
cmdname="cfg-audio-tmpl">Save</button>
<button id="commit-autoexec1" type="submit" class="btn btn-warning"
cmdname="cfg-audio-tmpl">Apply</button>
</fieldset>
</div>
</div>
</div>
<div class="tab-pane fade active show" id="tab-wifi">
<div class="card mb-3">
<div class="card-header">WiFi Status</div>
<div class="card-body if_eth" style="display: none">
<h2>Connected to Ethernet</h2>
<p>WiFi is inactive while connected to a wired network.
</div>
<div class="card-body if_wifi" style="display: none">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Joined</th>
<th scope="col">Name</th>
<th scope="col">Signal</th>
<th scope="col">Security</th>
</tr>
</thead>
<tbody id="wifiTable"></tbody>
</table>
<button type="button" id="updateAP" class="btn btn-info btn-sm">Scan</button>
</div>
<div class="modal" id="WiFiDisconnectConfirm">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Disconnect</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Disconnect from network? After disconnecting, the system won't be accessible from
the current address and will expose itself as access point name <span
id="apName"></span> with password <span id="apPass"></span> </p>
</div>
<div class="modal-footer connecting-success connecting-status">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Cancel</button>
<button id="btn_disconnect" type="button" class="btn btn-warning"
data-bs-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
<div class="modal" id="WifiConnectDialog" aria-hidden="true">
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title connecting connecting-init connecting-fail">Connect to WiFi
</h5>
<h5 class="modal-title connecting-status connecting-success">Status</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<fieldset class="connecting-init connecting-fail">
<div class="form-group"><label for="manual_ssid">Wifi Name</label><input
type="text" class="form-control" placeholder="Enter Name"
id="manual_ssid"></div>
<div class="form-group"><label for="manual_pwd">Password</label><input
type="password" class="form-control" placeholder="Enter Name"
id="manual_pwd"></div>
</fieldset>
<div id="connect-wait" class="connecting">
<div>Connecting to <span id="ssid-wait"></span> </div>
<div>
You may lose wifi access while the esp32 recalibrates
its radio. Please
wait until your device automatically reconnects. This can take up to
30s.
</div>
</div>
<div id="connect-success" class="connecting-success connecting-status">
<div> Connected to Access Point : <span id="connectedToSSID"></span></div>
<div> Device IP address : <span id="ipAddress"></span></div>
<div>Subnet Mask:<span id="netmask"></span></div>
<div>Default Gateway:<span id="gateway"></span></div>
</div>
<div id="connect-fail" class="connecting-fail">
<h3 class="text-error">Connection failed</h3>
<p>Please double-check wifi password if any and make sure the access point has
good signal.</p>
</div>
</div>
<div class="modal-footer ">
<button type="button"
class="btn btn-secondary connecting-init connecting-fail connecting"
data-bs-dismiss="modal">Close</button>
<button type="button" id="btnJoin"
class="btn btn-primary connecting-init connecting-fail">Join</button>
<button type="button" class="connecting btn btn-primary" disabled>
<span class="spinner-border spinner-border-sm" role="status"
aria-hidden="true"></span>
<span class="sr-only">Connecting...</span></button>
</div>
<div class="modal-footer connecting-success connecting-status justify-content-between"
style=""><button type="button" class="btn btn-primary"
data-bs-dismiss="modal">Ok</button><button type="button" class="btn btn-danger"
data-bs-toggle="modal" data-bs-dismiss="modal"
data-bs-target="#WiFiDisconnectConfirm">Disconnect</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade " id="tab-commands">
<fieldset id="commands-list"></fieldset>
</div>
<!-- Status -->
<div class="tab-pane fade " id="tab-syslog">
<div class="card border-primary mb-3">
<div class="card-header">Logs</div>
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Timestamp</th>
<th scope="col">Message</th>
</tr>
</thead>
<tbody id="syslogTable">
</tbody>
</table>
<div class="buttons">
<input id="clear-syslog" type="button" class="btn btn-danger btn-sm" value="Clear" />
</div>
</div>
</div>
<div class="card border-primary mb-3" id="pins" style="display: none;">
<div class="card-header">Pin Assignments</div>
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Device</th>
<th scope="col">Pin Name</th>
<th scope="col">GPIO Number</th>
<th scope="col">Type</th>
</tr>
</thead>
<tbody id="gpiotable"></tbody>
</table>
</div>
</div>
<div class="card border-primary mb-3" style="visibility: collapse;" id="tasks_sect">
<div class="card-header">Tasks</div>
<div class="card-body">
<table class="table table-hover">
<!-- console.log(msg_time.toLocaleString() + '\tname' + '\tcpu' + '\tstate' + '\tminstk' + '\tbprio' + '\tcprio' + '\tnum'); -->
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Task Name</th>
<th scope="col">CPU</th>
<th scope="col">State</th>
<th scope="col">Min Stack</th>
<th scope="col">Base Priority</th>
<th scope="col">Cur Priority</th>
</tr>
</thead>
<tbody id="tasks"></tbody>
</table>
</div>
</div>
</div>
<!-- syslog -->
<div class="tab-pane fade " id="tab-credits">
<div class="card mb-3">
<div class="card-header">Credits</div>
<div class="card-body">
<p><strong><a
href="https://github.com/sle118/squeezelite-esp32">squeezelite-esp32</a><br></strong>&copy;
2020, philippe44, sle118, daduke<br /><a href="https://opensource.org/licenses/MIT">This
software is released under the MIT License.</a></p>
<p>
This app would not be possible without the following libraries:
</p>
<ul>
<li>squeezelite, &copy; 2012-2019, Adrian Smith and Ralph Irving. Licensed under the GPL
License.</li>
<li>esp32-wifi-manager, &copy; 2017-2019, Tony Pottier. Licensed under the MIT License.</li>
<li>SpinKit, &copy; 2015, Tobias Ahlin. Licensed under the MIT License.</li>
<li>jQuery, The jQuery Foundation. Licensed under the MIT License.</li>
<li>cJSON, &copy; 2009-2017, Dave Gamble and cJSON contributors. Licensed under the MIT
License.
</li>
<li>esp32-rotary-encoder, &copy; 2011-2019, David Antliff and Ben Buxton. Licensed under the
GPL
License.</li>
<li>tarablessd1306, &copy; 2017-2018, Tara Keeling. Licensed under the MIT license.</li>
<li>CSpot, &copy; 2020 feelfreelinux & alufers. Licensed under the GPL License</li>
</ul>
</div>
</div>
<div class="card mb-3">
<div class="card-header">Extras/Overrides</div>
<div class="card-body">
<fieldset>
<div class="form-check">
<label class="form-check-label"><input type="checkbox" id="show-nvs"
class="form-check-input " value="">Show NVS Editor</label>
</div>
</fieldset>
<fieldset>
<div class="form-check">
<label class="form-check-label"><input type="checkbox" id="show-commands"
class="form-check-input " value="">Show Advanced Commands</label>
</div>
</fieldset>
</div>
</div>
</div>
<!-- credits -->
</div>
</div>
</main>
<footer>
<div class="fixed-bottom d-flex justify-content-between border-top border-dark p-3 bg-primary">
<span class="text-center" id="foot-fw"></span><button class="btn-warning ota_element " id="reboot_nav"
type="submit" style="display: none;">Reboot</button>
<button class="btn-warning recovery_element" id="reboot_ota_nav" type="submit" style="display: none;">Exit
Recovery</button><span class="text-center" id="foot-if"></span>
</div>
</footer>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
import 'bootstrap';
import './sass/main.scss';
import './assets/images/favicon-32x32.png';
import './js/custom.js';
File diff suppressed because it is too large Load Diff
+135
View File
@@ -0,0 +1,135 @@
let sd = {};
let rf=false;
function getStatus() {
const config = {};
$(`#valuesTable input:text, #valuesTable input:checked`).each(function(_index, entry) {
switch (entry.attributes.dtype.value) {
case 'string':
config[entry.name] = entry.value;
break;
case 'number':
config[entry.name] = Number(entry.value);
break;
case 'boolean':
config[entry.name] = entry.value=='true';
break;
default:
break;
}
});
return config;
}
// function getOptions(entry) {
// let output='';
// for (const property in entry) {
// output+=`<option value="${entry[property]}">${property}</option>`;
// }
// return output;
// }
function getRadioButton(entry){
let output='';
for (const property in sd[entry]) {
output+=`
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="${entry}_${sd[entry][property]}" name="${entry}" value="${sd[entry][property]}" dtype='${typeof(sd[entry][property])}'>
<label class="custom-control-label" for="${entry}_${sd[entry][property]}">${property}</label>
</div>
`;
}
return output;
}
var refreshStatus = function() {
if(Object.keys(sd).length>0){
if(rf) return;
rf=true;
$.getJSON('/status.json', function(data) {
for (const property in data) {
const val = data[property];
let input = $(`#val_${property}, #valuesTable input[name="${property}"]`) ;
if(input.length>0){
if(input.is(':radio') ){
$(`#${property}_${val ?? 0}`).prop('checked',true);
}
else {
if(input.val() !==val && !input.is(":focus")){
input.val(val);
}
}
}
else {
if(sd[property]){
$('#valuesTable').append(
`<tr><td>${property}</td>
<td >
${getRadioButton(property)}
</td></tr>`);
$(`#${property}_${val ?? 0}`).prop('checked',true);
}
else {
$('#valuesTable').append(`<tr><td>${property}</td><td><input type='text' class='value form-control nvs' id="val_${property}" name='${property}' dtype='${typeof(val)}' ></input></td></tr>`);
$(`#val_${property}`).val(val);
}
}
}
})
.fail(function() {
})
.done(function(){
rf=false;
});
}
else {
$.getJSON('/statusdefinition.json', function(data) {
sd=data;
})
.fail(function() {
})
.done(function(){
});
}
}
function pushStatus(){
const data = {
timestamp: Date.now(),
status: getStatus()
};
$.ajax({
url: '/status.json',
dataType: 'text',
method: 'POST',
cache: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data),
});
console.log('sent config JSON with data:', JSON.stringify(data));
}
$(document).ready(function() {
$('#save_status').on('click', function() {
pushStatus();
});
$( "#valuesTable" ).change(function() {
pushStatus();
});
setInterval(refreshStatus, 1000);
$('svg >> symbol').each(function() {
$('#allIcons').append( `<svg style="fill:white; width:1.5rem; height: 1.5rem;">
<use xlink:href="#${this.id}"></use>
</svg>`);
});
}) ;
@@ -0,0 +1,42 @@
// @import "~bootswatch/dist/darkly/variables"; -- remove darkly until bootswatch color is resolved
@import "utils/variables";
@import "~bootstrap/scss/bootstrap";
// @import "~bootstrap/scss/functions";
// @import "~bootstrap/scss/variables";
// @import "~bootstrap/scss/mixins";
// @import "~bootstrap/scss/utilities";
// // Layout & components
// @import "~bootstrap/scss/root";
// @import "~bootstrap/scss/reboot";
// @import "~bootstrap/scss/type";
// @import "~bootstrap/scss/images";
// @import "~bootstrap/scss/containers";
// @import "~bootstrap/scss/grid";
// @import "~bootstrap/scss/tables";
// @import "~bootstrap/scss/forms";
// @import "~bootstrap/scss/buttons";
// @import "~bootstrap/scss/transitions";
// @import "~bootstrap/scss/dropdown";
// @import "~bootstrap/scss/button-group";
// @import "~bootstrap/scss/nav";
// @import "~bootstrap/scss/navbar";
// @import "~bootstrap/scss/card";
// @import "~bootstrap/scss/badge";
// @import "~bootstrap/scss/alert";
// @import "~bootstrap/scss/progress";
// //@import "~bootstrap/scss/list-group";
// @import "~bootstrap/scss/close";
// @import "~bootstrap/scss/toasts";
// @import "~bootstrap/scss/modal";
// @import "~bootstrap/scss/tooltip";
// @import "~bootstrap/scss/placeholders";
// // Helpers
// @import "~bootstrap/scss/helpers";
// // Utilities
// @import "~bootstrap/scss/utilities/api";
// @import "~bootswatch/dist/darkly/bootswatch"; -- remove darkly until bootswatch color is resolved
@import "utils/style";
@@ -0,0 +1,24 @@
body {
min-height: 100vh;
}
.border-bottom {
border-width:3px !important;
}
.xl { font-size: 1.5em; line-height: 1em; vertical-align: -.075em; }
.border-top {
border-width:3px !important;
}
tr.hide {
display: none;
}
.rebooting {
display: none;
}
td.value {
width: 80%;
}
#boot-div {
float: right;
}
@@ -0,0 +1,3 @@
$enable-gradients: false;
// This is needed below, otherwise colors look washed out
$table-bg-level: 0;
+134
View File
@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>esp32-wifi-manager testing</title>
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon-32x32.png">
</head>
<body>
<div style="display:none">
<% if (htmlWebpackPlugin.files.sprites) { %>
<% for (var spriteFileName in htmlWebpackPlugin.files.sprites) { %>
<%= htmlWebpackPlugin.files.sprites[spriteFileName] %>
<% } %>
<% } %>
</div>
<div id="allIcons"><i class="recovery_element ri-device-recover-fill ri-xl" style="color:orange; " ></i>
<i class="ri-battery-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-headphone-fill ri-xl" style="fill:white; "></i>
<i class= "ri-bluetooth-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-speaker-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-voiceprint ri-xl" style="fill:white; " ></i>
<i class= "ri-signal-wifi-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-signal-wifi-3-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-signal-wifi-2-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-signal-wifi-1-fill ri-xl" style="fill:white; " ></i>
<i class= "ri-signal-wifi-line ri-xl" style="fill:white; " ></i>
</div>
<div class="card border-primary mb-3">
<div class="card-header">Status Variables</div>
<div class="card-body">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Variable</th>
<th scope="col">Value</th>
</tr>
</thead>
<tbody id="valuesTable">
</tbody>
</table>
<input id="save_status" type="button" class="btn btn-success" value="Commit">
</div>
</div>
<div>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">BT State</th>
<th scope="col">Sub state #</th>
<th scope="col">Sub state</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>Idle</td>
<td>0</td>
<td>bt_neutral</td>
</tr>
<tr>
<td>1</td>
<td>Discovering</td>
<td>0</td>
<td>bt_searching</td>
</tr>
<tr>
<td>2</td>
<td>Discovered</td>
<td>0</td>
<td>bt_searching</td>
</tr>
<tr>
<td>3</td>
<td>Unconnected</td>
<td>0</td>
<td>bt_disabled</td>
</tr>
<tr>
<td>4</td>
<td>Connecting</td>
<td>0</td>
<td>bt_disabled</td>
</tr>
<tr>
<td>5</td>
<td>Connected</td>
<td>0</td>
<td>bt_connected</td>
</tr>
<tr>
<td></td>
<td></td>
<td>1</td>
<td>play_circle_outline</td>
</tr>
<tr>
<td></td>
<td></td>
<td>2</td>
<td>bt_playing</td>
</tr>
<tr>
<td></td>
<td></td>
<td>3</td>
<td>pause</td>
</tr>
<tr>
<td></td>
<td></td>
<td>4</td>
<td>stop</td>
</tr>
<tr>
<td>6</td>
<td>Disconnecting</td>
<td>0</td>
<td>bt_neutral</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
import 'bootstrap';
import './sass/main.scss';
import './js/test.js';
+55
View File
@@ -0,0 +1,55 @@
const stats='';
// Merges webpack.common config with this production config
const fs = require('fs');
const glob = require('glob');
var getDirectories = function (src, callback) {
glob(src + '/**/*.gz', callback);
};
getDirectories('./webpack/', function (err, list) {
if (err) {
console.log('Error', err);
} else {
const regex = /^(.*\/)([^\/]*)$/
const relativeRegex = /(\w+\/[^\/]*)$/
const makePathRegex = /([^\.].*)$/
let exportDefHead=
'/***********************************\n'+
'webpack_headers\n'+
stats+'\n'+
'***********************************/\n'+
'#pragma once\n'+
'#include <inttypes.h>\n'+
'extern const char * resource_lookups[];\n'+
'extern const uint8_t * resource_map_start[];\n'+
'extern const uint8_t * resource_map_end[];\n';
let exportDef= '// Automatically generated. Do not edit manually!.\n'+
'#include <inttypes.h>\n';
let lookupDef='const char * resource_lookups[] = {\n';
let lookupMapStart='const uint8_t * resource_map_start[] = {\n';
let lookupMapEnd='const uint8_t * resource_map_end[] = {\n';
let cMake='';
list.forEach(fileName=>{
console.log(fileName);
let exportName=fileName.match(regex)[2].replace(/[\. \-]/gm,'_');
let relativeName=fileName.match(relativeRegex)[1];
exportDef+= 'extern const uint8_t '+exportName+'_start[] asm("_binary_'+exportName+'_start");\n'+
'extern const uint8_t '+exportName+'_end[] asm("_binary_'+exportName+'_end");\n';
lookupDef+='\t"/'+relativeName+'",\n';
lookupMapStart+='\t'+ exportName+'_start,\n';
lookupMapEnd+= '\t'+ exportName+'_end,\n';
cMake+='target_add_binary_data( __idf_wifi-manager ./webapp'+fileName.match(makePathRegex)[1]+' BINARY)\n';
});
lookupDef+='""\n};\n';
lookupMapStart=lookupMapStart.substring(0,lookupMapStart.length-2)+'\n};\n';
lookupMapEnd=lookupMapEnd.substring(0,lookupMapEnd.length-2)+'\n};\n';
try {
fs.writeFileSync('webapp.cmake', cMake);
fs.writeFileSync('webpack.c', exportDef+lookupDef+lookupMapStart+lookupMapEnd);
fs.writeFileSync('webpack.h', exportDefHead);
//file written successfully
} catch (err) {
console.error(err);
}
}
});
+1
View File
@@ -0,0 +1 @@
Some content!
+8
View File
@@ -0,0 +1,8 @@
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(4), -1);
});
});
});
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": [ "src/*"],
"@node_modules/*" : ["./node_modules/*"]},
"outDir": "./dist/",
"noImplicitAny": true,
"target": "es6",
"module": "CommonJS",
"composite": true,
// "jsx": "react",
"allowJs": true,
"allowSyntheticDefaultImports" : true,
"esModuleInterop" : true
},
"exclude": [
"./node_modules"
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {
"eofline": false,
"no-trailing-whitespace": false,
"comment-format": false,
"quotemark": false,
"no-console": false,
"one-line": false,
"no-consecutive-blank-lines": false,
"curly": false,
"ordered-imports": [false],
"object-literal-sort-keys": [false],
"only-arrow-functions": false,
"indent": false
},
"rulesDirectory": []
}
+5
View File
@@ -0,0 +1,5 @@
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.3b0bbfde52d921a84f9b.css.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.d35fda.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.d35fda.bundle.js.gz BINARY)
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}
+34
View File
@@ -0,0 +1,34 @@
// Automatically generated. Do not edit manually!.
#include <inttypes.h>
extern const uint8_t _index_3b0bbfde52d921a84f9b_css_gz_start[] asm("_binary_index_3b0bbfde52d921a84f9b_css_gz_start");
extern const uint8_t _index_3b0bbfde52d921a84f9b_css_gz_end[] asm("_binary_index_3b0bbfde52d921a84f9b_css_gz_end");
extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_start");
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
extern const uint8_t _index_d35fda_bundle_js_gz_start[] asm("_binary_index_d35fda_bundle_js_gz_start");
extern const uint8_t _index_d35fda_bundle_js_gz_end[] asm("_binary_index_d35fda_bundle_js_gz_end");
extern const uint8_t _node_vendors_d35fda_bundle_js_gz_start[] asm("_binary_node_vendors_d35fda_bundle_js_gz_start");
extern const uint8_t _node_vendors_d35fda_bundle_js_gz_end[] asm("_binary_node_vendors_d35fda_bundle_js_gz_end");
const char * resource_lookups[] = {
"/css/index.3b0bbfde52d921a84f9b.css.gz",
"/favicon-32x32.png",
"/index.html.gz",
"/js/index.d35fda.bundle.js.gz",
"/js/node_vendors.d35fda.bundle.js.gz",
""
};
const uint8_t * resource_map_start[] = {
_index_3b0bbfde52d921a84f9b_css_gz_start,
_favicon_32x32_png_start,
_index_html_gz_start,
_index_d35fda_bundle_js_gz_start,
_node_vendors_d35fda_bundle_js_gz_start
};
const uint8_t * resource_map_end[] = {
_index_3b0bbfde52d921a84f9b_css_gz_end,
_favicon_32x32_png_end,
_index_html_gz_end,
_index_d35fda_bundle_js_gz_end,
_node_vendors_d35fda_bundle_js_gz_end
};
+426
View File
@@ -0,0 +1,426 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require("copy-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const webpack = require("webpack");
const path = require("path");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const globSync = require("glob").sync;
const glob = require('glob');
const { merge } = require('webpack-merge');
const devserver = require('./webpack/webpack.dev.js');
const fs = require('fs');
const zlib = require("zlib");
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
const whitelister = require('purgecss-whitelister');
const PATHS = {
src: path.join(__dirname, 'src')
}
class BuildEventsHook {
constructor(name, fn, stage = 'afterEmit') {
this.name = name;
this.stage = stage;
this.function = fn;
}
apply(compiler) {
compiler.hooks[this.stage].tap(this.name, this.function);
}
}
module.exports = (env, options) => (
merge(
env.WEBPACK_SERVE ? devserver : {},
env.ANALYZE_SIZE?{ plugins: [ new BundleAnalyzerPlugin(
{
analyzerMode: 'static',
generateStatsFile: true,
statsFilename: 'stats.json',
}
) ]}:{},
{
entry:
{
index: './src/index.ts'
},
devtool:"source-map",
module: {
rules: [
{
test: /\.ejs$/,
loader: 'ejs-loader',
options: {
variable: 'data',
interpolate : '\\{\\{(.+?)\\}\\}',
evaluate : '\\[\\[(.+?)\\]\\]'
}
},
{
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
// {
// test: /\.s[ac]ss$/i,
// use: [{
// loader: 'style-loader', // inject CSS to page
// },
// {
// loader: MiniCssExtractPlugin.loader,
// options: {
// publicPath: "../",
// },
// },
// "css-loader",
// {
// loader: "postcss-loader",
// options: {
// postcssOptions: {
// plugins: [["autoprefixer"]],
// },
// },
// },
// "sass-loader",
// ]
// },
{
test: /\.(scss)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../",
},
},
// {
// // inject CSS to page
// loader: 'style-loader'
// },
{
// translates CSS into CommonJS modules
loader: 'css-loader'
},
{
// Run postcss actions
loader: 'postcss-loader',
options: {
// `postcssOptions` is needed for postcss 8.x;
// if you use postcss 7.x skip the key
postcssOptions: {
// postcss plugins, can be exported to postcss.config.js
plugins: function () {
return [
require('autoprefixer')
];
}
}
}
}, {
// compiles Sass to CSS
loader: 'sass-loader'
}]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: ['@babel/plugin-transform-runtime']
},
},
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
},
// {
// test: /\.html$/i,
// type: "asset/resource",
// },
{
test: /\.html$/i,
loader: "html-loader",
options: {
minimize: true,
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'SqueezeESP32',
template: './src/index.ejs',
filename: 'index.html',
inject: 'body',
minify: {
html5 : true,
collapseWhitespace : true,
minifyCSS : true,
minifyJS : true,
minifyURLs : false,
removeAttributeQuotes : true,
removeComments : true, // false for Vue SSR to find app placeholder
removeEmptyAttributes : true,
removeOptionalTags : true,
removeRedundantAttributes : true,
removeScriptTypeAttributes : true,
removeStyleLinkTypeAttributese : true,
useShortDoctype : true
},
favicon: "./src/assets/images/favicon-32x32.png",
excludeChunks: ['test'],
}),
// new CompressionPlugin({
// test: /\.(js|css|html|svg)$/,
// //filename: '[path].br[query]',
// filename: "[path][base].br",
// algorithm: 'brotliCompress',
// compressionOptions: { level: 11 },
// threshold: 100,
// minRatio: 0.8,
// deleteOriginalAssets: false
// }),
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash].css",
}),
new PurgeCSSPlugin({
keyframes: false,
paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, {
nodir: true
}),
whitelist: whitelister('bootstrap/dist/css/bootstrap.css')
}),
new webpack.ProvidePlugin({
$: "jquery",
// jQuery: "jquery",
// "window.jQuery": "jquery",
// Popper: ["popper.js", "default"],
// Util: "exports-loader?Util!bootstrap/js/dist/util",
// Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
}),
new CompressionPlugin({
//filename: '[path].gz[query]',
test: /\.js$|\.css$|\.html$/,
filename: "[path][base].gz",
algorithm: 'gzip',
threshold: 100,
minRatio: 0.8,
}),
new BuildEventsHook('Update C App',
function (stats, arguments) {
if (options.mode !== "production") return;
let buildRootPath = path.join(process.cwd(),'..','..','..');
let wifiManagerPath=glob.sync(path.join(buildRootPath,'components/**/wifi-manager*'))[0];
let buildCRootPath=glob.sync(buildRootPath)[0];
fs.appendFileSync('./dist/index.html.gz',
zlib.gzipSync(fs.readFileSync('./dist/index.html'),
{
chunckSize: 65536,
level: zlib.constants.Z_BEST_COMPRESSION
}));
var getDirectories = function (src, callback) {
var searchPath = path.posix.join(src, '/**/*(*.gz|favicon-32x32.png)');
console.log(`Post build: Getting file list from ${searchPath}`);
glob(searchPath, callback);
};
var cleanUpPath = path.posix.join(buildCRootPath, '/build/*.S');
console.log(`Post build: Cleaning up previous builds in ${cleanUpPath}`);
glob(cleanUpPath, function (err, list) {
if (err) {
console.error('Error', err);
} else {
list.forEach(fileName => {
try {
console.log(`Post build: Purging old binary file ${fileName} from C project.`);
fs.unlinkSync(fileName)
//file removed
} catch (ferr) {
console.error(ferr)
}
});
}
},
'afterEmit'
);
console.log('Generating C include files from webpack build output');
getDirectories('./dist', function (err, list) {
console.log(`Post build: found ${list.length} files. Relative path: ${wifiManagerPath}.`);
if (err) {
console.log('Error', err);
} else {
let exportDefHead =
`/***********************************
webpack_headers
${arguments[1]}
***********************************/
#pragma once
#include <inttypes.h>
extern const char * resource_lookups[];
extern const uint8_t * resource_map_start[];
extern const uint8_t * resource_map_end[];`;
let exportDef = '// Automatically generated. Do not edit manually!.\n' +
'#include <inttypes.h>\n';
let lookupDef = 'const char * resource_lookups[] = {\n';
let lookupMapStart = 'const uint8_t * resource_map_start[] = {\n';
let lookupMapEnd = 'const uint8_t * resource_map_end[] = {\n';
let cMake='';
list.forEach(foundFile => {
let exportName = path.basename(foundFile).replace(/[\. \-]/gm, '_');
//take the full path of the file and make it relative to the build directory
let cmakeFileName = path.posix.relative(wifiManagerPath,glob.sync(path.resolve(foundFile))[0]);
let httpRelativePath=path.posix.join('/',path.posix.relative('dist',foundFile));
exportDef += `extern const uint8_t _${exportName}_start[] asm("_binary_${exportName}_start");\nextern const uint8_t _${exportName}_end[] asm("_binary_${exportName}_end");\n`;
lookupDef += `\t"${httpRelativePath}",\n`;
lookupMapStart += '\t_' + exportName + '_start,\n';
lookupMapEnd += '\t_' + exportName + '_end,\n';
cMake += `target_add_binary_data( __idf_wifi-manager ${cmakeFileName} BINARY)\n`;
console.log(`Post build: adding cmake file reference to ${cmakeFileName} from C project, with web path ${httpRelativePath}.`);
});
lookupDef += '""\n};\n';
lookupMapStart = lookupMapStart.substring(0, lookupMapStart.length - 2) + '\n};\n';
lookupMapEnd = lookupMapEnd.substring(0, lookupMapEnd.length - 2) + '\n};\n';
try {
fs.writeFileSync('webapp.cmake', cMake);
fs.writeFileSync('webpack.c', exportDef + lookupDef + lookupMapStart + lookupMapEnd);
fs.writeFileSync('webpack.h', exportDefHead);
//file written successfully
} catch (e) {
console.error(e);
}
}
});
console.log('Post build completed.');
})
],
optimization: {
minimize: true,
providedExports: true,
usedExports: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
// enable parallel running
parallel: true,
}),
new HtmlMinimizerPlugin({
minimizerOptions: {
removeComments: true,
removeOptionalTags: true,
}
}
),
new CssMinimizerPlugin(),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
// Svgo configuration here https://github.com/svg/svgo#configuration
[
"svgo",
{
plugins: [
{
name: 'preset-default',
params: {
overrides: {
// customize default plugin options
inlineStyles: {
onlyMatchedOnce: false,
},
// or disable plugins
removeDoctype: false,
},
},
}
],
},
],
],
},
},
}),
],
splitChunks: {
cacheGroups: {
vendor: {
name: "node_vendors",
test: /[\\/]node_modules[\\/]/,
chunks: "all",
}
}
}
},
// output: {
// filename: "[name].js",
// path: path.resolve(__dirname, "dist"),
// publicPath: "",
// },
resolve: {
extensions: ['.tsx', '.ts', '.js', '.ejs' ],
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: './js/[name].[fullhash:6].bundle.js',
clean: true
},
}
)
);
+9
View File
@@ -0,0 +1,9 @@
/***********************************
webpack_headers
dist/css/index.3b0bbfde52d921a84f9b.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.d35fda.bundle.js.gz,dist/js/node_vendors.d35fda.bundle.js.gz
***********************************/
#pragma once
#include <inttypes.h>
extern const char * resource_lookups[];
extern const uint8_t * resource_map_start[];
extern const uint8_t * resource_map_end[];
@@ -0,0 +1,117 @@
const path = require("path");
const fs = require('fs');
const zlib = require("zlib");
const glob = require('glob');
class BuildEventsHook {
constructor(name, fn, stage = 'afterEmit') {
this.name = name;
this.stage = stage;
this.function = fn;
}
apply(compiler) {
compiler.hooks[this.stage].tap(this.name, this.function);
}
}
function createBuildEventsHook(options){
return new BuildEventsHook('Update C App',
function (stats, arguments) {
if (options.mode !== "production") return;
let buildRootPath = path.join(process.cwd(), '..', '..', '..');
let wifiManagerPath = glob.sync(path.join(buildRootPath, 'components/**/wifi-manager*'))[0];
let buildCRootPath = glob.sync(buildRootPath)[0];
fs.appendFileSync('./dist/index.html.gz',
zlib.gzipSync(fs.readFileSync('./dist/index.html'),
{
chunckSize: 65536,
level: zlib.constants.Z_BEST_COMPRESSION
}));
let getDirectories = function getDirectories (src, callback) {
let searchPath = path.posix.join(src, '/**/*(*.gz|favicon-32x32.png)');
console.log(`Post build: Getting file list from ${searchPath}`);
glob(searchPath, callback);
};
let cleanUpPath = path.posix.join(buildCRootPath, '/build/*.S');
console.log(`Post build: Cleaning up previous builds in ${cleanUpPath}`);
glob(cleanUpPath, function (err, list) {
if (err) {
console.error('Error', err);
} else {
list.forEach(fileName => {
try {
console.log(`Post build: Purging old binary file ${fileName} from C project.`);
fs.unlinkSync(fileName)
//file removed
} catch (ferr) {
console.error(ferr)
}
});
}
},
'afterEmit'
);
console.log('Generating C include files from webpack build output');
getDirectories('./dist', function (err, list) {
console.log(`Post build: found ${list.length} files. Relative path: ${wifiManagerPath}.`);
if (err) {
console.log('Error', err);
} else {
let exportDefHead =
`/***********************************
webpack_headers
${arguments[1]}
***********************************/
#pragma once
#include <inttypes.h>
extern const char * resource_lookups[];
extern const uint8_t * resource_map_start[];
extern const uint8_t * resource_map_end[];`;
let exportDef = '// Automatically generated. Do not edit manually!.\n' +
'#include <inttypes.h>\n';
let lookupDef = 'const char * resource_lookups[] = {\n';
let lookupMapStart = 'const uint8_t * resource_map_start[] = {\n';
let lookupMapEnd = 'const uint8_t * resource_map_end[] = {\n';
let cMake = '';
list.forEach(foundFile => {
let exportName = path.basename(foundFile).replace(/[\. \-]/gm, '_');
//take the full path of the file and make it relative to the build directory
let cmakeFileName = path.posix.relative(wifiManagerPath, glob.sync(path.resolve(foundFile))[0]);
let httpRelativePath = path.posix.join('/', path.posix.relative('dist', foundFile));
exportDef += `extern const uint8_t _${exportName}_start[] asm("_binary_${exportName}_start");\nextern const uint8_t _${exportName}_end[] asm("_binary_${exportName}_end");\n`;
lookupDef += `\t"${httpRelativePath}",\n`;
lookupMapStart += '\t_' + exportName + '_start,\n';
lookupMapEnd += '\t_' + exportName + '_end,\n';
cMake += `target_add_binary_data( __idf_wifi-manager ${cmakeFileName} BINARY)\n`;
console.log(`Post build: adding cmake file reference to ${cmakeFileName} from C project, with web path ${httpRelativePath}.`);
});
lookupDef += '""\n};\n';
lookupMapStart = lookupMapStart.substring(0, lookupMapStart.length - 2) + '\n};\n';
lookupMapEnd = lookupMapEnd.substring(0, lookupMapEnd.length - 2) + '\n};\n';
try {
fs.writeFileSync('webapp.cmake', cMake);
fs.writeFileSync('webpack.c', exportDef + lookupDef + lookupMapStart + lookupMapEnd);
fs.writeFileSync('webpack.h', exportDefHead);
//file written successfully
} catch (e) {
console.error(e);
}
}
});
console.log('Post build completed.');
})
}
module.exports = {
BuildEventsHook,
createBuildEventsHook
}

Some files were not shown because too many files have changed in this diff Show More