--- /dev/null
+CompileFlags:
+ Remove: [-f*, -m*]
--- /dev/null
+ARG DOCKER_TAG=latest
+FROM espressif/idf:${DOCKER_TAG}
+
+ENV LC_ALL=C.UTF-8
+ENV LANG=C.UTF-8
+
+RUN apt-get update -y && apt-get install udev -y
+
+RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
+
+ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
+
+CMD ["/bin/bash", "-c"]
\ No newline at end of file
--- /dev/null
+{
+ "name": "ESP-IDF QEMU",
+ "build": {
+ "dockerfile": "Dockerfile"
+ },
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "terminal.integrated.defaultProfile.linux": "bash",
+ "idf.gitPath": "/usr/bin/git"
+ },
+ "extensions": [
+ "espressif.esp-idf-extension",
+ "espressif.esp-idf-web"
+ ]
+ }
+ },
+ "runArgs": ["--privileged"]
+}
\ No newline at end of file
--- /dev/null
+# macOS
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Directory metadata
+.directory
+
+# Temporary files
+*~
+*.swp
+*.swo
+*.bak
+*.tmp
+
+# Log files
+*.log
+
+# Build artifacts and directories
+**/build/
+build/
+*.o
+*.a
+*.out
+*.exe # For any host-side utilities compiled on Windows
+
+# ESP-IDF specific build outputs
+*.bin
+*.elf
+*.map
+flasher_args.json # Generated in build directory
+sdkconfig.old
+sdkconfig
+
+# ESP-IDF dependencies
+# For older versions or manual component management
+/components/.idf/
+**/components/.idf/
+# For modern ESP-IDF component manager
+managed_components/
+# If ESP-IDF tools are installed/referenced locally to the project
+.espressif/
+
+# CMake generated files
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+install_manifest.txt
+CTestTestfile.cmake
+
+# Python environment files
+*.pyc
+*.pyo
+*.pyd
+__pycache__/
+*.egg-info/
+dist/
+
+# Virtual environment folders
+venv/
+.venv/
+env/
+
+# Language Servers
+.clangd/
+.ccls-cache/
+compile_commands.json
+
+# Windows specific
+Thumbs.db
+ehthumbs.db
+Desktop.ini
+
+# User-specific configuration files
+*.user
+*.workspace # General workspace files, can be from various tools
+*.suo # Visual Studio Solution User Options
+*.sln.docstates # Visual Studio
--- /dev/null
+{
+ "configurations": [
+ {
+ "name": "ESP-IDF",
+ "compilerPath": "C:\\Espressif\\tools\\xtensa-esp-elf\\esp-13.2.0_20240530\\xtensa-esp-elf\\bin\\xtensa-esp32-elf-gcc.exe",
+ "compileCommands": "${config:idf.buildPath}/compile_commands.json",
+ "includePath": [
+ "${workspaceFolder}/**"
+ ],
+ "browse": {
+ "path": [
+ "${workspaceFolder}"
+ ],
+ "limitSymbolsToIncludedHeaders": true
+ }
+ }
+ ],
+ "version": 4
+}
--- /dev/null
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "gdbtarget",
+ "request": "attach",
+ "name": "Eclipse CDT GDB Adapter"
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "C_Cpp.intelliSenseEngine": "default",
+ "idf.openOcdConfigs": [
+ "board/esp32c2-ftdi.cfg"
+ ],
+ "idf.portWin": "COM6",
+ "idf.currentSetup": "C:/Espressif/frameworks/esp-idf-v5.3.1/",
+ "idf.customExtraVars": {
+ "IDF_TARGET": "esp32c2"
+ },
+ "clangd.path": "C:\\Espressif\\tools\\esp-clang\\16.0.1-fe4f10a809\\esp-clang\\bin\\clangd.exe",
+ "clangd.arguments": [
+ "--background-index",
+ "--query-driver=**",
+ "--compile-commands-dir=d:\\1.work\\2.code\\ssl_mutual_auth\\build"
+ ],
+ "idf.flashType": "UART"
+}
--- /dev/null
+cmake_minimum_required(VERSION 3.16)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+project(ssl_mutual_auth)
\ No newline at end of file
--- /dev/null
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
+
+# ESP-MQTT SSL Sample application (mutual authentication)
+
+(See the README.md file in the upper level 'examples' directory for more information about examples.)
+
+This example connects to the broker test.mosquitto.org using ssl transport with client certificate and as a demonstration subscribes/unsubscribes and send a message on certain topic.
+(Please note that the public broker is maintained by the community so may not be always available, for details please visit http://test.mosquitto.org)
+
+It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker.
+
+## How to use example
+
+### Hardware Required
+
+This example can be executed on any ESP32 board, the only required interface is WiFi and connection to internet.
+
+### Configure the project
+
+* Open the project configuration menu (`idf.py menuconfig`)
+* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
+
+* Generate your client keys and certificate
+
+Navigate to the main directory
+
+```
+cd main
+```
+
+Generate a client key and a CSR. When you are generating the CSR, do not use the default values. At a minimum, the CSR must include the Country, Organisation and Common Name fields.
+
+```
+openssl genrsa -out client.key
+openssl req -out client.csr -key client.key -new
+```
+
+Paste the generated CSR in the [Mosquitto test certificate signer](https://test.mosquitto.org/ssl/index.php), click Submit and copy the downloaded `client.crt` in the `main` directory.
+
+Please note, that the supplied files `client.crt` and `client.key` in the `main` directory are only placeholders for your client certificate and key (i.e. the example "as is" would compile but would not connect to the broker)
+
+The server certificate `mosquitto.org.crt` can be downloaded in pem format from [mosquitto.org.crt](https://test.mosquitto.org/ssl/mosquitto.org.crt).
+
+### Build and Flash
+
+Build the project and flash it to the board, then run monitor tool to view serial output:
+
+```
+idf.py -p PORT flash monitor
+```
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+## Example Output
+
+```
+I (3714) event: sta ip: 192.168.0.139, mask: 255.255.255.0, gw: 192.168.0.2
+I (3714) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
+I (3964) MQTT_CLIENT: Sending MQTT CONNECT message, type: 1, id: 0000
+I (4164) MQTTS_EXAMPLE: MQTT_EVENT_CONNECTED
+I (4174) MQTTS_EXAMPLE: sent publish successful, msg_id=41464
+I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=17886
+I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=42970
+I (4184) MQTTS_EXAMPLE: sent unsubscribe successful, msg_id=50241
+I (4314) MQTTS_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=41464
+I (4484) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=17886
+I (4484) MQTTS_EXAMPLE: sent publish successful, msg_id=0
+I (4684) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=42970
+I (4684) MQTTS_EXAMPLE: sent publish successful, msg_id=0
+I (4884) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
+I (4884) MQTTS_EXAMPLE: MQTT_EVENT_DATA
+TOPIC=/topic/qos0
+DATA=data
+I (5194) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
+I (5194) MQTTS_EXAMPLE: MQTT_EVENT_DATA
+TOPIC=/topic/qos0
+DATA=data
+```
+
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDWTCCAkGgAwIBAgIURpSxKjdraq6TLFCENuhtjNelfLYwDQYJKoZIhvcNAQEL
+BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g
+SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTI1MDcxNDEyMjk1
+MloXDTQ5MTIzMTIzNTk1OVowHjEcMBoGA1UEAwwTQVdTIElvVCBDZXJ0aWZpY2F0
+ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMARxe7gi6kJPTDgNyiR
+X9SaFaYxe1nNUx6ukcNalUfdgy4QFRdxb2oRJgOiISsYnRvzDsGR5kKGYaHiuI+D
+oUT58f6h19++aLjF5fg2e42Di/zFBNZtRzByOUP/WulHA4xAGIEAxNtjytLzxO+W
+Dt4vCEEIfrYTW9P5r92+r8ZUaJKrSafll/LM5Zcj6GkcR9C39EX7uaYg95CIdx4Y
+bgvsYZbb/PIAP/4wRbOwzyXxrwjh+WYBzPb1dxnDixF5NfPDaHWzGHH9EtX2zqnY
++L2g+bgRfgjEIM1m8TCxnpzJTyyfhIb1Coc+bOdk3LROxKNQ/lsvpGJvIqBFCjQ0
+yqsCAwEAAaNgMF4wHwYDVR0jBBgwFoAU4dLvDsL/yIHxYiAY/6KLleZoDMowHQYD
+VR0OBBYEFOPECh7CdzVR61Dtfj0k9T0CYok9MAwGA1UdEwEB/wQCMAAwDgYDVR0P
+AQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQCjgzLzbRkxY7JFK4IvPRSWtYxm
+46apVPCdRFIqhv0LaZT74HSpHSvxmLvjdb9c/I5HwCtM+PI3/XRDDy8TOvQlFvAN
+zXDtocxO5nF06o1hado/XvJVO7t5EvEHqzYnOb1ntYL2FSZdNR/qX8Sthj3xxLYT
+RUgkzmACuP6Ivm94c3nJ85MKZS8Q+hlp9HQcQig6JKfbGh0zDluHOF0NcFSl7dTm
+MVfZbCQoC8jh7p7MAnKNs8/yvqSpCUOOzQMzEAdkZh/UWJvruJ9Ip4IikaCyHp4s
+5pB+GyXaiG9k//JLuL2CHijTLcCJrm6PG3TLvtZqgDgvlkVnKc9j1Yy+zCe7
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEAwBHF7uCLqQk9MOA3KJFf1JoVpjF7Wc1THq6Rw1qVR92DLhAV
+F3FvahEmA6IhKxidG/MOwZHmQoZhoeK4j4OhRPnx/qHX375ouMXl+DZ7jYOL/MUE
+1m1HMHI5Q/9a6UcDjEAYgQDE22PK0vPE75YO3i8IQQh+thNb0/mv3b6vxlRokqtJ
+p+WX8szllyPoaRxH0Lf0Rfu5piD3kIh3HhhuC+xhltv88gA//jBFs7DPJfGvCOH5
+ZgHM9vV3GcOLEXk188NodbMYcf0S1fbOqdj4vaD5uBF+CMQgzWbxMLGenMlPLJ+E
+hvUKhz5s52TctE7Eo1D+Wy+kYm8ioEUKNDTKqwIDAQABAoIBAQC2JWTHSC1KLdfY
+7RmCIHN4BHQ5er2XCVAlTbowQExHrfuEiH3oEIxvUznwwiWgYCRGaDd7POjX9+bJ
+BmCuwU8EQeDL8SHvLvzTFeIkhU6ggrsUCKewzktv1zMVmCnYBp+HtxVF6bvGrxme
++sytxWnuLT4vpmW8OBmiqiytJvQ9KRNsgNoHQqKhUQAP5Zg3jhTFdDGobvssdnLI
+6nT6EJ5K89jEoi5FK0kqcsqvRfgFctrQBY79kTv5glPm8vsbVms/CyyWARhsOFNE
+8nMwKrZBCILH7I0xtjLmDT1xIAxq13ndqnqjxQ32KN3bjuCRyVU6OsDFYwFuArDY
+L525Fso5AoGBAO/qdku3T3Z0eiwTDN25VRVEkufMv00fAywzAvLyyfWZ+9JPzaZL
+xK8YfO8h+xJmSEsu81jIu7hg8FziT18nOXWVhSl7/QSbWpd7oxpYHVya0WwMGQ/o
+5U99GP0oDBzE0L/+YLZFLWoYOvg67Gsz5T3aJathR1G4IKGIacJfSCyNAoGBAMzy
+JnEDCGA53N28GgHH3nGZUUL5PmLd7hQxHiNXd86rfWKlbkZGXm+jLtd7NIK8JhAY
+lr6OCm9fvAA1Rnu9bZKqedMimQZAre0xUcFqR0RaVwg/T1Ddu+1b4vXOvEdnWYN3
+MxxPnNbxkOCgeRGlRxVXlGMxL3eQLelFfkHo6nIXAoGBAJTNj2GW6KpHxB7iEfDT
+qnnudk9fJqfmvEkFuqaE/85dG1tuM9cY13zia1rGcLsQxXYcQMKofgX12h9CHoie
+A31yp4z7YgshcCbUgG0uiceOHqYtOr4rbU7IAF/EHv8Y84ChfcqPTYOoU6ryoQA8
+x8p9KzAIvftpgJOv0CjGgDVhAoGBAKeLeuO+z/UiuK5JHZXBGNgTt/whmN/ogL7f
+HL1Vv2skhR/FEG7BDmkDpcKhRV9vg0p7X5kus9czE5Wz+Agm51IUrf1udl1HOSkE
+vcp6IQL/O9FROH1qmDzGdrfvJ7rUAbjZFN6bMyQBXihU6EUFsiP/ch7ZUe3T38Sp
+fDtTt35HAoGBAMow/0jcQC67Rj6Of9z13QjqJ/gTr3OeWo1LwSnz1S40W9mF3LXY
+ipjcYdWNtNuJU/oAWv9UpoqnIluXVmLFF11QX9R2yNLlU9CFgCUA4zItwFx5dZWa
+hBk3V0vfvXrDRTkxVvybL0IZa69SVYT4KybXYPkKNZ9bqFaMz/hh47po
+-----END RSA PRIVATE KEY-----
--- /dev/null
+dependencies:
+ idf:
+ source:
+ type: idf
+ version: 5.3.1
+ protocol_examples_common:
+ dependencies: []
+ source:
+ path: C:\Espressif\frameworks\esp-idf-v5.3.1\examples\common_components\protocol_examples_common
+ type: local
+ version: '*'
+direct_dependencies:
+- protocol_examples_common
+manifest_hash: 9a9520c926aa0a3e6ab6efa4fb14c3591e654d3887543776c1f730f359b02661
+target: esp32c2
+version: 2.0.0
--- /dev/null
+idf_component_register(SRCS "app_main.c"
+ "iap.c"
+ "mqtt.c"
+ "project_common.c"
+ "aes.c"
+ "gap.c"
+ "gatt_svc.c"
+ "ble.c"
+ "wifi.c"
+ "user_flash.c"
+ "crc.c"
+ "http.c"
+ "uart.c"
+ PRIV_REQUIRES mqtt
+ esp_wifi
+ bt
+ nvs_flash
+ esp_http_client
+ esp_driver_uart
+ esp_driver_gpio
+ json
+ app_update
+ INCLUDE_DIRS ".")
--- /dev/null
+idf_component_register(SRCS "app_main.c"
+ "aes.c"
+ INCLUDE_DIRS ".")
\ No newline at end of file
--- /dev/null
+#include "aes.h"
+#include "string.h"
+
+
+// 为了能针对C51进行优化,并且又使代码可用于ARM和PC等环境,
+// 在非C51环境(没有定义__C51__)下需要把C51特定的关键字定义为空
+#ifndef __C51__
+ #define code
+ #define data
+ #define idata
+ #define xdata
+ #define pdata
+ typedef unsigned char BOOL;
+#else
+ typedef bit BOOL;
+#endif
+
+#define Nk (AES_KEY_LENGTH / 32) // 以“字”(4字节)为单位的密钥长度
+#define Nb 4 // 以“字”(4字节)为单位的加解密数据块大小,固定为4
+
+// Nr:加密的轮数
+#if AES_KEY_LENGTH == 128
+ #define Nr 10
+#elif AES_KEY_LENGTH == 192
+ #define Nr 12
+#elif AES_KEY_LENGTH == 256
+ #define Nr 14
+#else
+ #error AES_KEY_LENGTH must be 128, 192 or 256 BOOLs!
+#endif
+
+// GF(28) 多项式
+#define BPOLY 0x1B // Lower 8 BOOLs of (x^8 + x^4 + x^3 + x + 1), ie. (x^4 + x^3 + x + 1).
+
+/*****************************************************************************
+* Typedef Enum 枚举定义
+*****************************************************************************/
+
+/*****************************************************************************
+* Struct 数据结构定义
+******************************************************************************/
+
+
+/*****************************************************************************
+* Local variable 局部变量
+*****************************************************************************/
+
+// AES子密钥表,当密钥长度为128位时,占用176字节空间
+static xdata unsigned char g_roundKeyTable[4*Nb*(Nr+1)];
+
+// 加密用的SBox
+static code const unsigned char sBox[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+// 解密用的SBox
+static code const unsigned char invSBox[256] =
+{
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: rotation_word
+// 描述: 对一个“字”数据进行循环右移。
+// 输入参数: pWord -- 要右移的4字节数据。
+// 输出参数: pWord -- 右移后的4字节数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void rotation_word(unsigned char *pWord)
+{
+ unsigned char temp = pWord[0];
+ pWord[0] = pWord[1];
+ pWord[1] = pWord[2];
+ pWord[2] = pWord[3];
+ pWord[3] = temp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: xor_bytes
+// 描述: 批量异或两组数据。
+// 输入参数: pData1 -- 要异或的第一组数据。
+// pData1 -- 要异或的第二组数据。
+// nCount -- 要异或的数据长度。
+// 输出参数: pData1 -- 异或后的结果。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void xor_bytes(unsigned char *pData1, const unsigned char *pData2, unsigned char nCount)
+{
+ unsigned char i;
+
+ for (i = 0; i < nCount; i++)
+ {
+ pData1[i] ^= pData2[i];
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: AddRoundKey
+// 描述: 把 中间状态数据 加上(异或)子密钥,数据长度为16字节。
+// 输入参数: pState -- 状态数据。
+// pRoundKey -- 子密钥数据。
+// 输出参数: pState -- 加上子密钥后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+// static void AddRoundKey(unsigned char *pState, const unsigned char *pRoundKey)
+// {
+// xor_bytes(pState, pRoundKey, 4*Nb);
+// }
+
+// AddRoundKey的宏形式,比函数形式可以节省4字节的data数据
+#define AddRoundKey(pState, pRoundKey) \
+ xor_bytes((pState), (pRoundKey), 4*Nb)
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: sub_bytes
+// 描述: 通过S盒子置换状态数据。
+// 输入参数: pState -- 状态数据。
+// nCount -- 状态数据长度。
+// bInvert -- 是否使用反向S盒子(解密时使用)。
+// 输出参数: pState -- 置换后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void sub_bytes(unsigned char *pState, unsigned char nCount, BOOL bInvert)
+{
+ unsigned char i;
+ const unsigned char code *pSBox = bInvert ? invSBox : sBox;
+
+ for (i = 0; i < nCount; i++)
+ {
+ pState[i] = pSBox[pState[i]];
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: shift_rows
+// 描述: 把状态数据移行。
+// 输入参数: pState -- 状态数据。
+// bInvert -- 是否反向移行(解密时使用)。
+// 输出参数: pState -- 移行后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void shift_rows(unsigned char *pState, BOOL bInvert)
+{
+ // 注意:状态数据以列形式存放!
+
+ unsigned char r; // row, 行
+ unsigned char c; // column,列
+ unsigned char temp;
+ unsigned char rowData[4];
+
+ for (r = 1; r < 4; r++)
+ {
+ // 备份一行数据
+ for (c = 0; c < 4; c++)
+ {
+ rowData[c] = pState[r + 4*c];
+ }
+
+ temp = bInvert ? (4 - r) : r;
+ for (c = 0; c < 4; c++)
+ {
+ pState[r + 4*c] = rowData[(c + temp) % 4];
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: gf_mult_by02
+// 描述: 在GF(28)域的 乘2 运算。
+// 输入参数: num -- 乘数。
+// 输出参数: 无。
+// 返回值: num乘以2的结果。
+///////////////////////////////////////////////////////////////////////////////
+static unsigned char gf_mult_by02(unsigned char num)
+{
+ if ((num & 0x80) == 0)
+ {
+ num = num << 1;
+ }
+ else
+ {
+ num = (num << 1) ^ BPOLY;
+ }
+
+ return num;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: mix_columns
+// 描述: 混合状态各列数据。
+// 输入参数: pState -- 状态数据。
+// bInvert -- 是否反向混合(解密时使用)。
+// 输出参数: pState -- 混合列后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void mix_columns(unsigned char *pState, BOOL bInvert)
+{
+ unsigned char i;
+ unsigned char temp;
+ unsigned char a0Pa2_M4; // 4(a0 + a2)
+ unsigned char a1Pa3_M4; // 4(a1 + a3)
+ unsigned char result[4];
+
+ for (i = 0; i < 4; i++, pState += 4)
+ {
+ // b0 = 2a0 + 3a1 + a2 + a3
+ // = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0
+
+ temp = pState[0] ^ pState[1] ^ pState[2] ^ pState[3];
+ result[0] = temp ^ pState[0] ^ gf_mult_by02((unsigned char) (pState[0] ^ pState[1]));
+ result[1] = temp ^ pState[1] ^ gf_mult_by02((unsigned char) (pState[1] ^ pState[2]));
+ result[2] = temp ^ pState[2] ^ gf_mult_by02((unsigned char) (pState[2] ^ pState[3]));
+ result[3] = temp ^ pState[3] ^ gf_mult_by02((unsigned char) (pState[3] ^ pState[0]));
+
+ if (bInvert)
+ {
+ // b0' = 14a0 + 11a1 + 13a2 + 9a3
+ // = (a0 + a1 + a2 + a3) + 2(a0 + a1) + a0 (这部分为b0)
+ // + 2(4(a0 + a2) + 4(a1 + a3))
+ // + 4(a0 + a2)
+
+ a0Pa2_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[0] ^ pState[2])));
+ a1Pa3_M4 = gf_mult_by02(gf_mult_by02((unsigned char) (pState[1] ^ pState[3])));
+ temp = gf_mult_by02((unsigned char) (a0Pa2_M4 ^ a1Pa3_M4));
+ result[0] ^= temp ^ a0Pa2_M4;
+ result[1] ^= temp ^ a1Pa3_M4;
+ result[2] ^= temp ^ a0Pa2_M4;
+ result[3] ^= temp ^ a1Pa3_M4;
+ }
+
+ memcpy(pState, result, 4);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: block_encrypt
+// 描述: 对单块数据加密。
+// 输入参数: pState -- 状态数据。
+// 输出参数: pState -- 加密后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void block_encrypt(unsigned char *pState)
+{
+ unsigned char i;
+
+ AddRoundKey(pState, g_roundKeyTable);
+
+ for (i = 1; i <= Nr; i++) // i = [1, Nr]
+ {
+ sub_bytes(pState, 4*Nb, 0);
+ shift_rows(pState, 0);
+
+ if (i != Nr)
+ {
+ mix_columns(pState, 0);
+ }
+
+ AddRoundKey(pState, &g_roundKeyTable[4*Nb*i]);
+ }
+
+// 为了节省代码,合并到循化执行
+// sub_bytes(pState, 4*Nb);
+// shift_rows(pState, 0);
+// AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: block_decrypt
+// 描述: 对单块数据解密。
+// 输入参数: pState -- 状态数据。
+// 输出参数: pState -- 解密后的状态数据。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+static void block_decrypt(unsigned char *pState)
+{
+ unsigned char i;
+
+ AddRoundKey(pState, &g_roundKeyTable[4*Nb*Nr]);
+
+ for (i = Nr; i > 0; i--) // i = [Nr, 1]
+ {
+ shift_rows(pState, 1);
+ sub_bytes(pState, 4*Nb, 1);
+ AddRoundKey(pState, &g_roundKeyTable[4*Nb*(i-1)]);
+
+ if (i != 1)
+ {
+ mix_columns(pState, 1);
+ }
+ }
+
+// 为了节省代码,合并到循化执行
+// shift_rows(pState, 1);
+// sub_bytes(pState, 4*Nb, 1);
+// AddRoundKey(pState, g_roundKeyTable);
+}
+
+/*****************************************************************************
+* Global Functions 全局函数
+******************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: aes_init
+// 描述: 初始化,在此执行扩展密钥操作。
+// 输入参数: pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
+// 输出参数: 无。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+void aes_init(const void *pKey)
+{
+ // 扩展密钥
+ unsigned char i;
+ unsigned char *pRoundKey;
+ unsigned char Rcon[4] = {0x01, 0x00, 0x00, 0x00};
+
+ memcpy(g_roundKeyTable, pKey, 4*Nk);
+
+ pRoundKey = &g_roundKeyTable[4*Nk];
+
+ for (i = Nk; i < Nb*(Nr+1); pRoundKey += 4, i++)
+ {
+ memcpy(pRoundKey, pRoundKey - 4, 4);
+
+ if (i % Nk == 0)
+ {
+ rotation_word(pRoundKey);
+ sub_bytes(pRoundKey, 4, 0);
+ xor_bytes(pRoundKey, Rcon, 4);
+
+ Rcon[0] = gf_mult_by02(Rcon[0]);
+ }
+ else if (Nk > 6 && i % Nk == Nb)
+ {
+ sub_bytes(pRoundKey, 4, 0);
+ }
+
+ xor_bytes(pRoundKey, pRoundKey - 4*Nk, 4);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 函数名: aes_soft_encrypt
+// 描述: 加密数据
+// 输入参数: pPlainText -- 明文,即需加密的数据,其长度为nDataLen字节。
+// nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+// pIV -- 初始化向量,如果使用ECB模式,可设为NULL。
+// 输出参数: pCipherText -- 密文,即由明文加密后的数据,可以与pPlainText相同。
+// 返回值: 无。
+//////////////////////////////////////////////////////////////////////////
+void aes_soft_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
+ unsigned int nDataLen, const unsigned char *pIV)
+{
+ unsigned int i;
+ (void)pIV;
+
+ if (pPlainText != pCipherText)
+ {
+ memcpy(pCipherText, pPlainText, nDataLen);
+ }
+
+ for (i = nDataLen/(4*Nb); i > 0 ; i--, pCipherText += 4*Nb)
+ {
+ #if AES_MODE == AES_MODE_CBC
+ xor_bytes(pCipherText, pIV, 4*Nb);
+ #endif
+
+ block_encrypt(pCipherText);
+ pIV = pCipherText;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 函数名: aes_soft_decrypt
+// 描述: 解密数据
+// 输入参数: pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
+// nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+// pIV -- 初始化向量,如果使用ECB模式,可设为NULL。
+// 输出参数: pPlainText -- 明文,即由密文解密后的数据,可以与pCipherText相同。
+// 返回值: 无。
+//////////////////////////////////////////////////////////////////////////
+void aes_soft_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
+ unsigned int nDataLen, const unsigned char *pIV)
+{
+ unsigned int i;
+
+ if (pPlainText != pCipherText)
+ {
+ memcpy(pPlainText, pCipherText, nDataLen);
+ }
+
+ // 从最后一块数据开始解密,这样不用开辟空间来保存IV
+ pPlainText += nDataLen - 4*Nb;
+ for (i = nDataLen/(4*Nb); i > 0 ; i--, pPlainText -= 4*Nb)
+ {
+ block_decrypt(pPlainText);
+
+ #if AES_MODE == AES_MODE_CBC
+ if (i == 1)
+ {// 最后一块数据
+ xor_bytes(pPlainText, pIV, 4*Nb);
+ }
+ else
+ {
+ xor_bytes(pPlainText, pPlainText - 4*Nb, 4*Nb);
+ }
+ #endif
+ }
+}
--- /dev/null
+#ifndef _AES_H
+#define _AES_H
+
+
+// 以bit为单位的密钥长度,只能为 128,192 和 256 三种
+#define AES_KEY_LENGTH 128
+
+// 加解密模式
+#define AES_MODE_ECB 0 // 电子密码本模式(一般模式)
+#define AES_MODE_CBC 1 // 密码分组链接模式
+#define AES_MODE AES_MODE_ECB
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 函数名: aes_init
+// 描述: 初始化,在此执行扩展密钥操作。
+// 输入参数: pKey -- 原始密钥,其长度必须为 AES_KEY_LENGTH/8 字节。
+// 输出参数: 无。
+// 返回值: 无。
+///////////////////////////////////////////////////////////////////////////////
+void aes_init(const void *pKey);
+
+//////////////////////////////////////////////////////////////////////////
+// 函数名: aes_soft_encrypt
+// 描述: 加密数据
+// 输入参数: pPlainText -- 明文,即需加密的数据,其长度为nDataLen字节。
+// nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+// pIV -- 初始化向量,如果使用ECB模式,可设为NULL。
+// 输出参数: pCipherText -- 密文,即由明文加密后的数据,可以与pPlainText相同。
+// 返回值: 无。
+//////////////////////////////////////////////////////////////////////////
+void aes_soft_encrypt(const unsigned char *pPlainText, unsigned char *pCipherText,
+ unsigned int nDataLen, const unsigned char *pIV);
+
+//////////////////////////////////////////////////////////////////////////
+// 函数名: aes_soft_decrypt
+// 描述: 解密数据
+// 输入参数: pCipherText -- 密文,即需解密的数据,其长度为nDataLen字节。
+// nDataLen -- 数据长度,以字节为单位,必须为AES_KEY_LENGTH/8的整倍数。
+// pIV -- 初始化向量,如果使用ECB模式,可设为NULL。
+// 输出参数: pPlainText -- 明文,即由密文解密后的数据,可以与pCipherText相同。
+// 返回值: 无。
+//////////////////////////////////////////////////////////////////////////
+void aes_soft_decrypt( const unsigned char *pCipherText,unsigned char *pPlainText,
+ unsigned int nDataLen, const unsigned char *pIV);
+#endif /* _AES_H */
--- /dev/null
+/* MQTT Mutual Authentication Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include "project_common.h"
+#include "esp_timer.h"
+
+static const char *MAIN_TAG = "main";
+
+// 1秒定时器句柄
+static esp_timer_handle_t onesec_timer_handle = NULL;
+
+// 1秒定时器回调函数
+static void onesec_timer_callback(void* arg)
+{
+ // 在这里添加每秒执行的代码
+ ESP_LOGI(MAIN_TAG, "onesec_timer_callback memory head size: %" PRIu32 " bytes", esp_get_free_heap_size());
+ // 例如:检查状态、发送心跳等
+}
+
+
+#if (IOT_ENABLE)
+#if (1)
+const char* device_name = "PXN-W GTL";
+const char* http_url = "http://192.168.66.85:8080";//"http://107.23.202.137:8080";//"http://192.168.66.80:8080";//http://107.23.202.137:8080
+const char* http_token = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImJhZWRiZjUyLTUzMDgtNDRlOS04MWI3LTE1MmU4NGYwYzk5ZCJ9.fyxIGmmYD-pKd7VQ02DrL6FwBKVkqXoIu4iKSVMOUj8WubDvuSdbX6j8YzQw8K_t6UTRVZsRDTlO5me2KKhs7A";//"eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjRhNjBlZDdiLTExMDUtNDU5Ny1iNDBhLTg5ZDRiMzMzNTIyYSJ9.CUxkgU2F6BoxzE3HHVdXAin2OEDD1-D_iI0zh7VWTnlNsjsHHulvZVMq2hQLXF4cAQIJpLWwiMZJQO6Bvy9vwg";
+const uint32_t user_id = 1;
+const char* wifi_ssid = "XiaoMing1919810";
+const char* wifi_pwd = "XiaoMing1919810";
+
+const uint16_t mcu_vid = 0x36E6;
+const uint16_t mcu_pid = 0xA00B;
+#endif
+#endif
+
+void Main_Loop_Task(void *pvParameters)
+{
+ common_setting.heart_beat_interval = 1000;
+ common_setting.mcu_info_got_flag = 1;
+
+ // 创建1秒周期性定时器
+ const esp_timer_create_args_t onesec_timer_args = {
+ .callback = &onesec_timer_callback,
+ .arg = NULL,
+ .name = "onesec_timer"
+ };
+ ESP_ERROR_CHECK(esp_timer_create(&onesec_timer_args, &onesec_timer_handle));
+
+ // 启动1秒周期性定时器 (1000000微秒 = 1秒)
+ ESP_ERROR_CHECK(esp_timer_start_periodic(onesec_timer_handle, 1000000));
+
+ ESP_LOGI(MAIN_TAG, "1 second periodic timer started");
+
+#if (IOT_ENABLE)
+ if(common_storage.net_info.wifi_info_flag == 1 && common_storage.net_info.serial_number_flag == 1 && common_storage.net_info.device_id_flag == 1 && common_storage.ssl_cert[0].length != 0 && common_storage.ssl_cert[1].length != 0 && common_storage.ssl_cert[2].length != 0)
+ {
+ Wifi_Queue_Send(0, 0x03, 0);
+ }
+#if (USER_TEST_ENABLE)
+ // BLE Test
+ common_setting.mcu_info.vid = mcu_vid;
+ common_setting.mcu_info.pid = mcu_pid;
+ common_setting.mcu_info.fw_version = 0x0001;
+ common_setting.mcu_info.build_version = 0x0001;
+ memcpy(common_setting.mcu_info.product_name, device_name, strlen(device_name));
+ common_setting.mcu_info.product_name_len = strlen(device_name);
+ common_setting.mcu_info_got_flag = 1;
+ // Ble_Queue_Send(0xFF, 0x01);
+ xEventGroupSetBits(ble_event_group, BLE_ON_BIT);
+
+ memset(common_setting.net_pairing_info.http_url, 0x00, sizeof(common_setting.net_pairing_info.http_url));
+ memset(common_setting.net_pairing_info.http_token, 0x00, sizeof(common_setting.net_pairing_info.http_token));
+ memcpy(common_setting.net_pairing_info.http_url, http_url, strlen(http_url));
+ memcpy(common_setting.net_pairing_info.http_token, http_token, strlen(http_token));
+ common_setting.net_pairing_info.http_url_length = strlen(http_url);
+ common_setting.net_pairing_info.http_token_length = strlen(http_token);
+
+ common_setting.net_pairing_info.user_id = user_id;
+
+ common_setting.net_pairing_info.http_url_flag = 1;
+ common_setting.net_pairing_info.http_token_flag = 1;
+ common_setting.net_pairing_info.user_id_flag = 1;
+
+ memcpy(common_setting.wifi_status.cur_ssid, wifi_ssid, strlen(wifi_ssid));
+ memcpy(common_setting.wifi_status.cur_pwd, wifi_pwd, strlen(wifi_pwd));
+ common_setting.wifi_status.cur_ssid_len = strlen(wifi_ssid);
+ common_setting.wifi_status.cur_pwd_len = strlen(wifi_pwd);
+ Wifi_Queue_Send(0, 0x02, 0);
+#endif
+#endif
+ for(;;)
+ {
+#if (1)
+ Ble_Enable_Status_Check();
+
+ Wifi_Enable_Status_Check();
+
+ Http_Connect_Status_Check();
+
+ Mqtt_Connect_Status_Check();
+#endif
+ // heart beat
+ if(common_setting.heart_beat_enable == 1 && common_setting.heart_beat_interval != 0)
+ {
+ static uint32_t heart_beat_tick = 0;
+ heart_beat_tick += MAIN_LOOP_INTERVAL;
+ if(heart_beat_tick >= common_setting.heart_beat_interval)
+ {
+ heart_beat_tick = 0;
+ Check_Host_Type(0x00, NULL, 0, HOST_TYPE_UART);
+ if(common_setting.mcu_info_got_flag == 0)
+ {
+ Check_Host_Type(0x01, NULL, 0, HOST_TYPE_UART);
+ }
+ }
+ }
+
+ if((xEventGroupWaitBits(common_event_group, COMMON_RESET_BIT, pdFALSE, pdFALSE, 0) & COMMON_RESET_BIT) != 0)
+ {
+ xEventGroupClearBits(common_event_group, COMMON_RESET_BIT);
+ iap_end_cnt = 100;
+ }
+
+ if(iap_end_cnt > 0)
+ {
+ iap_end_cnt -= MAIN_LOOP_INTERVAL;
+ if(iap_end_cnt <= 0)
+ {
+ esp_restart();
+ }
+ }
+ vTaskDelay(MAIN_LOOP_INTERVAL / portTICK_PERIOD_MS);
+ }
+}
+
+void app_main(void)
+{
+ ESP_LOGI(MAIN_TAG, "[APP] Startup..");
+
+ ESP_LOGI(MAIN_TAG, "[APP] IDF version: %s", esp_get_idf_version());
+ ESP_LOGI(MAIN_TAG, "[DEVICE] Version: %04x %04x", FW_VERSION, BUILD_VERSION);
+ // esp_log_level_set("*", ESP_LOG_INFO);
+ // esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
+ // esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
+ // esp_log_level_set("transport", ESP_LOG_VERBOSE);
+ // esp_log_level_set("outbox", ESP_LOG_VERBOSE);
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory start: %" PRIu32 " bytes", esp_get_free_heap_size());
+
+ /* Initialize NVS. */
+ esp_err_t ret;
+ ret = nvs_flash_init();
+ if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
+ ESP_ERROR_CHECK(nvs_flash_erase());
+ ret = nvs_flash_init();
+ }
+ ESP_ERROR_CHECK( ret );
+
+ wifi_scan_mutex = xSemaphoreCreateBinary();
+ xSemaphoreGive(wifi_scan_mutex);
+ user_flash_mutex = xSemaphoreCreateBinary();
+ xSemaphoreGive(user_flash_mutex);
+ wifi_queue_handle = xQueueCreateStatic(WIFI_QUEUE_LENGTH, WIFI_QUEUE_ITEM_SIZE, wifi_queue_storage, &wifi_queue_buffer);
+ // ble_queue_handle = xQueueCreateStatic(BLE_QUEUE_LENGTH, BLE_QUEUE_ITEM_SIZE, ble_queue_storage, &ble_queue_buffer);
+ ble_event_group = xEventGroupCreate();
+ ble_write_queue_handle = xQueueCreateStatic(BLE_WRTIE_QUEUE_LENGTH, BLE_WRTIE_QUEUE_ITEM_SIZE, ble_write_queue_storage, &ble_write_queue_buffer);
+ ble_notify_queue_handle = xQueueCreateStatic(BLE_NOTIFY_QUEUE_LENGTH, BLE_NOTIFY_QUEUE_ITEM_SIZE, ble_notify_queue_storage, &ble_notify_queue_buffer);
+ uart_tx_queue_handle = xQueueCreateStatic(UART_TX_QUEUE_LENGTH, UART_TX_QUEUE_ITEM_SIZE, uart_tx_queue_storage, &uart_tx_queue_buffer);
+ common_event_group = xEventGroupCreate();
+
+ User_Flash_Check();
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory after User_Flash_Check: %" PRIu32 " bytes", esp_get_free_heap_size());
+ // UART
+ Uart_Initialize();
+ uart_task_handler = xTaskCreateStatic(Uart_Task, "Uart_Task", UART_TASK_STACK, NULL, 2, uart_task_stack, &uart_task_tcb);
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory after Uart_Initialize: %" PRIu32 " bytes", esp_get_free_heap_size());
+#if (1)//#if (IOT_ENABLE)
+ // LWIP
+ ESP_ERROR_CHECK(esp_netif_init());
+ ESP_ERROR_CHECK(esp_event_loop_create_default());
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory after lwip: %" PRIu32 " bytes", esp_get_free_heap_size());
+
+ // WIFI MQTT
+ Wifi_Sta_Init();
+
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory after wifi: %" PRIu32 " bytes", esp_get_free_heap_size());
+#endif
+
+ main_loop_task_handler = xTaskCreateStatic(Main_Loop_Task, "Main_Loop_Task", MAIN_LOOP_TASK_STACK, NULL, 4, main_loop_task_stack, &main_loop_task_tcb);
+ ESP_LOGI(MAIN_TAG, "[APP] Free memory after Main_Loop: %" PRIu32 " bytes", esp_get_free_heap_size());
+
+
+}
+
+
--- /dev/null
+#include "project_common.h"
+
+static const char *BLE_TAG = "ble";
+
+uint8_t ble_write_queue_storage[BLE_WRTIE_QUEUE_LENGTH*BLE_WRTIE_QUEUE_ITEM_SIZE];
+QueueHandle_t ble_write_queue_handle;
+StaticQueue_t ble_write_queue_buffer;
+
+uint8_t ble_notify_queue_storage[BLE_NOTIFY_QUEUE_LENGTH*BLE_NOTIFY_QUEUE_ITEM_SIZE];
+QueueHandle_t ble_notify_queue_handle;
+StaticQueue_t ble_notify_queue_buffer;
+
+/* Library function declarations */
+void ble_store_config_init(void);
+
+/* Private function declarations */
+static void on_stack_reset(int reason);
+static void on_stack_sync(void);
+static void nimble_host_config_init(void);
+static void nimble_host_task(void *param);
+
+/* Private functions */
+/*
+ * Stack event callback functions
+ * - on_stack_reset is called when host resets BLE stack due to errors
+ * - on_stack_sync is called when host has synced with controller
+ */
+static void on_stack_reset(int reason) {
+ /* On reset, print reset reason to console */
+ ESP_LOGI(BLE_TAG, "nimble stack reset, reset reason: %d", reason);
+}
+
+static void on_stack_sync(void) {
+ /* On stack sync, do advertising initialization */
+ adv_init();
+}
+
+static void nimble_host_config_init(void) {
+ /* Set host callbacks */
+ ble_hs_cfg.reset_cb = on_stack_reset;
+ ble_hs_cfg.sync_cb = on_stack_sync;
+ ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
+ ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
+
+ /* Store host configuration */
+ ble_store_config_init();
+}
+
+static void nimble_host_task(void *param) {
+ /* Task entry log */
+ ESP_LOGI(BLE_TAG, "nimble host task has been started!");
+
+ /* This function won't return until nimble_port_stop() is executed */
+ nimble_port_run();
+
+ /* Clean up at exit */
+ vTaskDelete(NULL);
+}
+
+static void ble_task(void *param)
+{
+ /* Task entry log */
+ ESP_LOGI(BLE_TAG, "ble task has been started!");
+
+ /* Loop forever */
+ while (1)
+ {
+ send_comm_2_indication();
+
+ /* Sleep */
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+ }
+
+ /* Clean up at exit */
+ vTaskDelete(NULL);
+}
+
+void Ble_Nimble_Init(void)
+{
+ /* Local variables */
+ int rc;
+ esp_err_t ret;
+
+ /* NimBLE stack initialization */
+ ret = nimble_port_init();
+ if (ret != ESP_OK) {
+ ESP_LOGE(BLE_TAG, "failed to initialize nimble stack, error code: %d ",
+ ret);
+ return;
+ }
+
+ /* GAP service initialization */
+ rc = gap_init();
+ if (rc != 0) {
+ ESP_LOGE(BLE_TAG, "failed to initialize GAP service, error code: %d", rc);
+ return;
+ }
+
+ /* GATT server initialization */
+ rc = gatt_svc_init();
+ if (rc != 0) {
+ ESP_LOGE(BLE_TAG, "failed to initialize GATT server, error code: %d", rc);
+ return;
+ }
+
+ /* NimBLE host configuration initialization */
+ nimble_host_config_init();
+
+ /* Start NimBLE host task thread and return */
+ nimble_task_handler = xTaskCreateStatic(nimble_host_task, "NimBLE", NIMBLE_TASK_STACK, NULL, 5, nimble_task_stack, &nimble_task_tcb);
+ ble_task_handler = xTaskCreateStatic(ble_task, "ble_task", BLE_TASK_STACK, NULL, 6, ble_task_stack, &ble_task_tcb);
+}
+
+// void Ble_Queue_Send(uint8_t host_type, uint8_t enable)
+// {
+// ble_queue_write[0] = host_type;
+// ble_queue_write[1] = enable;
+// xQueueSend(ble_queue_handle, ble_queue_write, 0);
+// }
+//common_setting.mcu_info_got_flag=0 common_storage.net_info.device_id_flag=0 common_storage.net_info.wifi_info_flag=0 common_setting.ble_status.ble_state=0
+void Ble_Enable_Status_Check(void)
+{
+ if(common_setting.mcu_info_got_flag)
+ {
+ if(common_storage.net_info.device_id_flag == 0 && common_storage.net_info.wifi_info_flag == 0 && common_setting.ble_status.ble_state == 0)
+ {
+ // Ble_Queue_Send(0xFF, 0x01);
+ xEventGroupSetBits(ble_event_group, BLE_ON_BIT);
+ ESP_LOGI(BLE_TAG, "[APP] Free memory device_id_flag1 on: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ else if(common_storage.net_info.device_id_flag && common_storage.net_info.wifi_info_flag && common_setting.ble_status.ble_state != 0)
+ {
+ // Ble_Queue_Send(0xFF, 0xFF);
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);
+ ESP_LOGI(BLE_TAG, "[APP] Free memory device_id_flag2 on: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ }
+
+ // static uint8_t ble_queue_read[BLE_QUEUE_ITEM_SIZE] = {0}; // byte0:0:串口 1:蓝牙 0xFF:本地 byte1:1:打开BLE 0xFF:关闭
+ EventBits_t ble_bits = xEventGroupWaitBits(ble_event_group, BLE_ON_BIT | BLE_OFF_BIT, pdFALSE, pdFALSE, 0);
+ if((ble_bits & BLE_ON_BIT) != 0)
+ {
+ ESP_LOGI(BLE_TAG, "[APP] Free memory BLE_ON_BIT: %d", common_setting.ble_status.ble_state);
+ xEventGroupClearBits(ble_event_group, BLE_ON_BIT);
+ if(common_setting.ble_status.ble_state == 0)//蓝牙开始广播并打开蓝牙开始配网
+ {
+ // 开始配网
+ common_setting.ble_status.ble_state = 1;
+ common_setting.ble_enable_tick = 0;
+
+ common_setting.net_pairing_info.http_url_flag = 0;
+ common_setting.net_pairing_info.http_token_flag = 0;
+ common_setting.net_pairing_info.user_id_flag = 0;
+ ESP_LOGI(BLE_TAG, "[APP] Free memory ble on1: %" PRIu32 " bytes", esp_get_free_heap_size());
+ Ble_Nimble_Init();
+
+
+ ESP_LOGI(BLE_TAG, "[APP] Free memory ble on2: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ }
+ else if((ble_bits & BLE_OFF_BIT) != 0)
+ {
+ ESP_LOGI(BLE_TAG, "[APP] Free memory stop_ble: %d", common_setting.ble_status.ble_state);
+ xEventGroupClearBits(ble_event_group, BLE_OFF_BIT);
+ if(common_setting.ble_status.ble_state > 0)
+ {
+ #if (IS_CLOSE_BLE)
+ common_setting.ble_status.ble_state = 0;
+ common_setting.ble_enable_tick = 0;
+ stop_advertising();//停止广播
+ #endif
+ // 停止配网
+ int ret = nimble_port_stop();
+ if (ret == 0)
+ {
+ if(ble_task_handler != NULL)
+ {
+ vTaskDelete(ble_task_handler);
+ }
+ nimble_port_deinit();
+
+ common_setting.ble_status.ble_state = 0;
+ common_setting.ble_enable_tick = 0;
+
+ ESP_LOGI(BLE_TAG, "nimble_port_stop\n");
+ }
+ else
+ {
+ ESP_LOGI(BLE_TAG, "nimble_port_stop fail\n");
+ }
+ ESP_LOGI(BLE_TAG, "[APP] Free memory ble off: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ }
+
+ // 30分钟无配网动作则关闭蓝牙
+ if(common_setting.ble_status.ble_state > 0)
+ {
+ common_setting.ble_enable_tick += MAIN_LOOP_INTERVAL;
+ if(common_setting.ble_enable_tick > (30*60*1000))
+ {
+ // Ble_Queue_Send(0xFF, 0xFF);
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);
+ common_setting.ble_enable_tick = 0;
+ }
+ }
+ // ESP_LOGI(BLE_TAG, "Ble_Enable_Status_Check\n");
+}
--- /dev/null
+#ifndef _BLE_H_
+#define _BLE_H_
+
+/* Includes */
+/* STD APIs */
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+/* ESP APIs */
+#include "esp_log.h"
+#include "nvs_flash.h"
+#include "sdkconfig.h"
+
+/* FreeRTOS APIs */
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+
+/* NimBLE stack APIs */
+#include "host/ble_hs.h"
+#include "host/ble_uuid.h"
+#include "host/util/util.h"
+#include "nimble/ble.h"
+#include "nimble/nimble_port.h"
+#include "nimble/nimble_port_freertos.h"
+
+/* Defines */
+#define DEVICE_NAME "PXN-W GTL"
+// #define DEVICE_NAME ""
+
+#define GATT_UUID_COMM_0 0xFFD0
+#define GATT_UUID_COMM_1 0xFFD1
+#define GATT_UUID_COMM_2 0xFFD2
+
+#define BLE_RECV_BUF_SIZE 512 //根据mtu最大设置23-512
+typedef struct
+{
+ uint16_t length;
+ uint8_t data[BLE_RECV_BUF_SIZE];
+}BLE_MESSAGE_T;
+
+
+#define BLE_WRTIE_QUEUE_LENGTH 2
+#define BLE_WRTIE_QUEUE_ITEM_SIZE (sizeof(BLE_MESSAGE_T))
+extern uint8_t ble_write_queue_storage[BLE_WRTIE_QUEUE_LENGTH*BLE_WRTIE_QUEUE_ITEM_SIZE];
+extern QueueHandle_t ble_write_queue_handle;
+extern StaticQueue_t ble_write_queue_buffer;
+
+#define BLE_NOTIFY_QUEUE_LENGTH 2
+#define BLE_NOTIFY_QUEUE_ITEM_SIZE (sizeof(BLE_MESSAGE_T))
+extern uint8_t ble_notify_queue_storage[BLE_NOTIFY_QUEUE_LENGTH*BLE_NOTIFY_QUEUE_ITEM_SIZE];
+extern QueueHandle_t ble_notify_queue_handle;
+extern StaticQueue_t ble_notify_queue_buffer;
+
+void Ble_Nimble_Init(void);
+
+// void Ble_Queue_Send(uint8_t host_type, uint8_t enable);
+void Ble_Enable_Status_Check(void);
+
+#endif
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDWTCCAkGgAwIBAgIURpSxKjdraq6TLFCENuhtjNelfLYwDQYJKoZIhvcNAQEL
+BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g
+SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTI1MDcxNDEyMjk1
+MloXDTQ5MTIzMTIzNTk1OVowHjEcMBoGA1UEAwwTQVdTIElvVCBDZXJ0aWZpY2F0
+ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMARxe7gi6kJPTDgNyiR
+X9SaFaYxe1nNUx6ukcNalUfdgy4QFRdxb2oRJgOiISsYnRvzDsGR5kKGYaHiuI+D
+oUT58f6h19++aLjF5fg2e42Di/zFBNZtRzByOUP/WulHA4xAGIEAxNtjytLzxO+W
+Dt4vCEEIfrYTW9P5r92+r8ZUaJKrSafll/LM5Zcj6GkcR9C39EX7uaYg95CIdx4Y
+bgvsYZbb/PIAP/4wRbOwzyXxrwjh+WYBzPb1dxnDixF5NfPDaHWzGHH9EtX2zqnY
++L2g+bgRfgjEIM1m8TCxnpzJTyyfhIb1Coc+bOdk3LROxKNQ/lsvpGJvIqBFCjQ0
+yqsCAwEAAaNgMF4wHwYDVR0jBBgwFoAU4dLvDsL/yIHxYiAY/6KLleZoDMowHQYD
+VR0OBBYEFOPECh7CdzVR61Dtfj0k9T0CYok9MAwGA1UdEwEB/wQCMAAwDgYDVR0P
+AQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQCjgzLzbRkxY7JFK4IvPRSWtYxm
+46apVPCdRFIqhv0LaZT74HSpHSvxmLvjdb9c/I5HwCtM+PI3/XRDDy8TOvQlFvAN
+zXDtocxO5nF06o1hado/XvJVO7t5EvEHqzYnOb1ntYL2FSZdNR/qX8Sthj3xxLYT
+RUgkzmACuP6Ivm94c3nJ85MKZS8Q+hlp9HQcQig6JKfbGh0zDluHOF0NcFSl7dTm
+MVfZbCQoC8jh7p7MAnKNs8/yvqSpCUOOzQMzEAdkZh/UWJvruJ9Ip4IikaCyHp4s
+5pB+GyXaiG9k//JLuL2CHijTLcCJrm6PG3TLvtZqgDgvlkVnKc9j1Yy+zCe7
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEAwBHF7uCLqQk9MOA3KJFf1JoVpjF7Wc1THq6Rw1qVR92DLhAV
+F3FvahEmA6IhKxidG/MOwZHmQoZhoeK4j4OhRPnx/qHX375ouMXl+DZ7jYOL/MUE
+1m1HMHI5Q/9a6UcDjEAYgQDE22PK0vPE75YO3i8IQQh+thNb0/mv3b6vxlRokqtJ
+p+WX8szllyPoaRxH0Lf0Rfu5piD3kIh3HhhuC+xhltv88gA//jBFs7DPJfGvCOH5
+ZgHM9vV3GcOLEXk188NodbMYcf0S1fbOqdj4vaD5uBF+CMQgzWbxMLGenMlPLJ+E
+hvUKhz5s52TctE7Eo1D+Wy+kYm8ioEUKNDTKqwIDAQABAoIBAQC2JWTHSC1KLdfY
+7RmCIHN4BHQ5er2XCVAlTbowQExHrfuEiH3oEIxvUznwwiWgYCRGaDd7POjX9+bJ
+BmCuwU8EQeDL8SHvLvzTFeIkhU6ggrsUCKewzktv1zMVmCnYBp+HtxVF6bvGrxme
++sytxWnuLT4vpmW8OBmiqiytJvQ9KRNsgNoHQqKhUQAP5Zg3jhTFdDGobvssdnLI
+6nT6EJ5K89jEoi5FK0kqcsqvRfgFctrQBY79kTv5glPm8vsbVms/CyyWARhsOFNE
+8nMwKrZBCILH7I0xtjLmDT1xIAxq13ndqnqjxQ32KN3bjuCRyVU6OsDFYwFuArDY
+L525Fso5AoGBAO/qdku3T3Z0eiwTDN25VRVEkufMv00fAywzAvLyyfWZ+9JPzaZL
+xK8YfO8h+xJmSEsu81jIu7hg8FziT18nOXWVhSl7/QSbWpd7oxpYHVya0WwMGQ/o
+5U99GP0oDBzE0L/+YLZFLWoYOvg67Gsz5T3aJathR1G4IKGIacJfSCyNAoGBAMzy
+JnEDCGA53N28GgHH3nGZUUL5PmLd7hQxHiNXd86rfWKlbkZGXm+jLtd7NIK8JhAY
+lr6OCm9fvAA1Rnu9bZKqedMimQZAre0xUcFqR0RaVwg/T1Ddu+1b4vXOvEdnWYN3
+MxxPnNbxkOCgeRGlRxVXlGMxL3eQLelFfkHo6nIXAoGBAJTNj2GW6KpHxB7iEfDT
+qnnudk9fJqfmvEkFuqaE/85dG1tuM9cY13zia1rGcLsQxXYcQMKofgX12h9CHoie
+A31yp4z7YgshcCbUgG0uiceOHqYtOr4rbU7IAF/EHv8Y84ChfcqPTYOoU6ryoQA8
+x8p9KzAIvftpgJOv0CjGgDVhAoGBAKeLeuO+z/UiuK5JHZXBGNgTt/whmN/ogL7f
+HL1Vv2skhR/FEG7BDmkDpcKhRV9vg0p7X5kus9czE5Wz+Agm51IUrf1udl1HOSkE
+vcp6IQL/O9FROH1qmDzGdrfvJ7rUAbjZFN6bMyQBXihU6EUFsiP/ch7ZUe3T38Sp
+fDtTt35HAoGBAMow/0jcQC67Rj6Of9z13QjqJ/gTr3OeWo1LwSnz1S40W9mF3LXY
+ipjcYdWNtNuJU/oAWv9UpoqnIluXVmLFF11QX9R2yNLlU9CFgCUA4zItwFx5dZWa
+hBk3V0vfvXrDRTkxVvybL0IZa69SVYT4KybXYPkKNZ9bqFaMz/hh47po
+-----END RSA PRIVATE KEY-----
--- /dev/null
+#include <stdint.h>
+#include "crc.h"
+#include "esp_partition.h"
+#include "esp_log.h"
+static const char *CHECKCRC_TAG = "COMMON";
+#if (0)
+/**
+ * @brief 字节按位逆序 1100 0101 -> 1010 0011
+ */
+static uint8_t bit8_reverse(uint8_t x)
+{
+ x = ((x >> 1) & 0x55) | ((x & 0x55) << 1);
+ x = ((x >> 2) & 0x33) | ((x & 0x33) << 2);
+
+ return ( x >> 4) | (x << 4);
+}
+
+static uint16_t bit16_reverse(uint16_t x)
+{
+ x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
+ x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
+ x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4);
+
+ return((x >> 8) | (x << 8));
+}
+
+static uint32_t bit32_reverse(uint32_t x)
+{
+ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+ x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+ x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+ x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+
+ return((x >> 16) | (x << 16));
+}
+
+uint8_t crc8_universal(uint8_t *data, uint32_t lenth, uint8_t POLY, uint8_t INIT, uint8_t XOROUT, bool REFIN, bool REFOUT)
+{
+ uint8_t i, new_data;
+ uint8_t crc;
+
+ crc = INIT;
+
+ for (; lenth> 0; lenth--)
+ {
+ new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));
+ crc = crc ^ (new_data);
+
+ for (i = 0; i < 8; i++)
+ {
+ if (crc & 0x80)
+ crc = (crc << 1) ^ POLY;
+ else
+ crc <<= 1;
+ }
+ }
+
+ crc = REFOUT? bit8_reverse(crc) : crc;
+ crc ^= XOROUT;
+
+ return(crc);
+}
+
+uint16_t crc16_universal(uint8_t *data, uint32_t lenth, uint16_t POLY, uint16_t INIT, uint16_t XOROUT, bool REFIN, bool REFOUT)
+{
+ uint8_t i, new_data;
+ uint16_t crc;
+
+ crc = INIT;
+
+ for (; lenth> 0; lenth--)
+ {
+ new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));
+ crc = crc ^ (new_data << 8);
+
+ for (i = 0; i < 8; i++)
+ {
+ if (crc & 0x8000)
+ crc = (crc << 1) ^ POLY;
+ else
+ crc <<= 1;
+ }
+ }
+
+ crc = REFOUT? bit16_reverse(crc) : crc;
+ crc ^= XOROUT;
+
+ return(crc);
+}
+
+uint32_t crc32_universal(uint8_t *data, uint32_t lenth, uint32_t POLY, uint32_t INIT, uint32_t XOROUT, bool REFIN, bool REFOUT)
+{
+ uint8_t i, new_data;
+ uint32_t crc;
+
+ crc = INIT;
+
+ for (; lenth> 0; lenth--)
+ {
+ new_data = REFIN? bit8_reverse(*(data++)) : (*(data++));
+ crc = crc ^ (new_data << 24);
+
+ for (i = 0; i < 8; i++)
+ {
+ if (crc & 0x80000000)
+ crc = (crc << 1) ^ POLY;
+ else
+ crc <<= 1;
+ }
+ }
+
+ crc = REFOUT? bit32_reverse(crc) : crc;
+ crc ^= XOROUT;
+
+ return(crc);
+}
+#endif
+
+/*********************************************** TABLE CRC8 ***********************************************/
+#if(CRC8_BUILD)
+static const uint8_t crc8_table[256] =
+{
+ 0x00,0x91,0xE3,0x72,0x07,0x96,0xE4,0x75,0x0E,0x9F,0xED,0x7C,0x09,0x98,0xEA,0x7B,
+ 0x1C,0x8D,0xFF,0x6E,0x1B,0x8A,0xF8,0x69,0x12,0x83,0xF1,0x60,0x15,0x84,0xF6,0x67,
+ 0x38,0xA9,0xDB,0x4A,0x3F,0xAE,0xDC,0x4D,0x36,0xA7,0xD5,0x44,0x31,0xA0,0xD2,0x43,
+ 0x24,0xB5,0xC7,0x56,0x23,0xB2,0xC0,0x51,0x2A,0xBB,0xC9,0x58,0x2D,0xBC,0xCE,0x5F,
+ 0x70,0xE1,0x93,0x02,0x77,0xE6,0x94,0x05,0x7E,0xEF,0x9D,0x0C,0x79,0xE8,0x9A,0x0B,
+ 0x6C,0xFD,0x8F,0x1E,0x6B,0xFA,0x88,0x19,0x62,0xF3,0x81,0x10,0x65,0xF4,0x86,0x17,
+ 0x48,0xD9,0xAB,0x3A,0x4F,0xDE,0xAC,0x3D,0x46,0xD7,0xA5,0x34,0x41,0xD0,0xA2,0x33,
+ 0x54,0xC5,0xB7,0x26,0x53,0xC2,0xB0,0x21,0x5A,0xCB,0xB9,0x28,0x5D,0xCC,0xBE,0x2F,
+ 0xE0,0x71,0x03,0x92,0xE7,0x76,0x04,0x95,0xEE,0x7F,0x0D,0x9C,0xE9,0x78,0x0A,0x9B,
+ 0xFC,0x6D,0x1F,0x8E,0xFB,0x6A,0x18,0x89,0xF2,0x63,0x11,0x80,0xF5,0x64,0x16,0x87,
+ 0xD8,0x49,0x3B,0xAA,0xDF,0x4E,0x3C,0xAD,0xD6,0x47,0x35,0xA4,0xD1,0x40,0x32,0xA3,
+ 0xC4,0x55,0x27,0xB6,0xC3,0x52,0x20,0xB1,0xCA,0x5B,0x29,0xB8,0xCD,0x5C,0x2E,0xBF,
+ 0x90,0x01,0x73,0xE2,0x97,0x06,0x74,0xE5,0x9E,0x0F,0x7D,0xEC,0x99,0x08,0x7A,0xEB,
+ 0x8C,0x1D,0x6F,0xFE,0x8B,0x1A,0x68,0xF9,0x82,0x13,0x61,0xF0,0x85,0x14,0x66,0xF7,
+ 0xA8,0x39,0x4B,0xDA,0xAF,0x3E,0x4C,0xDD,0xA6,0x37,0x45,0xD4,0xA1,0x30,0x42,0xD3,
+ 0xB4,0x25,0x57,0xC6,0xB3,0x22,0x50,0xC1,0xBA,0x2B,0x59,0xC8,0xBD,0x2C,0x5E,0xCF,
+};
+
+uint8_t Crc8_ROHC_Cal(uint8_t* data, uint32_t len)
+{
+ unsigned char crc8 = 0xff;
+
+ while(len--)
+ {
+ crc8 = crc8_table[(crc8 ^ *data++) & 0xff];
+ }
+ ESP_LOGI(CHECKCRC_TAG, "Crc8_ROHC_Cal %x bytes:", crc8);
+ return crc8;
+}
+#endif
+/*********************************************** TABLE CRC32 ***********************************************/
+#if(CRC16_BUILD)
+static const uint16_t crc16_table[256] =
+{
+ 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+ 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+ 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+ 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+ 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+ 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+ 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+ 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+ 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+ 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+ 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+ 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+ 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+ 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+ 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+ 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+ 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+ 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+ 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+ 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+ 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+ 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+ 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+ 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+ 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+ 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+ 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+ 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+ 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+ 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+ 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+ 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
+};
+
+uint16_t Crc16_Modbus_Cal(uint8_t* data, uint32_t len)
+{
+ uint16_t crc16 = 0xFFFF;
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ crc16 = (crc16 >> 8) ^ crc16_table[(crc16 & 0xFF) ^ *data++];
+ }
+
+ return crc16;
+}
+#endif
+/*********************************************** TABLE CRC32 ***********************************************/
+#if(CRC32_BUILD)
+static const uint32_t crc32_table[256] =
+{
+ 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L,
+ 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L,
+ 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L,
+ 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+ 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 0x136C9856L,
+ 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L,
+ 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L,
+ 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+ 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L,
+ 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, 0x26D930ACL, 0x51DE003AL,
+ 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L,
+ 0xB8BDA50FL, 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+ 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, 0x76DC4190L,
+ 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 0x71B18589L, 0x06B6B51FL,
+ 0x9FBFE4A5L, 0xE8B8D433L, 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL,
+ 0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+ 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 0x6C0695EDL,
+ 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, 0x65B0D9C6L, 0x12B7E950L,
+ 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L,
+ 0xFBD44C65L, 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+ 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, 0x4369E96AL,
+ 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 0x44042D73L, 0x33031DE5L,
+ 0xAA0A4C5FL, 0xDD0D7CC9L, 0x5005713CL, 0x270241AAL, 0xBE0B1010L,
+ 0xC90C2086L, 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+ 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 0x59B33D17L,
+ 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, 0xEDB88320L, 0x9ABFB3B6L,
+ 0x03B6E20CL, 0x74B1D29AL, 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L,
+ 0x73DC1683L, 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+ 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, 0xF00F9344L,
+ 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 0xF762575DL, 0x806567CBL,
+ 0x196C3671L, 0x6E6B06E7L, 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL,
+ 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+ 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L,
+ 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, 0xD80D2BDAL, 0xAF0A1B4CL,
+ 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL,
+ 0x4669BE79L, 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+ 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, 0xC5BA3BBEL,
+ 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L, 0xB5D0CF31L,
+ 0x2CD99E8BL, 0x5BDEAE1DL, 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL,
+ 0x026D930AL, 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+ 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 0x92D28E9BL,
+ 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, 0x86D3D2D4L, 0xF1D4E242L,
+ 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L,
+ 0x18B74777L, 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+ 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, 0xA00AE278L,
+ 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 0xA7672661L, 0xD06016F7L,
+ 0x4969474DL, 0x3E6E77DBL, 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L,
+ 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+ 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L,
+ 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L,
+ 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL,
+ 0x2D02EF8DL
+};
+
+void CRC32_Init(CRC32_CTX_T *ctx)
+{
+ ctx->crc = 0xFFFFFFFF;
+}
+
+void CRC32_Update(CRC32_CTX_T *ctx, uint8_t* data, uint32_t len)
+{
+ for (uint32_t i = 0; i < len; i++)
+ {
+ ctx->crc = (ctx->crc >> 8) ^ crc32_table[(ctx->crc & 0xFF) ^ *data++];
+ }
+}
+
+uint32_t CRC32_Final(CRC32_CTX_T *ctx)
+{
+ return (ctx->crc & 0xFFFFFFFF);
+}
+
+uint32_t Crc32_JAMCRC_Cal(uint8_t* data, uint32_t len)
+{
+ uint64_t crc32 = 0xFFFFFFFF;
+ for (uint32_t i = 0; i < len; i++)
+ {
+ crc32 = (crc32 >> 8) ^ crc32_table[(crc32 & 0xFF) ^ *data++];
+ }
+ return crc32;
+}
+#endif
+
--- /dev/null
+#ifndef _CRC_H_
+#define _CRC_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#if (0)
+#define CRC8_Cal(x, y) crc8_universal(x, y, 0x07, 0x00, 0x00, false, false)
+#define CRC8_ITU_Cal(x, y) crc8_universal(x, y, 0x07, 0x00, 0x55, false, false)
+#define CRC8_ROHC_Cal(x, y) crc8_universal(x, y, 0x07, 0xFF, 0x00, true, true)
+#define CRC8_Maxim_Cal(x, y) crc8_universal(x, y, 0x31, 0x00, 0x00, true, true)
+#define CRC16_IBM_Cal(x, y) crc16_universal(x, y, 0x8005, 0x0000, 0x0000, true, true)
+#define CRC16_Maxim_Cal(x, y) crc16_universal(x, y, 0x8005, 0x0000, 0xFFFF, true, true)
+#define CRC16_USB_Cal(x, y) crc16_universal(x, y, 0x8005, 0xFFFF, 0xFFFF, true, true)
+#define CRC16_Modbus_Cal(x, y) crc16_universal(x, y, 0x8005, 0xFFFF, 0x0000, true, true)
+#define CRC16_CCITT_Cal(x, y) crc16_universal(x, y, 0x1021, 0x0000, 0x0000, true, true)
+#define CRC16_CCITT_False_Cal(x, y) crc16_universal(x, y, 0x1021, 0xFFFF, 0x0000, false, false)
+#define CRC16_X25_Cal(x, y) crc16_universal(x, y, 0x1021, 0xFFFF, 0xFFFF, true, true)
+#define CRC16_Xmodem_Cal(x, y) crc16_universal(x, y, 0x1021, 0x0000, 0x0000, false, false)
+#define CRC16_DNP_Cal(x, y) crc16_universal(x, y, 0x3D65, 0x0000, 0xFFFF, true, true)
+#define CRC32_Cal(x, y) crc32_universal(x, y, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true)
+#define CRC32_MPEG2_Cal(x, y) crc32_universal(x, y, 0x04C11DB7, 0xFFFFFFFF, 0x00000000, false, false)
+
+/**
+ * @brief 计算CRC通用算法
+ * @param data 数据地址
+ * @param lenth 数据长度
+ * @param POLY 生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7
+ * @param INIT 这是算法开始时寄存器(crc)的初始化预置值,十六进制表示
+ * @param XOROUT 计算结果与此参数异或后得到最终的CRC值
+ * @param REFIN 待测数据的每个字节是否按位反转,True或False
+ * @param REFOUT 在计算后之后,异或输出之前,整个数据是否按位反转,True或False
+ */
+uint8_t crc8_universal(uint8_t *data, uint32_t lenth, uint8_t POLY, uint8_t INIT, \
+ uint8_t XOROUT, bool REFIN, bool REFOUT);
+
+uint16_t crc16_universal(uint8_t *data, uint32_t lenth, uint16_t POLY, uint16_t INIT, \
+ uint16_t XOROUT, bool REFIN, bool REFOUT);
+
+uint32_t crc32_universal(uint8_t *data, uint32_t lenth, uint32_t POLY, uint32_t INIT, \
+ uint32_t XOROUT, bool REFIN, bool REFOUT);
+#endif
+
+
+#define CRC8_BUILD 1
+#define CRC16_BUILD 1
+#define CRC32_BUILD 1
+
+
+uint8_t Crc8_ROHC_Cal(uint8_t* data, uint32_t len);
+
+uint16_t Crc16_Modbus_Cal(uint8_t* data, uint32_t len);
+
+typedef struct
+{
+ uint64_t crc;
+}CRC32_CTX_T; // JAMCRC
+
+void CRC32_Init(CRC32_CTX_T *ctx);
+void CRC32_Update(CRC32_CTX_T *ctx, uint8_t* data, uint32_t len);
+uint32_t CRC32_Final(CRC32_CTX_T *ctx);
+uint32_t Crc32_JAMCRC_Cal(uint8_t* data, uint32_t len);
+
+
+#endif
--- /dev/null
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+/* Includes */
+#include "project_common.h"
+
+static const char *GAP_TAG = "gap";
+uint16_t ble_mtu_max = 23; // 默认MTU为23字节,实际可用为20字节
+static bool ble_advertising_enabled = true; // 广播开关
+
+/* Private function declarations */
+inline static void format_addr(char *addr_str, uint8_t addr[]);
+static void print_conn_desc(struct ble_gap_conn_desc *desc);
+
+static int gap_event_handler(struct ble_gap_event *event, void *arg);
+
+void stop_advertising(void);
+
+/* Private variables */
+static uint8_t own_addr_type = 0;
+static uint8_t addr_val[6] = {0};
+uint8_t adv_vendor_data[29] = {0xFF, 0xFF, 0xE6, 0x36, 0x0B, 0xA0, 'P', 'X', 'N', '-', 'W', ' ', 'G', 'T', 'L'};
+uint8_t adv_vendor_len = 15;
+
+/* Private functions */
+inline static void format_addr(char *addr_str, uint8_t addr[]) {
+ sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1],
+ addr[2], addr[3], addr[4], addr[5]);
+}
+
+static void print_conn_desc(struct ble_gap_conn_desc *desc) {
+ /* Local variables */
+ char addr_str[18] = {0};
+
+ /* Connection handle */
+ ESP_LOGI(GAP_TAG, "connection handle: %d", desc->conn_handle);
+
+ /* Local ID address */
+ format_addr(addr_str, desc->our_id_addr.val);
+ ESP_LOGI(GAP_TAG, "device id address: type=%d, value=%s",
+ desc->our_id_addr.type, addr_str);
+
+ /* Peer ID address */
+ format_addr(addr_str, desc->peer_id_addr.val);
+ ESP_LOGI(GAP_TAG, "peer id address: type=%d, value=%s", desc->peer_id_addr.type,
+ addr_str);
+
+ /* Connection info */
+ ESP_LOGI(GAP_TAG,
+ "conn_itvl=%d, conn_latency=%d, supervision_timeout=%d, "
+ "encrypted=%d, authenticated=%d, bonded=%d\n",
+ desc->conn_itvl, desc->conn_latency, desc->supervision_timeout,
+ desc->sec_state.encrypted, desc->sec_state.authenticated,
+ desc->sec_state.bonded);
+}
+
+void start_advertising(void)
+{
+ /* Local variables */
+ int rc = 0;
+ // const char *name;
+ struct ble_hs_adv_fields adv_fields = {0};
+ struct ble_hs_adv_fields rsp_fields = {0};
+ struct ble_gap_adv_params adv_params = {0};
+
+ /* Set advertising flags */
+ adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
+
+ *(uint16_t*)&adv_vendor_data[0] = 0xFFFF; // BLE默认厂商字段前2字节为蓝牙联盟成员厂商ID,因此固定2个字节0xFFFF
+ *(uint16_t*)&adv_vendor_data[2] = common_setting.mcu_info.vid;
+ *(uint16_t*)&adv_vendor_data[4] = common_setting.mcu_info.pid;
+ memcpy(&adv_vendor_data[6], common_setting.mcu_info.product_name, common_setting.mcu_info.product_name_len);
+
+ adv_fields.mfg_data = adv_vendor_data;
+ adv_fields.mfg_data_len = adv_vendor_len;
+
+ /* Set device name */
+ // name = ble_svc_gap_device_name();
+ // adv_fields.name = (uint8_t *)name;
+ // adv_fields.name_len = strlen(name);
+ // adv_fields.name_is_complete = 1;
+
+ // /* Set device tx power */
+ // adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+ // adv_fields.tx_pwr_lvl_is_present = 1;
+
+ // /* Set device appearance */
+ // adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG;
+ // adv_fields.appearance_is_present = 1;
+
+ // /* Set device LE role */
+ // adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL;
+ // adv_fields.le_role_is_present = 1;
+
+ /* Set advertiement fields */
+ rc = ble_gap_adv_set_fields(&adv_fields);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to set advertising data, error code: %d", rc);
+ return;
+ }
+
+ rsp_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
+
+ rsp_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+ rsp_fields.tx_pwr_lvl_is_present = 1;
+
+ ble_uuid16_t uuids = BLE_UUID16_INIT(GATT_UUID_COMM_0);
+ rsp_fields.uuids16 = &uuids;
+ rsp_fields.num_uuids16 = 1;
+ rsp_fields.uuids16_is_complete = 1;
+
+ // /* Set device address */
+ // rsp_fields.device_addr = addr_val;
+ // rsp_fields.device_addr_type = own_addr_type;
+ // rsp_fields.device_addr_is_present = 1;
+
+ // /* Set URI */
+ // rsp_fields.uri = esp_uri;
+ // rsp_fields.uri_len = sizeof(esp_uri);
+
+ // /* Set advertising interval */
+ // rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500);
+ // rsp_fields.adv_itvl_is_present = 1;
+
+ /* Set scan response fields */
+ rc = ble_gap_adv_rsp_set_fields(&rsp_fields);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to set scan response data, error code: %d", rc);
+ return;
+ }
+
+ /* Set non-connetable and general discoverable mode to be a beacon */
+ adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
+ adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+
+ /* Set advertising interval */
+ adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500);
+ adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510);
+
+ /* Start advertising */
+ if (!ble_advertising_enabled) {
+ ESP_LOGI(GAP_TAG, "advertising disabled by flag, skip start");
+ return;
+ }
+
+ rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params,
+ gap_event_handler, NULL);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to start advertising, error code: %d", rc);
+ return;
+ }
+ ESP_LOGI(GAP_TAG, "advertising started!");
+}
+
+void stop_advertising(void)
+{
+ if (!ble_advertising_enabled) {
+ ESP_LOGI(GAP_TAG, "advertising already stopped");
+ return;
+ }
+
+ int rc = ble_gap_adv_stop();
+ if (rc == 0) {
+ ESP_LOGI(GAP_TAG, "advertising stopped");
+ } else {
+ ESP_LOGE(GAP_TAG, "failed to stop advertising, err=%d", rc);
+ }
+ ble_advertising_enabled = false;
+}
+
+/*
+ * NimBLE applies an event-driven model to keep GAP service going
+ * gap_event_handler is a callback function registered when calling
+ * ble_gap_adv_start API and called when a GAP event arrives
+ */
+static int gap_event_handler(struct ble_gap_event *event, void *arg) {
+ /* Local variables */
+ int rc = 0;
+ struct ble_gap_conn_desc desc;
+
+ /* Handle different GAP event */
+ switch (event->type) {
+
+ /* Connect event */
+ case BLE_GAP_EVENT_CONNECT:
+ /* A new connection was established or a connection attempt failed. */
+ ESP_LOGI(GAP_TAG, "connection %s; status=%d",
+ event->connect.status == 0 ? "established" : "failed",
+ event->connect.status);
+
+ /* Connection succeeded */
+ if (event->connect.status == 0)
+ {
+ /* Check connection handle */
+ rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+ if (rc != 0)
+ {
+ ESP_LOGE(GAP_TAG,
+ "failed to find connection by handle, error code: %d",
+ rc);
+ return rc;
+ }
+
+ /* Print connection descriptor */
+ print_conn_desc(&desc);
+
+ /* Try to update connection parameters */
+ struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl,
+ .itvl_max = desc.conn_itvl,
+ .latency = 3,
+ .supervision_timeout =
+ desc.supervision_timeout};
+ rc = ble_gap_update_params(event->connect.conn_handle, ¶ms);
+ if (rc != 0)
+ {
+ ESP_LOGE(
+ GAP_TAG,
+ "failed to update connection parameters, error code: %d",
+ rc);
+ return rc;
+ }
+ common_setting.ble_enable_tick = 0;
+ common_setting.ble_status.ble_state = 2;
+ }
+ /* Connection failed, restart advertising if allowed */
+ else
+ {
+ if (ble_advertising_enabled) {
+ start_advertising();
+ }
+ }
+ return rc;
+
+ /* Disconnect event */
+ case BLE_GAP_EVENT_DISCONNECT:
+ /* A connection was terminated, print connection descriptor */
+ ESP_LOGI(GAP_TAG, "disconnected from peer; reason=%d",
+ event->disconnect.reason);
+
+ /* Restart advertising if allowed */
+ if (ble_advertising_enabled) {
+ start_advertising();
+ }
+ return rc;
+
+ /* Connection parameters update event */
+ case BLE_GAP_EVENT_CONN_UPDATE:
+ /* The central has updated the connection parameters. */
+ ESP_LOGI(GAP_TAG, "connection updated; status=%d",
+ event->conn_update.status);
+
+ /* Print connection descriptor */
+ rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to find connection by handle, error code: %d",
+ rc);
+ return rc;
+ }
+ print_conn_desc(&desc);
+ return rc;
+
+ /* Advertising complete event */
+ case BLE_GAP_EVENT_ADV_COMPLETE:
+ /* Advertising completed */
+ ESP_LOGI(GAP_TAG, "advertise complete; reason=%d",
+ event->adv_complete.reason);
+ if (ble_advertising_enabled) {
+ start_advertising();
+ }
+ return rc;
+
+ /* Notification sent event */
+ case BLE_GAP_EVENT_NOTIFY_TX:
+ if ((event->notify_tx.status != 0) &&
+ (event->notify_tx.status != BLE_HS_EDONE)) {
+ /* Print notification info on error */
+ ESP_LOGI(GAP_TAG,
+ "notify event; conn_handle=%d attr_handle=%d "
+ "status=%d is_indication=%d",
+ event->notify_tx.conn_handle, event->notify_tx.attr_handle,
+ event->notify_tx.status, event->notify_tx.indication);
+ }
+ return rc;
+
+ /* Subscribe event */
+ case BLE_GAP_EVENT_SUBSCRIBE:
+ /* Print subscription info to log */
+ ESP_LOGI(GAP_TAG,
+ "subscribe event; conn_handle=%d attr_handle=%d "
+ "reason=%d prevn=%d curn=%d previ=%d curi=%d",
+ event->subscribe.conn_handle, event->subscribe.attr_handle,
+ event->subscribe.reason, event->subscribe.prev_notify,
+ event->subscribe.cur_notify, event->subscribe.prev_indicate,
+ event->subscribe.cur_indicate);
+
+ /* GATT subscribe event callback */
+ gatt_svr_subscribe_cb(event);
+ return rc;
+
+ /* MTU update event */
+ case BLE_GAP_EVENT_MTU:
+ /* Print MTU update info to log */
+ ESP_LOGI(GAP_TAG, "mtu update event; conn_handle=%d cid=%d mtu=%d",
+ event->mtu.conn_handle, event->mtu.channel_id,
+ event->mtu.value);
+ ble_mtu_max = event->mtu.value;
+ return rc;
+ }
+
+ return rc;
+}
+
+
+/* Public functions */
+void adv_init(void) {
+ /* Local variables */
+ int rc = 0;
+ char addr_str[18] = {0};
+
+ /* Make sure we have proper BT identity address set (random preferred) */
+ rc = ble_hs_util_ensure_addr(0);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "device does not have any available bt address!");
+ return;
+ }
+
+ /* Figure out BT address to use while advertising (no privacy for now) */
+ rc = ble_hs_id_infer_auto(0, &own_addr_type);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to infer address type, error code: %d", rc);
+ return;
+ }
+
+ /* Printing ADDR */
+ rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to copy device address, error code: %d", rc);
+ return;
+ }
+ format_addr(addr_str, addr_val);
+ ESP_LOGI(GAP_TAG, "device address: %s", addr_str);
+
+ /* Start advertising. */
+ start_advertising();
+}
+
+int gap_init(void) {
+ /* Local variables */
+ int rc = 0;
+
+ /* Call NimBLE GAP initialization API */
+ ble_svc_gap_init();
+
+ /* Set GAP device name */
+ rc = ble_svc_gap_device_name_set(DEVICE_NAME);
+ if (rc != 0) {
+ ESP_LOGE(GAP_TAG, "failed to set device name to %s, error code: %d",
+ DEVICE_NAME, rc);
+ return rc;
+ }
+ return rc;
+}
--- /dev/null
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+#ifndef GAP_SVC_H
+#define GAP_SVC_H
+
+/* Includes */
+/* NimBLE GAP APIs */
+#include "host/ble_gap.h"
+#include "services/gap/ble_svc_gap.h"
+
+/* Defines */
+#define BLE_GAP_APPEARANCE_GENERIC_TAG 0x0200
+#define BLE_GAP_URI_PREFIX_HTTPS 0x17
+#define BLE_GAP_LE_ROLE_PERIPHERAL 0x00
+
+/* Public function declarations */
+void start_advertising(void);
+void stop_advertising(void);
+void adv_init(void);
+int gap_init(void);
+
+#endif // GAP_SVC_H
--- /dev/null
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+/* Includes */
+#include "project_common.h"
+
+static const char *GATT_TAG = "gatt";
+
+/* Private function declarations */
+static int gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+/* Private variables */
+
+/* GATT_SERVER_COMM 0 */
+static uint16_t comm_1_chr_val_handle;
+// static uint8_t comm_1_chr_val;
+
+static uint16_t comm_2_chr_val_handle;
+static BLE_MESSAGE_T ble_notify = {0};
+static uint16_t comm_2_chr_conn_handle = 0;
+static bool comm_2_chr_conn_handle_inited = false;
+static bool comm_2_indicate_status = false;
+// static bool comm_2_notify_status = false;
+
+/* GATT services table */
+static const struct ble_gatt_svc_def gatt_svr_svcs[] =
+{
+ /* Common service */
+ {
+ .type = BLE_GATT_SVC_TYPE_PRIMARY,
+ .uuid = BLE_UUID16_DECLARE(GATT_UUID_COMM_0),
+ .characteristics =
+ (struct ble_gatt_chr_def[]){
+ {
+ .uuid = BLE_UUID16_DECLARE(GATT_UUID_COMM_1),
+ .access_cb = gatt_svc_access,
+ .flags = BLE_GATT_CHR_F_WRITE|BLE_GATT_CHR_F_WRITE_NO_RSP,
+ .val_handle = &comm_1_chr_val_handle,
+ },
+
+ {
+ .uuid = BLE_UUID16_DECLARE(GATT_UUID_COMM_2),
+ .access_cb = gatt_svc_access,
+ .flags = BLE_GATT_CHR_F_NOTIFY,
+ .val_handle = &comm_2_chr_val_handle,
+ },
+
+ {
+ 0
+ },
+ },
+ },
+
+ {
+ 0, /* No more services. */
+ },
+};
+
+/* Private functions */
+static int gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+ // const ble_uuid_t *uuid;
+ int rc = 0;
+
+ switch (ctxt->op) {
+ case BLE_GATT_ACCESS_OP_READ_CHR:
+ if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
+ MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
+ conn_handle, attr_handle);
+ } else {
+ MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
+ attr_handle);
+ }
+ // uuid = ctxt->chr->uuid;
+ if(attr_handle == comm_2_chr_val_handle)
+ {
+ // MODLOG_DFLT(INFO, "read comm_2_chr_val_handle\n");
+ rc = os_mbuf_append(ctxt->om, ble_notify.data, ble_notify.length);
+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+ }
+ goto unknown;
+
+ case BLE_GATT_ACCESS_OP_WRITE_CHR: //接受上位机下发的数据
+ if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
+ MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d",
+ conn_handle, attr_handle);
+ } else {
+ MODLOG_DFLT(INFO, "Characteristic write by NimBLE stack; attr_handle=%d",
+ attr_handle);
+ }
+ // uuid = ctxt->chr->uuid;
+ if (attr_handle == comm_1_chr_val_handle) {
+ // rc = gatt_svr_write(ctxt->om,
+ // sizeof(comm_1_chr_val),
+ // sizeof(comm_1_chr_val),
+ // &comm_1_chr_val, NULL);
+ // ble_gatts_chr_updated(attr_handle);
+ // MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
+ // "all subscribed peers.\n");
+ printf("write %d, %d, %d:\n", ctxt->om->om_flags, ctxt->om->om_pkthdr_len, ctxt->om->om_len);
+ for(size_t i=0;i<ctxt->om->om_len;i++)
+ {
+ printf("%02x ", ctxt->om->om_data[i]);
+ }
+ printf("\n");
+
+ memset(&ble_notify,0x00,sizeof(BLE_MESSAGE_T));
+ if(ctxt->om->om_len <= sizeof(ble_notify.data))
+ {
+ ble_notify.length = ctxt->om->om_len;
+ memcpy(ble_notify.data, ctxt->om->om_data, ctxt->om->om_len);
+ // xQueueSend(ble_notify_queue_handle, &ble_message_temp, 0); // 回传测试
+ xQueueSend(ble_write_queue_handle, &ble_notify, 0);
+ }
+ return rc;
+ }
+ goto unknown;
+
+ // case BLE_GATT_ACCESS_OP_READ_DSC:
+ // if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
+ // MODLOG_DFLT(INFO, "Descriptor read; conn_handle=%d attr_handle=%d\n",
+ // conn_handle, attr_handle);
+ // } else {
+ // MODLOG_DFLT(INFO, "Descriptor read by NimBLE stack; attr_handle=%d\n",
+ // attr_handle);
+ // }
+ // // uuid = ctxt->dsc->uuid;
+ // // if (ble_uuid_cmp(uuid, &gatt_svr_dsc_uuid.u) == 0) {
+ // // rc = os_mbuf_append(ctxt->om,
+ // // &gatt_svr_dsc_val,
+ // // sizeof(gatt_svr_chr_val));
+ // // return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+ // // }
+ // goto unknown;
+
+ // case BLE_GATT_ACCESS_OP_WRITE_DSC:
+ // goto unknown;
+
+ default:
+ goto unknown;
+ }
+
+unknown:
+ /* Unknown characteristic/descriptor;
+ * The NimBLE host should not have called this function;
+ */
+ assert(0);
+ return BLE_ATT_ERR_UNLIKELY;
+}
+
+/* Public functions */
+void send_comm_2_indication(void)
+{
+ if (comm_2_indicate_status && comm_2_chr_conn_handle_inited)
+ {
+ // static uint32_t cnt_tick = 0;
+ // cnt_tick += 10;
+ // if(cnt_tick >= 2000)
+ // {
+ // cnt_tick = 0;
+ // static BLE_MESSAGE_T ble_temp = {0};
+ // ble_temp.length = 256;
+ // for(uint16_t i=0;i<sizeof(ble_temp.data);i++)
+ // {
+ // ble_temp.data[i] = (esp_random() & 0xFF);
+ // }
+ // xQueueSend(ble_notify_queue_handle, &ble_temp, 0);
+ // }
+
+ if(xQueueReceive(ble_notify_queue_handle, &ble_notify, 0) == pdTRUE)
+ {
+ ESP_LOGI(GATT_TAG, "ble send");
+ ESP_LOG_BUFFER_HEX(GATT_TAG, ble_notify.data, ble_notify.length);
+ ble_gatts_notify(comm_2_chr_conn_handle, comm_2_chr_val_handle);
+ }
+ }
+
+ // if (comm_2_notify_status && comm_2_chr_conn_handle_inited) {
+ // ble_gatts_notify(comm_2_chr_conn_handle, comm_2_chr_val_handle);
+
+ // for(uint16_t i=0;i<sizeof(comm_2_notify_data);i++)
+ // {
+ // comm_2_notify_data[i] = i;
+ // }
+ // }
+}
+
+/*
+ * Handle GATT attribute register events
+ * - Service register event
+ * - Characteristic register event
+ * - Descriptor register event
+ */
+void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) {
+ /* Local variables */
+ char buf[BLE_UUID_STR_LEN];
+
+ /* Handle GATT attributes register events */
+ switch (ctxt->op) {
+
+ /* Service register event */
+ case BLE_GATT_REGISTER_OP_SVC:
+ ESP_LOGD(GATT_TAG, "registered service %s with handle=%d",
+ ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
+ ctxt->svc.handle);
+ break;
+
+ /* Characteristic register event */
+ case BLE_GATT_REGISTER_OP_CHR:
+ ESP_LOGD(GATT_TAG,
+ "registering characteristic %s with "
+ "def_handle=%d val_handle=%d",
+ ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
+ ctxt->chr.def_handle, ctxt->chr.val_handle);
+ break;
+
+ /* Descriptor register event */
+ case BLE_GATT_REGISTER_OP_DSC:
+ ESP_LOGD(GATT_TAG, "registering descriptor %s with handle=%d",
+ ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
+ ctxt->dsc.handle);
+ break;
+
+ /* Unknown event */
+ default:
+ assert(0);
+ break;
+ }
+}
+
+/*
+ * GATT server subscribe event callback
+ * 1. Update heart rate subscription status
+ */
+
+void gatt_svr_subscribe_cb(struct ble_gap_event *event) {
+ /* Check connection handle */
+ // if (event->subscribe.conn_handle != BLE_HS_CONN_HANDLE_NONE) {
+ // ESP_LOGI(GATT_TAG, "subscribe event; conn_handle=%d attr_handle=%d",
+ // event->subscribe.conn_handle, event->subscribe.attr_handle);
+ // } else {
+ // ESP_LOGI(GATT_TAG, "subscribe by nimble stack; attr_handle=%d",
+ // event->subscribe.attr_handle);
+ // }
+
+ /* Check attribute handle */
+ if(event->subscribe.attr_handle == comm_2_chr_val_handle)
+ {
+ comm_2_chr_conn_handle = event->subscribe.conn_handle;
+ comm_2_chr_conn_handle_inited = true;
+ comm_2_indicate_status = event->subscribe.cur_notify;
+ // comm_2_notify_status = event->subscribe.cur_notify;
+ }
+}
+
+/*
+ * GATT server initialization
+ * 1. Initialize GATT service
+ * 2. Update NimBLE host GATT services counter
+ * 3. Add GATT services to server
+ */
+int gatt_svc_init(void) {
+ /* Local variables */
+ int rc;
+
+ /* 1. GATT service initialization */
+ ble_svc_gatt_init();
+
+ /* 2. Update GATT services counter */
+ rc = ble_gatts_count_cfg(gatt_svr_svcs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* 3. Add GATT services */
+ rc = ble_gatts_add_svcs(gatt_svr_svcs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Unlicense OR CC0-1.0
+ */
+#ifndef GATT_SVR_H
+#define GATT_SVR_H
+
+/* Includes */
+/* NimBLE GATT APIs */
+#include "host/ble_gatt.h"
+#include "services/gatt/ble_svc_gatt.h"
+
+/* NimBLE GAP APIs */
+#include "host/ble_gap.h"
+
+/* Public function declarations */
+void send_comm_2_indication(void);
+
+void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
+void gatt_svr_subscribe_cb(struct ble_gap_event *event);
+int gatt_svc_init(void);
+
+#endif // GATT_SVR_H
--- /dev/null
+#include "project_common.h"
+
+static const char *HTTP_TAG = "http";
+
+esp_err_t _http_event_handler(esp_http_client_event_t *evt)
+{
+ switch (evt->event_id) {
+ case HTTP_EVENT_ERROR:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ERROR");
+ break;
+ case HTTP_EVENT_ON_CONNECTED:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_CONNECTED");
+ break;
+ case HTTP_EVENT_HEADER_SENT:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_HEADER_SENT");
+ break;
+ case HTTP_EVENT_ON_HEADER:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
+ break;
+ case HTTP_EVENT_ON_DATA:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
+ // if (!esp_http_client_is_chunked_response(evt->client))
+ // {
+ // printf("%.*s", evt->data_len, (char*)evt->data);
+ // uint8_t *data = (uint8_t*)evt->data;
+ // for(uint32_t i=0;i<evt->data_len;i++)
+ // {
+ // printf("%02x ", *(data++));
+ // }
+ // printf("\n");
+ // }
+ break;
+ case HTTP_EVENT_ON_FINISH:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_ON_FINISH");
+ break;
+ case HTTP_EVENT_DISCONNECTED:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_DISCONNECTED");
+ break;
+ case HTTP_EVENT_REDIRECT:
+ ESP_LOGI(HTTP_TAG, "HTTP_EVENT_REDIRECT");
+ break;
+ }
+ return ESP_OK;
+}
+
+static char http_download_cache[sizeof(common_storage.ssl_cert[0].content)] = {0};
+// esp_err_t http_get_cert(uint8_t cert_type, esp_http_client_handle_t http_client)
+// {
+// esp_err_t err = 0;
+// do
+// {
+// err = esp_http_client_open(http_client, 0);
+// if (err == ESP_OK)
+// {
+// int header_ret = esp_http_client_fetch_headers(http_client);
+// ESP_LOGI(HTTP_TAG, "esp_http_client_fetch_headers = %d", header_ret);
+
+// int code = esp_http_client_get_status_code(http_client);
+// if(code == 200)
+// {
+// int file_size = esp_http_client_get_content_length(http_client);
+// if(file_size <= (sizeof(common_storage.ssl_cert[0].content)))
+// {
+// int read_len = 0;
+// memset(http_download_cache, 0x00, sizeof(http_download_cache));
+// read_len = esp_http_client_read(http_client, http_download_cache, file_size);
+// if(read_len == file_size)
+// {
+// // 成功
+// ESP_LOGI(HTTP_TAG, "\nrecv data len%d: %s\n", file_size, http_download_cache);
+
+// if(common_storage.ssl_cert[cert_type].length == file_size && memcmp(http_download_cache, common_storage.ssl_cert[cert_type].content, file_size) == 0)
+// {
+// ESP_LOGI(HTTP_TAG, "cert same: %d", cert_type);
+// err = ESP_OK;
+// break;
+// }
+// common_storage.ssl_cert[cert_type].length = file_size;
+// memset(common_storage.ssl_cert[cert_type].content, 0x00, sizeof(common_storage.ssl_cert[0].content));
+// memcpy(common_storage.ssl_cert[cert_type].content, http_download_cache, file_size);
+// if(User_Flash_Write_With_Flag(UF_OFFSET_CERT_CLIENT_CRT_ADDR+FLASH_SEC_SIZE*cert_type, UF_OFFSET_CERT_CERT_FLAG, &common_storage.ssl_cert[cert_type], sizeof(SSL_CERT_T)) == ESP_OK)
+// {
+// err = ESP_OK;
+// }
+// else
+// {
+// ESP_LOGE(HTTP_TAG, "flash write error: %d\n", cert_type);
+// err = ESP_FAIL;
+// break;
+// }
+// }
+// else
+// {
+// ESP_LOGE(HTTP_TAG, "http read size low = %d", read_len);
+// err = ESP_FAIL;
+// break;
+// }
+// }
+// else
+// {
+// ESP_LOGE(HTTP_TAG, "file_size too large");
+// err = ESP_FAIL;
+// break;
+// }
+// }
+// else
+// {
+// ESP_LOGE(HTTP_TAG, "http req failed");
+// err = ESP_FAIL;
+// break;
+// }
+// }
+// else
+// {
+// err = ESP_FAIL;
+// }
+// }while(0);
+
+// return err;
+// }
+
+HTTP_GET_CERT_TASK_PARAM_T http_get_cert_task_param;
+void http_download_task(void *pvParameters)
+{
+ uint8_t success_bit = 0;
+ for(uint8_t cert_type=0;cert_type<3;cert_type++)
+ {
+ if(http_get_cert_task_param.url[cert_type][strlen(&http_get_cert_task_param.url[cert_type][0])-1] == ' ')
+ {
+ http_get_cert_task_param.url[cert_type][strlen(&http_get_cert_task_param.url[cert_type][0])-1] = 0;
+ }
+
+ esp_http_client_config_t http_config = {
+ // .url = "https://e-pxn.com.cn/pms/api/mqtt_ssl_mutual_auth.bin",
+ .url = (const char*)&http_get_cert_task_param.url[cert_type][0],
+ .crt_bundle_attach = esp_crt_bundle_attach,
+ .event_handler = _http_event_handler,
+ // .keep_alive_enable = true,
+ // .disable_auto_redirect = true,
+ };
+ // mbedtls_ssl_conf_authmode(&ssl_config, MBEDTLS_SSL_VERIFY_NONE);
+ ESP_LOGI(HTTP_TAG, "downloading %d", cert_type);
+
+ esp_err_t err = ESP_FAIL;
+ esp_http_client_handle_t http_client = NULL; // 提前定义
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ ESP_LOGI(HTTP_TAG, "[APP] Free memory get cer on: %" PRIu32 " bytes", esp_get_free_heap_size());
+ // printf("剩余堆内存: %" PRIu32, esp_get_free_heap_size());
+ http_client = esp_http_client_init(&http_config);
+ if(http_client == NULL)
+ {
+ ESP_LOGE(HTTP_TAG, "client init fail");
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTP_TAG, "esp_http_client_init");
+ err = esp_http_client_open(http_client, 0);
+ ESP_LOGI(HTTP_TAG, "esp_http_client_init err%d\n",err);
+ if (err == ESP_OK)
+ {
+ ESP_LOGI(HTTP_TAG, "esp_http_client_open");
+ int header_ret = esp_http_client_fetch_headers(http_client);
+ ESP_LOGI(HTTP_TAG, "esp_http_client_fetch_headers = %d", header_ret);
+
+ int code = esp_http_client_get_status_code(http_client);
+ if(code == 200)
+ {
+ ESP_LOGI(HTTP_TAG, "esp_http_client_get_status_code");
+ int file_size = esp_http_client_get_content_length(http_client);
+ if(file_size <= (sizeof(common_storage.ssl_cert[0].content)))
+ {
+ int read_len = 0;
+ memset(http_download_cache, 0x00, sizeof(http_download_cache));
+ read_len = esp_http_client_read(http_client, http_download_cache, file_size);
+ if(read_len == file_size)
+ {
+ // 成功
+ ESP_LOGI(HTTP_TAG, "\nrecv data len%d: %s\n", file_size, http_download_cache);
+
+ if(common_storage.ssl_cert[cert_type].length == file_size && memcmp(http_download_cache, common_storage.ssl_cert[cert_type].content, file_size) == 0)
+ {
+ ESP_LOGI(HTTP_TAG, "cert same: %d", cert_type);
+ err = ESP_OK;
+ success_bit |= (1 << cert_type);
+ }
+ else{
+ common_storage.ssl_cert[cert_type].length = file_size;
+ memset(common_storage.ssl_cert[cert_type].content, 0x00, sizeof(common_storage.ssl_cert[0].content));
+ memcpy(common_storage.ssl_cert[cert_type].content, http_download_cache, file_size);
+ if(common_storage.net_info.wifi_pwd_len != 0 && common_storage.net_info.wifi_ssid_len != 0)
+ {
+ if(User_Flash_Write_With_Flag(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info.wifi_ssid, sizeof(NET_INFO_T)) == ESP_OK)
+ {
+ err = ESP_OK;
+ ESP_LOGE(HTTP_TAG, "flash write wifi ssid success: \n");
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "flash write wifi ssid failed: \n");
+ err = ESP_FAIL;
+
+ }
+
+ if(User_Flash_Write_With_Flag(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info.wifi_pwd, sizeof(NET_INFO_T)) == ESP_OK)
+ {
+ err = ESP_OK;
+ ESP_LOGE(HTTP_TAG, "flash write wifi pwd success: \n");
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "flash write wifi pwd failed: \n");
+ err = ESP_FAIL;
+
+ }
+ }
+
+ if(User_Flash_Write_With_Flag(UF_OFFSET_CERT_CLIENT_CRT_ADDR+FLASH_SEC_SIZE*cert_type, UF_OFFSET_CERT_CERT_FLAG, &common_storage.ssl_cert[cert_type], sizeof(SSL_CERT_T)) == ESP_OK)
+ {
+ err = ESP_OK;
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "flash write error: %d\n", cert_type);
+ err = ESP_FAIL;
+ }
+ }
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "http read size low = %d", read_len);
+ err = ESP_FAIL;
+ }
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "file_size too large");
+ err = ESP_FAIL;
+ }
+ }
+ else
+ {
+ ESP_LOGE(HTTP_TAG, "http req failed");
+ err = ESP_FAIL;
+ }
+
+ }
+ else
+ {
+ err = ESP_FAIL;
+ }
+ if(http_client != NULL)
+ {
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+ http_client = NULL;
+ }
+ if(err == ESP_OK)
+ {
+ success_bit |= (1 << cert_type);
+ break;
+ }
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ }
+
+ if(err != ESP_OK)
+ {
+ ESP_LOGI(HTTP_TAG, "download fail %d", cert_type);
+ break;
+ }
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ }
+
+
+ if(success_bit == ((1 << SSL_CLIENT_CRT) | (1 << SSL_CLIENT_KEY) | (1 << SSL_SERVER_CRT)))
+ {
+ //成功
+ // Ble_Queue_Send(0xFF, 0xFF);
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);//关闭蓝牙配网
+ ESP_LOGI(HTTP_TAG, "download clientcer clientkey mqtt \n");
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//
+ }
+
+ vTaskDelete(NULL);
+ return;
+}
+#define HTTP_RETRY_NUMBER_MAX (3) //HTTP请求失败重试次数最大值
+#define HTTP_GET 0
+#define HTTP_POST 0
+#define HTTP_GET_MQTT_URL_CER_ENABLE 1 //设备请求下发mqtt地址 证书
+#define HTTP_GET_DEVICEID_ENBALE 0 //设备上报serialNumber 服务器返回deviceID等信息 本产品暂时不用deviceID,所以这个功能先关闭,后续如果需要可以打开
+#define HTTP_PUT_REPORT_MAC_RSSI_ENABLE 1 //PUT请求上报mac和rssi信息
+#define HTTP_GET_SERIAL_NUMBER_ENBALE 1 //GET请求获取serialNumber,服务器根据设备token mac pid等信息返回对应的serialNumber=deviceID等信息
+#define HTTP_GET_URL_MAX_SIZE NET_PAIRING_INFO_MAX_LEN+128
+char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
+void http_get_url_task(void *pvParameters)
+{
+ if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.user_id_flag == 0 || common_setting.mcu_info_got_flag == 0 || common_setting.net_pairing_info.http_url_length == 0 || common_setting.net_pairing_info.http_token_length == 0 || common_setting.net_pairing_info.http_url_length > NET_PAIRING_INFO_MAX_LEN || common_setting.net_pairing_info.http_token_length > NET_PAIRING_INFO_MAX_LEN)
+ {
+ ESP_LOGI(HTTP_TAG, "param wrong:%d %d %d %d %d %d\n", common_setting.net_pairing_info.http_url_flag, common_setting.net_pairing_info.http_token_flag, common_setting.net_pairing_info.user_id_flag, common_setting.mcu_info_got_flag, common_setting.net_pairing_info.http_url_length, common_setting.net_pairing_info.http_token_length);
+ vTaskDelete(NULL);
+ return;
+ }
+ //
+ uint8_t result = 0;
+ cJSON* pClientCrt = NULL;
+ cJSON* pClientkey = NULL;
+ cJSON* pServerCrt = NULL;
+ cJSON* pMqttSubUrl = NULL;
+ esp_http_client_config_t http_config =
+ {
+ .event_handler = _http_event_handler,
+ .disable_auto_redirect = true,
+ .keep_alive_enable = true,
+ };
+ #if HTTP_GET_SERIAL_NUMBER_ENBALE
+ // Get(Send:PID/Get:serialNumber) deviceID
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1.......GET serialNumber=deviceID.................\n");
+ esp_http_client_handle_t http_client = NULL;
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+
+ if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0)
+ {
+ result = 3;
+ break;
+ }
+
+ char url[HTTP_GET_URL_MAX_SIZE+1] = {0};//预留一个结束符\0
+ const char path[] = "/iot/device/getDeviceByPid/";
+ memset(url, 0x00, sizeof(url));
+
+ if(common_setting.net_pairing_info.http_url_length > 0)//copy失败会返回负数,所以这里判断>0
+ {
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ }
+ // memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ //剩余的长度必须大于path长度+4字节pid的长度+1字节结束符\0的长度,否则可能会导致内存越界
+ if((sizeof(url) - common_setting.net_pairing_info.http_url_length) >= (strlen(path) + 4))
+ {
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ snprintf(&url[common_setting.net_pairing_info.http_url_length+strlen(path)], sizeof(url) - (common_setting.net_pairing_info.http_url_length+strlen(path)), "0x%04x", common_setting.mcu_info.pid);
+ }
+ http_config.url = url;
+
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1..666........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ http_client = esp_http_client_init(&http_config);
+ if(http_client == NULL)
+ {
+ http_client=NULL;
+ ESP_LOGI(HTTP_TAG, "%s esp_http_client_init FAILE\n",__func__);
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1..666........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);//设置header,key为Authorization,value为http_token
+ esp_http_client_set_method(http_client, HTTP_METHOD_GET);//设置请求方法为GET
+ ESP_LOGI(HTTP_TAG, "%s esp_http_client_open...1.....%d %" PRIu32 " bytes",__func__,result,esp_get_free_heap_size());
+ esp_err_t err = esp_http_client_open(http_client, 0);//开始连接服务器并发送HTTP请求,write_len参数为0表示没有要发送的请求体
+ ESP_LOGI(HTTP_TAG, "%s esp_http_client_open....2....%d %" PRIu32 " bytes",__func__,result,esp_get_free_heap_size());
+ if(err == ESP_OK)
+ {
+ int header_ret = esp_http_client_fetch_headers(http_client);//获取HTTP响应头,返回值为响应头的总长度,如果返回值小于0表示获取响应头失败
+ ESP_LOGI(HTTP_TAG, "esp_http_client_fetch_headers = %d", header_ret);
+ if (header_ret >= 0)
+ {
+ memset(output_buffer, 0x00, sizeof(output_buffer));
+ int data_read = esp_http_client_read_response(http_client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);//读取HTTP响应体,output_buffer为存储响应体的缓冲区,MAX_HTTP_OUTPUT_BUFFER为缓冲区的大小,返回值为实际读取的字节数,如果返回值小于0表示读取响应体失败
+ if (data_read >= 0)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);//获取HTTP响应状态码,返回值为状态码的整数值,例如200表示请求成功,404表示资源未找到等
+ int read_len = esp_http_client_get_content_length(http_client);//获取HTTP响应体的长度,返回值为响应体的字节数,如果返回值小于0表示获取响应体长度失败
+ ESP_LOGI(HTTP_TAG, "HTTP GET Status = %d, content_length = %d", status_code, read_len);
+ // ESP_LOG_BUFFER_CHAR(HTTP_TAG, output_buffer, data_read);
+ ESP_LOGI(HTTP_TAG, "\nrecv data: %s\n", output_buffer);
+ output_buffer[data_read]='\0';
+ if(status_code == 200)
+ {
+ cJSON* root_base = cJSON_Parse(output_buffer);
+ if(root_base != NULL)
+ {
+ cJSON* pData = cJSON_GetObjectItem(root_base,"data");
+ if(pData != NULL)
+ {
+ cJSON* pSerialNumber = cJSON_GetObjectItem(pData,"serialNumber");
+ //get the value
+ if(pSerialNumber != NULL && cJSON_IsString(pSerialNumber))
+ {
+ char* str_serialNumber = pSerialNumber->valuestring;
+ ESP_LOGI(HTTP_TAG, "serialNumber: %s\n", str_serialNumber);
+
+
+ uint8_t serial_number_len = strlen(str_serialNumber);
+ if(serial_number_len == 0)
+ {
+ ESP_LOGI(HTTP_TAG, "serialNumber length is 0\n");
+ cJSON_Delete(root_base);
+ result=2;
+ }else{
+
+ if(serial_number_len > SERIAL_NUMBER_MAX_LEN)
+ {
+ serial_number_len= SERIAL_NUMBER_MAX_LEN;
+ }
+ //临时使用的数据
+ memset(common_setting.net_pairing_info.serial_number, 0x00, SERIAL_NUMBER_MAX_LEN+1);
+ memccpy(common_setting.net_pairing_info.serial_number, str_serialNumber, 0, serial_number_len);
+ common_setting.net_pairing_info.serial_number[serial_number_len] = '\0';
+ common_setting.net_pairing_info.serial_number_length = serial_number_len;
+ common_setting.net_pairing_info.serial_number_flag = 1;
+
+ //真正需要存储的flash数据
+ memset(common_storage.net_info.serial_number, 0x00, SERIAL_NUMBER_MAX_LEN+1);
+ memccpy(common_storage.net_info.serial_number, str_serialNumber, 0, serial_number_len);
+ common_storage.net_info.serial_number[serial_number_len] = '\0';
+
+ //保存flash后,
+ if(User_Flash_Write_With_Flag(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info, sizeof(NET_INFO_T)) == ESP_OK)
+ {
+ ESP_LOGI(HTTP_TAG, "flash write user config info success\n");
+ if(User_Flash_Read_Check(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info, sizeof(NET_INFO_T)) == ESP_OK)
+ {
+ ESP_LOGI(HTTP_TAG, "read serialNumber: %s\n", common_storage.net_info.serial_number);
+ }
+ result = 1;
+
+ }else
+ {
+ ESP_LOGE(HTTP_TAG, "flash write error\n");
+ result = 2;
+
+ }
+ }
+
+ }
+ else
+ {
+ result = 2;
+ }
+ }
+ else
+ {
+ result = 2;
+ }
+ cJSON_Delete(root_base);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGI(HTTP_TAG, "root_base is null\n");
+ }
+ }
+ else
+ {
+ result = 2;
+ }
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTP_TAG, "Failed to read response");
+ }
+ }
+ }
+ if(http_client != NULL){
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+ http_client = NULL;
+ }
+
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1..5555........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ vTaskDelay(50);
+ }
+ if(result != 1)
+ {
+ // 失败
+ // ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1.......GET serialNumber=deviceID............%d\n", result);
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 1.......GET serialNumber=deviceID........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ vTaskDelete(NULL);
+ return;
+ }
+ #endif
+ //put
+ //report token mac rssi
+ #if HTTP_PUT_REPORT_MAC_RSSI_ENABLE
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 2...PUT......report rssi.....status.....macadder.....");
+ // JSON字段说明
+ //{
+ // "rssi": 0,
+ // "serialNumber": "PXN1A8O0D45XD6",
+ // "status": 3,
+ // "macAddress":"99-97-77-77-07"
+ // }
+
+
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+ http_client=NULL;
+ char url[NET_PAIRING_INFO_MAX_LEN] = {0};
+ const char path[] = "/iot/device/";
+ memset(url, 0x00, sizeof(url));
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ http_config.url = url;
+ cJSON *pRoot = cJSON_CreateObject();
+
+ if(pRoot == NULL)
+ {
+ ESP_LOGE(HTTP_TAG, "cJSON_CreateObject fail");
+ result = 3;
+ vTaskDelay(50);
+ continue;
+ }
+ uint8_t mac[6] = {0};
+ char str_mac[32] = {0};
+ esp_read_mac(mac, ESP_MAC_BT);//获取mac地址
+ sprintf(str_mac, "%02X-%02X-%02X-%02X-%02X-%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ cJSON_AddStringToObject(pRoot, "serialNumber", (const char*)common_setting.net_pairing_info.serial_number);
+ cJSON_AddStringToObject(pRoot, "macAddress", str_mac);
+ cJSON_AddNumberToObject(pRoot, "rssi", common_setting.wifi_status.rssi);
+ uint8_t status = 3;//已激活设备 固定值
+ cJSON_AddNumberToObject(pRoot, "status", status);
+ // cJSON_AddItemToArray(pArray, pProductId);
+ // cJSON_AddNumberToObject(pProductId, "productId", common_setting.net_pairing_info.device_id);
+
+ // cJSON_AddNumberToObject(pRoot, "userId", common_setting.net_pairing_info.user_id);
+
+ char *post_data = cJSON_Print(pRoot);
+ if(strlen(post_data) == 0 && post_data == NULL)//数据为空说明cJSON构建失败
+ {
+ cJSON_Delete(pRoot);
+ // ESP_LOGE(HTTP_TAG, "cJSON_Print fail");
+ ESP_LOGI(HTTP_TAG, "\ncJSON_Print fail.....%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTP_TAG, "put data:%s\n", post_data);
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+
+ http_client = esp_http_client_init(&http_config);
+ if(http_client == NULL)
+ {
+
+ ESP_LOGI(HTTP_TAG, "%s http_config.url = %s",__func__, http_config.url);
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ vTaskDelay(50);
+ continue;
+ }
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
+ esp_http_client_set_method(http_client, HTTP_METHOD_PUT);
+ esp_http_client_set_header(http_client, "Content-Type", "application/json");
+
+ esp_http_client_set_post_field(http_client, post_data, strlen(post_data));
+ esp_err_t err = esp_http_client_perform(http_client);
+ if (err == ESP_OK)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ if(status_code == 200)
+ {
+ result = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ ESP_LOGI(HTTP_TAG, "HTTP PUT Status = %d, content_length = %d", status_code, read_len);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTP_TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
+ }
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ if(http_client != NULL)
+ {
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+ http_client=NULL;
+ }
+
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ vTaskDelay(50);
+ }
+ if(result != 1)
+ {
+ // 失败
+ // ESP_LOGI(HTTP_TAG, "http_put_mac_rssi_task fail 3:%d\n", result);
+ // ESP_LOGI(HTTP_TAG, "\nHTTP STEP 2....PUT.....report rssi.....status.....macadder...faile..%d\n",result);
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 3......PUT.....report rssi.....status...........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ vTaskDelete(NULL);
+ return;
+ }
+ #endif
+ //GET 配置配网服务器下发成功 下发证书 mqtt地址
+
+ #if HTTP_GET_MQTT_URL_CER_ENABLE
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 3........GET MQTT CER................\n");
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+ http_client = NULL;
+ if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.serial_number_flag == 0)
+ {
+ result = 3;
+ break;
+ }
+
+ char url[NET_PAIRING_INFO_MAX_LEN] = {0};
+ const char path[] = "/iot/device/getDeviceBySerialNumber/";
+ memset(url, 0x00, sizeof(url));
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ memcpy(&url[common_setting.net_pairing_info.http_url_length+strlen(path)], common_setting.net_pairing_info.serial_number, common_setting.net_pairing_info.serial_number_length);
+ http_config.url = url;
+
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+ ESP_LOGI(HTTP_TAG, "HTTP_TAG1 memory head size: %" PRIu32 " bytes", esp_get_free_heap_size());
+ http_client = esp_http_client_init(&http_config);
+ if(http_client == NULL)
+ {
+ ESP_LOGI(HTTP_TAG, "%s esp_http_client_init.failed = %s",__func__,http_config.url);
+ vTaskDelay(50);
+ continue;
+ }
+ ESP_LOGI(HTTP_TAG, "HTTP_TAG2 memory head size: %" PRIu32 " bytes", esp_get_free_heap_size());
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
+ esp_http_client_set_method(http_client, HTTP_METHOD_GET);
+
+ esp_err_t err = esp_http_client_open(http_client, 0);
+ if(err == ESP_OK)
+ {
+ int header_ret = esp_http_client_fetch_headers(http_client);
+ ESP_LOGI(HTTP_TAG, "esp_http_client_fetch_headers = %d", header_ret);
+ if (header_ret >= 0)
+ {
+ memset(output_buffer, 0x00, sizeof(output_buffer));
+ int data_read = esp_http_client_read_response(http_client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
+ if (data_read >= 0)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ ESP_LOGI(HTTP_TAG, "%s HTTP GET Status = %d, content_length = %d data_read = %d\n",__func__, status_code, read_len,data_read);
+ // ESP_LOG_BUFFER_CHAR(HTTP_TAG, output_buffer, data_read);
+ ESP_LOGI(HTTP_TAG, "\nrecv data: %s\n", output_buffer);
+ output_buffer[data_read]='\0';
+ if(status_code == 200)
+ {
+ cJSON* root_base = cJSON_Parse(output_buffer);
+ if(root_base != NULL)
+ {
+ cJSON* pData = cJSON_GetObjectItem(root_base,"data");
+ if(pData != NULL)
+ {
+ // cJSON* pDevice_id = cJSON_GetObjectItem(pData,"deviceId");
+ // {
+ // "serialNumber":"PXN1LJ1QUR078E",
+ // "firmwareVersion":1.0,
+ // "status":4,
+ // "rssi":-80,
+ // "clientcrtUrl":"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/02/69ce08f0bfcbe4e5bea9a6a5.crt",
+ // "clientkeyUrl":"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/02/69ce08b3bfcbe4e5bea9a6a4.key",
+ // "mosquittoorgcrtUrl":"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/02/69ce0836bfcbe4e5bea9a6a3.crt",
+ // "mqttUrl":"mqtts://a3l6aw6tvk7fvq-ats.iot.us-east-1.amazonaws.com:8883",
+ // "macAddress":"1",
+ // "pid":"0xA00B"
+ // }
+ pClientCrt = cJSON_GetObjectItem(pData,"clientcrtUrl");
+ pClientkey = cJSON_GetObjectItem(pData,"clientkeyUrl");
+ pServerCrt = cJSON_GetObjectItem(pData,"mosquittoorgcrtUrl");
+ pMqttSubUrl = cJSON_GetObjectItem(pData,"mqttUrl");
+
+ memset(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], 0x00, sizeof(http_get_cert_task_param.url[SSL_CLIENT_CRT]));
+ memset(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], 0x00, strlen(http_get_cert_task_param.url[SSL_CLIENT_KEY]));
+ memset(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], 0x00, strlen(http_get_cert_task_param.url[SSL_SERVER_CRT]));
+ //get the value
+ if((pClientCrt != NULL && cJSON_IsString(pClientCrt)) &&
+ (pClientkey != NULL && cJSON_IsString(pClientkey)) &&
+ (pServerCrt != NULL && cJSON_IsString(pServerCrt)) &&
+ (pMqttSubUrl != NULL && cJSON_IsString(pMqttSubUrl)))
+ {
+ ESP_LOGI(HTTP_TAG, "get 证书 mqtt 地址\n");
+ // common_setting.net_pairing_info.device_id = pDevice_id->valueint;
+ // common_setting.net_pairing_info.device_id_flag = 1;
+ result = 1;
+
+ memcpy(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], pClientCrt->valuestring, strlen((const char*)pClientCrt->valuestring));
+ memcpy(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], pClientkey->valuestring, strlen((const char*)pClientkey->valuestring));
+ memcpy(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], pServerCrt->valuestring, strlen((const char*)pServerCrt->valuestring));
+
+ memset(common_setting.net_pairing_info.mqtt_sub_url, 0x00, sizeof(common_setting.net_pairing_info.mqtt_sub_url));
+ memcpy(common_setting.net_pairing_info.mqtt_sub_url, pMqttSubUrl->valuestring, strlen((const char*)pMqttSubUrl->valuestring));
+ common_setting.net_pairing_info.mqtt_sub_url_length = strlen((const char*)pMqttSubUrl->valuestring);
+ common_setting.net_pairing_info.mqtt_sub_url_flag = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ }
+ else
+ {
+ result = 3;
+ }
+ cJSON_Delete(root_base);
+ }
+ else
+ {
+ result = 4;
+ ESP_LOGI(HTTP_TAG, "root_base is null\n");
+ }
+ }
+ else
+ {
+ result = 5;
+ }
+ }
+ else
+ {
+ result = 6;
+ ESP_LOGE(HTTP_TAG, "Failed to read response");
+ }
+ }
+ }
+ if(http_client != NULL)
+ {
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+ http_client=NULL;
+ }
+
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ vTaskDelay(50);
+ }
+ if(result != 1)
+ {
+ // 失败
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 3........GET MQTT CER......FAILED..........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ // ESP_LOGI(HTTP_TAG, "HTTP_TAG1 memory head size: %" PRIu32 " bytes", esp_get_free_heap_size());
+ vTaskDelete(NULL);
+ return;
+ }
+ #endif
+
+ #if HTTP_GET_DEVICEID_ENBALE
+ // GET(Send:serialNumber/Get:device_id)
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 4........................");
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+
+ if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.serial_number_flag == 0)
+ {
+ result = 3;
+ break;
+ }
+
+ char url[NET_PAIRING_INFO_MAX_LEN] = {0};
+ const char path[] = "/iot/device/getDeviceBySerialNumber/";
+ memset(url, 0x00, sizeof(url));
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ memcpy(&url[common_setting.net_pairing_info.http_url_length+strlen(path)], common_setting.net_pairing_info.serial_number, common_setting.net_pairing_info.serial_number_length);
+ http_config.url = url;
+
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+ esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
+ esp_http_client_set_method(http_client, HTTP_METHOD_GET);
+
+ esp_err_t err = esp_http_client_open(http_client, 0);
+ if(err == ESP_OK)
+ {
+ int header_ret = esp_http_client_fetch_headers(http_client);
+ ESP_LOGI(HTTP_TAG, "esp_http_client_fetch_headers = %d", header_ret);
+ if (header_ret >= 0)
+ {
+ memset(output_buffer, 0x00, sizeof(output_buffer));
+ int data_read = esp_http_client_read_response(http_client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
+ if (data_read >= 0)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ ESP_LOGI(HTTP_TAG, "HTTP GET Status = %d, content_length = %d", status_code, read_len);
+ // ESP_LOG_BUFFER_CHAR(HTTP_TAG, output_buffer, data_read);
+ ESP_LOGI(HTTP_TAG, "\nrecv data: %s\n", output_buffer);
+ output_buffer[data_read]='\0';
+ if(status_code == 200)
+ {
+ cJSON* root_base = cJSON_Parse(output_buffer);
+ if(root_base != NULL)
+ {
+ cJSON* pData = cJSON_GetObjectItem(root_base,"data");
+ if(pData != NULL)
+ {
+ cJSON* pDevice_id = cJSON_GetObjectItem(pData,"deviceId");
+
+ pClientCrt = cJSON_GetObjectItem(pData,"clientcrtUrl");
+ pClientkey = cJSON_GetObjectItem(pData,"clientkeyUrl");
+ pServerCrt = cJSON_GetObjectItem(pData,"mosquittoorgcrtUrl");
+ pMqttSubUrl = cJSON_GetObjectItem(pData,"mqttUrl");
+
+ memset(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], 0x00, sizeof(http_get_cert_task_param.url[SSL_CLIENT_CRT]));
+ memset(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], 0x00, strlen(http_get_cert_task_param.url[SSL_CLIENT_KEY]));
+ memset(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], 0x00, strlen(http_get_cert_task_param.url[SSL_SERVER_CRT]));
+ //get the value
+ if((pDevice_id != NULL && cJSON_IsString(pDevice_id) == false) &&
+ (pClientCrt != NULL && cJSON_IsString(pClientCrt)) &&
+ (pClientkey != NULL && cJSON_IsString(pClientkey)) &&
+ (pServerCrt != NULL && cJSON_IsString(pServerCrt)) &&
+ (pMqttSubUrl != NULL && cJSON_IsString(pMqttSubUrl)))
+ {
+ ESP_LOGI(HTTP_TAG, "deviceId: %d\n", pDevice_id->valueint);
+ common_setting.net_pairing_info.device_id = pDevice_id->valueint;
+ common_setting.net_pairing_info.device_id_flag = 1;
+ result = 1;
+
+ memcpy(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], pClientCrt->valuestring, strlen((const char*)pClientCrt->valuestring));
+ memcpy(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], pClientkey->valuestring, strlen((const char*)pClientkey->valuestring));
+ memcpy(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], pServerCrt->valuestring, strlen((const char*)pServerCrt->valuestring));
+
+ memset(common_setting.net_pairing_info.mqtt_sub_url, 0x00, sizeof(common_setting.net_pairing_info.mqtt_sub_url));
+ memcpy(common_setting.net_pairing_info.mqtt_sub_url, pMqttSubUrl->valuestring, strlen((const char*)pMqttSubUrl->valuestring));
+ common_setting.net_pairing_info.mqtt_sub_url_length = strlen((const char*)pMqttSubUrl->valuestring);
+ common_setting.net_pairing_info.mqtt_sub_url_flag = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ }
+ else
+ {
+ result = 2;
+ }
+ cJSON_Delete(root_base);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGI(HTTP_TAG, "root_base is null\n");
+ }
+ }
+ else
+ {
+ result = 2;
+ }
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTP_TAG, "Failed to read response");
+ }
+ }
+ }
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ }
+ if(result != 1)
+ {
+ // 失败
+ ESP_LOGI(HTTP_TAG, "http_get_DEVICEID_task fail 2:%d\n", result);
+ vTaskDelete(NULL);
+ return;
+ }
+
+ #endif
+
+ #if 0
+ // PUT(Send:device_id rssi serial_number status macAddress/Get:status_code)
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 5........................");
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+
+ char url[NET_PAIRING_INFO_MAX_LEN] = {0};
+ const char path[] = "/iot/device";
+ memset(url, 0x00, sizeof(url));
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ http_config.url = url;
+
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+ esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
+ esp_http_client_set_method(http_client, HTTP_METHOD_PUT);
+ esp_http_client_set_header(http_client, "Content-Type", "application/json");
+
+ cJSON *pRoot = cJSON_CreateObject();
+ uint8_t mac[6] = {0};
+ char str_mac[32] = {0};
+ esp_read_mac(mac, ESP_MAC_BT);
+ sprintf(str_mac, "%02x-%02x-%02x-%02x-%02x-%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ cJSON_AddNumberToObject(pRoot, "deviceId", common_setting.net_pairing_info.device_id);
+ cJSON_AddNumberToObject(pRoot, "rssi", common_setting.wifi_status.rssi);
+ cJSON_AddStringToObject(pRoot, "serialNumber", (const char*)common_setting.net_pairing_info.serial_number);
+ cJSON_AddNumberToObject(pRoot, "status", 2);
+ cJSON_AddStringToObject(pRoot, "macAddress", (const char*)str_mac);
+ char *post_data = cJSON_Print(pRoot);
+ ESP_LOGI(HTTP_TAG, "post data:%s\n", post_data);
+ esp_http_client_set_post_field(http_client, post_data, strlen(post_data));
+ esp_err_t err = esp_http_client_perform(http_client);
+ if (err == ESP_OK)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ if(status_code == 200)
+ {
+ result = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ ESP_LOGI(HTTP_TAG, "HTTP POST Status = %d, content_length = %d", status_code, read_len);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTP_TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
+ }
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ }
+ if(result != 1)
+ {
+ // 失败
+ ESP_LOGI(HTTP_TAG, "http_get_url_task fail 3:%d\n", result);
+ vTaskDelete(NULL);
+ return;
+ }
+ #endif
+ // GET(Get:download_url)
+ result = 0;
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 6........................");
+ if(pClientCrt != NULL && pClientkey != NULL && pServerCrt != NULL && pMqttSubUrl != NULL)
+ {
+ result = 1;
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP 3........CER.....HTTP..........%d %" PRIu32 " bytes",result,esp_get_free_heap_size());
+ xEventGroupSetBits(common_event_group, COMMON_HTTP_DOWNLOAD_BIT);
+ }
+ else
+ {
+ result = 2;
+ }
+ vTaskDelete(NULL);
+ return;
+}
+
+void http_bind_task(void *pvParameters)
+{
+ if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.user_id_flag == 0 || common_setting.mcu_info_got_flag == 0 || common_setting.net_pairing_info.http_url_length == 0 || common_setting.net_pairing_info.http_token_length == 0 || common_setting.net_pairing_info.http_url_length > NET_PAIRING_INFO_MAX_LEN || common_setting.net_pairing_info.http_token_length > NET_PAIRING_INFO_MAX_LEN)
+ {
+ ESP_LOGI(HTTP_TAG, "param wrong:%d %d %d %d %d %d\n", common_setting.net_pairing_info.http_url_flag, common_setting.net_pairing_info.http_token_flag, common_setting.net_pairing_info.user_id_flag, common_setting.mcu_info_got_flag, common_setting.net_pairing_info.http_url_length, common_setting.net_pairing_info.http_token_length);
+ vTaskDelete(NULL);
+ return;
+ }
+
+ uint8_t result = 0;
+ esp_http_client_config_t http_config =
+ {
+ .event_handler = _http_event_handler,
+ .disable_auto_redirect = true,
+ .keep_alive_enable = true,
+ };
+
+ // POST(Send:device_Number(serial_number) productId(deviceId) userId/Get:status_code)
+ ESP_LOGI(HTTP_TAG, "\nHTTP STEP Binding........................");
+ for(uint8_t retry=0;retry<3;retry++)
+ {
+ result = 0;
+
+ char url[NET_PAIRING_INFO_MAX_LEN] = {0};
+ const char path[] = "/iot/device/relateUser";
+ memset(url, 0x00, sizeof(url));
+ memcpy(url, common_setting.net_pairing_info.http_url, common_setting.net_pairing_info.http_url_length);
+ memcpy(&url[common_setting.net_pairing_info.http_url_length], path, strlen(path));
+ http_config.url = url;
+
+ ESP_LOGI(HTTP_TAG, "http_config.url = %s", http_config.url);
+ esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
+ esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
+ esp_http_client_set_method(http_client, HTTP_METHOD_POST);
+ esp_http_client_set_header(http_client, "Content-Type", "application/json");
+
+ cJSON *pRoot = cJSON_CreateObject();
+ cJSON *pArray = cJSON_CreateArray();
+ cJSON_AddItemToObject(pRoot, "deviceNumberAndProductIds", pArray);
+ cJSON *pDeviceNumber = cJSON_CreateObject();
+ cJSON *pProductId = cJSON_CreateObject();
+
+ cJSON_AddItemToArray(pArray, pDeviceNumber);
+ cJSON_AddStringToObject(pDeviceNumber, "deviceNumber", (const char*)common_setting.net_pairing_info.serial_number);
+ cJSON_AddItemToArray(pArray, pProductId);
+ cJSON_AddNumberToObject(pProductId, "productId", common_setting.net_pairing_info.device_id);
+
+ cJSON_AddNumberToObject(pRoot, "userId", common_setting.net_pairing_info.user_id);
+
+ char *post_data = cJSON_Print(pRoot);
+ ESP_LOGI(HTTP_TAG, "post data:%s\n", post_data);
+ esp_http_client_set_post_field(http_client, post_data, strlen(post_data));
+ esp_err_t err = esp_http_client_perform(http_client);
+ if (err == ESP_OK)
+ {
+ int status_code = esp_http_client_get_status_code(http_client);
+ int read_len = esp_http_client_get_content_length(http_client);
+ if(status_code == 200)
+ {
+ result = 1;
+ }
+ else
+ {
+ result = 2;
+ }
+ ESP_LOGI(HTTP_TAG, "HTTP POST Status = %d, content_length = %d", status_code, read_len);
+ }
+ else
+ {
+ result = 2;
+ ESP_LOGE(HTTP_TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
+ }
+ cJSON_free(post_data);
+ cJSON_Delete(pRoot);
+ esp_http_client_close(http_client);
+ esp_http_client_cleanup(http_client);
+
+ // 结果
+ if(result == 1)
+ {
+ break;
+ }
+ }
+ if(result != 1)
+ {
+ // 失败
+ ESP_LOGI(HTTP_TAG, "http_get_url_task fail 3:%d\n", result);
+ vTaskDelete(NULL);
+ return;
+ }
+
+ vTaskDelete(NULL);
+ return;
+}
+
+void Http_Connect_Status_Check(void)
+{
+ if((xEventGroupWaitBits(common_event_group, COMMON_HTTP_DOWNLOAD_BIT, pdFALSE, pdFALSE, 0) & COMMON_HTTP_DOWNLOAD_BIT) != 0)
+ {
+ xEventGroupClearBits(common_event_group, COMMON_HTTP_DOWNLOAD_BIT);
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ xTaskCreate(http_download_task, "http_download_task", HTTP_DOWNLOAD_CRT_TASK_STACK, NULL, 2, NULL);
+ ESP_LOGI(HTTP_TAG, "[APP] Free memory http2 on: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+}
+
+
+
+
+
--- /dev/null
+#ifndef _HTTP_H_
+#define _HTTP_H_
+
+#include "esp_http_client.h"
+
+#define MAX_HTTP_OUTPUT_BUFFER 2560
+#define CONFIG_EXAMPLE_ENABLE_RESPONSE_BUFFER_DUMP 1
+
+typedef struct
+{
+ char url[3][128];
+}HTTP_GET_CERT_TASK_PARAM_T;
+
+extern HTTP_GET_CERT_TASK_PARAM_T http_get_cert_task_param;;
+
+esp_err_t _http_event_handler(esp_http_client_event_t *evt);
+
+void http_get_url_task(void *pvParameters);
+void http_download_task(void *pvParameters);
+
+void Http_Connect_Status_Check(void);
+
+#endif
--- /dev/null
+#include "project_common.h"
+
+static const char *IAP_TAG = "IAP";
+
+static const esp_partition_t *update_partition = NULL;
+
+esp_ota_handle_t update_handle = 0;
+
+IAP_CMD_REPLY_T iap_cmd;
+IAP_CMD_REPLY_T iap_reply;
+
+int32_t iap_end_cnt = 0;
+
+uint8_t iap_auth = 0;
+
+static uint8_t iap_data[FLASH_SEC_SIZE];
+
+uint8_t Iap_Erase(uint32_t addr, uint32_t size)
+{
+ (void)addr;
+ (void)size;
+ update_partition = NULL;
+
+ update_handle = 0;
+
+
+
+ // 获取要升级的分区
+ update_partition = esp_ota_get_next_update_partition(NULL);
+ if(update_partition == NULL)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+ ESP_LOGI(IAP_TAG, "update_partition subtype: %d, offset: 0x%x", update_partition->subtype, (unsigned int)update_partition->address);
+
+ // 开始并擦除
+ esp_err_t err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
+ if (err != ESP_OK || update_handle == 0)
+ {
+ ESP_LOGE(IAP_TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
+ return REPLY_STATUS_FAIL;
+ }
+ return REPLY_STATUS_OK;
+}
+
+uint8_t Iap_Write(uint32_t addr, uint8_t packet_size, uint8_t* data)
+{
+ if(update_handle == 0)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+
+ esp_err_t err = esp_ota_write_with_offset(update_handle, data, packet_size, addr);
+ if(err != ESP_OK)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+
+ return REPLY_STATUS_OK;
+}
+
+uint8_t Iap_Read(uint32_t addr, uint8_t packet_size, uint8_t* data)
+{
+ esp_err_t err = 0;
+
+ //读取flash
+ err = esp_partition_read(update_partition, addr, data, packet_size);
+
+ if(err != 0)
+ {
+ ESP_LOGI(IAP_TAG, "user flash read err %d, offset:0x%08x, size:0x%x", err, (unsigned int)addr, packet_size);
+ return REPLY_STATUS_FAIL;
+ }
+ return REPLY_STATUS_OK;
+}
+
+uint32_t Iap_Check(uint32_t start_addr, uint32_t size, uint8_t *result)
+{
+ esp_err_t err = 0;
+ CRC32_CTX_T ctx = {0};
+ CRC32_Init(&ctx);
+
+ uint32_t read_num = size/FLASH_SEC_SIZE + ((size%FLASH_SEC_SIZE) != 0);
+ uint32_t read_cnt = 0;
+ uint32_t remain = 0;
+
+ memset(iap_data, 0x00, sizeof(iap_data));
+
+ if(update_partition == NULL)
+ {
+ *result = 1;
+ return 0xFFFFFFFF;
+ }
+
+ for(read_cnt = 0;read_cnt<read_num;read_cnt++)
+ {
+ if(read_cnt+1 >= read_num)
+ {
+ remain = size - (read_num-1)*FLASH_SEC_SIZE;
+ }
+ else
+ {
+ remain = FLASH_SEC_SIZE;
+ }
+ err = esp_partition_read(update_partition, start_addr+read_cnt*FLASH_SEC_SIZE, iap_data, remain);
+ if(err != ESP_OK)
+ {
+ *result = 2;
+ return 0xFFFFFFFF;
+ }
+ CRC32_Update(&ctx, iap_data, remain);
+ // ESP_LOGI(IAP_TAG, "check_crc32:%d %d %08x\n", read_cnt, read_num, CRC32_Final(&ctx));
+ }
+
+ uint32_t crc_result = CRC32_Final(&ctx);
+ *result = 0;
+ return crc_result;
+}
+
+uint8_t Iap_Verify(uint32_t addr, uint8_t packet_size, uint8_t* data)
+{
+ uint8_t temp[64];
+ if(packet_size > sizeof(temp) || update_partition == NULL)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+ esp_err_t err = esp_partition_read(update_partition, addr, temp, packet_size);
+
+ if(err == ESP_OK && memcmp(temp, data, packet_size) == 0)
+ {
+ return REPLY_STATUS_OK;
+ }
+ return REPLY_STATUS_FAIL;
+}
+
+uint8_t Iap_Cache(uint16_t position, uint16_t size, uint8_t* data)
+{
+ if(update_handle == 0)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+
+ if(position == 0)
+ {
+ memset(iap_data, 0xFF, sizeof(iap_data));
+ }
+
+ memcpy(&iap_data[position], data, size);
+
+ return REPLY_STATUS_OK;
+}
+
+uint8_t Iap_Write_Cache(uint32_t addr, uint16_t cache_size)
+{
+ if(update_handle == 0)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+
+ esp_err_t err = esp_ota_write_with_offset(update_handle, iap_data, cache_size, addr);
+ if(err != ESP_OK)
+ {
+ return REPLY_STATUS_FAIL;
+ }
+
+ return REPLY_STATUS_OK;
+}
+
+void Iap_Process(uint8_t* data, uint8_t len)
+{
+ memset(iap_reply.other.buf, 0xFF, sizeof(IAP_CMD_REPLY_T));
+ memcpy(iap_cmd.other.buf, data, len);
+ memcpy(iap_reply.other.buf, iap_cmd.other.buf, 3);
+ iap_reply.cmd.status = REPLY_STATUS_NO_CMD;
+
+ if(iap_cmd.cmd.cmd1 != CMD1_IAP_CHIP6)
+ {
+ return;
+ }
+
+ if(iap_cmd.cmd.cmd2 == CMD2_IAP_FETCH || iap_cmd.cmd.cmd2 == CMD2_IAP_CERTIFICATE || iap_cmd.cmd.cmd2 == CMD2_IAP_END || iap_auth == 1)
+ {
+ // 分析命令码
+ switch(iap_cmd.cmd.cmd2)
+ {
+ // 获取信息
+ case CMD2_IAP_FETCH:
+ {
+ iap_reply.fetch.status = REPLY_STATUS_OK;
+ iap_reply.fetch.type = iap_cmd.fetch.type;
+ if(iap_cmd.fetch.type == FETCH_VID_PID)
+ {
+ *(uint16_t*)&iap_reply.fetch.data[0] = DEVICE_VID;
+ *(uint16_t*)&iap_reply.fetch.data[2] = DEVICE_PID;
+ }
+ else if(iap_cmd.fetch.type == FETCH_FW_VERSION)
+ {
+ *(uint16_t*)&iap_reply.fetch.data[0] = FW_VERSION;
+ *(uint16_t*)&iap_reply.fetch.data[2] = BUILD_VERSION;
+ }
+ else if(iap_cmd.fetch.type == FETCH_FW_HEADER_CODE)
+ {
+ char code[FW_HEADER_CODE_SIZE] = FW_HEADER_CODE;
+ iap_reply.fetch.data[0] = FW_HEADER_CODE_SIZE;
+ memcpy(&iap_reply.fetch.data[1], code, FW_HEADER_CODE_SIZE);
+ }
+ else if(iap_cmd.fetch.type == FETCH_APP_PARTITION_INFO)
+ {
+ iap_reply.fetch.data[0] = iap_cmd.fetch.data[0];
+ if(iap_cmd.fetch.data[0] == 0x10)
+ {
+ const esp_partition_t *running_partition = NULL;
+ // 获取当前系统执行的固件所在的Flash分区
+ running_partition = esp_ota_get_running_partition();
+ if(running_partition == NULL)
+ {
+ iap_reply.fetch.status = REPLY_STATUS_FAIL;
+ }
+ else
+ {
+ *(uint32_t*)&iap_reply.fetch.data[1] = (running_partition->address) & 0xFFFFFF;
+ *(uint32_t*)&iap_reply.fetch.data[4] = (running_partition->size);
+ }
+ }
+ else if(iap_cmd.fetch.data[0] == 0x11)
+ {
+ if(update_partition == NULL)
+ {
+ update_partition = esp_ota_get_next_update_partition(NULL);
+ }
+ if(update_partition == NULL)
+ {
+ iap_reply.fetch.status = REPLY_STATUS_FAIL;
+ }
+ else
+ {
+ *(uint32_t*)&iap_reply.fetch.data[1] = (update_partition->address) & 0xFFFFFF;
+ *(uint32_t*)&iap_reply.fetch.data[4] = (update_partition->size);
+ }
+ }
+ else
+ {
+ iap_reply.fetch.status = REPLY_STATUS_NO_CMD;
+ }
+ }
+ else
+ {
+ iap_reply.fetch.status = REPLY_STATUS_NO_CMD;
+ }
+ }
+ break;
+
+ // 认证
+ case CMD2_IAP_CERTIFICATE:
+ {
+ char code[FW_HEADER_CODE_SIZE] = FW_HEADER_CODE;
+
+ if(memcmp(iap_cmd.certificate.code, code, iap_cmd.certificate.size) == 0)
+ {
+ iap_auth = 1;
+ iap_reply.certificate.status = REPLY_STATUS_OK;
+ }
+ else
+ {
+ iap_reply.certificate.status = REPLY_STATUS_FAIL;
+ }
+ }
+ break;
+
+ // 擦除
+ case CMD2_IAP_ERASE:
+ {
+ iap_reply.erase.status = Iap_Erase(0, 0);
+ }
+ break;
+
+ // 写入
+ case CMD2_IAP_WRITE:
+ {
+ uint32_t start_addr = iap_cmd.write.start_addr[0] | (iap_cmd.write.start_addr[1]<<8) | (iap_cmd.write.start_addr[2]<<16);
+ iap_reply.write.status = Iap_Write(start_addr, iap_cmd.write.packet_size, iap_cmd.write.data);
+ }
+ break;
+
+ // 读取
+ case CMD2_IAP_READ:
+ {
+ uint32_t start_addr = iap_cmd.read.start_addr[0] | (iap_cmd.read.start_addr[1]<<8) | (iap_cmd.read.start_addr[2]<<16);
+ iap_reply.read.start_addr[0] = iap_cmd.read.start_addr[0];
+ iap_reply.read.start_addr[1] = iap_cmd.read.start_addr[1];
+ iap_reply.read.start_addr[2] = iap_cmd.read.start_addr[2];
+ iap_reply.read.packet_size = iap_cmd.read.packet_size;
+ iap_reply.read.status = Iap_Read(start_addr, iap_cmd.read.packet_size, iap_reply.read.data);
+ }
+ break;
+
+ // crc校验
+ case CMD2_IAP_CHECK:
+ {
+ uint32_t start_addr = iap_cmd.check.start_addr[0] | (iap_cmd.check.start_addr[1]<<8) | (iap_cmd.check.start_addr[2]<<16);
+ memcpy(&iap_reply.check.start_addr[0], &iap_cmd.check.start_addr[0], 11);
+
+ uint8_t result = 0;
+ uint32_t crc_result = Iap_Check(start_addr, iap_cmd.check.size, &result);
+ ESP_LOGI(IAP_TAG, "CRC32_Update:%08x %08x\n", (unsigned int)crc_result, (unsigned int)iap_cmd.check.crc32);
+ if(crc_result == iap_cmd.check.crc32)
+ {
+ if(result == 0)
+ {
+ iap_reply.check.status = REPLY_STATUS_OK;
+ }
+ else
+ {
+ iap_reply.check.status = REPLY_STATUS_FAIL;
+ }
+ }
+ else
+ {
+ iap_reply.check.status = REPLY_STATUS_FAIL;
+ }
+ }
+ break;
+
+ // 检验
+ case CMD2_IAP_VERIFY:
+ {
+ uint32_t start_addr = iap_cmd.verify.start_addr[0] | (iap_cmd.verify.start_addr[1]<<8) | (iap_cmd.verify.start_addr[2]<<16);
+ iap_reply.verify.start_addr[0] = iap_cmd.verify.start_addr[0];
+ iap_reply.verify.start_addr[1] = iap_cmd.verify.start_addr[1];
+ iap_reply.verify.start_addr[2] = iap_cmd.verify.start_addr[2];
+ iap_reply.verify.status = Iap_Verify(start_addr, iap_cmd.verify.packet_size, iap_cmd.verify.data);
+ }
+ break;
+
+ // 结束
+ case CMD2_IAP_END:
+ {
+ esp_err_t err = esp_ota_end(update_handle);
+ if(err == ESP_OK)
+ {
+ err = esp_ota_set_boot_partition(update_partition);
+ if(err == ESP_OK)
+ {
+ iap_reply.verify.status = REPLY_STATUS_OK;
+ }
+ else
+ {
+ iap_reply.verify.status = REPLY_STATUS_FAIL;
+ }
+ }
+ else
+ {
+ iap_reply.verify.status = REPLY_STATUS_FAIL;
+ }
+ xEventGroupSetBits(common_event_group, COMMON_RESET_BIT);
+ }
+ break;
+
+ // 缓存
+ case CMD2_IAP_CACHE:
+ {
+ iap_reply.cache.cache_position = iap_cmd.cache.cache_position;
+ iap_reply.cache.packet_size = iap_cmd.cache.packet_size;
+ iap_reply.cache.status = Iap_Cache(iap_cmd.cache.cache_position, iap_cmd.cache.packet_size, iap_cmd.cache.data);
+ }
+ break;
+
+ // 写入缓存
+ case CMD2_IAP_WRITE_CACHE:
+ {
+ uint32_t addr = iap_cmd.write_cache.start_addr[0] | (iap_cmd.write_cache.start_addr[1]<<8) | (iap_cmd.write_cache.start_addr[2]<<16);
+ memcpy(iap_reply.write_cache.start_addr, iap_cmd.write_cache.start_addr, 5);
+ iap_reply.write_cache.status = Iap_Write_Cache(addr, iap_cmd.write_cache.cache_size);
+ }
+ break;
+
+ default:
+ iap_reply.end.status = REPLY_STATUS_NO_CMD;
+
+ ESP_LOGI(IAP_TAG, "unkown cmd\n");
+ break;
+ }
+ }
+ else
+ {
+ iap_reply.cmd.status = REPLY_STATUS_UNAUTH;
+ // 01 b1 01 0C 57 47 54 4C 5F 45 53 50 33 32 43 32
+ ESP_LOGI(IAP_TAG, "unauth\n");
+ }
+
+ Ble_Pairing_Reply(iap_reply.cmd.cmd1, iap_reply.other.buf, sizeof(iap_reply.other.buf), HOST_TYPE_UART);
+}
+
+
+
+
+
--- /dev/null
+#ifndef _IAP_H_
+#define _IAP_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* usb data length is 64 */
+#define IAP_FW_LEN (56)
+#define IAP_LEN (63)
+
+
+
+// 固件更新
+#define CMD1_IAP_BASE 0xB0
+#define CMD1_IAP_PANEL 0xB1
+#define CMD1_IAP_CHIP1 0xB2
+#define CMD1_IAP_CHIP2 0xB3
+#define CMD1_IAP_CHIP3 0xB4
+#define CMD1_IAP_CHIP4 0xB5
+#define CMD1_IAP_CHIP5 0xB6
+#define CMD1_IAP_CHIP6 0xB7
+
+#define CMD2_IAP_FETCH 0x00
+#define CMD2_IAP_CERTIFICATE 0x01
+#define CMD2_IAP_ERASE 0x02
+#define CMD2_IAP_WRITE 0x03
+#define CMD2_IAP_READ 0x04
+#define CMD2_IAP_CHECK 0x05
+#define CMD2_IAP_VERIFY 0x06
+#define CMD2_IAP_END 0x07
+#define CMD2_IAP_MOVE 0x08
+#define CMD2_IAP_CACHE 0x09
+#define CMD2_IAP_WRITE_CACHE 0x0A
+
+typedef enum
+{
+ FETCH_VID_PID = 0,
+ FETCH_FW_VERSION,
+ FETCH_FW_HEADER_CODE,
+ FETCH_APP_PARTITION_INFO,
+}IAP_FETCH_T;
+
+typedef union
+{
+ // 获取信息
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t type;
+ uint8_t data[IAP_LEN-4];
+ }__attribute__((packed)) fetch;
+
+ // 认证
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t size;
+ uint8_t code[IAP_LEN-4];
+ }__attribute__((packed)) certificate;
+
+ // 擦除
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint32_t size;
+ }__attribute__((packed)) erase;
+
+ // 写入
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint8_t packet_size;
+ uint8_t data[IAP_FW_LEN];
+ }__attribute__((packed)) write;
+
+ // 读出
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint8_t packet_size;
+ uint8_t data[IAP_FW_LEN];
+ }__attribute__((packed)) read;
+
+ // 校验
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint32_t size;
+ uint32_t crc32;
+ }__attribute__((packed)) check;
+
+ // 检验
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint8_t packet_size;
+ uint8_t data[IAP_FW_LEN];
+ }__attribute__((packed)) verify;
+
+ // 结束
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ }__attribute__((packed)) end;
+
+ // 搬运
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t type;
+ }__attribute__((packed)) move;
+
+ // 缓存
+ struct
+ {
+ uint8_t report_id;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint16_t cache_position;
+ uint16_t packet_size;
+ uint8_t data[IAP_FW_LEN];
+ }__attribute__((packed))cache;
+
+ // 写入缓存
+ struct
+ {
+ uint8_t report_id;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ uint8_t start_addr[3];
+ uint16_t cache_size;
+ }__attribute__((packed))write_cache;
+
+ // 命令
+ struct
+ {
+ uint8_t report_id:4;
+ uint8_t device:4;
+ uint8_t cmd1;
+ uint8_t cmd2:5;
+ uint8_t status:3;
+ }__attribute__((packed)) cmd;
+
+ // 其它
+ struct
+ {
+ uint8_t buf[IAP_LEN];
+ }__attribute__((packed)) other;
+}__attribute__((packed)) IAP_CMD_REPLY_T;
+
+
+
+extern IAP_CMD_REPLY_T iap_cmd;
+extern IAP_CMD_REPLY_T iap_reply;
+
+extern int32_t iap_end_cnt;
+
+
+void Iap_Process(uint8_t* data, uint8_t len);
+
+#endif
--- /dev/null
+dependencies:
+ protocol_examples_common:
+ path: ${IDF_PATH}/examples/common_components/protocol_examples_common
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIUBY1hlCGvdj4NhBXkZ/uLUZNILAwwDQYJKoZIhvcNAQEL
+BQAwgZAxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwG
+A1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1vc3F1aXR0bzELMAkGA1UECwwCQ0ExFjAU
+BgNVBAMMDW1vc3F1aXR0by5vcmcxHzAdBgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hv
+by5vcmcwHhcNMjAwNjA5MTEwNjM5WhcNMzAwNjA3MTEwNjM5WjCBkDELMAkGA1UE
+BhMCR0IxFzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTES
+MBAGA1UECgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVp
+dHRvLm9yZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBAME0HKmIzfTOwkKLT3THHe+ObdizamPg
+UZmD64Tf3zJdNeYGYn4CEXbyP6fy3tWc8S2boW6dzrH8SdFf9uo320GJA9B7U1FW
+Te3xda/Lm3JFfaHjkWw7jBwcauQZjpGINHapHRlpiCZsquAthOgxW9SgDgYlGzEA
+s06pkEFiMw+qDfLo/sxFKB6vQlFekMeCymjLCbNwPJyqyhFmPWwio/PDMruBTzPH
+3cioBnrJWKXc3OjXdLGFJOfj7pP0j/dr2LH72eSvv3PQQFl90CZPFhrCUcRHSSxo
+E6yjGOdnz7f6PveLIB574kQORwt8ePn0yidrTC1ictikED3nHYhMUOUCAwEAAaNT
+MFEwHQYDVR0OBBYEFPVV6xBUFPiGKDyo5V3+Hbh4N9YSMB8GA1UdIwQYMBaAFPVV
+6xBUFPiGKDyo5V3+Hbh4N9YSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBAGa9kS21N70ThM6/Hj9D7mbVxKLBjVWe2TPsGfbl3rEDfZ+OKRZ2j6AC
+6r7jb4TZO3dzF2p6dgbrlU71Y/4K0TdzIjRj3cQ3KSm41JvUQ0hZ/c04iGDg/xWf
++pp58nfPAYwuerruPNWmlStWAXf0UTqRtg4hQDWBuUFDJTuWuuBvEXudz74eh/wK
+sMwfu1HFvjy5Z0iMDU8PUDepjVolOCue9ashlS4EB5IECdSR2TItnAIiIwimx839
+LdUdRudafMu5T5Xma182OC0/u/xRlEm+tvKGGmfFcN0piqVl8OrSPBgIlb+1IKJE
+m/XriWr/Cq4h/JfB7NTsezVslgkBaoU=
+-----END CERTIFICATE-----
--- /dev/null
+#include "mqtt.h"
+
+static const char *MQTT_TAG = "MQTT";
+
+#define MQTT_MAX_TRY_CONNECT_TIME 10
+static uint8_t retry_connect_cnt = 0;
+// extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start");
+// extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end");
+// extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start");
+// extern const uint8_t client_key_pem_end[] asm("_binary_client_key_end");
+// extern const uint8_t server_cert_pem_start[] asm("_binary_mosquitto_org_crt_start");
+// extern const uint8_t server_cert_pem_end[] asm("_binary_mosquitto_org_crt_end");
+
+static void log_error_if_nonzero(const char *message, int error_code)
+{
+ if (error_code != 0) {
+ ESP_LOGE(MQTT_TAG, "Last error %s: 0x%x", message, error_code);
+ }
+}
+
+/*
+ * @brief Event handler registered to receive MQTT events
+ *
+ * This function is called by the MQTT client event loop.
+ *
+ * @param handler_args user data registered to the event.
+ * @param base Event base for the handler(always MQTT Base in this example).
+ * @param event_id The id for the received event.
+ * @param event_data The data for the event, esp_mqtt_event_handle_t.
+ */
+static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
+{
+ ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32, base, event_id);
+ esp_mqtt_event_handle_t event = event_data;
+ esp_mqtt_client_handle_t client = event->client;
+ int msg_id;
+
+ switch ((esp_mqtt_event_id_t)event_id) {
+ case MQTT_EVENT_CONNECTED:
+ retry_connect_cnt = 0;
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
+ // modify
+ // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
+ // ESP_LOGI(MQTT_TAG, "sent subscribe successful, msg_id=%d", msg_id);
+
+ msg_id = esp_mqtt_client_subscribe(client, "sdk/test/python", 0);
+ ESP_LOGI(MQTT_TAG, "sent subscribe successful, msg_id=%d", msg_id);
+
+ // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
+ // ESP_LOGI(MQTT_TAG, "sent subscribe successful, msg_id=%d", msg_id);
+
+ // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
+ // ESP_LOGI(MQTT_TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
+
+ break;
+ case MQTT_EVENT_DISCONNECTED:
+ if(common_setting.wifi_status.connect_mode != 3 && ++retry_connect_cnt >= MQTT_MAX_TRY_CONNECT_TIME)
+ {
+
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_DISCONNECT_BIT);
+ }
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DISCONNECTED");
+ break;
+
+ case MQTT_EVENT_SUBSCRIBED:
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
+ // modify
+ // msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
+ msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "good123", 0, 0, 0);
+ ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
+ break;
+
+ case MQTT_EVENT_UNSUBSCRIBED:
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
+ break;
+
+ case MQTT_EVENT_PUBLISHED:
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
+ break;
+
+ case MQTT_EVENT_DATA:
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DATA");
+ ESP_LOGI(MQTT_TAG, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
+ ESP_LOGI(MQTT_TAG, "DATA=%.*s\r\n", event->data_len, event->data);
+
+ // modify
+ // msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "good 456", 0, 0, 0);
+ // ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
+
+ // msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "PXN8888888", 0, 0, 0);
+ // ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
+
+ // msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "{angle=888}", 0, 0, 0);
+ // ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
+
+ break;
+
+ case MQTT_EVENT_ERROR:
+ ESP_LOGI(MQTT_TAG, "MQTT_EVENT_ERROR");
+ if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
+ log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
+ log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
+ log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
+ ESP_LOGI(MQTT_TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
+
+ }
+ break;
+
+ case MQTT_EVENT_BEFORE_CONNECT:
+ // mqtt用户信息有误
+
+ break;
+
+ default:
+ ESP_LOGI(MQTT_TAG, "Other event id:%d", event->event_id);
+ break;
+ }
+}
+
+static esp_err_t Mqtt_App_Init(void)
+{
+ esp_err_t err = ESP_FAIL;
+ if(common_setting.wifi_status.wifi_state != 1)
+ {
+ ESP_LOGI(MQTT_TAG, "wifi disconnected");
+ return ESP_FAIL;
+ }
+ if(common_storage.ssl_cert[SSL_CLIENT_CRT].length == 0 || common_storage.ssl_cert[SSL_CLIENT_KEY].length == 0 || common_storage.ssl_cert[SSL_SERVER_CRT].length == 0)
+ {
+ ESP_LOGI(MQTT_TAG, "cert error");
+ return ESP_FAIL;
+ }
+ if(common_setting.net_pairing_info.mqtt_sub_url_flag == 0 || common_setting.net_pairing_info.mqtt_sub_url_length == 0)
+ {
+ ESP_LOGI(MQTT_TAG, "mqtt url error");
+ return ESP_FAIL;
+ }
+
+ // esp_mqtt_client_config_t mqtt_cfg =
+ // {
+ // // modify
+ // // .broker.address.uri = "mqtts://test.mosquitto.org:8884",
+ // .broker.address.uri = "mqtts://a3s73cbw1oa6bc-ats.iot.us-east-1.amazonaws.com:8883",
+ // .broker.verification.certificate = (const char *)common_storage.ssl_cert[SSL_SERVER_CRT].content,
+ // .credentials =
+ // {
+ // .authentication =
+ // {
+ // .certificate = (const char *)common_storage.ssl_cert[SSL_CLIENT_CRT].content,
+ // .key = (const char *)common_storage.ssl_cert[SSL_CLIENT_KEY].content,
+ // },
+ // // modify
+ // .client_id = "basicPubSub",
+ // }
+ // };
+
+ retry_connect_cnt = 0;
+ // common_setting.mqtt_cfg.session.keepalive = 60;
+ common_setting.mqtt_cfg.network.disable_auto_reconnect = false;
+ // common_setting.mqtt_cfg.broker.address.transport = MQTT_TRANSPORT_OVER_TCP;
+ // common_setting.mqtt_cfg.buffer.out_size = 2048;
+ // common_setting.mqtt_cfg.buffer.size = 2048;
+
+ // ESP_LOGI(MQTT_TAG, "URI: %s", common_setting.net_pairing_info.mqtt_sub_url);
+
+ common_setting.mqtt_cfg.broker.address.uri = (const char *)common_setting.net_pairing_info.mqtt_sub_url;
+ common_setting.mqtt_cfg.broker.verification.certificate = (const char *)common_storage.ssl_cert[SSL_SERVER_CRT].content;
+ common_setting.mqtt_cfg.credentials.authentication.certificate = (const char *)common_storage.ssl_cert[SSL_CLIENT_CRT].content;
+ common_setting.mqtt_cfg.credentials.authentication.key = (const char *)common_storage.ssl_cert[SSL_CLIENT_KEY].content;
+ // common_setting.mqtt_cfg.credentials.client_id = (const char *)common_setting.net_pairing_info.serial_number;
+ common_setting.mqtt_cfg.credentials.client_id = "basicPubSub";
+
+ common_setting.mqtt_client_handle = esp_mqtt_client_init(&common_setting.mqtt_cfg);
+
+ /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
+ err = esp_mqtt_client_register_event(common_setting.mqtt_client_handle, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
+ if(err == ESP_OK)
+ {
+ err = esp_mqtt_client_start(common_setting.mqtt_client_handle);
+ }
+ return err;
+}
+
+void Mqtt_Connect_Status_Check(void)
+{
+ if((xEventGroupWaitBits(common_event_group, COMMON_MQTT_CONNECT_BIT, pdFALSE, pdFALSE, 0) & COMMON_MQTT_CONNECT_BIT) != 0)
+ {
+ xEventGroupClearBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ if(Mqtt_App_Init() == ESP_OK)
+ {
+ ESP_LOGI(MQTT_TAG, "[APP] Free memory mqtt on: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ else
+ {
+ ESP_LOGI(MQTT_TAG, "Mqtt init fail");
+ }
+ }
+
+ if((xEventGroupWaitBits(common_event_group, COMMON_MQTT_DISCONNECT_BIT, pdFALSE, pdFALSE, 0) & COMMON_MQTT_DISCONNECT_BIT) != 0)
+ {
+ xEventGroupClearBits(common_event_group, COMMON_MQTT_DISCONNECT_BIT);
+ vTaskDelay(50 / portTICK_PERIOD_MS);
+ if(esp_mqtt_client_stop(common_setting.mqtt_client_handle) == ESP_OK)
+ {
+ retry_connect_cnt = 0;
+ ESP_LOGI(MQTT_TAG, "[APP] Free memory mqtt off: %" PRIu32 " bytes", esp_get_free_heap_size());
+ }
+ else
+ {
+ ESP_LOGI(MQTT_TAG, "Mqtt stop fail");
+ }
+ }
+}
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef _MQTT_H_
+#define _MQTT_H_
+
+#include "project_common.h"
+
+
+
+
+
+void Mqtt_Connect_Status_Check(void);
+
+#endif
--- /dev/null
+#include "project_common.h"
+#include <inttypes.h>
+static const char *COMMON_TAG = "COMMON";
+
+const FW_FILE_HEADER_T firmware_header =
+{
+ .header_magic = 0xBAD0C0FFEE00CAFE,
+ .reserved0 = 0x0000,
+ .file_type = 0x0001,
+ .protocol_version = 0x01,
+ .device_type = 0xB7,
+
+ .code_size = FW_HEADER_CODE_SIZE,
+ .code = FW_HEADER_CODE,
+
+ .single_write_page_size = FLASH_SEC_SIZE,
+
+ .vid_app = DEVICE_VID,
+ .pid_app = DEVICE_PID,
+ .vid_boot = DEVICE_VID,
+ .pid_boot = DEVICE_PID,
+
+ .fw_version = FW_VERSION,
+ .build_version = BUILD_VERSION,
+
+ .write_erase_start_addr = 0x00000000,
+ .write_erase_size = 0xFFFFFFFF,
+ .file_start_addr = 0x0100,
+
+ // .header_type_1.cmd[0] = {.enable = 2, .content = {CMD2_IAP_MOVE, 1}},
+ // .header_type_1.cmd[1] = {.enable = 3, .content = {CMD2_IAP_MOVE, 2}},
+};
+
+/**************** Task ****************/
+// MAIN_LOOP
+TaskHandle_t main_loop_task_handler;
+StackType_t main_loop_task_stack[MAIN_LOOP_TASK_STACK];
+StaticTask_t main_loop_task_tcb;
+
+// UART
+TaskHandle_t uart_task_handler;
+StackType_t uart_task_stack[UART_TASK_STACK];
+StaticTask_t uart_task_tcb;
+
+// BLE
+TaskHandle_t nimble_task_handler;
+StackType_t nimble_task_stack[NIMBLE_TASK_STACK];
+StaticTask_t nimble_task_tcb;
+
+TaskHandle_t ble_task_handler;
+StackType_t ble_task_stack[BLE_TASK_STACK];
+StaticTask_t ble_task_tcb;
+
+// WIFI
+TaskHandle_t wifi_scan_task_handler;
+StackType_t wifi_scan_task_stack[WIFI_SCAN_TASK_STACK];
+StaticTask_t wifi_scan_task_tcb;
+
+// HTTP
+// TaskHandle_t http_get_url_task_handler;
+// StackType_t http_get_url_task_stack[HTTP_GET_URL_TASK_STACK];
+// StaticTask_t http_get_url_task_tcb;
+
+// TaskHandle_t http_download_crt_task_handler;
+// StackType_t http_download_crt_task_stack[HTTP_DOWNLOAD_CRT_TASK_STACK];
+// StaticTask_t http_download_crt_task_tcb;
+
+
+uint8_t wifi_queue_storage[WIFI_QUEUE_LENGTH*WIFI_QUEUE_ITEM_SIZE];
+QueueHandle_t wifi_queue_handle;
+StaticQueue_t wifi_queue_buffer;
+uint8_t wifi_queue_write[WIFI_QUEUE_ITEM_SIZE] = {0};
+
+// uint8_t ble_queue_storage[BLE_QUEUE_LENGTH*BLE_QUEUE_ITEM_SIZE];
+// QueueHandle_t ble_queue_handle;
+// StaticQueue_t ble_queue_buffer;
+// uint8_t ble_queue_write[BLE_QUEUE_ITEM_SIZE] = {0};
+EventGroupHandle_t ble_event_group;
+
+EventGroupHandle_t common_event_group;
+
+COMMON_STORAGE_T common_storage =
+{
+ .net_info = {.device_id_flag = 0, .wifi_info_flag = 0},
+ .ssl_cert = {[SSL_CLIENT_CRT]{.buffer = {0}}, [SSL_CLIENT_KEY]{.buffer = {0}}, [SSL_SERVER_CRT]{.buffer = {0}}},
+};
+
+COMMON_SETTING_T common_setting =
+{
+ // UNIVERSAL
+ .heart_beat_enable = 1,
+ .heart_beat_interval = 1000, // 默认上电后1秒一次
+
+ // WIFI
+ .wifi_config =
+ {
+ .sta =
+ {
+ .ssid = EXAMPLE_ESP_WIFI_SSID,
+ .password = EXAMPLE_ESP_WIFI_PASS,
+ /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8).
+ * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
+ * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
+ * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
+ */
+ .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
+ .sae_pwe_h2e = ESP_WIFI_SAE_MODE,
+ .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
+ },
+ },
+
+ //MQTT
+ // .mqtt_cfg = NULL,
+ .mqtt_client_handle = NULL,
+};
+
+// static BLE_SEND_REPLY_T net_pairing_reply;
+
+#define NET_PAIRING_REPLY_MAX_PAYLOAD (BLE_BUF_SIZE - 5) // 5 = header(1) + cmd(1) + len(2) + crc(1)
+
+#define UART_REPLY_MAX_PAYLOAD UART_BUF_SIZE // 4 = header(1) + cmd(1) + len(1) + crc(1)
+
+
+void Check_Host_Type(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type)
+{
+ switch (host_type)
+ {
+ case HOST_TYPE_UART:
+ Uart_Reply(cmd, pbuf, len, host_type);
+ /* code */
+ break;
+ case HOST_TYPE_BLE:
+ Ble_Pairing_Reply(cmd, pbuf, len, host_type);
+ break;
+
+ default:
+ break;
+ }
+}
+
+//*pub不包含帧头 命令 crcr长度等协议字段,纯数据部分,len为数据部分长度
+void Uart_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type)
+{
+ if (len > UART_REPLY_MAX_PAYLOAD-4) // 5 = header(1) + cmd(1) + len(2) + crc(1) 暂时len为1个字节
+ {
+ ESP_LOGE(COMMON_TAG, "Uart_Reply length too large: %d\n", len);
+ return;
+ }
+ static UART_RECV_DATA_T uart_pairing_reply = { 0 };
+ uint8_t header[4] = {FRAMEHEAD_IOT_TO_PANEL, cmd, 0x00, 0x00};
+ memcpy(&header[2], &len, 2);
+ uart_pairing_reply.size = len + 1 + 1 + 2 + 1; // header(1)+cmd(1)+len(2)+crc(1)
+
+ memcpy(uart_pairing_reply.buffer, header, 4);
+ if (len > 0 && pbuf != NULL)
+ {
+ memcpy(&uart_pairing_reply.buffer[4], pbuf, len);
+ }
+
+ uint8_t crc = Crc8_ROHC_Cal(&uart_pairing_reply.buffer[1], len + 3);
+ uart_pairing_reply.buffer[len + 4] = crc;
+ ESP_LOGI(COMMON_TAG, "%s crc %02x len %d",__func__, crc, len);
+
+ xQueueSend(uart_tx_queue_handle, &uart_pairing_reply, 0);
+}
+
+void Ble_Pairing_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type)
+{
+ if (len > NET_PAIRING_REPLY_MAX_PAYLOAD)
+ {
+ ESP_LOGE(COMMON_TAG, "Ble_Pairing_Reply length too large: %d\n", len);
+ return;
+ }
+
+ static BLE_RECV_DATA_T net_pairing_reply = { 0 };
+ uint8_t header[4] = {FRAMEHEAD_ESP_TO_APP, cmd, 0x00, 0x00};
+ memcpy(&header[2], &len, 2);
+ net_pairing_reply.size = len + 1 + 1 + 2 + 1; // header(1)+cmd(1)+len(2)+crc(1)
+
+ memcpy(net_pairing_reply.buffer, header, 4);
+ if (len > 0 && pbuf != NULL)
+ {
+ memcpy(&net_pairing_reply.buffer[4], pbuf, len);
+ }
+ uint8_t crc = Crc8_ROHC_Cal(&net_pairing_reply.buffer[1], len + 3);
+ net_pairing_reply.buffer[len + 4] = crc;
+ ESP_LOGI(COMMON_TAG, "Ble_Pairing_Reply crc %02x len %u", crc, len);
+
+ xQueueSend(ble_notify_queue_handle, &net_pairing_reply, 0);
+}
+//原始数据流程保留,上层协议流程修改为直接调用Uart_Reply和Net_Pairing_Reply接口,底层协议流程由接口内部实现
+// void Ble_Pairing_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type)
+// {
+// static UART_RECV_DATA_T net_pairing_reply = {0};
+// uint8_t header[4] ={FRAMEHEAD_ESP_TO_APP,cmd, 0x00,0x00};
+// memcpy(&header[2], &len, 2);
+// net_pairing_reply.size = len+sizeof(uint8_t)+sizeof(uint8_t)+sizeof(uint16_t)+sizeof(uint8_t);//帧头(1)+命令(1)+长度(2)+CRC(1)
+
+// memcpy(net_pairing_reply.buffer, header, 4);
+// if(len > 0 && pbuf != NULL)
+// {
+// memcpy(&net_pairing_reply.buffer[4], pbuf, len);
+// }
+// uint8_t crc = Crc8_ROHC_Cal(&net_pairing_reply.buffer[1], len+3);//len+3 数据+cmd+2个字节的数据长度类型
+// net_pairing_reply.buffer[len+4] = crc;
+// ESP_LOGI(COMMON_TAG, "crc %x bytes:", net_pairing_reply.buffer[len+4]);
+// if(host_type == HOST_TYPE_UART)
+// {
+// xQueueSend(uart_tx_queue_handle, &net_pairing_reply, 0);
+// }
+// else if(host_type == HOST_TYPE_BLE)
+// {
+// xQueueSend(ble_notify_queue_handle, &net_pairing_reply, 0);
+// }
+// }
+void Uart_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
+{
+
+ //串口-ESP PROTUCOL协议指令解析
+ if(len >= 4 && len <= UART_BUF_SIZE && data[0] == FRAMEHEAD_PANEL_TO_IOT && Crc8_ROHC_Cal(&data[1], len-2) == data[len-1] && host_type == HOST_TYPE_UART)
+ {
+ ESP_LOGI(COMMON_TAG, "uart recv %d bytes:cmd %0x", len, data[1]);
+ // ESP_LOGI(COMMON_TAG, "Read %d bytes:", len);
+ // ESP_LOG_BUFFER_HEX(COMMON_TAG, data, len);
+ static UART_RECV_REPLY_T uart_pairing_reply = {0};
+ memset(&uart_pairing_reply, 0x00, sizeof(UART_RECV_REPLY_T));
+
+ // Process
+ uart_pairing_reply.cmd = data[1];
+ common_setting.ble_enable_tick = 0; // 刷新蓝牙关闭倒计时
+ switch(data[1])
+ {
+ // 心跳检测
+ case 0x00:
+ {
+ if(data[3] == 0)
+ {
+ common_setting.heart_beat_enable = 0;
+ }
+ else
+ {
+ common_setting.heart_beat_enable = 1;
+ common_setting.heart_beat_interval = data[3] * 1000;
+ }
+ }
+ break;
+
+ // 主控产品信息
+ case 0x01:
+ {
+ // 需要至少 12 字节(0~11),并且 product_name 中还有内容时要继续检查
+ if (len >= 12 && data[2] >= 9)
+ {
+ common_setting.mcu_info.vid = *(uint16_t*)&data[3];
+ common_setting.mcu_info.pid = *(uint16_t*)&data[5];
+ common_setting.mcu_info.fw_version = *(uint16_t*)&data[7];
+ common_setting.mcu_info.build_version = *(uint16_t*)&data[9];
+ memset(common_setting.mcu_info.product_name, 0x00, sizeof(common_setting.mcu_info.product_name));
+ uint8_t name_len = data[11];
+ if (name_len > PRODUCT_NAME_MAX_LEN)
+ {
+ name_len = PRODUCT_NAME_MAX_LEN;
+ }
+
+ if (name_len > 0)
+ {
+ if (len >= 12 + name_len)
+ {
+ memcpy(common_setting.mcu_info.product_name, &data[12], name_len);
+ common_setting.mcu_info.product_name[name_len] = '\0'; // 确保字符串结尾
+ }
+ else
+ {
+ ESP_LOGW(COMMON_TAG, "%s mcu info name len out of range, data len %d, want %d\n",__func__, len, (12 + name_len));
+ name_len = 0;
+ }
+ }
+ common_setting.mcu_info.product_name_len = name_len;
+ common_setting.mcu_info_got_flag = 1;
+ }
+ }
+ break;
+
+ // 网络状态通知
+ case 0x03:
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 1;
+
+ uart_pairing_reply.content[0] = 0x00; // 未处于配网状态
+ if(common_setting.ble_status.ble_state == 1)
+ {
+ uart_pairing_reply.content[0] = 0x01; // 蓝牙广播中
+ }
+ if(common_setting.ble_status.ble_state == 2)
+ {
+ uart_pairing_reply.content[0] = 0x02; // 蓝牙已连接
+ }
+ if(common_setting.wifi_status.wifi_mode != 1)
+ {
+ if(common_setting.wifi_status.wifi_mode == 2)
+ {
+ uart_pairing_reply.content[0] = 0x03; // wifi连接中
+ }
+ if(common_setting.wifi_status.wifi_state == 1)
+ {
+ uart_pairing_reply.content[0] = 0x04; // wifi已连接
+ }
+ }
+
+ // if(common_setting.wifi_status.wifi_state == 1)
+ // {
+ // uart_pairing_reply.content[0] = 0x02; // mqtt已连接
+ // }
+ }
+ break;
+
+ // // 属性设置
+ // case 0x06:
+ // {
+
+ // }
+ // break;
+
+ // 属性上报
+ case 0x07:
+ {
+ // mqtt_upload_len = data[2];
+ // memcpy(mqtt_upload_data, &data[3], data[2]);
+ }
+ break;
+
+ // // 属性全部查询
+ // case 0x08:
+ // {
+
+ // }
+ // break;
+
+ // // 属性批量查询
+ // case 0x09:
+ // {
+
+ // }
+ // break;
+
+ // 获取模组MAC地址
+ case 0x0A:
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 6;
+ esp_read_mac(uart_pairing_reply.content, ESP_MAC_BT);
+ }
+ break;
+ // 获取模组WIFI信息
+ case 0x0B:
+ {
+ uart_pairing_reply.send_flag = 1;
+ if(common_storage.net_info.wifi_info_flag == 0)
+ {
+ uart_pairing_reply.len = 2;
+ uart_pairing_reply.content[0] = 0; // 失败
+ uart_pairing_reply.content[1] = 0;
+ }
+ else
+ {
+ uart_pairing_reply.len = 2 + common_storage.net_info.wifi_ssid_len;
+ if(common_setting.net_pairing_status >= NET_PAIRING_WIFI_CONNECTED_AP)
+ {
+ *(int8_t*)&uart_pairing_reply.content[0] = common_setting.wifi_status.rssi;
+ }
+ else
+ {
+ uart_pairing_reply.content[0] = 1; // 未连接
+ }
+ uart_pairing_reply.content[1] = 1;
+ memcpy(&uart_pairing_reply.content[2], common_storage.net_info.wifi_ssid, common_storage.net_info.wifi_ssid_len);
+ }
+ }
+ break;
+
+ // 获取模组固件版本
+ case 0x0C:
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 6;
+
+ *(uint16_t*)&uart_pairing_reply.content[0] = DEVICE_PID;
+ *(uint16_t*)&uart_pairing_reply.content[2] = FW_VERSION;
+ *(uint16_t*)&uart_pairing_reply.content[4] = BUILD_VERSION;
+ }
+ break;
+
+ // 关闭心跳检测
+ case 0x0F:
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 0;
+
+ common_setting.heart_beat_enable = 0;
+ }
+ break;
+
+ // 事件上报
+ case 0x10:
+ {
+ if (len < 5) break;
+ if(data[4] == 0) // 模组填充时间戳
+ {
+
+ }
+ else if(data[4] == 1) // 主控时间戳
+ {
+
+ }
+ else
+ {
+
+ }
+ }
+ break;
+
+ // 属性同步通知
+ case 0x11:
+ {
+
+ }
+ break;
+
+ // 获取时间戳
+ case 0x12:
+ {
+ uart_pairing_reply.send_flag = 1;
+ if(common_setting.timestamp.sync_flag)
+ {
+ uart_pairing_reply.len = 10;
+ uart_pairing_reply.content[0] = 0;
+ uart_pairing_reply.content[1] = common_setting.timestamp.time_zone;
+ *(uint64_t*)&uart_pairing_reply.content[2] = common_setting.timestamp.real_time;
+ }
+ else
+ {
+ uart_pairing_reply.len = 1;
+ uart_pairing_reply.content[0] = 1;
+ }
+ }
+ break;
+
+ // 扫描WIFI列表
+ case 0x14:
+ {
+ // 开始扫描
+ Wifi_Queue_Send(host_type, 4, 0);
+ }
+ break;
+
+ // 连接WIFI
+ case 0x15:
+ {
+ uint8_t parse_done = 0;
+ char wifi_ssid[32+1] = {0};
+ char wifi_pwd[64+1] = {0};
+
+ if (len < 105)
+ {
+ ESP_LOGW(COMMON_TAG, "%s wifi conn data too short (%u)\n",__func__, len);
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 3;
+ uart_pairing_reply.content[0] = 0x04; // 失败,数据不足
+ uart_pairing_reply.content[1] = data[3];
+ uart_pairing_reply.content[2] = data[4];
+ break;
+ }
+
+ size_t max_ssid_src = (len > 5) ? len - 5 : 0;
+ size_t max_pwd_src = (len > 37) ? len - 37 : 0;
+ size_t wifi_ssid_len = strnlen((const char*)&data[5], max_ssid_src);
+ size_t wifi_pwd_len = strnlen((const char*)&data[37], max_pwd_src);
+
+ if (wifi_ssid_len >= 32)//
+ {
+ wifi_ssid_len = 32;
+ }
+ if (wifi_pwd_len >= 64)//
+ {
+ wifi_pwd_len = 64;
+ }
+
+ if (Crc32_JAMCRC_Cal(&data[37], 64) != *(uint32_t*)&data[101]) // 校验密文完整性
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 3;
+ uart_pairing_reply.content[0] = 0x03; // 失败,校验错误
+ uart_pairing_reply.content[1] = data[3];
+ uart_pairing_reply.content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s net pairing wifi pwd crc32 err:%08x %08x\n",__func__, (unsigned int)Crc32_JAMCRC_Cal(&data[37], 64), (unsigned int)*(uint32_t*)&data[101]);
+ break;
+ }
+
+ memcpy(wifi_ssid, &data[5], wifi_ssid_len);
+ switch(data[4]) // 加密方案
+ {
+ case 0: // 明文
+ {
+ memcpy(wifi_pwd, &data[37], 64);
+ uart_pairing_reply.send_flag = 0;
+ // 开始连接
+ parse_done = 1;
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd no encrypt\n",__func__);
+ }
+ break;
+
+ case 1: // AES128-ECB
+ {
+ const uint8_t aes_key[16] = {0x53,0x59,0x53,0x54,0x45,0x4D,0x5F,0x53,0x48,0x4F,0x43,0x4B,0x5F,0x50,0x58,0x4E};
+ aes_init(aes_key);
+ aes_soft_decrypt(&data[37], (uint8_t*)wifi_pwd, 64, NULL);
+ uart_pairing_reply.send_flag = 0;
+ // 开始连接
+ parse_done = 1;
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd encrypt\n",__func__);
+ }
+ break;
+ }
+
+
+ if(parse_done)
+ {
+ for(uint8_t i=0;i<64;i++)
+ {
+ if(wifi_pwd[i] == 0)
+ {
+ wifi_pwd_len = i;
+ break;
+ }
+ }
+
+ common_setting.wifi_status.cur_ssid_len = wifi_ssid_len;
+ memcpy(common_setting.wifi_status.cur_ssid, wifi_ssid, wifi_ssid_len);
+ common_setting.wifi_status.cur_pwd_len = wifi_pwd_len;
+ memcpy(common_setting.wifi_status.cur_pwd, wifi_pwd, wifi_pwd_len);
+ ESP_LOGI(COMMON_TAG, "%s wifi ssid len: %d\n",__func__, wifi_ssid_len);
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_ssid, wifi_ssid_len);
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd len: %d\n",__func__, wifi_pwd_len);
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_pwd, wifi_pwd_len);
+
+
+ if(common_setting.net_pairing_info.http_url_flag && common_setting.net_pairing_info.http_token_flag && common_setting.net_pairing_info.user_id_flag)
+ {
+ if(data[3] == 0)
+ {
+ // 厂测配网,单次连接
+ uart_pairing_reply.send_flag = 0;
+ // uart_pairing_reply.send_flag = 1;
+ // uart_pairing_reply.len = 3;
+ // uart_pairing_reply.content[0] = 0;
+ // uart_pairing_reply.content[1] = data[3];
+ // uart_pairing_reply.content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s wifi test start\n",__func__);
+ Wifi_Queue_Send(host_type, 1, data[4]);
+ }
+ else if(data[3] == 1)
+ {
+ // 用户配网
+ uart_pairing_reply.send_flag = 0;
+ // uart_pairing_reply.send_flag = 1;
+ // uart_pairing_reply.len = 3;
+ // uart_pairing_reply.content[0] = 0;
+ // uart_pairing_reply.content[1] = data[3];
+ // uart_pairing_reply.content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s wifi pair start\n",__func__);
+ Wifi_Queue_Send(host_type, 2, data[4]);
+ }
+ else
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 3;
+ uart_pairing_reply.content[0] = 2; // 成功接收配网信息,但缺少必要的配网认证信息
+ uart_pairing_reply.content[1] = data[3];
+ uart_pairing_reply.content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s wifi pair wrong\n",__func__);
+ }
+ }
+ else
+ {
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 3;
+ uart_pairing_reply.content[0] = 0; // 成功接收配网信息,但缺少必要的配网认证信息
+ uart_pairing_reply.content[1] = data[3];
+ uart_pairing_reply.content[2] = data[4];
+ }
+ }
+ else
+ {
+ // 解析失败
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 3;
+ uart_pairing_reply.content[0] = 1;
+ uart_pairing_reply.content[1] = data[3];
+ uart_pairing_reply.content[2] = data[4];
+ ESP_LOGE(COMMON_TAG, "wifi pwd encrypt profile not exist");
+ }
+ }
+ break;
+
+ // 配网认证信息
+ case 0x16:
+ {
+ if (len < 13)
+ {
+ ESP_LOGW(COMMON_TAG, "net pairing 0x16 len too small (%u)", len);
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 1;
+ uart_pairing_reply.content[0] = 0x10;
+ break;
+ }
+
+ uint16_t total_len = *(uint16_t*)&data[4];
+ uint16_t start_byte = *(uint16_t*)&data[9];
+ uint8_t packet_bytes = data[11];
+
+ if ((size_t)packet_bytes > len - 13)
+ {
+ ESP_LOGW(COMMON_TAG, "net pairing 0x16 pkt too long %u > %u", packet_bytes, len - 13);
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 1;
+ uart_pairing_reply.content[0] = 0x10;
+ break;
+ }
+
+ uart_pairing_reply.send_flag = 1;
+ uart_pairing_reply.len = 9;
+ memcpy(uart_pairing_reply.content, &data[3], 9);
+
+ if(total_len <= NET_PAIRING_INFO_MAX_LEN && start_byte + packet_bytes <= total_len)
+ {
+ size_t copy_bytes = packet_bytes;
+ if (start_byte + copy_bytes > NET_PAIRING_INFO_MAX_LEN)
+ copy_bytes = NET_PAIRING_INFO_MAX_LEN - start_byte;
+
+ if (data[3] == 0) // http配网服务器地址
+ {
+ if(start_byte == 0)
+ {
+ memset(common_setting.net_pairing_info.http_url, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+ memcpy(&common_setting.net_pairing_info.http_url[start_byte], &data[12], copy_bytes);
+ if(data[8] == 1)
+ {
+ if(Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_url, total_len) == *(uint16_t*)&data[6])
+ {
+ common_setting.net_pairing_info.http_url_length = total_len;
+ common_setting.net_pairing_info.http_url_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s http_url:%s\n",__func__, common_setting.net_pairing_info.http_url);
+ }
+ else
+ {
+ uart_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s http_url crc16 err:%04x %04x\n",__func__, Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_url, total_len), *(uint16_t*)&data[6]);
+ }
+ }
+ }
+ else if(data[3] == 1) // token
+ {
+ if(start_byte == 0)
+ {
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+ memcpy(&common_setting.net_pairing_info.http_token[start_byte], &data[12], copy_bytes);
+ if(data[8] == 1)
+ {
+ if(Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_token, total_len) == *(uint16_t*)&data[6])
+ {
+ common_setting.net_pairing_info.http_token_length = total_len;
+ common_setting.net_pairing_info.http_token_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s http_token:%s\n",__func__, common_setting.net_pairing_info.http_token);
+ }
+ else
+ {
+ // 校验失败
+ uart_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s http_token crc16 err:%04x %04x\n",__func__, Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_token, total_len), *(uint16_t*)&data[6]);
+ }
+ }
+ }
+ else if(data[3] == 2) // user_id
+ {
+ if(start_byte == 0)
+ {
+ common_setting.net_pairing_info.user_id = 0;
+ }
+ memcpy(&common_setting.net_pairing_info.user_id, &data[12], packet_bytes);
+ if(data[8] == 1)
+ {
+ if(Crc16_Modbus_Cal((uint8_t*)&common_setting.net_pairing_info.user_id, total_len) == *(uint16_t*)&data[6])
+ {
+ common_setting.net_pairing_info.user_id_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s user:%d\n",__func__, *(int*)common_setting.net_pairing_info.user_id);
+ }
+ else
+ {
+ // 校验失败
+ uart_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s user id crc16 err:%04x %04x\n",__func__, Crc16_Modbus_Cal((uint8_t*)&common_setting.net_pairing_info.user_id, total_len), *(uint16_t*)&data[6]);
+ }
+ }
+ }
+ else
+ {
+ // 类型错误
+ uart_pairing_reply.content[5] |= 0x30;
+ ESP_LOGI(COMMON_TAG, "%s net pair info type err\n",__func__);
+ }
+ }
+ else
+ {
+ // 失败
+ uart_pairing_reply.content[5] |= 0x10;
+ ESP_LOGI(COMMON_TAG, "%s total_len err:%d %d %"PRIu16,__func__, start_byte, packet_bytes, total_len);
+ }
+ }
+ break;
+
+ // 其它命令
+ case 0x20://APP检查到iot服务器地址不可达,通知iot模块停止配网,等待APP重新发起配网
+ {
+ if(data[3] == 1) // 停止配网
+ {
+ common_setting.net_pairing_info.http_url_flag = 0;
+ common_setting.net_pairing_info.http_token_flag = 0;
+ common_setting.net_pairing_info.user_id_flag = 0;
+
+ }
+ }
+ break;
+
+ // 固件升级
+ case CMD1_IAP_CHIP6:
+ {
+ if(host_type == HOST_TYPE_UART)
+ {
+ Iap_Process(&data[3], data[2]);
+ }
+ }
+ break;
+
+ // 欺骗编译器,勿删
+ case 0xFF:
+ {
+ if(data[0] != FRAMEHEAD_PANEL_TO_IOT)
+ {
+ for(uint16_t i=0;i<(sizeof(FW_FILE_HEADER_T));i++)
+ {
+ printf("%c", ((char*)&firmware_header)[i]);
+ }
+ }
+ }
+ }
+
+ if(uart_pairing_reply.send_flag)
+ {
+ Check_Host_Type(uart_pairing_reply.cmd, uart_pairing_reply.content, uart_pairing_reply.len, host_type);
+ }
+ }
+ else if(data[0] == FRAMEHEAD_PANEL_TO_IOT)
+ {
+ if(len < 4 || len > UART_BUF_SIZE)
+ {
+ ESP_LOGE(COMMON_TAG, "net pairing len err:%d", len);
+ }
+ else if(Crc8_ROHC_Cal(&data[1], len-2) != data[len-1])
+ {
+ ESP_LOGE(COMMON_TAG, "net pairing crc8 err:%02x %02x", Crc8_ROHC_Cal(&data[1], len-2), data[len-1]);
+ }
+ }
+}
+
+
+void Ble_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
+{
+ //APP-ESP PROTUCOL协议指令解析 ble接收的数据不需要做数据长度判断 app层处理即可
+ if(len >= 4 && len <= sizeof(BLE_SEND_REPLY_T) && data[0] == FRAMEHEAD_APP_TO_ESP && Crc8_ROHC_Cal(&data[1], len-2) == data[len-1] && host_type == HOST_TYPE_BLE)
+ {
+ ESP_LOGI(COMMON_TAG, "%s ble recv %d bytes:cmd %0x\n",__func__, len, data[1]);
+ // ESP_LOG_BUFFER_HEX(COMMON_TAG, data, len);
+ static BLE_SEND_REPLY_T net_pairing_reply = {0};
+ // net_pairing_reply = (BLE_SEND_REPLY_T *)pvPortMalloc(sizeof(BLE_SEND_REPLY_T));
+ // if(net_pairing_reply == NULL) {
+ // ESP_LOGE(COMMON_TAG, "malloc failed for net_pairing_reply");
+ // return;
+ // }
+ memset(&net_pairing_reply, 0x00, sizeof(BLE_SEND_REPLY_T));
+
+ // Process
+ //data[0] = 0xff
+ //data[1] = cmd
+ //data[2~3] = len
+ //data[4~(4+len-1)] = payload
+ //data[len-1] = crc
+ net_pairing_reply.cmd = data[1];
+ common_setting.ble_enable_tick = 0; // 刷新蓝牙关闭倒计时
+ switch(data[1])
+ {
+ // 心跳检测
+ case 0x00://ble协议暂时使用
+ // {
+ // if(data[3] == 0)
+ // {
+ // common_setting.heart_beat_enable = 0;
+ // }
+ // else
+ // {
+ // common_setting.heart_beat_enable = 1;
+ // common_setting.heart_beat_interval = data[3] * 1000;
+ // }
+ // }
+ break;
+
+ // app查询设备的pid、vid、固件版本等信息,建议APP在配网前调用一次,获取主控信息后再决定是否继续配网
+ case 0x01:
+ {
+ net_pairing_reply.len = 8;
+ memcpy(&net_pairing_reply.content[0], (uint16_t*)&common_setting.mcu_info.vid, 2);
+ memcpy(&net_pairing_reply.content[2], (uint16_t*)&common_setting.mcu_info.pid, 2);
+ memcpy(&net_pairing_reply.content[4], (uint16_t*)&common_setting.mcu_info.fw_version, 2);
+ memcpy(&net_pairing_reply.content[6], (uint16_t*)&common_setting.mcu_info.build_version, 2);
+ net_pairing_reply.send_flag = 1;//是否需要回复对方
+ }
+ break;
+ // app查询设备的pid,MAC地址
+ case 0x02:
+ {
+ net_pairing_reply.len = 8;
+ common_setting.mcu_info.pid=0xA00B;
+ memcpy(&net_pairing_reply.content[0], (uint16_t*)&common_setting.mcu_info.pid, 2);
+ esp_read_mac(&net_pairing_reply.content[2], ESP_MAC_BT);
+
+ net_pairing_reply.send_flag = 1;//是否需要回复对方
+ }
+ break;
+ // 网络状态通知
+ case 0x03:
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 1;
+
+ net_pairing_reply.content[0] = 0x00; // 未处于配网状态
+ if(common_setting.ble_status.ble_state == 1)
+ {
+ net_pairing_reply.content[0] = 0x01; // 蓝牙广播中
+ }
+ if(common_setting.ble_status.ble_state == 2)
+ {
+ net_pairing_reply.content[0] = 0x02; // 蓝牙已连接
+ }
+ if(common_setting.wifi_status.wifi_mode != 1)
+ {
+ if(common_setting.wifi_status.wifi_mode == 2)
+ {
+ net_pairing_reply.content[0] = 0x03; // wifi连接中
+ }
+ if(common_setting.wifi_status.wifi_state == 1)
+ {
+ net_pairing_reply.content[0] = 0x04; // wifi已连接
+ }
+ }
+
+ // if(common_setting.wifi_status.wifi_state == 1)
+ // {
+ // net_pairing_reply->content[0] = 0x02; // mqtt已连接
+ // }
+ }
+ break;
+
+ // // 属性设置
+ // case 0x06:
+ // {
+
+ // }
+ // break;
+
+ // 属性上报
+ case 0x07:
+ {
+ // mqtt_upload_len = data[2];
+ // memcpy(mqtt_upload_data, &data[3], data[2]);
+ }
+ break;
+
+ // // 属性全部查询
+ // case 0x08:
+ // {
+
+ // }
+ // break;
+
+ // // 属性批量查询
+ // case 0x09:
+ // {
+
+ // }
+ // break;
+
+ // 获取模组MAC地址
+ case 0x0A:
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 6;
+ esp_read_mac(net_pairing_reply.content, ESP_MAC_BT);
+ }
+ break;
+ // 获取模组WIFI信息
+ case 0x0B:
+ {
+ net_pairing_reply.send_flag = 1;
+ if(common_storage.net_info.wifi_info_flag == 0)
+ {
+ net_pairing_reply.len = 2;
+ net_pairing_reply.content[0] = 0; // 失败
+ net_pairing_reply.content[1] = 0;
+ }
+ else
+ {
+ net_pairing_reply.len = 2 + common_storage.net_info.wifi_ssid_len;
+ if(common_setting.net_pairing_status >= NET_PAIRING_WIFI_CONNECTED_AP)
+ {
+ *(int8_t*)&net_pairing_reply.content[0] = common_setting.wifi_status.rssi;
+ }
+ else
+ {
+ net_pairing_reply.content[0] = 1; // 未连接
+ }
+ net_pairing_reply.content[1] = 1;
+ memcpy(&net_pairing_reply.content[2], common_storage.net_info.wifi_ssid, common_storage.net_info.wifi_ssid_len);
+ }
+ }
+ break;
+
+ // 获取模组固件版本
+ case 0x0C:
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 6;
+
+ *(uint16_t*)&net_pairing_reply.content[0] = DEVICE_PID;
+ *(uint16_t*)&net_pairing_reply.content[2] = FW_VERSION;
+ *(uint16_t*)&net_pairing_reply.content[4] = BUILD_VERSION;
+ }
+ break;
+
+ // 关闭心跳检测
+ case 0x0F:
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 0;
+
+ common_setting.heart_beat_enable = 0;
+ }
+ break;
+
+ // 事件上报
+ case 0x10:
+ {
+
+ }
+ break;
+
+ // 属性同步通知
+ case 0x11:
+ {
+
+ }
+ break;
+
+ // 获取时间戳
+ case 0x12:
+ {
+ net_pairing_reply.send_flag = 1;
+ if(common_setting.timestamp.sync_flag)
+ {
+ net_pairing_reply.len = 10;
+ net_pairing_reply.content[0] = 0;
+ net_pairing_reply.content[1] = common_setting.timestamp.time_zone;
+ *(uint64_t*)&net_pairing_reply.content[2] = common_setting.timestamp.real_time;
+ }
+ else
+ {
+ net_pairing_reply.len = 1;
+ net_pairing_reply.content[0] = 1;
+ }
+ }
+ break;
+
+ // 扫描WIFI列表
+ case 0x14:
+ {
+ // 开始扫描
+ Wifi_Queue_Send(host_type, 4, 0);
+ }
+ break;
+
+ // 连接WIFI
+ case 0x15:
+ {
+ uint8_t parse_done = 0;
+ char wifi_ssid[32+1] = {0};
+ char wifi_pwd[64+1] = {0};
+
+ if (len < 106)
+ {
+ ESP_LOGW(COMMON_TAG, "%s wifi conn data too short (%u)\n", __func__,len);
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 3;
+ net_pairing_reply.content[0] = 4; // 数据不足代码
+ net_pairing_reply.content[1] = data[4];
+ net_pairing_reply.content[2] = data[5];
+ break;
+ }
+
+ size_t max_ssid_src = (len > 6) ? len - 6 : 0;
+ size_t max_pwd_src = (len > 38) ? len - 38 : 0;
+ size_t wifi_ssid_len = strnlen((const char*)&data[6], max_ssid_src);
+ size_t wifi_pwd_len = strnlen((const char*)&data[38], max_pwd_src);
+
+ if (wifi_ssid_len > 32)
+ {
+ wifi_ssid_len = 32;
+ }
+ if (wifi_pwd_len > 64)
+ {
+ wifi_pwd_len = 64;
+ }
+
+ if(Crc32_JAMCRC_Cal(&data[38], 64) != *(uint32_t*)&data[102]) // 校验密文完整性
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 3;
+ net_pairing_reply.content[0] = 2;
+ net_pairing_reply.content[1] = data[4];
+ net_pairing_reply.content[2] = data[5];
+ ESP_LOGI(COMMON_TAG, "%s net pairing wifi pwd crc32 err:%08x %08x\n",__func__, (unsigned int)Crc32_JAMCRC_Cal(&data[38], 64), (unsigned int)*(uint32_t*)&data[102]);
+ break;
+ }
+
+ memcpy(wifi_ssid, &data[6], wifi_ssid_len);
+ if(wifi_ssid_len > 32)
+ {
+
+ wifi_ssid[31] = '\0';//加上结束符 防止后续使用字符串函数时越界 显示乱码名称
+ }
+ switch(data[5]) // 加密方案
+ {
+ case 0: // 明文
+ {
+ memcpy(wifi_pwd, &data[38], 64);
+ if(wifi_pwd_len > 64)
+ {
+ wifi_pwd[63] = '\0';//加上结束符 防止后续使用字符串函数时越界 显示乱码密码
+ }
+ net_pairing_reply.send_flag = 0;
+ // 开始连接
+ parse_done = 1;
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd no encrypt\n",__func__);
+ }
+ break;
+
+ case 1: // AES128-ECB
+ {
+ const uint8_t aes_key[16] = {0x53,0x59,0x53,0x54,0x45,0x4D,0x5F,0x53,0x48,0x4F,0x43,0x4B,0x5F,0x50,0x58,0x4E};
+ aes_init(aes_key);
+ aes_soft_decrypt(&data[38], (uint8_t*)wifi_pwd, 64, NULL);
+ net_pairing_reply.send_flag = 0;
+ // 开始连接
+ parse_done = 1;
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd encrypt\n",__func__);
+ }
+ break;
+ }
+
+
+ if(parse_done)
+ {
+ for(uint8_t i=0;i<64;i++)
+ {
+ if(wifi_pwd[i] == 0)
+ {
+ wifi_pwd_len = i;
+ break;
+ }
+ }
+
+ common_setting.wifi_status.cur_ssid_len = wifi_ssid_len;
+ memset(common_setting.wifi_status.cur_ssid,0,32);
+ memcpy(common_setting.wifi_status.cur_ssid, wifi_ssid, wifi_ssid_len);
+ common_setting.wifi_status.cur_ssid[wifi_ssid_len]='\0';
+ common_setting.wifi_status.cur_pwd_len = wifi_pwd_len;
+ memset(common_setting.wifi_status.cur_pwd,0,64);
+ memcpy(common_setting.wifi_status.cur_pwd, wifi_pwd, wifi_pwd_len);
+ common_setting.wifi_status.cur_pwd[wifi_pwd_len]='\0';
+ ESP_LOGI(COMMON_TAG, "%s wifi ssid len: %d\n",__func__, wifi_ssid_len);
+
+ memset(common_storage.net_info.wifi_ssid,0,32);
+ common_storage.net_info.wifi_ssid_len=wifi_ssid_len;
+
+ memcpy(common_storage.net_info.wifi_ssid, wifi_ssid, wifi_ssid_len);
+ memset(common_storage.net_info.wifi_pwd,0,64);
+ memcpy(common_storage.net_info.wifi_pwd, wifi_pwd, wifi_pwd_len);
+ common_storage.net_info.wifi_pwd_len=wifi_pwd_len;
+
+
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_ssid, wifi_ssid_len);
+ ESP_LOGI(COMMON_TAG, "%s wifi pwd len: %d\n",__func__, wifi_pwd_len);
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_pwd, wifi_pwd_len);
+
+ ESP_LOGI(COMMON_TAG, "%s wifi flag: %d %d %d\n",__func__,common_setting.net_pairing_info.http_url_flag, common_setting.net_pairing_info.http_token_flag, common_setting.net_pairing_info.user_id_flag);
+
+ if(common_setting.net_pairing_info.http_url_flag && common_setting.net_pairing_info.http_token_flag && common_setting.net_pairing_info.user_id_flag)
+ {
+ if(data[4] == 0)
+ {
+ // 厂测配网,单次连接
+ net_pairing_reply.send_flag = 0;
+ // net_pairing_reply->send_flag = 1;
+ // net_pairing_reply->len = 3;
+ // net_pairing_reply->content[0] = 0;
+ // net_pairing_reply->content[1] = data[3];
+ // net_pairing_reply->content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s wifi test start\n",__func__);
+ Wifi_Queue_Send(host_type, 1, data[5]);
+ }
+ else if(data[4] == 1)
+ {
+ // 用户配网
+ net_pairing_reply.send_flag = 0;
+ // net_pairing_reply->send_flag = 1;
+ // net_pairing_reply->len = 3;
+ // net_pairing_reply->content[0] = 0;
+ // net_pairing_reply.content[1] = data[3];
+ // net_pairing_reply.content[2] = data[4];
+ ESP_LOGI(COMMON_TAG, "%s wifi pair start\n",__func__);
+ Wifi_Queue_Send(host_type, 2, data[5]);
+ }
+ else
+ {
+ ESP_LOGI(COMMON_TAG, "%s wifi pair wrong\n",__func__);
+ }
+ }
+ else
+ {
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 3;
+ net_pairing_reply.content[0] = 0;
+ net_pairing_reply.content[1] = data[4];
+ net_pairing_reply.content[2] = data[5];
+ }
+ }
+ else
+ {
+ // 解析失败
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 3;
+ net_pairing_reply.content[0] = 0;
+ net_pairing_reply.content[1] = data[4];
+ net_pairing_reply.content[2] = data[5];
+ ESP_LOGE(COMMON_TAG, "wifi pwd encrypt profile not exist");
+ }
+ }
+ break;
+
+ // 配网认证信息
+ case 0x16:
+ {
+ if (len < 13)
+ {
+ ESP_LOGW(COMMON_TAG, "net pairing 0x16 len too small (%u)", len);
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 1;
+ net_pairing_reply.content[0] = 0x10;
+ break;
+ }
+
+ uint16_t recv_total_len = *(uint16_t*)&data[2];//不包含cmd+帧头+crc
+ uint16_t total_len = *(uint16_t*)&data[5];//52
+ uint16_t start_byte = *(uint16_t*)&data[10];
+ uint8_t packet_bytes = data[12];
+ static uint8_t http_end = 0;//
+ static uint8_t http_end_flag = 0;//本次接收的包是否是http url包的最后一包,0表示不是最后一包,1表示是最后一包
+ static uint8_t token_end = 0;//
+ static uint8_t token_end_flag = 0;//本次接收的包是否是token包的最后一包,0表示不是最后一包,1表示是最后一包
+
+ if ((size_t)packet_bytes > len - 13)
+ {
+ ESP_LOGW(COMMON_TAG, "%s net pairing 0x16 packet_bytes too big (%u > %u)\n",__func__, packet_bytes, len - 13);
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 1;
+ net_pairing_reply.content[0] = 0x10;
+ break;
+ }
+
+ net_pairing_reply.send_flag = 1;
+ net_pairing_reply.len = 9;
+ memcpy(net_pairing_reply.content, &data[4], 9);
+ ESP_LOGI(COMMON_TAG, "%s 认证信息数据: %d %d %d %d\n", __func__,recv_total_len, total_len,start_byte, packet_bytes);
+
+ if(packet_bytes <= NET_PAIRING_INFO_MAX_LEN-13 && start_byte + packet_bytes <= total_len && packet_bytes + 9 <= recv_total_len)
+ {
+ if(data[4] == 0) // http配网服务器地址
+ {
+ if(start_byte == 0)
+ {
+ http_end=0;
+ http_end_flag=1;
+ memset(common_setting.net_pairing_info.http_url, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+
+ //
+ size_t copy_len = MIN(packet_bytes, NET_PAIRING_INFO_MAX_LEN - start_byte);
+ if(copy_len > 0)
+ {
+ // ESP_LOGI(COMMON_TAG, "认证信息数据1: %d %d %d %d %d\n", recv_total_len, total_len,start_byte, packet_bytes,copy_len);
+ memcpy(&common_setting.net_pairing_info.http_url[start_byte], &data[13], copy_len);
+ ESP_LOGI(COMMON_TAG, "%s 认证信息数据2: %d %d %d %d\n",__func__, recv_total_len, total_len,start_byte, packet_bytes);
+ }
+
+ // ==========================================
+ //
+ // ==========================================
+ if(data[9] == 1)
+ {
+ //
+ total_len = start_byte + copy_len;
+
+ //
+ if(total_len > NET_PAIRING_INFO_MAX_LEN)
+ total_len = NET_PAIRING_INFO_MAX_LEN;
+ }
+
+ // 字符串结束符(不影响有效数据)
+ uint32_t str_end = start_byte + copy_len;
+ if (str_end >= NET_PAIRING_INFO_MAX_LEN)
+ str_end = NET_PAIRING_INFO_MAX_LEN;
+ common_setting.net_pairing_info.http_url[str_end] = '\0';
+ // ESP_LOGI(COMMON_TAG, "认证信息数据3: %d %d %d %d\n", recv_total_len, total_len,start_byte, packet_bytes);
+ if(data[9] == 1)
+ {
+ // CRC
+ uint16_t calc_crc = Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_url, total_len);
+ uint16_t packet_crc = (data[7] << 8) | data[8];
+
+ ESP_LOGI(COMMON_TAG, "%s 正确 http url: %s (len=%u)\n",__func__, common_setting.net_pairing_info.http_url, total_len);
+
+ //本次结束接收后数据校验出错了,然后又下发最后一包不完整的数据,结束了上一次的完整包 但是后面又下发了最后一包数据不完整
+ if(http_end == 1 || http_end_flag == 0)
+ {
+ //上一次已经接收完成了一个完整的http url包了,但校验失败了
+ ESP_LOGI(COMMON_TAG, "%s 上一次http url包接收完成了,但校验失败了,这一次http url包校验成功了\n",__func__);
+ http_end=0;
+ memset(common_setting.net_pairing_info.http_url, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ net_pairing_reply.content[5] |= 0x20;
+ break;//提前退出,等待APP重新发送一个新的http url包过来
+ }
+ http_end_flag=0;//一开始为0说明不是第一包不做数据处理,当接收到第一包数据时把http_end_flag置为1,
+ if(packet_crc == calc_crc)
+ {
+
+ http_end=0;
+ common_setting.net_pairing_info.http_url_length = total_len;
+ common_setting.net_pairing_info.http_url_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s 校验成功: %s\n",__func__, common_setting.net_pairing_info.http_url);
+ }
+ else
+ {
+ http_end=1;
+ memset(common_setting.net_pairing_info.http_url, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ net_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s CRC错误: 计算=%04x 接收=%04x\n",__func__, calc_crc, packet_crc);
+ }
+ }
+ }
+ else if(data[4] == 1) // token
+ {
+ if(start_byte == 0)//第一包数据
+ {
+ token_end=0;
+ token_end_flag=1;//本次接收的包是token包的第一包
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+
+ //
+ size_t copy_len = MIN(packet_bytes, NET_PAIRING_INFO_MAX_LEN - start_byte);
+ if(copy_len > 0)
+ {
+ memcpy(&common_setting.net_pairing_info.http_token[start_byte], &data[13], copy_len);
+ }
+
+ // ==========================================
+ //
+ // ==========================================
+ if(data[9] == 1)
+ {
+ //
+ total_len = start_byte + copy_len;
+
+ //
+ if(total_len > NET_PAIRING_INFO_MAX_LEN)
+ total_len = NET_PAIRING_INFO_MAX_LEN;
+ }
+
+ // 字符串结束
+ uint32_t str_end = start_byte + copy_len;
+ if (str_end >= NET_PAIRING_INFO_MAX_LEN)
+ str_end = NET_PAIRING_INFO_MAX_LEN;
+ common_setting.net_pairing_info.http_token[str_end] = '\0';
+
+ if(data[9] == 1)
+ {
+ //
+ uint16_t calc_crc = Crc16_Modbus_Cal((uint8_t*)common_setting.net_pairing_info.http_token, total_len);
+ uint16_t packet_crc = (data[7] << 8) | data[8];
+
+ ESP_LOGI(COMMON_TAG, "%s 正确token: %s (len=%u)\n",__func__, common_setting.net_pairing_info.http_token, total_len);
+ //本次结束后校验出错了,然后又下发最后一包不完整的数据
+ if(token_end == 1 || token_end_flag == 0)//上一次已经接收完成了一个完整的http url包了,但校验失败了,APP又继续发了一个新的http url包过来,那么这一次即使校验成功了,也不应该认为http url接收完成了,因为可能是APP在重试发送同一个有问题的http url包,而不是在发送一个新的正确的http url包,所以需要等到连续两次接收完成的http url包都校验成功了,才认为http url接收完成了
+ {
+ ESP_LOGI(COMMON_TAG, "%s 上一次http url包接收完成了,但校验失败了\n",__func__);
+ token_end=0;
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ net_pairing_reply.content[5] |= 0x20;
+ break;//提前退出,等待APP重新发送一个新的http url包过来
+ }
+ token_end_flag=0;//一开始为0说明不是第一包不做数据处理,当接收到第一包数据时把token_end_flag置为1,
+ if(packet_crc == calc_crc)
+ {
+ token_end=0;
+ common_setting.net_pairing_info.http_token_length = total_len;
+ common_setting.net_pairing_info.http_token_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s 校验成功: %s",__func__,common_setting.net_pairing_info.http_token);
+ }
+ else
+ {
+ token_end=1;
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ net_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s CRC错误: 计算=%04x 接收=%04x",__func__, calc_crc, packet_crc);
+ }
+ }
+ }
+
+ else if(data[4] == 2) // user_id
+ {
+ // ESP_LOGI(COMMON_TAG, "net pairing 0x16 user_id overflow: start=%u packet=%u", start_b);
+ // if(start_byte >= sizeof(int) || packet_bytes > sizeof(int) || (size_t)start_byte + packet_bytes > sizeof(int))
+ // {
+ // ESP_LOGI(COMMON_TAG, "net pairing 0x16 user_id overflow: start=%u packet=%u", start_byte, packet_bytes);
+ // net_pairing_reply.content[5] |= 0x10;
+ // break;
+ // }
+ if(start_byte == 0)
+ {
+ common_setting.net_pairing_info.user_id=0;
+ }
+ uint16_t copy_len = (packet_bytes < (sizeof(int) - start_byte)) ? packet_bytes : (sizeof(int) - start_byte);
+ memcpy(&common_setting.net_pairing_info.user_id, &data[13], copy_len);
+
+ if(data[9] == 1)
+ {
+ if(total_len > sizeof(int))
+ {
+ total_len = sizeof(int);
+ }
+ uint16_t calc_crc = Crc16_Modbus_Cal((uint8_t*)&common_setting.net_pairing_info.user_id, total_len);
+ uint16_t packet_crc = (data[7] << 8) | data[8];
+
+ ESP_LOGI(COMMON_TAG, "%s user_id: %08x\n",__func__, (unsigned int)common_setting.net_pairing_info.user_id);
+
+ //本次结束后校验出错了,然后又下发最后一包不完整的数据
+ if(packet_crc == calc_crc)
+ {
+ ESP_LOGI(COMMON_TAG, "%s user_id crc16 check success: %04x\n", __func__,calc_crc);
+ common_setting.net_pairing_info.user_id_flag = 1;
+ ESP_LOGI(COMMON_TAG, "%s user_id: %08x\n",__func__, (unsigned int)common_setting.net_pairing_info.user_id);
+ }
+ else
+ {
+ common_setting.net_pairing_info.user_id=0;
+ // 校验失败
+ net_pairing_reply.content[5] |= 0x20;
+ ESP_LOGI(COMMON_TAG, "%s BLE user id crc16 err:%04x %04x\n", __func__,packet_crc, calc_crc);
+ }
+ }
+ }
+ else
+ {
+ // 类型错误
+ net_pairing_reply.content[5] |= 0x30;
+ ESP_LOGI(COMMON_TAG, "%s net pair info type err\n",__func__);
+ }
+ }
+ else //当前包的大小加上上一包的数据大小超出了总数据的大小 异常数据处理0x00
+ {
+ if(data[4] == 0) // http配网服务器地址
+ {
+ memset(common_setting.net_pairing_info.http_url, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+ else if(data[4] == 1) // token
+ {
+ memset(common_setting.net_pairing_info.http_token, 0x00, NET_PAIRING_INFO_MAX_LEN);
+ }
+ else if(data[4] == 2) // user_id
+ {
+ common_setting.net_pairing_info.user_id = 0;
+ }
+ // 失败
+ net_pairing_reply.content[5] |= 0x10;
+ ESP_LOGI(COMMON_TAG, "%s total_len err:%d %d %"PRIu16,__func__, start_byte, packet_bytes, total_len);
+ }
+ }
+ break;
+
+ // 其它命令
+ case 0x20:
+ {
+ if (len < 5) break;
+ if(data[4] == 1) // 停止配网
+ {
+ // common_setting.net_pairing_info.net_pair_cooldown = 0;
+ common_setting.net_pairing_info.http_url_flag = 0;
+ common_setting.net_pairing_info.http_token_flag = 0;
+ common_setting.net_pairing_info.user_id_flag = 0;
+ net_pairing_reply.content[0] = 1;//0成功 1失败
+ net_pairing_reply.content[1] = data[4]; //1停止配网
+ net_pairing_reply.len = 2;
+ net_pairing_reply.send_flag = 1;
+ //关闭蓝牙取消配网动作
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);//停止配网,除非重启设备或者app下发wifi信息重新配网
+ ESP_LOGI(COMMON_TAG, "%s net pairing stop by app\n",__func__);
+ }
+ }
+ break;
+ //蓝牙开关
+ case 0x21:
+ {
+ if (len < 5) break;
+ if(data[4] == 1) // 开启蓝牙
+ {
+ xEventGroupSetBits(ble_event_group, BLE_ON_BIT);
+ ESP_LOGI(COMMON_TAG, "%s ble on by app\n",__func__);
+ }
+ else if(data[4] == 0) // 关闭蓝牙
+ {
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);
+ ESP_LOGI(COMMON_TAG, "%s ble off by app\n",__func__);
+ }
+ }
+ break;
+ // 固件升级
+ case CMD1_IAP_CHIP6:
+ {
+ if (len < 5) break;
+ if(host_type == HOST_TYPE_UART)
+ {
+ Iap_Process(&data[4], data[3]);
+ }
+ }
+ break;
+
+ // 欺骗编译器,勿删
+ case 0xFF:
+ {
+
+ switch (data[4])
+ {
+ case 0x01://连接wifi测试
+ common_setting.wifi_status.cur_ssid_len = 32;
+ memset(common_setting.wifi_status.cur_ssid,0x00,32);
+ memcpy(common_setting.wifi_status.cur_ssid, &data[5], 32);
+
+ common_setting.wifi_status.cur_pwd_len = 64;
+ memset(common_setting.wifi_status.cur_pwd,0x00,64);
+ memcpy(common_setting.wifi_status.cur_pwd, &data[5+32], 64);
+ ESP_LOGI(COMMON_TAG, "%s wifi test ssid len: %d\n",__func__, 32);
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_ssid, 32);
+ ESP_LOGI(COMMON_TAG, "%s wifi test len: %d\n",__func__, 64);
+ ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_pwd, 64);
+ common_setting.net_pairing_info.http_url_flag=1;
+ common_setting.net_pairing_info.http_token_flag=1;
+ common_setting.net_pairing_info.user_id_flag=1;
+ common_setting.ble_status.ble_state=0;//
+ xEventGroupSetBits(ble_event_group, BLE_ON_BIT);//打开蓝牙配网
+ Wifi_Queue_Send(HOST_TYPE_BLE,1,0);
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ }
+
+ if(net_pairing_reply.send_flag)
+ {
+ printf("%s ble reply: cmd=%02x len=%d content:\n",__func__, net_pairing_reply.cmd, net_pairing_reply.len);
+ Ble_Pairing_Reply(net_pairing_reply.cmd, net_pairing_reply.content, net_pairing_reply.len, host_type);
+ printf("%s ble reply end\n",__func__);
+ }
+ }
+ else if(data[0] == FRAMEHEAD_PANEL_TO_IOT)
+ {
+ if(len < 4 || len > UART_BUF_SIZE)
+ {
+ ESP_LOGE(COMMON_TAG, "%s net pairing len err:%d\n",__func__, len);
+ }
+ else if(Crc8_ROHC_Cal(&data[1], len-2) != data[len-1])
+ {
+ ESP_LOGE(COMMON_TAG, "%s net pairing crc8 err:%02x %02x\n",__func__, Crc8_ROHC_Cal(&data[1], len-2), data[len-1]);
+ }
+ }
+ else if(data[0] == FRAMEHEAD_APP_TO_ESP)
+ {
+ //发送调试数据不需要crc校验
+ ESP_LOGI(COMMON_TAG, "%s no need checkcrc recv %d bytes:cmd %0x",__func__,len, data[1]);
+ // ESP_LOG_BUFFER_HEX(COMMON_TAG, data, len);
+ // BLE_SEND_REPLY_T net_pairing_reply = {0};
+ // memset(&net_pairing_reply, 0x00, sizeof(BLE_SEND_REPLY_T));
+ // char wifi_ssid[10+1] = {0};
+ // char wifi_pwd[15+1] = {0};
+ // switch (data[1])
+ // {
+ // case 0xFE://fe + cmd+cmd1+dataLen+data+crc8
+ // {
+
+
+ // switch (data[4])
+ // {
+ // case 0x01://调试app下发wifi名称和密码重新连接新的wifi,不需要加密
+ // //调试指令
+ // if (len < 20)
+ // {
+ // ESP_LOGW(COMMON_TAG, "APP 0xFE len too short %u", len);
+ // break;
+ // }
+ // memcpy(wifi_ssid, &data[5], 10);
+ // wifi_ssid[10] = '\0';
+ // memcpy(wifi_pwd, &data[15], 15);
+ // wifi_pwd[15] = '\0';
+ // common_setting.wifi_status.cur_ssid_len = 10;
+ // memcpy(common_setting.wifi_status.cur_ssid, wifi_ssid, 10);
+ // common_setting.wifi_status.cur_pwd_len = 15;
+ // memcpy(common_setting.wifi_status.cur_pwd, wifi_pwd, 15);
+ // ESP_LOGI(COMMON_TAG, "wifi ssid len: %d", 10);
+ // ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_ssid, 10);
+ // ESP_LOGI(COMMON_TAG, "wifi pwd len: %d", 15);
+ // ESP_LOG_BUFFER_CHAR(COMMON_TAG, common_setting.wifi_status.cur_pwd, 15);
+ // ESP_LOGI(COMMON_TAG, "wifi test start");
+ // Wifi_Queue_Send(host_type, 1, 0);
+ // /* code */
+ // break;
+
+ // default:
+ // break;
+ // }
+
+ // }
+ // break;
+
+ // default:
+ // break;
+ // }
+ }
+}
+
--- /dev/null
+#ifndef _PROJECT_COMMON_H_
+#define _PROJECT_COMMON_H_
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "esp_wifi.h"
+#include "esp_system.h"
+#include "nvs_flash.h"
+#include "esp_event.h"
+#include "esp_netif.h"
+#include "protocol_examples_common.h"
+#include "esp_log.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "freertos/queue.h"
+
+#include "user_flash.h"
+#include "aes.h"
+
+#include "lwip/sockets.h"
+#include "lwip/dns.h"
+#include "lwip/netdb.h"
+
+#include "esp_http_client.h"
+#include "esp_crt_bundle.h"
+#include "wifi.h"
+#include "http.h"
+#include "cJSON.h"
+
+#include "mqtt_client.h"
+#include "mqtt.h"
+
+#include "esp_mac.h"
+#include "ble.h"
+#include "gap.h"
+#include "gatt_svc.h"
+
+#include "driver/gpio.h"
+#include "driver/uart.h"
+#include "uart.h"
+
+#include "crc.h"
+
+#include "iap.h"
+#include "esp_ota_ops.h"
+
+// Project
+#define FW_VERSION (0x0001) // 固件版本
+#define BUILD_VERSION (0x0004) // 编译测试版本
+#define DEVICE_VID (0x36E6) // 设备厂商代码
+#define DEVICE_PID (0xEC01) // 设备型号代码
+#define LWIP_LOCAL_HOSTNAME "PXN-Device" // WIFI本地主机名称
+#define FW_HEADER_CODE_SIZE 12
+#define FW_HEADER_CODE "WGTL_ESP32C2"
+#define IOT_ENABLE 1
+#define USER_TEST_ENABLE 1
+#define BLE_TEST_WIFI_CONNECT_ENABLE 1//BLE下发wifixin不需要做htttp token user_id校验
+#define IS_CLOSE_BLE 0 //是否关闭蓝牙广播暂时测试不关闭 一直广播
+
+#define WIFI_SSID_MAX_LEN 32
+#define WIFI_PWD_MAX_LEN 64
+/**************** Task ****************/
+// MAIN_LOOP
+#define MAIN_LOOP_TASK_STACK (2*1024)
+extern TaskHandle_t main_loop_task_handler;
+extern StackType_t main_loop_task_stack[MAIN_LOOP_TASK_STACK];
+extern StaticTask_t main_loop_task_tcb;
+
+// UART
+#define UART_TASK_STACK (2*512)
+extern TaskHandle_t uart_task_handler;
+extern StackType_t uart_task_stack[UART_TASK_STACK];
+extern StaticTask_t uart_task_tcb;
+
+// BLE
+#define NIMBLE_TASK_STACK (2*1024)
+extern TaskHandle_t nimble_task_handler;
+extern StackType_t nimble_task_stack[NIMBLE_TASK_STACK];
+extern StaticTask_t nimble_task_tcb;
+#define BLE_TASK_STACK (1*1024)
+extern TaskHandle_t ble_task_handler;
+extern StackType_t ble_task_stack[BLE_TASK_STACK];
+extern StaticTask_t ble_task_tcb;
+
+// WIFI
+#define WIFI_SCAN_TASK_STACK (1*1024)
+extern TaskHandle_t wifi_scan_task_handler;
+extern StackType_t wifi_scan_task_stack[WIFI_SCAN_TASK_STACK];
+extern StaticTask_t wifi_scan_task_tcb;
+
+// HTTP
+#define HTTP_GET_URL_TASK_STACK (2*1024)
+// extern TaskHandle_t http_get_url_task_handler;
+// extern StackType_t http_get_url_task_stack[HTTP_GET_URL_TASK_STACK];
+// extern StaticTask_t http_get_url_task_tcb;
+#define HTTP_DOWNLOAD_CRT_TASK_STACK (4*1024)
+// extern TaskHandle_t http_download_crt_task_handler;
+// extern StackType_t http_download_crt_task_stack[HTTP_DOWNLOAD_CRT_TASK_STACK];
+// extern StaticTask_t http_download_crt_task_tcb;
+
+#define NET_PAIRING_INFO_MAX_LEN 256
+#define SERIAL_NUMBER_MAX_LEN 32
+
+// WIFI
+#if CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HUNT_AND_PECK
+#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HUNT_AND_PECK
+#define EXAMPLE_H2E_IDENTIFIER ""
+#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HASH_TO_ELEMENT
+#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HASH_TO_ELEMENT
+#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID
+#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_BOTH
+#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH
+#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID
+#endif
+#if CONFIG_ESP_WIFI_AUTH_OPEN
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
+#elif CONFIG_ESP_WIFI_AUTH_WEP
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
+#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
+#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
+#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
+#endif
+
+#define MAIN_LOOP_INTERVAL 50
+
+typedef enum
+{
+ COMMON_NONE_BIT = 0,
+ COMMON_RESET_BIT = BIT0,
+ COMMON_HTTP_DOWNLOAD_BIT = BIT1,
+ COMMON_MQTT_CONNECT_BIT = BIT2,
+ COMMON_MQTT_DISCONNECT_BIT = BIT3,
+}COMMON_EVENT_GROUP_BIT_E;
+
+typedef enum
+{
+ HOST_TYPE_LOCAL = 0,
+ HOST_TYPE_USB,
+ HOST_TYPE_UART,
+ HOST_TYPE_BLE,
+ HOST_TYPE_HTTP,
+ HOST_TYPE_MQTT,
+}HOST_TYPE_E;
+
+typedef enum
+{
+ SSL_CLIENT_CRT,
+ SSL_CLIENT_KEY,
+ SSL_SERVER_CRT,
+}CERT_TYPE_E;
+
+typedef union
+{
+ struct
+ {
+ uint16_t length;
+ uint8_t content[2560-2];
+ };
+ uint8_t buffer[2560];
+}__attribute__((packed)) SSL_CERT_T;
+
+typedef union
+{
+ struct
+ {
+ uint8_t wifi_info_flag:1;
+ uint8_t serial_number_flag:1;
+ uint8_t device_id_flag:1;
+ uint8_t reserved:6;
+
+ uint8_t wifi_ssid_len;
+ uint8_t wifi_ssid[WIFI_SSID_MAX_LEN+1];
+ uint8_t wifi_pwd_len;
+ uint8_t wifi_pwd[WIFI_PWD_MAX_LEN+1];
+ uint8_t serial_number_len;
+ uint8_t serial_number[SERIAL_NUMBER_MAX_LEN+1];
+ uint8_t device_id_len;
+ uint8_t device_id[32];
+ };
+}__attribute__((packed)) NET_INFO_T;
+
+typedef struct
+{
+ NET_INFO_T net_info;
+ SSL_CERT_T ssl_cert[3];
+}__attribute__((packed)) COMMON_STORAGE_T;
+
+#define PRODUCT_NAME_MAX_LEN 23
+typedef struct
+{
+ uint16_t vid;
+ uint16_t pid;
+ uint16_t fw_version;
+ uint16_t build_version;
+ uint8_t product_name_len;
+ char product_name[PRODUCT_NAME_MAX_LEN+1]; // 产品名称最长23字节
+}__attribute__((packed)) MCU_INFO_T;
+
+typedef enum
+{
+ NET_PAIRING_BLE_CONFIGURING,
+ NET_PAIRING_WIFI_CONFIGURING,
+ NET_PAIRING_WIFI_CONNECTTING,
+ NET_PAIRING_WIFI_CONNECTED_AP,
+ NET_PAIRING_WIFI_CONNECTED_SERVER,
+}NET_PAIRING_STATUS_E;
+
+typedef struct
+{
+ uint8_t sync_flag;
+ int8_t time_zone;
+ uint64_t real_time;
+ uint64_t system_time;
+}__attribute__((packed)) TIMESTAMP_T;
+
+typedef struct
+{
+ uint8_t ble_state; // 0:关闭 1:广播 2:已连接
+}__attribute__((packed)) BLE_STATUS_T;
+
+typedef struct
+{
+ uint8_t wifi_mode; // 0:关闭 1:扫描 2:打开
+
+ uint8_t wifi_state:1; // 0:disconnected 1:connected
+ uint8_t connect_mode:2; // 1:厂测模式 2:用户配网模式 3:正常连接
+ uint8_t reserved:5;
+
+ uint8_t net_pair_host;
+ uint8_t net_pair_encrypt_profile; // 0:明文 1:AES-128 ECB
+
+ uint8_t cur_ssid_len;
+ uint8_t cur_pwd_len;
+ char cur_ssid[WIFI_SSID_MAX_LEN+1];
+ char cur_pwd[WIFI_PWD_MAX_LEN+1];
+
+ int32_t rssi;
+}__attribute__((packed)) WIFI_STATUS_T;
+
+
+typedef struct
+{
+ uint8_t serial_number_flag:1;
+ uint8_t device_id_flag:1;
+ uint8_t http_url_flag:1;
+ uint8_t http_token_flag:1;
+ uint8_t user_id_flag:1;
+ uint8_t mqtt_sub_url_flag:1;
+ uint8_t reserved:2;
+
+ // int32_t net_pair_cooldown;
+
+ uint16_t serial_number_length;
+ uint16_t http_url_length;
+ uint16_t http_token_length;
+ uint16_t mqtt_sub_url_length;
+
+ char serial_number[SERIAL_NUMBER_MAX_LEN+1];
+ int device_id;
+ char http_url[NET_PAIRING_INFO_MAX_LEN+1];
+ char http_token[NET_PAIRING_INFO_MAX_LEN+1];
+ uint32_t user_id;
+ char mqtt_sub_url[128];
+}__attribute__((packed)) NET_PAIR_INFO_T;
+
+typedef struct
+{
+ uint8_t heart_beat_enable:1;
+ uint8_t mcu_info_got_flag:1;
+ uint8_t reserved:6;
+
+ // UNIVERSAL
+ uint32_t heart_beat_interval; // ms
+ MCU_INFO_T mcu_info;
+ uint8_t net_pairing_status;
+ TIMESTAMP_T timestamp;
+
+ // BLE
+ BLE_STATUS_T ble_status;
+ uint32_t ble_enable_tick;
+
+ // WIFI
+ WIFI_STATUS_T wifi_status;
+ wifi_config_t wifi_config;
+
+ // NET PAIR
+ NET_PAIR_INFO_T net_pairing_info;
+
+ // MQTT
+ esp_mqtt_client_config_t mqtt_cfg;
+ esp_mqtt_client_handle_t mqtt_client_handle;
+}COMMON_SETTING_T;
+
+#define WIFI_QUEUE_LENGTH 2
+#define WIFI_QUEUE_ITEM_SIZE 8
+extern uint8_t wifi_queue_storage[WIFI_QUEUE_LENGTH*WIFI_QUEUE_ITEM_SIZE];
+extern QueueHandle_t wifi_queue_handle;
+extern StaticQueue_t wifi_queue_buffer;
+extern uint8_t wifi_queue_write[WIFI_QUEUE_ITEM_SIZE];
+
+// #define BLE_QUEUE_LENGTH 2
+// #define BLE_QUEUE_ITEM_SIZE 8
+// extern uint8_t ble_queue_storage[BLE_QUEUE_LENGTH*BLE_QUEUE_ITEM_SIZE];
+// extern QueueHandle_t ble_queue_handle;
+// extern StaticQueue_t ble_queue_buffer;
+// extern uint8_t ble_queue_write[BLE_QUEUE_ITEM_SIZE];
+#define BLE_ON_BIT BIT0
+#define BLE_OFF_BIT BIT1
+extern EventGroupHandle_t ble_event_group;
+
+extern EventGroupHandle_t common_event_group;
+
+extern COMMON_STORAGE_T common_storage;
+extern COMMON_SETTING_T common_setting;
+
+#define ESP_PROTOCOL_MAX_BUF_SZIE 512
+
+//设备接收数据解析并处理后回复给发送方的结构体,包含协议头、命令、长度、数据内容等
+typedef struct
+{
+ uint8_t send_flag:1;
+ uint8_t reserved:7;
+
+ union
+ {
+ struct
+ {
+ uint8_t cmd;
+ uint16_t len;
+ uint8_t content[ESP_PROTOCOL_MAX_BUF_SZIE-4];
+ // uint8_t crc;
+ };
+ uint8_t buffer[ESP_PROTOCOL_MAX_BUF_SZIE-2];
+ };
+}__attribute__((packed)) BLE_SEND_REPLY_T;
+
+//设备接收BLE的原始数据size + BUFFER
+typedef struct
+{
+ uint16_t size;
+ uint8_t buffer[ESP_PROTOCOL_MAX_BUF_SZIE];
+}__attribute__((packed)) BLE_RECV_DATA_T;
+
+
+void Ble_Pairing_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type);
+void Ble_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type);
+
+void Uart_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type);
+void Uart_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type);
+
+
+void Check_Host_Type(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type);
+
+
+
+typedef struct
+{
+ uint8_t enable; // 1:认证前 2:认证后 3:写入后
+ uint8_t content[15];
+}__attribute__((packed)) FW_FILE_HEADER_CMD_T;
+
+typedef struct
+{
+ uint64_t header_magic;
+ uint32_t reserved0;
+ uint16_t file_type;
+ uint8_t protocol_version;
+ uint8_t device_type;
+
+ uint32_t code_size;
+ uint8_t reserved1[4];
+ uint16_t single_write_page_size;
+ uint8_t reserved2[6];
+
+ char code[64];
+
+ uint16_t vid_app;
+ uint16_t pid_app;
+ uint16_t vid_boot;
+ uint16_t pid_boot;
+ uint8_t reserved3[8];
+
+ uint16_t fw_version;
+ uint16_t build_version;
+ uint8_t reserved4[12];
+
+ uint32_t write_erase_start_addr;
+ uint32_t write_erase_size;
+ uint32_t file_start_addr;
+ uint32_t file_size;
+
+ union
+ {
+ // 额外命令
+ struct
+ {
+ FW_FILE_HEADER_CMD_T cmd[7];
+ }header_type_1;
+
+ uint8_t data[112];
+ };
+}__attribute__((packed)) FW_FILE_HEADER_T;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
--- /dev/null
+#include "project_common.h"
+
+static const char *UART_TAG = "UART_TASK";
+
+// static const int uart_rx_max = UART_BUF_SIZE;
+static uint8_t uart_rx_data[UART_BUF_SIZE] = {0};
+
+uint8_t uart_tx_queue_storage[UART_TX_QUEUE_LENGTH*UART_TX_QUEUE_ITEM_SIZE];
+QueueHandle_t uart_tx_queue_handle;
+StaticQueue_t uart_tx_queue_buffer;
+
+void Uart_Initialize(void)
+{
+ const uart_config_t uart_config = {
+ .baud_rate = 921600,//115200,
+ .data_bits = UART_DATA_8_BITS,
+ .parity = UART_PARITY_DISABLE,
+ .stop_bits = UART_STOP_BITS_1,
+ .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
+ .source_clk = UART_SCLK_DEFAULT,
+ };
+ uart_param_config(UART_NUM_1, &uart_config);
+ uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
+ uart_driver_install(UART_NUM_1, UART_BUF_SIZE, 0, 0, NULL, 0);
+}
+
+void Uart_Tx_Query_Process(void)
+{
+ static UART_RECV_DATA_T uart_tx_data = {0};
+ if(xQueueReceive(uart_tx_queue_handle, &uart_tx_data, 0) == pdTRUE)
+ {
+ taskENTER_CRITICAL(1);
+ uart_write_bytes(UART_NUM_1, uart_tx_data.buffer, uart_tx_data.size);
+ taskEXIT_CRITICAL(1);
+
+ // ESP_LOGI(UART_TAG, "Send %d bytes: ", uart_tx_data.size);
+ // ESP_LOG_BUFFER_HEX(UART_TAG, uart_tx_data.buffer, uart_tx_data.size);
+ }
+}
+
+void Uart_Task(void *arg)
+{
+ esp_log_level_set(UART_TAG, ESP_LOG_INFO);
+ memset(uart_rx_data, 0x00, sizeof(uart_rx_data));
+ while (1)
+ {
+ const int uart_rx_size = uart_read_bytes(UART_NUM_1, uart_rx_data, UART_BUF_SIZE, 1 / portTICK_PERIOD_MS);
+ if (uart_rx_size > 0)
+ {
+ Uart_Pairing_Handle(uart_rx_data, uart_rx_size, HOST_TYPE_UART);
+ }
+
+ static BLE_MESSAGE_T ble_write = {0};
+ if(xQueueReceive(ble_write_queue_handle, &ble_write, 0) == pdTRUE)
+ {
+ Ble_Pairing_Handle(ble_write.data, ble_write.length, HOST_TYPE_BLE);
+ }
+
+ Uart_Tx_Query_Process();
+
+ vTaskDelay(1 / portTICK_PERIOD_MS);
+ }
+}
+
+
--- /dev/null
+#ifndef _UART_H_
+#define _UART_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#define TXD_PIN (1)
+#define RXD_PIN (0)
+
+#define UART_BUF_SIZE 255
+
+#define BLE_BUF_SIZE 512
+
+#define FRAMEHEAD_IOT_TO_PANEL (0xF1)
+#define FRAMEHEAD_PANEL_TO_IOT (0xF2)
+
+#define FRAMEHEAD_APP_TO_ESP (0xFF)
+#define FRAMEHEAD_ESP_TO_APP (0xFE)
+
+typedef enum
+{
+ REPLY_STATUS_NONE = 0,
+ REPLY_STATUS_OK = 1,
+ REPLY_STATUS_FAIL,
+ REPLY_STATUS_NO_CMD,
+ REPLY_STATUS_LACK_OF_PARAM,
+ REPLY_STATUS_UNAUTH,
+}REPLY_STATUS_T;
+
+//uart接收数据
+typedef struct
+{
+ uint16_t size;
+ uint8_t buffer[UART_BUF_SIZE];
+}__attribute__((packed)) UART_RECV_DATA_T;
+
+//串口接收数据本地解析回传给UART发送的结构体,包含协议头、命令、长度、数据内容等
+typedef struct
+{
+ uint8_t send_flag:1;
+ uint8_t reserved:7;
+
+ union
+ {
+ struct
+ {
+ uint8_t cmd;
+ uint16_t len;
+ uint8_t content[UART_BUF_SIZE-4];
+ // uint8_t crc;
+ };
+ uint8_t buffer[UART_BUF_SIZE-2];
+ };
+}__attribute__((packed)) UART_RECV_REPLY_T;
+
+#define UART_TX_QUEUE_LENGTH 3
+#define UART_TX_QUEUE_ITEM_SIZE (sizeof(UART_RECV_DATA_T))
+
+extern uint8_t uart_tx_queue_storage[UART_TX_QUEUE_LENGTH*UART_TX_QUEUE_ITEM_SIZE];
+extern QueueHandle_t uart_tx_queue_handle;
+extern StaticQueue_t uart_tx_queue_buffer;
+
+void Uart_Initialize(void);
+
+void Uart_Tx_Query_Process(void);
+
+void Uart_Task(void *arg);
+
+#endif
--- /dev/null
+#include "project_common.h"
+
+#define PARA_FLASH_NAME "user_data"
+static const char *FLASH_TAG = "user_flash";
+
+static const esp_partition_t *partition;
+
+SemaphoreHandle_t user_flash_mutex;
+// static uint32_t user_flash_write[FLASH_SEC_SIZE/4] = {0};
+// static uint32_t user_flash_read[FLASH_SEC_SIZE/4] = {0};
+static uint32_t user_flash_data[FLASH_SEC_SIZE/sizeof(uint32_t)] = {0};
+
+void User_Flash_Check(void)
+{
+ //寻找分区表
+ partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARA_FLASH_NAME);
+ assert(partition != NULL);
+
+ if(User_Flash_Read_Check(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info, sizeof(NET_INFO_T)) != ESP_OK)
+ {
+ printf("%s read common_storage failed\n",__func__);
+ common_storage.net_info.wifi_info_flag = 0;
+ common_storage.net_info.device_id_flag = 0;
+
+ }else{
+ printf("%s read serialNumber %s\n",__func__,common_storage.net_info.serial_number);
+ }
+
+ if(User_Flash_Read_Check(UF_OFFSET_CERT_CLIENT_CRT_ADDR, UF_OFFSET_CERT_CERT_FLAG, &common_storage.ssl_cert[SSL_CLIENT_CRT], sizeof(SSL_CERT_T)) != ESP_OK)
+ {
+ common_storage.ssl_cert[SSL_CLIENT_CRT].length = 0;
+ printf("%s read client_ssl_cer failed\n",__func__);
+ }else{
+ printf("%s read client_ssl_cer success %d\n",__func__,common_storage.ssl_cert[SSL_CLIENT_CRT].length);
+ }
+ if(User_Flash_Read_Check(UF_OFFSET_CERT_CLIENT_KEY_ADDR, UF_OFFSET_CERT_CERT_FLAG, &common_storage.ssl_cert[SSL_CLIENT_KEY], sizeof(SSL_CERT_T)) != ESP_OK)
+ {
+ common_storage.ssl_cert[SSL_CLIENT_KEY].length = 0;
+ printf("%s read client_ssl_cer_key failed\n",__func__);
+ }
+ else{
+ printf("%s read client_ssl_cer success %d\n",__func__,common_storage.ssl_cert[SSL_CLIENT_KEY].length);
+ }
+ if(User_Flash_Read_Check(UF_OFFSET_CERT_SERVER_CRT_ADDR, UF_OFFSET_CERT_CERT_FLAG, &common_storage.ssl_cert[SSL_SERVER_CRT], sizeof(SSL_CERT_T)) != ESP_OK)
+ {
+ common_storage.ssl_cert[SSL_SERVER_CRT].length = 0;
+ printf("%s read server_ssl_cer failed\n",__func__);
+ }else{
+ printf("%s read client_ssl_cer success %d\n",__func__,common_storage.ssl_cert[SSL_CLIENT_KEY].length);
+ }
+}
+
+esp_err_t User_Flash_Erase(size_t offset, size_t size)
+{
+ esp_err_t err = 0;
+
+ if(size % partition->erase_size != 0)
+ {
+ err = ESP_ERR_INVALID_SIZE;
+ }
+ else
+ {
+ //擦除flash
+ err = esp_partition_erase_range(partition, offset, size);
+ }
+
+ if(err != 0)
+ {
+ ESP_LOGI(FLASH_TAG, "user flash erase error %d, offset:0x%08x, size:0x%x", err, offset, size);
+ }
+ return err;
+}
+
+esp_err_t User_Flash_Write(size_t offset, void* buf, size_t size)
+{
+ esp_err_t err = 0;
+
+ //写入flash
+ err = esp_partition_write(partition, offset, buf, size);
+ if(err != 0)
+ {
+ ESP_LOGI(FLASH_TAG, "user flash write error %d, offset:0x%08x, size:0x%x", err, offset, size);
+ }
+ return err;
+}
+
+//在指定地址读出数组
+esp_err_t User_Flash_Read(size_t offset, void* buf, size_t size)
+{
+ esp_err_t err = 0;
+
+ //读取flash
+ err = esp_partition_read(partition, offset, buf, size);
+
+ if(err != 0)
+ {
+ ESP_LOGI(FLASH_TAG, "user flash read err %d, offset:0x%08x, size:0x%x", err, offset, size);
+ }
+ return err;
+}
+
+esp_err_t User_Flash_Write_With_Flag(uint32_t addr, uint32_t flag, void* data, uint16_t size)
+{
+ esp_err_t err = ESP_FAIL;
+ if(xSemaphoreTake(user_flash_mutex, portMAX_DELAY) == pdTRUE)
+ {
+ uint16_t size_word = ((size/4) + ((size)%4 > 0 ? 1:0)) + 1 + 1;
+ memset(user_flash_data, 0xFF, sizeof(user_flash_data));
+ user_flash_data[0] = flag;
+ memcpy(&user_flash_data[1], data, size);
+ user_flash_data[size_word-1] = Crc32_JAMCRC_Cal(data, size);
+
+ User_Flash_Erase(addr, FLASH_SEC_SIZE);
+
+ // DUG_PRINTF("write word %d:", size_word);
+ // for(uint16_t i=0;i<size_word;i++)
+ // {
+ // DUG_PRINTF("(%d)%08x ", err, user_flash_data[i]);
+ // }
+ // DUG_PRINTF("\n");
+ err = User_Flash_Write(addr, user_flash_data, size_word*4);
+
+#if (0)
+ uint8_t read[16] = {0};
+ Flash_Read(addr, read, 16);
+ DUG_PRINTF("read: ");
+ for(uint16_t i=0;i<16;i++)
+ {
+ DUG_PRINTF("%02x ", read[i]);
+ }
+ DUG_PRINTF("\n");
+#endif
+ xSemaphoreGive(user_flash_mutex);
+ }
+ return err;
+}
+
+esp_err_t User_Flash_Read_Check(uint32_t addr, uint32_t flag, void* buf, uint16_t size)
+{
+ esp_err_t err = ESP_FAIL;
+ if(xSemaphoreTake(user_flash_mutex, portMAX_DELAY) == pdTRUE)
+ {
+
+ memset(user_flash_data, 0xFF, sizeof(user_flash_data));
+ uint16_t word_size = ((size/4) + ((size)%4 > 0 ? 1:0)) + 1 + 1;
+ if(User_Flash_Read(addr, user_flash_data, word_size*4) == ESP_OK)
+ {
+ if(user_flash_data[0] == flag && Crc32_JAMCRC_Cal((uint8_t*)&user_flash_data[1], size) == user_flash_data[word_size-1])
+ {
+ memcpy(buf, &user_flash_data[1], size);
+ err = ESP_OK;
+ }
+ }
+ xSemaphoreGive(user_flash_mutex);
+ }
+ return err;
+}
+
+
--- /dev/null
+#ifndef _USER_FLASH_H_
+#define _USER_FLASH_H_
+
+#include <stdint.h>
+#include "esp_partition.h"
+
+#define FLASH_SEC_SIZE 4096
+
+#define FLAG_SIZE 4
+#define CRC_SIZE 4
+
+//USER_CONFIGDATA_T结构体的大小不能超过FLASH_SEC_SIZE
+#define UF_OFFSET_START_ADDR 0x00000000
+#define UF_OFFSET_USER_CONFIG_INFO_ADDR UF_OFFSET_START_ADDR
+#define UF_OFFSET_USER_CONFIG_INFO_SIZE_NUM 1 //保存配置信息所需要的大小单位是4096
+
+#define UF_OFFSET_USER_CONFIG_INFO_FLAG 0xABCD0001
+
+#define UF_OFFSET_CERT_CLIENT_CRT_ADDR UF_OFFSET_USER_CONFIG_INFO_ADDR+FLASH_SEC_SIZE*UF_OFFSET_USER_CONFIG_INFO_SIZE_NUM
+#define UF_OFFSET_CERT_CLIENT_CRT_SIZE 1 //保存配置所需要的大小单位是4096
+
+#define UF_OFFSET_CERT_CLIENT_KEY_ADDR UF_OFFSET_CERT_CLIENT_CRT_ADDR+FLASH_SEC_SIZE*UF_OFFSET_CERT_CLIENT_CRT_SIZE
+#define UF_OFFSET_CERT_CLIENT_KEY_SIZE 1 //保存配置所需要的大小单位是4096
+
+#define UF_OFFSET_CERT_SERVER_CRT_ADDR UF_OFFSET_CERT_CLIENT_KEY_ADDR+FLASH_SEC_SIZE*UF_OFFSET_CERT_CLIENT_KEY_SIZE
+#define UF_OFFSET_CERT_SERVER_CRT_SIZE 1 //保存配置所需要的大小单位是4096
+
+#define UF_OFFSET_CERT_CERT_FLAG 0xABCD0001
+
+extern SemaphoreHandle_t user_flash_mutex;
+
+void User_Flash_Check(void);
+
+esp_err_t User_Flash_Write_With_Flag(uint32_t addr, uint32_t flag, void* data, uint16_t size);
+esp_err_t User_Flash_Read_Check(uint32_t addr, uint32_t flag, void* buf, uint16_t size);
+
+#endif
--- /dev/null
+/* WiFi
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include <string.h>
+#include "project_common.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 "nvs_flash.h"
+
+// #include "lwip/err.h"
+// #include "lwip/sys.h"
+
+// #include "wifi.h"
+// #include "mqtt_client.h"
+// #include "user_flash.h"
+
+/* FreeRTOS event group to signal when we are connected*/
+static EventGroupHandle_t s_wifi_event_group;
+
+esp_netif_t *wifi_sta_netif = NULL;
+
+/* The event group allows multiple bits for each event, but we only care about two events:
+ * - we are connected to the AP with an IP
+ * - we failed to connect after the maximum amount of retries */
+#define WIFI_CONNECTED_BIT BIT0
+#define WIFI_FAIL_BIT BIT1
+#define WIFI_AP_NOT_FOUND_BIT BIT2
+#define WIFI_PWD_FAIL_BIT BIT3
+
+static const char *WIFI_TAG = "wifi station";
+
+static int s_retry_num = 0;
+static uint32_t wifi_connect_retry_max = 0xFFFFFFFF;//EXAMPLE_ESP_MAXIMUM_RETRY;
+
+SemaphoreHandle_t wifi_scan_mutex;
+
+
+//获取wifi的rssi事件处理函数
+static void esp_bss_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
+{
+ wifi_event_bss_rssi_low_t *event = event_data;
+
+ // ESP_LOGI(WIFI_TAG, "%s:bss rssi is=%ld", __func__, event->rssi);
+ common_setting.wifi_status.rssi = event->rssi;
+}
+
+// wifi事件处理函数 断开 连接 获取ip等事件都会进入这个函数
+static void event_handler(void* arg, esp_event_base_t event_base,
+ int32_t event_id, void* event_data)
+{
+ ESP_LOGE(WIFI_TAG, "event_handler %" PRId32 "\n", event_id);
+ if(event_base == WIFI_EVENT)
+ {
+ switch(event_id)
+ {
+ case WIFI_EVENT_STA_START:
+ {
+ if(common_setting.ble_status.ble_state > 0)//只有蓝牙开启才能连接wifi,其他情况不连接wifi,除非重启设备或者app下发wifi信息重新配网
+ {
+ esp_wifi_connect();
+ common_setting.wifi_status.wifi_state = 0;
+ }
+ }
+ break;
+
+ case WIFI_EVENT_STA_DISCONNECTED:
+ {
+ wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
+ ESP_LOGE(WIFI_TAG, "Disconnect reason : %d", disconnected->reason);
+ uint8_t fail_reason = 0;
+ /* Set code corresponding to the reason for disconnection */
+ switch (disconnected->reason)
+ {
+ case WIFI_REASON_AUTH_EXPIRE:
+ case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
+ case WIFI_REASON_AUTH_FAIL:
+ case WIFI_REASON_HANDSHAKE_TIMEOUT:
+ case WIFI_REASON_MIC_FAILURE:
+ ESP_LOGE(WIFI_TAG, "STA Auth Error");
+ fail_reason = 2;
+ break;
+ case WIFI_REASON_NO_AP_FOUND:
+ ESP_LOGE(WIFI_TAG, "STA AP Not found");
+ fail_reason = 1;
+ break;
+ }
+
+ if (s_retry_num < wifi_connect_retry_max)//尝试重连wifi的次数,默认为0xFFFFFFFF,即一直重试
+ {
+ esp_wifi_connect();
+ s_retry_num++;
+ ESP_LOGI(WIFI_TAG, "retry to connect to the AP");
+ }
+ else
+ {
+ if(fail_reason == 1)//连接失败次数已上线了就不需要再开启wifi连接了,除非重启设备或者app下发wifi信息重新配网
+ {
+ xEventGroupSetBits(s_wifi_event_group, WIFI_AP_NOT_FOUND_BIT);
+ }
+ else if(fail_reason == 2)//pwm错误不需要再开启wifi连接了,除非重启设备或者app下发wifi信息重新配网
+ {
+ xEventGroupSetBits(s_wifi_event_group, WIFI_PWD_FAIL_BIT);
+ }
+ xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
+
+ }
+ ESP_LOGI(WIFI_TAG,"connect to the AP fail");
+ common_setting.wifi_status.wifi_state = 0;
+ }
+ break;
+ }
+ }
+ else if(event_base == IP_EVENT)
+ {
+ switch(event_id)
+ {
+ case IP_EVENT_STA_GOT_IP://连接路由成功获取ip地址事件
+ {
+ ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
+ ESP_LOGI(WIFI_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
+ s_retry_num = 0;
+ common_setting.wifi_status.wifi_state = 1;
+ Wifi_Connect_Timerout_Stop();//连接成功了就关闭定时器
+ xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
+ esp_wifi_set_rssi_threshold(WIFI_RSSI_THRESHOLD);
+ }
+ break;
+ }
+ }
+}
+
+void Wifi_Sta_Init(void)
+{
+ s_wifi_event_group = xEventGroupCreate();
+
+ // ESP_ERROR_CHECK(esp_netif_init());
+
+ // ESP_ERROR_CHECK(esp_event_loop_create_default());
+ wifi_sta_netif = esp_netif_create_default_wifi_sta();
+
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+
+ esp_event_handler_instance_t instance_any_id;
+ esp_event_handler_instance_t instance_got_ip;
+ ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+ ESP_EVENT_ANY_ID,
+ &event_handler,
+ NULL,
+ &instance_any_id));
+ ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
+ IP_EVENT_STA_GOT_IP,
+ &event_handler,
+ NULL,
+ &instance_got_ip));
+
+ ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, &esp_bss_rssi_low_handler, NULL));
+
+ // wifi_config_t wifi_config = {
+ // .sta = {
+ // .ssid = EXAMPLE_ESP_WIFI_SSID,
+ // .password = EXAMPLE_ESP_WIFI_PASS,
+ // /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8).
+ // * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
+ // * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
+ // * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
+ // */
+ // .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
+ // .sae_pwe_h2e = ESP_WIFI_SAE_MODE,
+ // .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
+ // },
+ // };
+ // ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
+ // ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &common_setting.wifi_config) );
+ // ESP_ERROR_CHECK(esp_wifi_start());
+
+ // ESP_LOGI(WIFI_TAG, "wifi_init finished.");
+}
+
+#define SEC_TO_US(sec) ((sec) * 1000000ULL)
+static void Wifi_connect_timerout_callback(void* arg)
+{
+ ESP_LOGI(WIFI_TAG, "One-time timer triggered after 80 s");
+ xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);//超时了就关闭ble,停止配网,除非重启设备或者app下发wifi信息重新配网
+}
+static esp_timer_handle_t wifi_one_timer_handle;//创建定时器handle
+static uint8_t wifi_one_timer_flag = 0;//0:未创建 1:已创建
+void Wifi_Connect_Timerout_Start(void)
+{
+ #if (1)
+ // Create and start one-time timer for 80 ms
+
+ const esp_timer_create_args_t one_time_timer_args = {
+ .callback = &Wifi_connect_timerout_callback,
+ .arg = NULL,
+ .name = "one_time_timer"
+ };
+ esp_timer_create(&one_time_timer_args, &wifi_one_timer_handle);
+ esp_timer_start_once(wifi_one_timer_handle, SEC_TO_US(80)); // 80 s in microseconds 根据客户自定义修改超时时间
+ wifi_one_timer_flag = 1;
+ #endif
+}
+void Wifi_Connect_Timerout_Stop(void)
+{
+ if(wifi_one_timer_flag)
+ {
+ // Stop and delete the timer if it's still running
+ wifi_one_timer_flag = 0;
+ esp_timer_stop(wifi_one_timer_handle);
+ esp_timer_delete(wifi_one_timer_handle);
+
+ }
+}
+void Wifi_Start(void)
+{
+ memset(common_setting.wifi_config.sta.ssid, 0x00, sizeof(common_setting.wifi_config.sta.ssid));
+ memset(common_setting.wifi_config.sta.password, 0x00, sizeof(common_setting.wifi_config.sta.password));
+ // memcpy(common_setting.wifi_config.sta.ssid, "H0110W", 7);
+ // memcpy(common_setting.wifi_config.sta.password, "264222264222", 13);
+ // memcpy(common_setting.wifi_config.sta.ssid, "PXN@SZoffice", 13);
+ // memcpy(common_setting.wifi_config.sta.password, "PXN201807", 10);
+ // memcpy(common_setting.wifi_config.sta.ssid, "ChinaNet-LaDe", 13);
+ // memcpy(common_setting.wifi_config.sta.password, "9596w3wq", 9);
+ memcpy(common_setting.wifi_config.sta.ssid, common_setting.wifi_status.cur_ssid, common_setting.wifi_status.cur_ssid_len);
+ memcpy(common_setting.wifi_config.sta.password, common_setting.wifi_status.cur_pwd, common_setting.wifi_status.cur_pwd_len);
+
+ ESP_LOGI(WIFI_TAG, "Wifi connnect ssid: %s", common_setting.wifi_config.sta.ssid);
+ ESP_LOGI(WIFI_TAG, "Wifi connnect pwd: %s", common_setting.wifi_config.sta.password);
+ ESP_ERROR_CHECK(esp_netif_set_hostname(wifi_sta_netif, LWIP_LOCAL_HOSTNAME));
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &common_setting.wifi_config));
+ s_retry_num = 0;
+ Wifi_Connect_Timerout_Start();
+ ESP_ERROR_CHECK(esp_wifi_start());
+ common_setting.wifi_status.wifi_mode = 2;
+
+ // common_setting.net_pairing_info.net_pair_cooldown = 80 * 60 * 1000;
+ ESP_LOGI(WIFI_TAG, "[APP] Free memory wifi on: %" PRIu32 " bytes", esp_get_free_heap_size());
+}
+void Wifi_Stop(void)
+{
+ if(common_setting.wifi_status.wifi_mode > 0)
+ {
+ xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | WIFI_AP_NOT_FOUND_BIT | WIFI_PWD_FAIL_BIT);
+ ESP_ERROR_CHECK(esp_wifi_stop());
+ ESP_LOGI(WIFI_TAG, "[APP] Free memory wifi off: %" PRIu32 " bytes", esp_get_free_heap_size());
+ xSemaphoreGive(wifi_scan_mutex);
+ common_setting.wifi_status.wifi_mode = 0;
+ common_setting.wifi_status.wifi_state = 0;
+ common_setting.net_pairing_info.http_url_flag = 0;
+ common_setting.net_pairing_info.http_token_flag = 0;
+ common_setting.net_pairing_info.user_id_flag = 0;
+ }
+}
+
+static void print_auth_mode(int authmode)
+{
+ switch (authmode) {
+ case WIFI_AUTH_OPEN:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_OPEN");
+ break;
+ case WIFI_AUTH_OWE:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_OWE");
+ break;
+ case WIFI_AUTH_WEP:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WEP");
+ break;
+ case WIFI_AUTH_WPA_PSK:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
+ break;
+ case WIFI_AUTH_WPA2_PSK:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
+ break;
+ case WIFI_AUTH_WPA_WPA2_PSK:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
+ break;
+ case WIFI_AUTH_ENTERPRISE:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_ENTERPRISE");
+ break;
+ case WIFI_AUTH_WPA3_PSK:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
+ break;
+ case WIFI_AUTH_WPA2_WPA3_PSK:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
+ break;
+ // case WIFI_AUTH_WPA3_ENTERPRISE:
+ // ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA3_ENTERPRISE");
+ // break;
+ // case WIFI_AUTH_WPA2_WPA3_ENTERPRISE:
+ // ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_ENTERPRISE");
+ // break;
+ case WIFI_AUTH_WPA3_ENT_192:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_WPA3_ENT_192");
+ break;
+ default:
+ ESP_LOGI(WIFI_TAG, "Authmode \tWIFI_AUTH_UNKNOWN");
+ break;
+ }
+}
+
+static void print_cipher_type(int pairwise_cipher, int group_cipher)
+{
+ switch (pairwise_cipher) {
+ case WIFI_CIPHER_TYPE_NONE:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
+ break;
+ case WIFI_CIPHER_TYPE_WEP40:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
+ break;
+ case WIFI_CIPHER_TYPE_WEP104:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
+ break;
+ case WIFI_CIPHER_TYPE_TKIP:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
+ break;
+ case WIFI_CIPHER_TYPE_CCMP:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
+ break;
+ case WIFI_CIPHER_TYPE_TKIP_CCMP:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
+ break;
+ case WIFI_CIPHER_TYPE_AES_CMAC128:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_AES_CMAC128");
+ break;
+ case WIFI_CIPHER_TYPE_SMS4:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_SMS4");
+ break;
+ case WIFI_CIPHER_TYPE_GCMP:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP");
+ break;
+ case WIFI_CIPHER_TYPE_GCMP256:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP256");
+ break;
+ default:
+ ESP_LOGI(WIFI_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
+ break;
+ }
+
+ switch (group_cipher) {
+ case WIFI_CIPHER_TYPE_NONE:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
+ break;
+ case WIFI_CIPHER_TYPE_WEP40:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
+ break;
+ case WIFI_CIPHER_TYPE_WEP104:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
+ break;
+ case WIFI_CIPHER_TYPE_TKIP:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
+ break;
+ case WIFI_CIPHER_TYPE_CCMP:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
+ break;
+ case WIFI_CIPHER_TYPE_TKIP_CCMP:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
+ break;
+ case WIFI_CIPHER_TYPE_SMS4:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_SMS4");
+ break;
+ case WIFI_CIPHER_TYPE_GCMP:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP");
+ break;
+ case WIFI_CIPHER_TYPE_GCMP256:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP256");
+ break;
+ default:
+ ESP_LOGI(WIFI_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
+ break;
+ }
+}
+
+typedef struct
+{
+ uint8_t cnt;
+ char ssid[32];
+ int8_t rssi;
+ uint8_t auth_mode;
+ uint8_t pairwise_cipher;
+ uint8_t group_cipher;
+ uint8_t channel;
+}WIFI_SCAN_UNIT_T;
+
+#define WIFI_SCAN_PACKET_WIFI_NUM 6
+#define DEFAULT_SCAN_LIST_SIZE 24
+void Wifi_Scan_Task(void *pvParameters)
+{
+ // wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ // ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+ static BLE_SEND_REPLY_T wifi_scan_reply={0};
+ memset(&wifi_scan_reply, 0x00, sizeof(BLE_SEND_REPLY_T));
+ wifi_scan_reply.send_flag = 1;
+ wifi_scan_reply.cmd = 0x14;
+
+ uint8_t host_type = *(uint8_t*)pvParameters;
+
+ uint16_t number = DEFAULT_SCAN_LIST_SIZE;
+ wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
+ uint16_t ap_count = 0;
+ memset(ap_info, 0, sizeof(ap_info));
+ common_setting.wifi_status.wifi_mode = 1;
+ ESP_ERROR_CHECK(esp_netif_set_hostname(wifi_sta_netif, LWIP_LOCAL_HOSTNAME));
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_wifi_start());
+ esp_wifi_disconnect();
+ if(esp_wifi_scan_start(NULL, true) == ESP_OK)
+ {
+ ESP_LOGI(WIFI_TAG, "Max AP number ap_info can hold = %u", number);
+ ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
+ ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
+ ESP_LOGI(WIFI_TAG, "Total APs scanned = %u, actual AP number ap_info holds = %u\n", ap_count, number);
+
+ // 填装配网回复
+ for (int i = 0; i < number; i++)
+ {
+ ESP_LOGI(WIFI_TAG, "SSID \t\t%s", ap_info[i].ssid);
+ ESP_LOGI(WIFI_TAG, "RSSI \t\t%d", ap_info[i].rssi);
+ print_auth_mode(ap_info[i].authmode);
+ if (ap_info[i].authmode != WIFI_AUTH_WEP) {
+ print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);
+ }
+ ESP_LOGI(WIFI_TAG, "Channel \t\t%d\n", ap_info[i].primary);
+
+ // 填装配网回复
+ WIFI_SCAN_UNIT_T wifi_scan_unit = {0};
+ wifi_scan_unit.cnt = i;
+ memcpy(wifi_scan_unit.ssid, ap_info[i].ssid, sizeof(wifi_scan_unit.ssid));
+ wifi_scan_unit.rssi = ap_info[i].rssi;
+ wifi_scan_unit.auth_mode = ap_info[i].authmode;
+ wifi_scan_unit.pairwise_cipher = ap_info[i].pairwise_cipher;
+ wifi_scan_unit.group_cipher = ap_info[i].group_cipher;
+ wifi_scan_unit.channel = ap_info[i].primary;
+
+ memcpy(&wifi_scan_reply.content[3+(i%WIFI_SCAN_PACKET_WIFI_NUM)*sizeof(wifi_scan_unit.ssid)], &wifi_scan_unit, sizeof(wifi_scan_unit));
+
+ if((i+1) >= number || (i+1) % WIFI_SCAN_PACKET_WIFI_NUM == 0)
+ {
+ wifi_scan_reply.len = 3+((i%WIFI_SCAN_PACKET_WIFI_NUM)+1)*sizeof(wifi_scan_unit.ssid);
+
+ wifi_scan_reply.content[0] = number > 0xFF ? 0xFF:number;
+ wifi_scan_reply.content[1] = i/WIFI_SCAN_PACKET_WIFI_NUM;
+ wifi_scan_reply.content[2] = i%WIFI_SCAN_PACKET_WIFI_NUM;
+
+ Check_Host_Type(wifi_scan_reply.cmd, wifi_scan_reply.content, wifi_scan_reply.len, host_type);
+ memset(&wifi_scan_reply, 0x00, sizeof(BLE_SEND_REPLY_T));
+ }
+ }
+ }
+ else
+ {
+ ESP_LOGI(WIFI_TAG, "esp_wifi_scan_start fail\n");
+ wifi_scan_reply.len = 3;
+ wifi_scan_reply.content[0] = 0;
+ wifi_scan_reply.content[1] = 0;
+ wifi_scan_reply.content[2] = 0;
+ Check_Host_Type(wifi_scan_reply.cmd, wifi_scan_reply.content, wifi_scan_reply.len, host_type);
+ }
+
+ Wifi_Stop();
+ vTaskDelete(NULL);
+ return;
+}
+
+void Wifi_Queue_Send(uint8_t host, uint8_t enable, uint8_t net_pair_encrypt_profile)
+{
+ ESP_LOGI(WIFI_TAG, "Wifi_Queue_Send %d %d %d\n",host,enable,net_pair_encrypt_profile);
+ wifi_queue_write[0] = host;
+ wifi_queue_write[1] = enable;
+ wifi_queue_write[2] = net_pair_encrypt_profile;
+ xQueueSend(wifi_queue_handle, wifi_queue_write, 0);
+}
+
+void Wifi_Enable_Status_Check(void)
+{
+ static uint8_t wifi_queue_read[WIFI_QUEUE_ITEM_SIZE] = {0}; // byte0:0:本地 2:串口 3:蓝牙 byte1:1:厂测连接 2:用户配网 3:正常连接 4:扫描wifi列表 0xFF:关闭
+ if(xQueueReceive(wifi_queue_handle, wifi_queue_read, 0) == pdTRUE)
+ {
+ common_setting.wifi_status.net_pair_host = wifi_queue_read[0];
+ if(wifi_queue_read[1] == 4)
+ {
+ common_setting.wifi_status.connect_mode = 0;
+ // 扫描wifi列表
+ Wifi_Stop();
+ if(xSemaphoreTake(wifi_scan_mutex, 0) == pdTRUE)
+ {
+ wifi_scan_task_handler = xTaskCreateStatic(Wifi_Scan_Task, "Wifi_Scan_Task", WIFI_SCAN_TASK_STACK, &common_setting.wifi_status.net_pair_host, 2, wifi_scan_task_stack, &wifi_scan_task_tcb);
+ ESP_LOGI(WIFI_TAG, "[APP] Free memory wifi scan: %" PRIu32 " bytes", esp_get_free_heap_size());
+ vTaskDelay(10 / portTICK_PERIOD_MS);
+ }
+ }
+ else if(wifi_queue_read[1] == 1)
+ {
+ ESP_LOGI(WIFI_TAG, "厂测连接wifi\n");
+ // 厂测连接
+ Wifi_Stop();
+ if(xSemaphoreTake(wifi_scan_mutex, 0) == pdTRUE)
+ {
+ common_setting.wifi_status.connect_mode = 1;
+ common_setting.wifi_status.net_pair_encrypt_profile = wifi_queue_read[2];
+ wifi_connect_retry_max = EXAMPLE_ESP_MAXIMUM_RETRY;
+ Wifi_Start();
+ }
+ }
+ else if(wifi_queue_read[1] == 2)
+ {
+ // 用户配网
+ Wifi_Stop();
+ if(xSemaphoreTake(wifi_scan_mutex, 0) == pdTRUE)
+ {
+ common_setting.wifi_status.connect_mode = 2;
+ common_setting.wifi_status.net_pair_encrypt_profile = wifi_queue_read[2];
+ wifi_connect_retry_max = EXAMPLE_ESP_MAXIMUM_RETRY;
+ Wifi_Start();
+ }
+ }
+ else if(wifi_queue_read[1] == 3)
+ {
+ // 正常连接
+ Wifi_Stop();
+ if(xSemaphoreTake(wifi_scan_mutex, 0) == pdTRUE)
+ {
+ common_setting.wifi_status.connect_mode = 3;
+ wifi_connect_retry_max = 0xFFFFFFFF;
+ Wifi_Start();
+ }
+ }
+ else if(wifi_queue_read[1] == 0xFF)
+ {
+ common_setting.wifi_status.connect_mode = 0;
+ // 关闭
+ Wifi_Stop();
+ }
+
+ }
+
+ static EventBits_t bits_last = 0;
+ EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | WIFI_AP_NOT_FOUND_BIT | WIFI_PWD_FAIL_BIT, pdFALSE, pdFALSE, 0);
+
+ if(bits_last != (bits&(WIFI_CONNECTED_BIT | WIFI_FAIL_BIT)))
+ {
+ bits_last = (bits&(WIFI_CONNECTED_BIT | WIFI_FAIL_BIT));
+ if (bits & WIFI_CONNECTED_BIT)
+ {
+ ESP_LOGI(WIFI_TAG, "wifi connected\n");
+
+ if((common_setting.wifi_status.connect_mode == 1 || common_setting.wifi_status.connect_mode == 2))
+ {
+
+ static BLE_SEND_REPLY_T wifi_pairing_reply={0};
+ wifi_pairing_reply.send_flag = 1;
+ wifi_pairing_reply.cmd = 0x15;
+ wifi_pairing_reply.len = 3;
+ wifi_pairing_reply.content[0] = 0;
+ wifi_pairing_reply.content[1] = common_setting.wifi_status.connect_mode-1;
+ wifi_pairing_reply.content[2] = common_setting.wifi_status.net_pair_encrypt_profile;
+ Check_Host_Type(wifi_pairing_reply.cmd, wifi_pairing_reply.content, wifi_pairing_reply.len, common_setting.wifi_status.net_pair_host);
+ Wifi_Connect_Timerout_Stop();//关闭定时器
+ if (USER_TEST_ENABLE)
+ {
+ common_setting.net_pairing_info.http_url_flag = 1;
+ common_setting.net_pairing_info.http_token_flag = 1;
+ common_setting.net_pairing_info.user_id_flag = 1;
+ }
+
+ ESP_LOGI(WIFI_TAG, "connect_mode:%d %d %d %d\n", common_setting.wifi_status.connect_mode,common_setting.net_pairing_info.http_url_flag,common_setting.net_pairing_info.http_token_flag,\
+ common_setting.net_pairing_info.user_id_flag);
+ if(common_setting.net_pairing_info.http_url_flag && common_setting.net_pairing_info.http_token_flag && common_setting.net_pairing_info.user_id_flag)
+ {
+ ESP_LOGI(WIFI_TAG, "http_get_url_task start\n");
+ // http_get_url_task_handler = xTaskCreateStatic(http_get_url_task, "http_get_url_task", HTTP_GET_URL_TASK_STACK, NULL, 2, http_get_url_task_stack, &http_get_url_task_tcb);
+ xTaskCreate(http_get_url_task, "http_get_url_task", HTTP_GET_URL_TASK_STACK, NULL, 2, NULL);
+ ESP_LOGI(WIFI_TAG, "[APP] Free memory http1 on: %" PRIu32 " bytes", esp_get_free_heap_size());
+
+ // ESP_LOGI(WIFI_TAG, "http_download_task start\n");
+ // memset(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], 0x00, sizeof(http_get_cert_task_param.url[SSL_CLIENT_CRT]));
+ // memset(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], 0x00, strlen(http_get_cert_task_param.url[SSL_CLIENT_KEY]));
+ // memset(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], 0x00, strlen(http_get_cert_task_param.url[SSL_SERVER_CRT]));
+ // memcpy(&http_get_cert_task_param.url[SSL_CLIENT_CRT][0], "https://e-pxn.com.cn/pms/api/client.crt", 40);
+ // memcpy(&http_get_cert_task_param.url[SSL_CLIENT_KEY][0], "https://e-pxn.com.cn/pms/api/client.key", 40);
+ // memcpy(&http_get_cert_task_param.url[SSL_SERVER_CRT][0], "https://e-pxn.com.cn/pms/api/mosquitto.org.crt", 47);
+ // http_download_crt_task_handler = xTaskCreateStatic(http_download_task, "http_download_task", HTTP_DOWNLOAD_CRT_TASK_STACK, NULL, 2, http_download_crt_task_stack, &http_download_crt_task_tcb);
+ }
+ }
+
+
+ // if(common_setting.mqtt_client_handle != NULL)
+ // {
+ // // esp_mqtt_client_start(common_setting.mqtt_client_handle);
+ // }
+ }
+ else if (bits & WIFI_FAIL_BIT)
+ {
+ ESP_LOGI(WIFI_TAG, "wifi connect fail\n");
+
+ if((common_setting.wifi_status.connect_mode == 1 || common_setting.wifi_status.connect_mode == 2))
+ {
+ static BLE_SEND_REPLY_T wifi_pairing_reply={0};
+ wifi_pairing_reply.send_flag = 1;
+ wifi_pairing_reply.cmd = 0x15;
+ wifi_pairing_reply.len = 3;
+ if(bits & WIFI_AP_NOT_FOUND_BIT)
+ {
+ wifi_pairing_reply.content[0] = 2;
+ }
+ else if(bits & WIFI_PWD_FAIL_BIT)
+ {
+ wifi_pairing_reply.content[0] = 3;
+ }
+ else
+ {
+ wifi_pairing_reply.content[0] = 1;
+ }
+ wifi_pairing_reply.content[1] = common_setting.wifi_status.connect_mode-1;
+ wifi_pairing_reply.content[2] = common_setting.wifi_status.net_pair_encrypt_profile;
+ Check_Host_Type(wifi_pairing_reply.cmd, wifi_pairing_reply.content, wifi_pairing_reply.len, common_setting.wifi_status.net_pair_host);
+ }
+ // if(common_setting.mqtt_client_handle != NULL)
+ // {
+ // // esp_mqtt_client_stop(common_setting.mqtt_client_handle);
+ // }
+ }
+ else
+ {
+ ESP_LOGI(WIFI_TAG, "wifi stop\n");
+ }
+ }
+
+ // if((common_setting.wifi_status.connect_mode == 1 || common_setting.wifi_status.connect_mode == 2) && common_setting.net_pairing_info.net_pair_cooldown > 0)
+ // {
+ // common_setting.net_pairing_info.net_pair_cooldown -= MAIN_LOOP_INTERVAL;
+ // if(common_setting.net_pairing_info.net_pair_cooldown <= 0)
+ // {
+ // common_setting.net_pairing_info.net_pair_cooldown = 0;
+ // Wifi_Queue_Send(0, 0xFF, 0); // 关闭配网
+ // }
+ // }
+
+ if(common_setting.wifi_status.wifi_state == 1)
+ {
+ static uint32_t rssi_tick = 0;
+ rssi_tick += MAIN_LOOP_INTERVAL;
+ if(rssi_tick >= 1000)
+ {
+ rssi_tick = 0;
+ esp_wifi_set_rssi_threshold(WIFI_RSSI_THRESHOLD);
+ }
+ }
+}
--- /dev/null
+#ifndef _WIFI_H_
+#define _WIFI_H_
+
+#define EXAMPLE_ESP_WIFI_SSID CONFIG_EXAMPLE_WIFI_SSID
+#define EXAMPLE_ESP_WIFI_PASS CONFIG_EXAMPLE_WIFI_PASSWORD
+#define EXAMPLE_ESP_MAXIMUM_RETRY (36) // 连接失败重试次数,默认为12次,设置为0xFFFFFFFF则一直重试
+
+#define CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_BOTH 1
+#define CONFIG_ESP_WIFI_AUTH_WPA2_PSK 1
+#define CONFIG_ESP_WIFI_PW_ID ""
+
+#define WIFI_RSSI_THRESHOLD (-1)
+
+extern esp_netif_t *wifi_sta_netif;
+
+extern SemaphoreHandle_t wifi_scan_mutex;
+
+void Wifi_Sta_Init(void);
+
+void Wifi_Start(void);
+
+void Wifi_Queue_Send(uint8_t host, uint8_t enable, uint8_t net_pair_encrypt_profile);
+void Wifi_Enable_Status_Check(void);
+
+void Wifi_Connect_Timerout_Start(void);
+void Wifi_Connect_Timerout_Stop(void);
+#endif
--- /dev/null
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 16K,
+otadata, data, ota, 0xd000, 8K,
+phy_init, data, phy, 0xf000, 4K,
+ota_0, app, ota_0, 0x10000, 960K,
+ota_1, app, ota_1, 0x100000, 960K,
+user_data, data, nvs, 0x1f0000, 64K,
\ No newline at end of file
--- /dev/null
+#
+# Automatically generated file. DO NOT EDIT.
+# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Configuration
+#
+CONFIG_SOC_ADC_SUPPORTED=y
+CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y
+CONFIG_SOC_UART_SUPPORTED=y
+CONFIG_SOC_GDMA_SUPPORTED=y
+CONFIG_SOC_AHB_GDMA_SUPPORTED=y
+CONFIG_SOC_GPTIMER_SUPPORTED=y
+CONFIG_SOC_PHY_SUPPORTED=y
+CONFIG_SOC_BT_SUPPORTED=y
+CONFIG_SOC_WIFI_SUPPORTED=y
+CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y
+CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y
+CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK=y
+CONFIG_SOC_EFUSE_SUPPORTED=y
+CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y
+CONFIG_SOC_LEDC_SUPPORTED=y
+CONFIG_SOC_I2C_SUPPORTED=y
+CONFIG_SOC_GPSPI_SUPPORTED=y
+CONFIG_SOC_SHA_SUPPORTED=y
+CONFIG_SOC_ECC_SUPPORTED=y
+CONFIG_SOC_FLASH_ENC_SUPPORTED=y
+CONFIG_SOC_SECURE_BOOT_SUPPORTED=y
+CONFIG_SOC_SYSTIMER_SUPPORTED=y
+CONFIG_SOC_BOD_SUPPORTED=y
+CONFIG_SOC_CLK_TREE_SUPPORTED=y
+CONFIG_SOC_ASSIST_DEBUG_SUPPORTED=y
+CONFIG_SOC_WDT_SUPPORTED=y
+CONFIG_SOC_SPI_FLASH_SUPPORTED=y
+CONFIG_SOC_RNG_SUPPORTED=y
+CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y
+CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y
+CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y
+CONFIG_SOC_PM_SUPPORTED=y
+CONFIG_SOC_XTAL_SUPPORT_26M=y
+CONFIG_SOC_XTAL_SUPPORT_40M=y
+CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y
+CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y
+CONFIG_SOC_ADC_MONITOR_SUPPORTED=y
+CONFIG_SOC_ADC_PERIPH_NUM=1
+CONFIG_SOC_ADC_MAX_CHANNEL_NUM=5
+CONFIG_SOC_ADC_ATTEN_NUM=4
+CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=1
+CONFIG_SOC_ADC_PATT_LEN_MAX=8
+CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12
+CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12
+CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2
+CONFIG_SOC_ADC_DIGI_MONITOR_NUM=2
+CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333
+CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611
+CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=12
+CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12
+CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y
+CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y
+CONFIG_SOC_ADC_SHARED_POWER=y
+CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y
+CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y
+CONFIG_SOC_CPU_CORES_NUM=1
+CONFIG_SOC_CPU_INTR_NUM=32
+CONFIG_SOC_CPU_HAS_FLEXIBLE_INTC=y
+CONFIG_SOC_CPU_HAS_CSR_PC=y
+CONFIG_SOC_CPU_BREAKPOINTS_NUM=2
+CONFIG_SOC_CPU_WATCHPOINTS_NUM=2
+CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=0x80000000
+CONFIG_SOC_CPU_IDRAM_SPLIT_USING_PMP=y
+CONFIG_SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK=y
+CONFIG_SOC_AHB_GDMA_VERSION=1
+CONFIG_SOC_GDMA_NUM_GROUPS_MAX=1
+CONFIG_SOC_GDMA_PAIRS_PER_GROUP_MAX=1
+CONFIG_SOC_GPIO_PORT=1
+CONFIG_SOC_GPIO_PIN_COUNT=21
+CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y
+CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y
+CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y
+CONFIG_SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP=y
+CONFIG_SOC_GPIO_IN_RANGE_MAX=20
+CONFIG_SOC_GPIO_OUT_RANGE_MAX=20
+CONFIG_SOC_GPIO_DEEP_SLEEP_WAKE_VALID_GPIO_MASK=0
+CONFIG_SOC_GPIO_DEEP_SLEEP_WAKE_SUPPORTED_PIN_CNT=6
+CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00000000001FFFC0
+CONFIG_SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX=y
+CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3
+CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8
+CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8
+CONFIG_SOC_DEDIC_PERIPH_ALWAYS_ENABLE=y
+CONFIG_SOC_I2C_NUM=1
+CONFIG_SOC_HP_I2C_NUM=1
+CONFIG_SOC_I2C_FIFO_LEN=16
+CONFIG_SOC_I2C_CMD_REG_NUM=8
+CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y
+CONFIG_SOC_I2C_SUPPORT_XTAL=y
+CONFIG_SOC_I2C_SUPPORT_RTC=y
+CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y
+CONFIG_SOC_LEDC_SUPPORT_PLL_DIV_CLOCK=y
+CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y
+CONFIG_SOC_LEDC_CHANNEL_NUM=6
+CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14
+CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y
+CONFIG_SOC_MMU_PAGE_SIZE_CONFIGURABLE=y
+CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=1
+CONFIG_SOC_MMU_PERIPH_NUM=1
+CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000
+CONFIG_SOC_MPU_REGIONS_MAX_NUM=8
+CONFIG_SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH=128
+CONFIG_SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM=108
+CONFIG_SOC_RTCIO_PIN_COUNT=0
+CONFIG_SOC_RSA_MAX_BIT_LEN=3072
+CONFIG_SOC_SHA_SUPPORT_RESUME=y
+CONFIG_SOC_SHA_SUPPORT_SHA1=y
+CONFIG_SOC_SHA_SUPPORT_SHA224=y
+CONFIG_SOC_SHA_SUPPORT_SHA256=y
+CONFIG_SOC_SPI_PERIPH_NUM=2
+CONFIG_SOC_SPI_MAX_CS_NUM=6
+CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64
+CONFIG_SOC_SPI_SUPPORT_DDRCLK=y
+CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y
+CONFIG_SOC_SPI_SUPPORT_CD_SIG=y
+CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y
+CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y
+CONFIG_SOC_SPI_SUPPORT_CLK_XTAL=y
+CONFIG_SOC_SPI_SUPPORT_CLK_PLL_F40M=y
+CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y
+CONFIG_SOC_SPI_SCT_SUPPORTED=y
+CONFIG_SOC_SPI_SCT_REG_NUM=14
+CONFIG_SOC_SPI_SCT_BUFFER_NUM_MAX=y
+CONFIG_SOC_SPI_SCT_CONF_BITLEN_MAX=0x3FFFA
+CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y
+CONFIG_SOC_SPI_MAX_PRE_DIVIDER=16
+CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y
+CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y
+CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_RESUME=y
+CONFIG_SOC_SPI_MEM_SUPPORT_IDLE_INTR=y
+CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y
+CONFIG_SOC_SPI_MEM_SUPPORT_CHECK_SUS=y
+CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y
+CONFIG_SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED=y
+CONFIG_SOC_MEMSPI_SRC_FREQ_30M_SUPPORTED=y
+CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y
+CONFIG_SOC_MEMSPI_SRC_FREQ_15M_SUPPORTED=y
+CONFIG_SOC_SYSTIMER_COUNTER_NUM=2
+CONFIG_SOC_SYSTIMER_ALARM_NUM=3
+CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32
+CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=20
+CONFIG_SOC_SYSTIMER_FIXED_DIVIDER=y
+CONFIG_SOC_SYSTIMER_INT_LEVEL=y
+CONFIG_SOC_SYSTIMER_ALARM_MISS_COMPENSATE=y
+CONFIG_SOC_TIMER_GROUPS=1
+CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=1
+CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=54
+CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y
+CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=1
+CONFIG_SOC_MWDT_SUPPORT_XTAL=y
+CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y
+CONFIG_SOC_EFUSE_DIS_PAD_JTAG=y
+CONFIG_SOC_EFUSE_DIS_DIRECT_BOOT=y
+CONFIG_SOC_SECURE_BOOT_V2_ECC=y
+CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=1
+CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32
+CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y
+CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y
+CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y
+CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED=y
+CONFIG_SOC_UART_NUM=2
+CONFIG_SOC_UART_HP_NUM=2
+CONFIG_SOC_UART_FIFO_LEN=128
+CONFIG_SOC_UART_BITRATE_MAX=2500000
+CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y
+CONFIG_SOC_UART_SUPPORT_PLL_F40M_CLK=y
+CONFIG_SOC_UART_SUPPORT_RTC_CLK=y
+CONFIG_SOC_UART_SUPPORT_XTAL_CLK=y
+CONFIG_SOC_UART_SUPPORT_FSM_TX_WAIT_SEND=y
+CONFIG_SOC_SUPPORT_COEXISTENCE=y
+CONFIG_SOC_COEX_HW_PTI=y
+CONFIG_SOC_EXTERNAL_COEX_ADVANCE=y
+CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21
+CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12
+CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y
+CONFIG_SOC_PM_SUPPORT_BT_WAKEUP=y
+CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y
+CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y
+CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y
+CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y
+CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y
+CONFIG_SOC_CLK_OSC_SLOW_SUPPORTED=y
+CONFIG_SOC_WIFI_HW_TSF=y
+CONFIG_SOC_WIFI_FTM_SUPPORT=y
+CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y
+CONFIG_SOC_WIFI_PHY_NEEDS_USB_WORKAROUND=y
+CONFIG_SOC_BLE_SUPPORTED=y
+CONFIG_SOC_ESP_NIMBLE_CONTROLLER=y
+CONFIG_SOC_BLE_50_SUPPORTED=y
+CONFIG_SOC_BLE_DEVICE_PRIVACY_SUPPORTED=y
+CONFIG_SOC_BLUFI_SUPPORTED=y
+CONFIG_SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED=y
+CONFIG_SOC_PHY_IMPROVE_RX_11B=y
+CONFIG_SOC_PHY_COMBO_MODULE=y
+CONFIG_IDF_CMAKE=y
+CONFIG_IDF_TOOLCHAIN="gcc"
+CONFIG_IDF_TARGET_ARCH_RISCV=y
+CONFIG_IDF_TARGET_ARCH="riscv"
+CONFIG_IDF_TARGET="esp32c2"
+CONFIG_IDF_INIT_VERSION="$IDF_INIT_VERSION"
+CONFIG_IDF_TARGET_ESP32C2=y
+CONFIG_IDF_FIRMWARE_CHIP_ID=0x000C
+
+#
+# Build type
+#
+CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y
+# CONFIG_APP_BUILD_TYPE_RAM is not set
+CONFIG_APP_BUILD_GENERATE_BINARIES=y
+CONFIG_APP_BUILD_BOOTLOADER=y
+CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y
+# CONFIG_APP_REPRODUCIBLE_BUILD is not set
+# CONFIG_APP_NO_BLOBS is not set
+# end of Build type
+
+#
+# Bootloader config
+#
+
+#
+# Bootloader manager
+#
+CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y
+CONFIG_BOOTLOADER_PROJECT_VER=1
+# end of Bootloader manager
+
+CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0
+CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
+# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
+# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
+# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
+CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
+# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
+CONFIG_BOOTLOADER_LOG_LEVEL=0
+
+#
+# Serial Flash Configurations
+#
+# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set
+CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y
+# end of Serial Flash Configurations
+
+# CONFIG_BOOTLOADER_FACTORY_RESET is not set
+# CONFIG_BOOTLOADER_APP_TEST is not set
+CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y
+CONFIG_BOOTLOADER_WDT_ENABLE=y
+# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set
+CONFIG_BOOTLOADER_WDT_TIME_MS=9000
+# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set
+# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set
+# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set
+# end of Bootloader config
+
+#
+# Security features
+#
+CONFIG_SECURE_BOOT_V2_ECC_SUPPORTED=y
+CONFIG_SECURE_BOOT_V2_PREFERRED=y
+# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
+# CONFIG_SECURE_BOOT is not set
+# CONFIG_SECURE_FLASH_ENC_ENABLED is not set
+CONFIG_SECURE_ROM_DL_MODE_ENABLED=y
+# end of Security features
+
+#
+# Application manager
+#
+CONFIG_APP_COMPILE_TIME_DATE=y
+# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
+# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
+# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set
+CONFIG_APP_RETRIEVE_LEN_ELF_SHA=9
+# end of Application manager
+
+CONFIG_ESP_ROM_HAS_CRC_LE=y
+CONFIG_ESP_ROM_HAS_CRC_BE=y
+CONFIG_ESP_ROM_UART_CLK_IS_XTAL=y
+CONFIG_ESP_ROM_HAS_RETARGETABLE_LOCKING=y
+CONFIG_ESP_ROM_GET_CLK_FREQ=y
+CONFIG_ESP_ROM_HAS_RVFPLIB=y
+CONFIG_ESP_ROM_HAS_HAL_WDT=y
+CONFIG_ESP_ROM_HAS_HAL_SYSTIMER=y
+CONFIG_ESP_ROM_HAS_HEAP_TLSF=y
+CONFIG_ESP_ROM_TLSF_CHECK_PATCH=y
+CONFIG_ESP_ROM_MULTI_HEAP_WALK_PATCH=y
+CONFIG_ESP_ROM_HAS_LAYOUT_TABLE=y
+CONFIG_ESP_ROM_HAS_SPI_FLASH=y
+CONFIG_ESP_ROM_HAS_NEWLIB=y
+CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y
+CONFIG_ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE=y
+CONFIG_ESP_ROM_RAM_APP_NEEDS_MMU_INIT=y
+CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB=y
+CONFIG_ESP_ROM_HAS_SW_FLOAT=y
+CONFIG_ESP_ROM_USB_OTG_NUM=-1
+CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1
+CONFIG_ESP_ROM_HAS_VERSION=y
+
+#
+# Boot ROM Behavior
+#
+# CONFIG_BOOT_ROM_LOG_ALWAYS_ON is not set
+CONFIG_BOOT_ROM_LOG_ALWAYS_OFF=y
+# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set
+# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set
+# end of Boot ROM Behavior
+
+#
+# Serial flasher config
+#
+# CONFIG_ESPTOOLPY_NO_STUB is not set
+# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set
+# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
+CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
+# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
+CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
+CONFIG_ESPTOOLPY_FLASHMODE="dio"
+CONFIG_ESPTOOLPY_FLASHFREQ_60M=y
+# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set
+# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
+# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set
+CONFIG_ESPTOOLPY_FLASHFREQ="60m"
+# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
+# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
+# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
+CONFIG_ESPTOOLPY_BEFORE_RESET=y
+# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
+CONFIG_ESPTOOLPY_BEFORE="default_reset"
+CONFIG_ESPTOOLPY_AFTER_RESET=y
+# CONFIG_ESPTOOLPY_AFTER_NORESET is not set
+CONFIG_ESPTOOLPY_AFTER="hard_reset"
+CONFIG_ESPTOOLPY_MONITOR_BAUD=74880
+# end of Serial flasher config
+
+#
+# Partition Table
+#
+# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
+# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
+# CONFIG_PARTITION_TABLE_TWO_OTA is not set
+CONFIG_PARTITION_TABLE_CUSTOM=y
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_OFFSET=0x8000
+CONFIG_PARTITION_TABLE_MD5=y
+# end of Partition Table
+
+#
+# Example Connection Configuration
+#
+CONFIG_ENV_GPIO_RANGE_MIN=0
+CONFIG_ENV_GPIO_RANGE_MAX=18
+CONFIG_ENV_GPIO_IN_RANGE_MAX=18
+CONFIG_ENV_GPIO_OUT_RANGE_MAX=18
+CONFIG_EXAMPLE_CONNECT_WIFI=y
+# CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN is not set
+CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD=y
+CONFIG_EXAMPLE_WIFI_SSID="dxy"
+CONFIG_EXAMPLE_WIFI_PASSWORD="p3833058"
+CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY=5
+CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST=y
+# CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL is not set
+
+#
+# WiFi Scan threshold
+#
+CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD=-127
+CONFIG_EXAMPLE_WIFI_AUTH_OPEN=y
+# CONFIG_EXAMPLE_WIFI_AUTH_WEP is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK is not set
+# CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK is not set
+# end of WiFi Scan threshold
+
+CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL=y
+# CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY is not set
+# CONFIG_EXAMPLE_CONNECT_ETHERNET is not set
+# CONFIG_EXAMPLE_CONNECT_PPP is not set
+CONFIG_EXAMPLE_CONNECT_IPV4=y
+# CONFIG_EXAMPLE_CONNECT_IPV6 is not set
+# end of Example Connection Configuration
+
+#
+# Compiler options
+#
+# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set
+CONFIG_COMPILER_OPTIMIZATION_SIZE=y
+# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
+# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
+# CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB is not set
+CONFIG_COMPILER_FLOAT_LIB_FROM_RVFPLIB=y
+CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2
+# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set
+CONFIG_COMPILER_HIDE_PATHS_MACROS=y
+# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
+# CONFIG_COMPILER_CXX_RTTI is not set
+CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
+# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
+# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
+# CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS is not set
+# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set
+# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set
+# CONFIG_COMPILER_DUMP_RTL_FILES is not set
+CONFIG_COMPILER_RT_LIB_GCCLIB=y
+CONFIG_COMPILER_RT_LIB_NAME="gcc"
+CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y
+# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set
+# end of Compiler options
+
+#
+# Component config
+#
+
+#
+# Application Level Tracing
+#
+# CONFIG_APPTRACE_DEST_JTAG is not set
+CONFIG_APPTRACE_DEST_NONE=y
+CONFIG_APPTRACE_DEST_UART=y
+CONFIG_APPTRACE_DEST_UART_NOUSB=y
+CONFIG_APPTRACE_DEST_UART1=y
+# CONFIG_APPTRACE_DEST_UART_NONE is not set
+CONFIG_APPTRACE_UART_TX_GPIO=12
+CONFIG_APPTRACE_UART_RX_GPIO=13
+CONFIG_APPTRACE_UART_BAUDRATE=1000000
+CONFIG_APPTRACE_UART_RX_BUFF_SIZE=128
+CONFIG_APPTRACE_UART_TX_BUFF_SIZE=4096
+CONFIG_APPTRACE_UART_TX_MSG_SIZE=128
+CONFIG_APPTRACE_UART_TASK_PRIO=1
+CONFIG_APPTRACE_ENABLE=y
+CONFIG_APPTRACE_LOCK_ENABLE=y
+CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
+CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH=0
+
+#
+# FreeRTOS SystemView Tracing
+#
+# CONFIG_APPTRACE_SV_ENABLE is not set
+# end of FreeRTOS SystemView Tracing
+
+# CONFIG_APPTRACE_GCOV_ENABLE is not set
+# end of Application Level Tracing
+
+#
+# Bluetooth
+#
+CONFIG_BT_ENABLED=y
+# CONFIG_BT_BLUEDROID_ENABLED is not set
+CONFIG_BT_NIMBLE_ENABLED=y
+# CONFIG_BT_CONTROLLER_ONLY is not set
+CONFIG_BT_CONTROLLER_ENABLED=y
+# CONFIG_BT_CONTROLLER_DISABLED is not set
+
+#
+# NimBLE Options
+#
+CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
+# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
+# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
+# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
+# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set
+CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y
+# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set
+CONFIG_BT_NIMBLE_LOG_LEVEL=1
+CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
+CONFIG_BT_NIMBLE_MAX_BONDS=2
+CONFIG_BT_NIMBLE_MAX_CCCDS=2
+CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0
+CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
+CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
+CONFIG_BT_NIMBLE_ROLE_CENTRAL=y
+CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y
+CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y
+# CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set
+# CONFIG_BT_NIMBLE_NVS_PERSIST is not set
+# CONFIG_BT_NIMBLE_SMP_ID_RESET is not set
+# CONFIG_BT_NIMBLE_SECURITY_ENABLE is not set
+# CONFIG_BT_NIMBLE_DEBUG is not set
+# CONFIG_BT_NIMBLE_DYNAMIC_SERVICE is not set
+CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME=""
+CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=30
+CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=517
+CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0
+
+#
+# Memory Settings
+#
+CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=12
+CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=100
+CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=4
+CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320
+CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=12
+CONFIG_BT_NIMBLE_TRANSPORT_ACL_SIZE=255
+CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
+CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=5
+CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT=3
+CONFIG_BT_NIMBLE_L2CAP_COC_SDU_BUFF_COUNT=1
+# end of Memory Settings
+
+CONFIG_BT_NIMBLE_GATT_MAX_PROCS=4
+# CONFIG_BT_NIMBLE_HS_FLOW_CTRL is not set
+CONFIG_BT_NIMBLE_RPA_TIMEOUT=900
+# CONFIG_BT_NIMBLE_MESH is not set
+CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
+CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
+CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=y
+CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT=3
+# CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT is not set
+CONFIG_BT_NIMBLE_WHITELIST_SIZE=2
+# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
+# CONFIG_BT_NIMBLE_BLUFI_ENABLE is not set
+CONFIG_BT_NIMBLE_USE_ESP_TIMER=y
+# CONFIG_BT_NIMBLE_BLE_GATT_BLOB_TRANSFER is not set
+
+#
+# GAP Service
+#
+
+#
+# GAP Appearance write permissions
+#
+# CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE is not set
+# end of GAP Appearance write permissions
+
+CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM=0
+CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC=0
+CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN=0
+CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR=0
+CONFIG_BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP=y
+# CONFIG_BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP is not set
+# CONFIG_BT_NIMBLE_SVC_GAP_CAR_SUPP is not set
+CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION=-1
+
+#
+# GAP device name write permissions
+#
+# CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE is not set
+# end of GAP device name write permissions
+
+CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM=0
+CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC=0
+CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN=0
+CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR=0
+CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL=0
+CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL=0
+CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY=0
+CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO=0
+# end of GAP Service
+
+#
+# BLE Services
+#
+# CONFIG_BT_NIMBLE_HID_SERVICE is not set
+# end of BLE Services
+
+# CONFIG_BT_NIMBLE_VS_SUPPORT is not set
+# CONFIG_BT_NIMBLE_ENC_ADV_DATA is not set
+# CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL is not set
+# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set
+
+#
+# Host-controller Transport
+#
+CONFIG_UART_HW_FLOWCTRL_DISABLE=y
+# CONFIG_UART_HW_FLOWCTRL_CTS_RTS is not set
+CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL=0
+CONFIG_BT_NIMBLE_HCI_UART_RTS_PIN=19
+CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23
+# end of Host-controller Transport
+# end of NimBLE Options
+
+#
+# Controller Options
+#
+
+#
+# HCI Config
+#
+CONFIG_BT_LE_HCI_INTERFACE_USE_RAM=y
+# CONFIG_BT_LE_HCI_INTERFACE_USE_UART is not set
+# end of HCI Config
+
+CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT=y
+CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE=4096
+# CONFIG_BT_LE_CONTROLLER_LOG_ENABLED is not set
+CONFIG_BT_LE_LL_RESOLV_LIST_SIZE=4
+CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT=20
+CONFIG_BT_LE_LL_SCA=60
+# CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
+CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
+CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
+# CONFIG_BT_LE_SLEEP_ENABLE is not set
+CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL=y
+# CONFIG_BT_LE_LP_CLK_SRC_DEFAULT is not set
+CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED=y
+# CONFIG_BT_LE_TX_CCA_ENABLED is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N24 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N21 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N18 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N15 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N12 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N9 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N6 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N3 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_N0 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P3 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P6 is not set
+CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P9=y
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P12 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P15 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P18 is not set
+# CONFIG_BT_LE_DFT_TX_POWER_LEVEL_P20 is not set
+CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF=9
+# end of Controller Options
+
+# CONFIG_BT_RELEASE_IRAM is not set
+
+#
+# Common Options
+#
+CONFIG_BT_ALARM_MAX_NUM=50
+# end of Common Options
+
+# CONFIG_BT_HCI_LOG_DEBUG_EN is not set
+# end of Bluetooth
+
+# CONFIG_BLE_MESH is not set
+
+#
+# Console Library
+#
+# CONFIG_CONSOLE_SORTED_HELP is not set
+# end of Console Library
+
+#
+# Driver Configurations
+#
+
+#
+# Legacy ADC Driver Configuration
+#
+# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set
+
+#
+# Legacy ADC Calibration Configuration
+#
+# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set
+# end of Legacy ADC Calibration Configuration
+# end of Legacy ADC Driver Configuration
+
+#
+# Legacy Timer Group Driver Configurations
+#
+# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set
+# end of Legacy Timer Group Driver Configurations
+
+#
+# Legacy Temperature Sensor Driver Configurations
+#
+# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set
+# end of Legacy Temperature Sensor Driver Configurations
+# end of Driver Configurations
+
+#
+# eFuse Bit Manager
+#
+# CONFIG_EFUSE_CUSTOM_TABLE is not set
+# CONFIG_EFUSE_VIRTUAL is not set
+CONFIG_EFUSE_MAX_BLK_LEN=256
+# end of eFuse Bit Manager
+
+#
+# ESP-TLS
+#
+CONFIG_ESP_TLS_USING_MBEDTLS=y
+# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set
+# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set
+# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set
+# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set
+# CONFIG_ESP_TLS_PSK_VERIFICATION is not set
+# CONFIG_ESP_TLS_INSECURE is not set
+# end of ESP-TLS
+
+#
+# ADC and ADC Calibration
+#
+# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set
+# CONFIG_ADC_ENABLE_DEBUG_LOG is not set
+# end of ADC and ADC Calibration
+
+#
+# Wireless Coexistence
+#
+CONFIG_ESP_COEX_ENABLED=y
+CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
+# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set
+# end of Wireless Coexistence
+
+#
+# Common ESP-related
+#
+CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
+# end of Common ESP-related
+
+#
+# ESP-Driver:GPIO Configurations
+#
+# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set
+# end of ESP-Driver:GPIO Configurations
+
+#
+# ESP-Driver:GPTimer Configurations
+#
+# CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM is not set
+# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set
+# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set
+# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
+# end of ESP-Driver:GPTimer Configurations
+
+#
+# ESP-Driver:I2C Configurations
+#
+# CONFIG_I2C_ISR_IRAM_SAFE is not set
+# CONFIG_I2C_ENABLE_DEBUG_LOG is not set
+# end of ESP-Driver:I2C Configurations
+
+#
+# ESP-Driver:LEDC Configurations
+#
+# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set
+# end of ESP-Driver:LEDC Configurations
+
+#
+# ESP-Driver:SPI Configurations
+#
+# CONFIG_SPI_MASTER_ISR_IN_IRAM is not set
+# CONFIG_SPI_SLAVE_IN_IRAM is not set
+# CONFIG_SPI_SLAVE_ISR_IN_IRAM is not set
+# end of ESP-Driver:SPI Configurations
+
+#
+# ESP-Driver:Temperature Sensor Configurations
+#
+# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set
+# end of ESP-Driver:Temperature Sensor Configurations
+
+#
+# ESP-Driver:UART Configurations
+#
+# end of ESP-Driver:UART Configurations
+
+#
+# Ethernet
+#
+CONFIG_ETH_ENABLED=y
+CONFIG_ETH_USE_SPI_ETHERNET=y
+# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set
+# CONFIG_ETH_SPI_ETHERNET_W5500 is not set
+# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set
+# CONFIG_ETH_USE_OPENETH is not set
+# CONFIG_ETH_TRANSMIT_MUTEX is not set
+# end of Ethernet
+
+#
+# Event Loop Library
+#
+# CONFIG_ESP_EVENT_LOOP_PROFILING is not set
+CONFIG_ESP_EVENT_POST_FROM_ISR=y
+# CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR is not set
+# end of Event Loop Library
+
+#
+# GDB Stub
+#
+CONFIG_ESP_GDBSTUB_ENABLED=y
+# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set
+CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y
+CONFIG_ESP_GDBSTUB_MAX_TASKS=32
+# end of GDB Stub
+
+#
+# ESP HTTP client
+#
+CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
+# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
+# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set
+# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set
+# end of ESP HTTP client
+
+#
+# HTTP Server
+#
+CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
+CONFIG_HTTPD_MAX_URI_LEN=512
+CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
+CONFIG_HTTPD_PURGE_BUF_LEN=32
+# CONFIG_HTTPD_LOG_PURGE_DATA is not set
+# CONFIG_HTTPD_WS_SUPPORT is not set
+# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set
+# end of HTTP Server
+
+#
+# ESP HTTPS OTA
+#
+# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set
+# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set
+# end of ESP HTTPS OTA
+
+#
+# ESP HTTPS server
+#
+# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
+# end of ESP HTTPS server
+
+#
+# Hardware Settings
+#
+
+#
+# Chip revision
+#
+CONFIG_ESP32C2_REV_MIN_1=y
+# CONFIG_ESP32C2_REV_MIN_1_1 is not set
+CONFIG_ESP32C2_REV_MIN_FULL=100
+CONFIG_ESP_REV_MIN_FULL=100
+
+#
+# Maximum Supported ESP32-C2 Revision (Rev v1.99)
+#
+CONFIG_ESP32C2_REV_MAX_FULL=199
+CONFIG_ESP_REV_MAX_FULL=199
+# CONFIG_ESP32C2_REV2_DEVELOPMENT is not set
+# end of Chip revision
+
+#
+# MAC Config
+#
+CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y
+CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y
+CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y
+CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y
+CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y
+CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4
+# CONFIG_ESP32C2_UNIVERSAL_MAC_ADDRESSES_TWO is not set
+CONFIG_ESP32C2_UNIVERSAL_MAC_ADDRESSES_FOUR=y
+CONFIG_ESP32C2_UNIVERSAL_MAC_ADDRESSES=4
+# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set
+# end of MAC Config
+
+#
+# Sleep Config
+#
+# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set
+CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y
+CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y
+CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y
+CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0
+# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set
+# CONFIG_ESP_SLEEP_DEBUG is not set
+CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y
+# end of Sleep Config
+
+#
+# RTC Clock Config
+#
+CONFIG_RTC_CLK_SRC_INT_RC=y
+# CONFIG_RTC_CLK_SRC_EXT_OSC is not set
+# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set
+CONFIG_RTC_CLK_CAL_CYCLES=1024
+# end of RTC Clock Config
+
+#
+# Peripheral Control
+#
+# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM is not set
+# end of Peripheral Control
+
+#
+# GDMA Configurations
+#
+CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y
+# CONFIG_GDMA_ISR_IRAM_SAFE is not set
+# CONFIG_GDMA_ENABLE_DEBUG_LOG is not set
+# end of GDMA Configurations
+
+#
+# Main XTAL Config
+#
+CONFIG_XTAL_FREQ_26=y
+# CONFIG_XTAL_FREQ_40 is not set
+CONFIG_XTAL_FREQ=26
+# end of Main XTAL Config
+# end of Hardware Settings
+
+#
+# LCD and Touch Panel
+#
+
+#
+# LCD Touch Drivers are maintained in the IDF Component Registry
+#
+
+#
+# LCD Peripheral Configuration
+#
+# CONFIG_LCD_ENABLE_DEBUG_LOG is not set
+# end of LCD Peripheral Configuration
+# end of LCD and Touch Panel
+
+#
+# ESP NETIF Adapter
+#
+CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120
+CONFIG_ESP_NETIF_TCPIP_LWIP=y
+# CONFIG_ESP_NETIF_LOOPBACK is not set
+CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
+# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
+# CONFIG_ESP_NETIF_L2_TAP is not set
+# CONFIG_ESP_NETIF_BRIDGE_EN is not set
+# end of ESP NETIF Adapter
+
+#
+# Partition API Configuration
+#
+# end of Partition API Configuration
+
+#
+# PHY
+#
+CONFIG_ESP_PHY_ENABLED=y
+CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
+# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set
+CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20
+CONFIG_ESP_PHY_MAX_TX_POWER=20
+# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set
+# CONFIG_ESP_PHY_ENABLE_USB is not set
+CONFIG_ESP_PHY_RF_CAL_PARTIAL=y
+# CONFIG_ESP_PHY_RF_CAL_NONE is not set
+# CONFIG_ESP_PHY_RF_CAL_FULL is not set
+CONFIG_ESP_PHY_CALIBRATION_MODE=0
+# CONFIG_ESP_PHY_IMPROVE_RX_11B is not set
+# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set
+# end of PHY
+
+#
+# Power Management
+#
+# CONFIG_PM_ENABLE is not set
+# end of Power Management
+
+#
+# ESP PSRAM
+#
+
+#
+# ESP Ringbuf
+#
+CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
+CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y
+# end of ESP Ringbuf
+
+#
+# ESP System Settings
+#
+# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_120=y
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=120
+
+#
+# Cache config
+#
+# CONFIG_ESP32C2_INSTRUCTION_CACHE_WRAP is not set
+# end of Cache config
+
+# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set
+CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
+# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
+# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
+CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0
+CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y
+# CONFIG_ESP_SYSTEM_USE_EH_FRAME is not set
+
+#
+# Memory protection
+#
+CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=y
+# end of Memory protection
+
+CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=16
+CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
+CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
+# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
+CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
+CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
+CONFIG_ESP_CONSOLE_UART_DEFAULT=y
+# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
+# CONFIG_ESP_CONSOLE_NONE is not set
+CONFIG_ESP_CONSOLE_UART=y
+CONFIG_ESP_CONSOLE_UART_NUM=0
+CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0
+CONFIG_ESP_CONSOLE_UART_BAUDRATE=74880
+CONFIG_ESP_INT_WDT=y
+CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
+CONFIG_ESP_TASK_WDT_EN=y
+CONFIG_ESP_TASK_WDT_USE_ESP_TIMER=y
+CONFIG_ESP_TASK_WDT_INIT=y
+# CONFIG_ESP_TASK_WDT_PANIC is not set
+CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
+CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
+# CONFIG_ESP_PANIC_HANDLER_IRAM is not set
+# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set
+CONFIG_ESP_DEBUG_OCDAWARE=y
+CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y
+
+#
+# Brownout Detector
+#
+CONFIG_ESP_BROWNOUT_DET=y
+CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y
+# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set
+# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set
+# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set
+# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set
+# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set
+CONFIG_ESP_BROWNOUT_DET_LVL=7
+# end of Brownout Detector
+
+CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y
+CONFIG_ESP_SYSTEM_HW_STACK_GUARD=y
+CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y
+CONFIG_ESP_SYSTEM_HW_PC_RECORD=y
+# end of ESP System Settings
+
+#
+# IPC (Inter-Processor Call)
+#
+CONFIG_ESP_IPC_TASK_STACK_SIZE=2048
+# end of IPC (Inter-Processor Call)
+
+#
+# ESP Timer (High Resolution Timer)
+#
+# CONFIG_ESP_TIMER_PROFILING is not set
+CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y
+CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y
+CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
+CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1
+# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set
+CONFIG_ESP_TIMER_TASK_AFFINITY=0x0
+CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y
+CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y
+CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD=y
+CONFIG_ESP_TIMER_IMPL_SYSTIMER=y
+# end of ESP Timer (High Resolution Timer)
+
+#
+# Wi-Fi
+#
+CONFIG_ESP_WIFI_ENABLED=y
+CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10
+CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
+# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set
+CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y
+CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1
+CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32
+CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
+# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
+CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0
+CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
+CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
+CONFIG_ESP_WIFI_TX_BA_WIN=6
+CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
+CONFIG_ESP_WIFI_RX_BA_WIN=6
+CONFIG_ESP_WIFI_NVS_ENABLED=y
+CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752
+CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32
+# CONFIG_ESP_WIFI_IRAM_OPT is not set
+# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set
+# CONFIG_ESP_WIFI_RX_IRAM_OPT is not set
+CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y
+CONFIG_ESP_WIFI_ENABLE_SAE_PK=y
+CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y
+# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
+CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50
+CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10
+CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15
+# CONFIG_ESP_WIFI_FTM_ENABLE is not set
+CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y
+CONFIG_ESP_WIFI_GMAC_SUPPORT=y
+# CONFIG_ESP_WIFI_SOFTAP_SUPPORT is not set
+# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set
+CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=2
+CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y
+CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y
+# CONFIG_ESP_WIFI_11KV_SUPPORT is not set
+# CONFIG_ESP_WIFI_MBO_SUPPORT is not set
+# CONFIG_ESP_WIFI_DPP_SUPPORT is not set
+# CONFIG_ESP_WIFI_11R_SUPPORT is not set
+
+#
+# WPS Configuration Options
+#
+# CONFIG_ESP_WIFI_WPS_STRICT is not set
+# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set
+# end of WPS Configuration Options
+
+# CONFIG_ESP_WIFI_DEBUG_PRINT is not set
+# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set
+CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y
+CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER=y
+# end of Wi-Fi
+
+#
+# Core dump
+#
+# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set
+# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set
+CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y
+# end of Core dump
+
+#
+# FAT Filesystem support
+#
+CONFIG_FATFS_VOLUME_COUNT=2
+CONFIG_FATFS_LFN_NONE=y
+# CONFIG_FATFS_LFN_HEAP is not set
+# CONFIG_FATFS_LFN_STACK is not set
+# CONFIG_FATFS_SECTOR_512 is not set
+CONFIG_FATFS_SECTOR_4096=y
+# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
+CONFIG_FATFS_CODEPAGE_437=y
+# CONFIG_FATFS_CODEPAGE_720 is not set
+# CONFIG_FATFS_CODEPAGE_737 is not set
+# CONFIG_FATFS_CODEPAGE_771 is not set
+# CONFIG_FATFS_CODEPAGE_775 is not set
+# CONFIG_FATFS_CODEPAGE_850 is not set
+# CONFIG_FATFS_CODEPAGE_852 is not set
+# CONFIG_FATFS_CODEPAGE_855 is not set
+# CONFIG_FATFS_CODEPAGE_857 is not set
+# CONFIG_FATFS_CODEPAGE_860 is not set
+# CONFIG_FATFS_CODEPAGE_861 is not set
+# CONFIG_FATFS_CODEPAGE_862 is not set
+# CONFIG_FATFS_CODEPAGE_863 is not set
+# CONFIG_FATFS_CODEPAGE_864 is not set
+# CONFIG_FATFS_CODEPAGE_865 is not set
+# CONFIG_FATFS_CODEPAGE_866 is not set
+# CONFIG_FATFS_CODEPAGE_869 is not set
+# CONFIG_FATFS_CODEPAGE_932 is not set
+# CONFIG_FATFS_CODEPAGE_936 is not set
+# CONFIG_FATFS_CODEPAGE_949 is not set
+# CONFIG_FATFS_CODEPAGE_950 is not set
+CONFIG_FATFS_CODEPAGE=437
+CONFIG_FATFS_FS_LOCK=0
+CONFIG_FATFS_TIMEOUT_MS=10000
+CONFIG_FATFS_PER_FILE_CACHE=y
+# CONFIG_FATFS_USE_FASTSEEK is not set
+CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
+# CONFIG_FATFS_IMMEDIATE_FSYNC is not set
+# CONFIG_FATFS_USE_LABEL is not set
+CONFIG_FATFS_LINK_LOCK=y
+# end of FAT Filesystem support
+
+#
+# FreeRTOS
+#
+
+#
+# Kernel
+#
+# CONFIG_FREERTOS_SMP is not set
+CONFIG_FREERTOS_UNICORE=y
+CONFIG_FREERTOS_HZ=1000
+CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
+CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
+# CONFIG_FREERTOS_USE_IDLE_HOOK is not set
+# CONFIG_FREERTOS_USE_TICK_HOOK is not set
+CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
+# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set
+CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc"
+# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set
+CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y
+CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF
+CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1
+CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
+CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
+CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
+CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1
+# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
+# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set
+# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
+# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set
+# end of Kernel
+
+#
+# Port
+#
+# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
+CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
+# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
+# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set
+CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
+CONFIG_FREERTOS_ISR_STACKSIZE=1536
+CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
+CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y
+CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y
+# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set
+CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y
+CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
+# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
+# end of Port
+
+CONFIG_FREERTOS_PORT=y
+CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
+CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
+CONFIG_FREERTOS_DEBUG_OCDAWARE=y
+CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y
+CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
+CONFIG_FREERTOS_NUMBER_OF_CORES=1
+# end of FreeRTOS
+
+#
+# Hardware Abstraction Layer (HAL) and Low Level (LL)
+#
+CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y
+# CONFIG_HAL_ASSERTION_DISABLE is not set
+# CONFIG_HAL_ASSERTION_SILENT is not set
+# CONFIG_HAL_ASSERTION_ENABLE is not set
+CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
+CONFIG_HAL_SYSTIMER_USE_ROM_IMPL=y
+CONFIG_HAL_WDT_USE_ROM_IMPL=y
+# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
+
+#
+# Heap memory debugging
+#
+CONFIG_HEAP_POISONING_DISABLED=y
+# CONFIG_HEAP_POISONING_LIGHT is not set
+# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
+CONFIG_HEAP_TRACING_OFF=y
+# CONFIG_HEAP_TRACING_STANDALONE is not set
+# CONFIG_HEAP_TRACING_TOHOST is not set
+# CONFIG_HEAP_USE_HOOKS is not set
+# CONFIG_HEAP_TASK_TRACKING is not set
+# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set
+CONFIG_HEAP_TLSF_USE_ROM_IMPL=y
+# end of Heap memory debugging
+
+#
+# Log output
+#
+# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
+# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
+# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
+CONFIG_LOG_DEFAULT_LEVEL_INFO=y
+# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
+# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
+CONFIG_LOG_DEFAULT_LEVEL=3
+CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y
+# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set
+# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set
+CONFIG_LOG_MAXIMUM_LEVEL=3
+# CONFIG_LOG_MASTER_LEVEL is not set
+# CONFIG_LOG_COLORS is not set
+CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
+# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
+# end of Log output
+
+#
+# LWIP
+#
+CONFIG_LWIP_ENABLE=y
+CONFIG_LWIP_LOCAL_HOSTNAME="PXN-Device"
+# CONFIG_LWIP_NETIF_API is not set
+CONFIG_LWIP_TCPIP_TASK_PRIO=18
+# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set
+# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set
+CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
+# CONFIG_LWIP_L2_TO_L3_COPY is not set
+# CONFIG_LWIP_IRAM_OPTIMIZATION is not set
+# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set
+CONFIG_LWIP_TIMERS_ONDEMAND=y
+CONFIG_LWIP_MAX_SOCKETS=10
+# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
+# CONFIG_LWIP_SO_LINGER is not set
+CONFIG_LWIP_SO_REUSE=y
+CONFIG_LWIP_SO_REUSE_RXTOALL=y
+# CONFIG_LWIP_SO_RCVBUF is not set
+# CONFIG_LWIP_NETBUF_RECVINFO is not set
+CONFIG_LWIP_IP_DEFAULT_TTL=64
+CONFIG_LWIP_IP4_FRAG=y
+# CONFIG_LWIP_IP4_REASSEMBLY is not set
+CONFIG_LWIP_IP_REASS_MAX_PBUFS=10
+# CONFIG_LWIP_IP_FORWARD is not set
+# CONFIG_LWIP_STATS is not set
+CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
+CONFIG_LWIP_GARP_TMR_INTERVAL=60
+CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
+# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
+CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
+# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
+CONFIG_LWIP_DHCP_OPTIONS_LEN=68
+CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0
+CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1
+
+#
+# DHCP server
+#
+CONFIG_LWIP_DHCPS=y
+CONFIG_LWIP_DHCPS_LEASE_UNIT=60
+CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
+CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y
+# end of DHCP server
+
+# CONFIG_LWIP_AUTOIP is not set
+CONFIG_LWIP_IPV4=y
+# CONFIG_LWIP_IPV6 is not set
+# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=y
+CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
+
+#
+# TCP
+#
+CONFIG_LWIP_MAX_ACTIVE_TCP=16
+CONFIG_LWIP_MAX_LISTENING_TCP=16
+CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y
+CONFIG_LWIP_TCP_MAXRTX=12
+CONFIG_LWIP_TCP_SYNMAXRTX=12
+CONFIG_LWIP_TCP_MSS=1440
+CONFIG_LWIP_TCP_TMR_INTERVAL=250
+CONFIG_LWIP_TCP_MSL=60000
+CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000
+CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760
+CONFIG_LWIP_TCP_WND_DEFAULT=5760
+CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6
+CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
+CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6
+CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
+# CONFIG_LWIP_TCP_SACK_OUT is not set
+CONFIG_LWIP_TCP_OVERSIZE_MSS=y
+# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
+# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
+CONFIG_LWIP_TCP_RTO_TIME=1500
+# end of TCP
+
+#
+# UDP
+#
+CONFIG_LWIP_MAX_UDP_PCBS=16
+CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
+# end of UDP
+
+#
+# Checksums
+#
+# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set
+# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set
+CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y
+# end of Checksums
+
+CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
+CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
+# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
+CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
+# CONFIG_LWIP_PPP_SUPPORT is not set
+# CONFIG_LWIP_SLIP_SUPPORT is not set
+
+#
+# ICMP
+#
+CONFIG_LWIP_ICMP=y
+# CONFIG_LWIP_MULTICAST_PING is not set
+# CONFIG_LWIP_BROADCAST_PING is not set
+# end of ICMP
+
+#
+# LWIP RAW API
+#
+CONFIG_LWIP_MAX_RAW_PCBS=16
+# end of LWIP RAW API
+
+#
+# SNTP
+#
+CONFIG_LWIP_SNTP_MAX_SERVERS=1
+# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set
+CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000
+CONFIG_LWIP_SNTP_STARTUP_DELAY=y
+CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000
+# end of SNTP
+
+#
+# DNS
+#
+CONFIG_LWIP_DNS_MAX_SERVERS=3
+# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set
+# end of DNS
+
+CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7
+CONFIG_LWIP_ESP_LWIP_ASSERT=y
+
+#
+# Hooks
+#
+# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set
+CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y
+# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set
+CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
+# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set
+# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
+# end of Hooks
+
+# CONFIG_LWIP_DEBUG is not set
+# end of LWIP
+
+#
+# mbedTLS
+#
+CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
+# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
+# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
+CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
+CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=2048
+CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=1024
+CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
+CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
+CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y
+# CONFIG_MBEDTLS_DEBUG is not set
+
+#
+# mbedTLS v3.x related
+#
+# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set
+# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set
+# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set
+# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set
+CONFIG_MBEDTLS_PKCS7_C=y
+# end of mbedTLS v3.x related
+
+#
+# Certificate Bundle
+#
+CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
+# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set
+CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
+# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set
+# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set
+# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set
+CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200
+# end of Certificate Bundle
+
+# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set
+CONFIG_MBEDTLS_CMAC_C=y
+CONFIG_MBEDTLS_HARDWARE_SHA=y
+CONFIG_MBEDTLS_HARDWARE_ECC=y
+CONFIG_MBEDTLS_ECC_OTHER_CURVES_SOFT_FALLBACK=y
+CONFIG_MBEDTLS_ROM_MD5=y
+# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set
+# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set
+CONFIG_MBEDTLS_HAVE_TIME=y
+# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set
+# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
+CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y
+CONFIG_MBEDTLS_SHA512_C=y
+CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
+# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
+# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
+# CONFIG_MBEDTLS_TLS_DISABLED is not set
+CONFIG_MBEDTLS_TLS_SERVER=y
+CONFIG_MBEDTLS_TLS_CLIENT=y
+CONFIG_MBEDTLS_TLS_ENABLED=y
+
+#
+# TLS Key Exchange Methods
+#
+# CONFIG_MBEDTLS_PSK_MODES is not set
+CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
+# end of TLS Key Exchange Methods
+
+CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
+# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set
+# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
+CONFIG_MBEDTLS_SSL_ALPN=y
+CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
+
+#
+# Symmetric Ciphers
+#
+CONFIG_MBEDTLS_AES_C=y
+# CONFIG_MBEDTLS_CAMELLIA_C is not set
+# CONFIG_MBEDTLS_DES_C is not set
+# CONFIG_MBEDTLS_BLOWFISH_C is not set
+# CONFIG_MBEDTLS_XTEA_C is not set
+CONFIG_MBEDTLS_CCM_C=y
+CONFIG_MBEDTLS_GCM_C=y
+# CONFIG_MBEDTLS_NIST_KW_C is not set
+# end of Symmetric Ciphers
+
+# CONFIG_MBEDTLS_RIPEMD160_C is not set
+
+#
+# Certificates
+#
+CONFIG_MBEDTLS_PEM_PARSE_C=y
+CONFIG_MBEDTLS_PEM_WRITE_C=y
+CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
+CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
+# end of Certificates
+
+CONFIG_MBEDTLS_ECP_C=y
+# CONFIG_MBEDTLS_DHM_C is not set
+CONFIG_MBEDTLS_ECDH_C=y
+CONFIG_MBEDTLS_ECDSA_C=y
+# CONFIG_MBEDTLS_ECJPAKE_C is not set
+CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
+CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
+# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set
+# CONFIG_MBEDTLS_POLY1305_C is not set
+# CONFIG_MBEDTLS_CHACHA20_C is not set
+# CONFIG_MBEDTLS_HKDF_C is not set
+# CONFIG_MBEDTLS_THREADING_C is not set
+CONFIG_MBEDTLS_ERROR_STRINGS=y
+# end of mbedTLS
+
+#
+# ESP-MQTT Configurations
+#
+CONFIG_MQTT_PROTOCOL_311=y
+# CONFIG_MQTT_PROTOCOL_5 is not set
+CONFIG_MQTT_TRANSPORT_SSL=y
+# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
+# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
+# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
+# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
+# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
+# CONFIG_MQTT_CUSTOM_OUTBOX is not set
+# end of ESP-MQTT Configurations
+
+#
+# Newlib
+#
+CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
+CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
+CONFIG_NEWLIB_NANO_FORMAT=y
+CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
+# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set
+# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set
+# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set
+# end of Newlib
+
+#
+# NVS
+#
+# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
+# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
+# end of NVS
+
+#
+# OpenThread
+#
+# CONFIG_OPENTHREAD_ENABLED is not set
+
+#
+# Thread Operational Dataset
+#
+CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP"
+CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64"
+CONFIG_OPENTHREAD_NETWORK_CHANNEL=15
+CONFIG_OPENTHREAD_NETWORK_PANID=0x1234
+CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe"
+CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff"
+CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53"
+# end of Thread Operational Dataset
+
+CONFIG_OPENTHREAD_XTAL_ACCURACY=130
+# CONFIG_OPENTHREAD_SPINEL_ONLY is not set
+# CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE is not set
+
+#
+# Thread Address Query Config
+#
+# end of Thread Address Query Config
+# end of OpenThread
+
+#
+# Protocomm
+#
+CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y
+CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y
+CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y
+# end of Protocomm
+
+#
+# PThreads
+#
+CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5
+CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
+CONFIG_PTHREAD_STACK_MIN=768
+CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1
+CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread"
+# end of PThreads
+
+#
+# MMU Config
+#
+CONFIG_MMU_PAGE_SIZE_32KB=y
+CONFIG_MMU_PAGE_MODE="32KB"
+CONFIG_MMU_PAGE_SIZE=0x8000
+# end of MMU Config
+
+#
+# Main Flash configuration
+#
+
+#
+# SPI Flash behavior when brownout
+#
+CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y
+CONFIG_SPI_FLASH_BROWNOUT_RESET=y
+# end of SPI Flash behavior when brownout
+
+#
+# Optional and Experimental Features (READ DOCS FIRST)
+#
+
+#
+# Features here require specific hardware (READ DOCS FIRST!)
+#
+CONFIG_SPI_FLASH_SUSPEND_QVL_SUPPORTED=y
+# CONFIG_SPI_FLASH_AUTO_SUSPEND is not set
+CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50
+# end of Optional and Experimental Features (READ DOCS FIRST)
+# end of Main Flash configuration
+
+#
+# SPI Flash driver
+#
+# CONFIG_SPI_FLASH_VERIFY_WRITE is not set
+# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
+CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
+# CONFIG_SPI_FLASH_ROM_IMPL is not set
+CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y
+# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set
+# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set
+# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set
+CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y
+CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20
+CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1
+CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192
+# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set
+# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set
+# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set
+
+#
+# Auto-detect flash chips
+#
+CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y
+CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y
+CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y
+# end of Auto-detect flash chips
+
+CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y
+# end of SPI Flash driver
+
+#
+# SPIFFS Configuration
+#
+CONFIG_SPIFFS_MAX_PARTITIONS=3
+
+#
+# SPIFFS Cache Configuration
+#
+CONFIG_SPIFFS_CACHE=y
+CONFIG_SPIFFS_CACHE_WR=y
+# CONFIG_SPIFFS_CACHE_STATS is not set
+# end of SPIFFS Cache Configuration
+
+CONFIG_SPIFFS_PAGE_CHECK=y
+CONFIG_SPIFFS_GC_MAX_RUNS=10
+# CONFIG_SPIFFS_GC_STATS is not set
+CONFIG_SPIFFS_PAGE_SIZE=256
+CONFIG_SPIFFS_OBJ_NAME_LEN=32
+# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set
+CONFIG_SPIFFS_USE_MAGIC=y
+CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
+CONFIG_SPIFFS_META_LENGTH=4
+CONFIG_SPIFFS_USE_MTIME=y
+
+#
+# Debug Configuration
+#
+# CONFIG_SPIFFS_DBG is not set
+# CONFIG_SPIFFS_API_DBG is not set
+# CONFIG_SPIFFS_GC_DBG is not set
+# CONFIG_SPIFFS_CACHE_DBG is not set
+# CONFIG_SPIFFS_CHECK_DBG is not set
+# CONFIG_SPIFFS_TEST_VISUALISATION is not set
+# end of Debug Configuration
+# end of SPIFFS Configuration
+
+#
+# TCP Transport
+#
+
+#
+# Websocket
+#
+# CONFIG_WS_TRANSPORT is not set
+# end of Websocket
+# end of TCP Transport
+
+#
+# Unity unit testing library
+#
+CONFIG_UNITY_ENABLE_FLOAT=y
+CONFIG_UNITY_ENABLE_DOUBLE=y
+# CONFIG_UNITY_ENABLE_64BIT is not set
+# CONFIG_UNITY_ENABLE_COLOR is not set
+CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
+# CONFIG_UNITY_ENABLE_FIXTURE is not set
+# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set
+# end of Unity unit testing library
+
+#
+# Virtual file system
+#
+CONFIG_VFS_SUPPORT_IO=y
+CONFIG_VFS_SUPPORT_DIR=y
+CONFIG_VFS_SUPPORT_SELECT=y
+CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
+# CONFIG_VFS_SELECT_IN_RAM is not set
+CONFIG_VFS_SUPPORT_TERMIOS=y
+CONFIG_VFS_MAX_COUNT=8
+
+#
+# Host File System I/O (Semihosting)
+#
+CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1
+# end of Host File System I/O (Semihosting)
+# end of Virtual file system
+
+#
+# Wear Levelling
+#
+# CONFIG_WL_SECTOR_SIZE_512 is not set
+CONFIG_WL_SECTOR_SIZE_4096=y
+CONFIG_WL_SECTOR_SIZE=4096
+# end of Wear Levelling
+
+#
+# Wi-Fi Provisioning Manager
+#
+CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
+CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
+# CONFIG_WIFI_PROV_BLE_BONDING is not set
+CONFIG_WIFI_PROV_BLE_SEC_CONN=y
+# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
+# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set
+CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
+# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
+# end of Wi-Fi Provisioning Manager
+# end of Component config
+
+# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set
+
+# Deprecated options for backward compatibility
+# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set
+# CONFIG_NO_BLOBS is not set
+CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y
+# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set
+# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
+CONFIG_LOG_BOOTLOADER_LEVEL=0
+# CONFIG_APP_ROLLBACK_ENABLE is not set
+# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
+# CONFIG_FLASHMODE_QIO is not set
+# CONFIG_FLASHMODE_QOUT is not set
+CONFIG_FLASHMODE_DIO=y
+# CONFIG_FLASHMODE_DOUT is not set
+CONFIG_MONITOR_BAUD=74880
+# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
+# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
+# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
+CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
+CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
+CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
+# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
+# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
+CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2
+# CONFIG_CXX_EXCEPTIONS is not set
+CONFIG_STACK_CHECK_NONE=y
+# CONFIG_STACK_CHECK_NORM is not set
+# CONFIG_STACK_CHECK_STRONG is not set
+# CONFIG_STACK_CHECK_ALL is not set
+# CONFIG_WARN_WRITE_STRINGS is not set
+# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
+CONFIG_ESP32_APPTRACE_DEST_NONE=y
+CONFIG_ESP32_APPTRACE_ENABLE=y
+CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
+CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO=-1
+CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH=0
+# CONFIG_SYSVIEW_ENABLE is not set
+# CONFIG_ESP32_GCOV_ENABLE is not set
+# CONFIG_BLUEDROID_ENABLED is not set
+CONFIG_NIMBLE_ENABLED=y
+CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
+# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
+CONFIG_NIMBLE_MAX_CONNECTIONS=1
+CONFIG_NIMBLE_MAX_BONDS=2
+CONFIG_NIMBLE_MAX_CCCDS=2
+CONFIG_NIMBLE_L2CAP_COC_MAX_NUM=0
+CONFIG_NIMBLE_PINNED_TO_CORE=0
+CONFIG_NIMBLE_TASK_STACK_SIZE=4096
+CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096
+CONFIG_NIMBLE_ROLE_CENTRAL=y
+CONFIG_NIMBLE_ROLE_PERIPHERAL=y
+CONFIG_NIMBLE_ROLE_BROADCASTER=y
+# CONFIG_NIMBLE_ROLE_OBSERVER is not set
+# CONFIG_NIMBLE_NVS_PERSIST is not set
+# CONFIG_NIMBLE_DEBUG is not set
+CONFIG_NIMBLE_SVC_GAP_DEVICE_NAME=""
+CONFIG_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=30
+CONFIG_NIMBLE_ATT_PREFERRED_MTU=517
+CONFIG_NIMBLE_SVC_GAP_APPEARANCE=0
+CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12
+CONFIG_BT_NIMBLE_ACL_BUF_COUNT=12
+CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255
+CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
+CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=5
+CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=3
+# CONFIG_NIMBLE_HS_FLOW_CTRL is not set
+CONFIG_NIMBLE_RPA_TIMEOUT=900
+# CONFIG_NIMBLE_MESH is not set
+CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y
+# CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
+CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
+CONFIG_SW_COEXIST_ENABLE=y
+CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
+CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y
+# CONFIG_EVENT_LOOP_PROFILING is not set
+CONFIG_POST_EVENTS_FROM_ISR=y
+# CONFIG_POST_EVENTS_FROM_IRAM_ISR is not set
+CONFIG_GDBSTUB_SUPPORT_TASKS=y
+CONFIG_GDBSTUB_MAX_TASKS=32
+# CONFIG_OTA_ALLOW_HTTP is not set
+# CONFIG_ESP_SYSTEM_PD_FLASH is not set
+CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
+# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
+CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
+CONFIG_ESP32_PHY_MAX_TX_POWER=20
+# CONFIG_REDUCE_PHY_TX_POWER is not set
+# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set
+CONFIG_SYSTEM_EVENT_QUEUE_SIZE=16
+CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
+CONFIG_MAIN_TASK_STACK_SIZE=4096
+CONFIG_CONSOLE_UART_DEFAULT=y
+# CONFIG_CONSOLE_UART_CUSTOM is not set
+# CONFIG_CONSOLE_UART_NONE is not set
+# CONFIG_ESP_CONSOLE_UART_NONE is not set
+CONFIG_CONSOLE_UART=y
+CONFIG_CONSOLE_UART_NUM=0
+CONFIG_CONSOLE_UART_BAUDRATE=74880
+CONFIG_INT_WDT=y
+CONFIG_INT_WDT_TIMEOUT_MS=300
+CONFIG_TASK_WDT=y
+CONFIG_ESP_TASK_WDT=y
+# CONFIG_TASK_WDT_PANIC is not set
+CONFIG_TASK_WDT_TIMEOUT_S=5
+CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
+# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set
+CONFIG_BROWNOUT_DET=y
+CONFIG_BROWNOUT_DET_LVL_SEL_7=y
+# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
+# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
+CONFIG_BROWNOUT_DET_LVL=7
+CONFIG_IPC_TASK_STACK_SIZE=2048
+CONFIG_TIMER_TASK_STACK_SIZE=3584
+CONFIG_ESP32_WIFI_ENABLED=y
+CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
+CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
+# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set
+CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y
+CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1
+CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
+CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
+CONFIG_ESP32_WIFI_TX_BA_WIN=6
+CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
+CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
+CONFIG_ESP32_WIFI_RX_BA_WIN=6
+CONFIG_ESP32_WIFI_RX_BA_WIN=6
+CONFIG_ESP32_WIFI_NVS_ENABLED=y
+CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
+CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
+# CONFIG_ESP32_WIFI_IRAM_OPT is not set
+# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
+CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
+CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y
+CONFIG_WPA_MBEDTLS_CRYPTO=y
+CONFIG_WPA_MBEDTLS_TLS_CLIENT=y
+# CONFIG_WPA_11KV_SUPPORT is not set
+# CONFIG_WPA_MBO_SUPPORT is not set
+# CONFIG_WPA_DPP_SUPPORT is not set
+# CONFIG_WPA_11R_SUPPORT is not set
+# CONFIG_WPA_WPS_STRICT is not set
+# CONFIG_WPA_DEBUG_PRINT is not set
+# CONFIG_WPA_TESTING_OPTIONS is not set
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
+CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
+CONFIG_TIMER_TASK_PRIORITY=1
+CONFIG_TIMER_TASK_STACK_DEPTH=2048
+CONFIG_TIMER_QUEUE_LENGTH=10
+# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
+# CONFIG_HAL_ASSERTION_SILIENT is not set
+# CONFIG_L2_TO_L3_COPY is not set
+CONFIG_ESP_GRATUITOUS_ARP=y
+CONFIG_GARP_TMR_INTERVAL=60
+CONFIG_TCPIP_RECVMBOX_SIZE=32
+CONFIG_TCP_MAXRTX=12
+CONFIG_TCP_SYNMAXRTX=12
+CONFIG_TCP_MSS=1440
+CONFIG_TCP_MSL=60000
+CONFIG_TCP_SND_BUF_DEFAULT=5760
+CONFIG_TCP_WND_DEFAULT=5760
+CONFIG_TCP_RECVMBOX_SIZE=6
+CONFIG_TCP_QUEUE_OOSEQ=y
+CONFIG_TCP_OVERSIZE_MSS=y
+# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
+# CONFIG_TCP_OVERSIZE_DISABLE is not set
+CONFIG_UDP_RECVMBOX_SIZE=6
+CONFIG_TCPIP_TASK_STACK_SIZE=3072
+CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
+# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set
+CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF
+# CONFIG_PPP_SUPPORT is not set
+CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5
+CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
+CONFIG_ESP32_PTHREAD_STACK_MIN=768
+CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1
+CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
+CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
+# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
+# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
+CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
+CONFIG_SUPPORT_TERMIOS=y
+CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
+# End of deprecated options