├── .codespellrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── stale.yml └── workflows │ ├── auto-github-actions.yml │ ├── report-size-deltas.yml │ └── spell-check.yml ├── .gitignore ├── CONTRIBUTING.md ├── Images ├── Configuration.png ├── Configuration_1-0-11.png ├── Configuration_1-0-8.png ├── Configuration_1-0-9.png ├── Configuration_Simple.png ├── Configuration_Standard.png ├── Info.png ├── Info_Short.png ├── Info_Short_1-0-5.png ├── Main.png ├── Main_1-0-5.png └── Saved.png ├── LICENSE ├── README.md ├── changelog.md ├── esp32s2_WebServer_Patch ├── WebServer.cpp └── WebServer.h ├── examples ├── AutoConnect │ └── AutoConnect.ino ├── AutoConnectWithFSParameters │ └── AutoConnectWithFSParameters.ino ├── AutoConnectWithFeedback │ └── AutoConnectWithFeedback.ino ├── AutoConnectWithFeedbackLED │ └── AutoConnectWithFeedbackLED.ino ├── ConfigOnDRD_FS_MQTT_Ptr │ └── ConfigOnDRD_FS_MQTT_Ptr.ino ├── ConfigOnDRD_FS_MQTT_Ptr_Complex │ └── ConfigOnDRD_FS_MQTT_Ptr_Complex.ino ├── ConfigOnDRD_FS_MQTT_Ptr_Medium │ └── ConfigOnDRD_FS_MQTT_Ptr_Medium.ino ├── ConfigOnDoubleReset │ └── ConfigOnDoubleReset.ino ├── ConfigOnDoubleReset_Multi │ ├── ConfigOnDoubleReset_Multi.cpp │ ├── ConfigOnDoubleReset_Multi.h │ └── ConfigOnDoubleReset_Multi.ino ├── ConfigOnStartup │ └── ConfigOnStartup.ino ├── ConfigOnSwitch │ ├── ConfigOnSwitch.ino │ └── README.md ├── ConfigOnSwitchFS │ └── ConfigOnSwitchFS.ino ├── ConfigOnSwitchFS_MQTT_Ptr │ └── ConfigOnSwitchFS_MQTT_Ptr.ino ├── ConfigPortalParamsOnSwitch │ └── ConfigPortalParamsOnSwitch.ino ├── ESP32_FSWebServer │ ├── ESP32_FSWebServer.ino │ ├── README.md │ ├── data │ │ ├── CanadaFlag_1.png │ │ ├── CanadaFlag_2.png │ │ ├── CanadaFlag_3.jpg │ │ ├── edit.htm.gz │ │ ├── favicon.ico │ │ ├── graphs.js.gz │ │ └── index.htm │ └── pics │ │ ├── esp8266fs.local.png │ │ └── esp8266fs.local_edit.png ├── ESP32_FSWebServer_DRD │ ├── ESP32_FSWebServer_DRD.ino │ ├── README.md │ ├── data │ │ ├── CanadaFlag_1.png │ │ ├── CanadaFlag_2.png │ │ ├── CanadaFlag_3.jpg │ │ ├── edit.htm.gz │ │ ├── favicon.ico │ │ ├── graphs.js.gz │ │ └── index.htm │ └── pics │ │ ├── esp8266fs.local.png │ │ └── esp8266fs.local_edit.png ├── ESP_FSWebServer │ ├── ESP_FSWebServer.ino │ ├── README.md │ ├── data │ │ ├── CanadaFlag_1.png │ │ ├── CanadaFlag_2.png │ │ ├── CanadaFlag_3.jpg │ │ ├── edit.htm.gz │ │ ├── favicon.ico │ │ ├── graphs.js.gz │ │ └── index.htm │ └── pics │ │ ├── esp8266fs.local.png │ │ └── esp8266fs.local_edit.png └── ESP_FSWebServer_DRD │ ├── ESP_FSWebServer_DRD.ino │ ├── README.md │ ├── data │ ├── CanadaFlag_1.png │ ├── CanadaFlag_2.png │ ├── CanadaFlag_3.jpg │ ├── edit.htm.gz │ ├── favicon.ico │ ├── graphs.js.gz │ └── index.htm │ └── pics │ ├── esp8266fs.local.png │ └── esp8266fs.local_edit.png ├── keywords.txt ├── library.json ├── library.properties ├── platformio └── platformio.ini ├── src ├── ESP_WiFiManager-Impl.h ├── ESP_WiFiManager.h ├── ESP_WiFiManager.hpp ├── ESP_WiFiManager_Debug.h └── utils │ └── TZ.h ├── travis └── common.sh └── utils ├── astyle_library.conf └── restyle.sh /.codespellrc: -------------------------------------------------------------------------------- 1 | # See: https://github.com/codespell-project/codespell#using-a-config-file 2 | [codespell] 3 | # In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: 4 | ignore-words-list = , 5 | check-filenames = 6 | check-hidden = 7 | skip = ./.git,./src,./examples,./Packages_Patches,./LibraryPatches 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Describe the bug 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | ### Steps to Reproduce 15 | 16 | Steps to reproduce the behavior. Including the [MRE](https://stackoverflow.com/help/minimal-reproducible-example) sketches 17 | 18 | ### Expected behavior 19 | 20 | A clear and concise description of what you expected to happen. 21 | 22 | ### Actual behavior 23 | 24 | A clear and concise description of what you expected to happen. 25 | 26 | ### Debug and AT-command log (if applicable) 27 | 28 | A clear and concise description of what you expected to happen. 29 | 30 | ### Screenshots 31 | 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | ### Information 35 | 36 | Please ensure to specify the following, or your post will be ignored and deleted: 37 | 38 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 39 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.0.2 or ESP32 v2.0.5) 40 | * Contextual information (e.g. what you were trying to achieve) 41 | * Simplest possible steps to reproduce 42 | * Anything that might be relevant in your opinion, such as: 43 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 44 | * Network configuration 45 | 46 | 47 | ### Example 48 | 49 | ``` 50 | Arduino IDE version: 1.8.19 51 | ESP8266 Core Version 3.0.2 52 | OS: Ubuntu 20.04 LTS 53 | Linux xy-Inspiron-3593 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 54 | 55 | Context: 56 | I encountered a crash when using this library 57 | 58 | Steps to reproduce: 59 | 1. ... 60 | 2. ... 61 | 3. ... 62 | 4. ... 63 | ``` 64 | --- 65 | 66 | ### Sending Feature Requests 67 | 68 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 69 | 70 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 71 | 72 | --- 73 | 74 | ### Sending Pull Requests 75 | 76 | Pull Requests with changes and fixes are also welcome! 77 | 78 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 79 | 80 | 1. Change directory to the library GitHub 81 | 82 | ``` 83 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_WifiManager_GitHub/ 84 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WifiManager_GitHub$ 85 | ``` 86 | 87 | 2. Issue astyle command 88 | 89 | ``` 90 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WifiManager_GitHub$ bash utils/restyle.sh 91 | ``` 92 | 93 | 94 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Is your feature request related to a problem? Please describe. 11 | 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | ### Describe the solution you'd like 15 | 16 | A clear and concise description of what you want to happen. 17 | 18 | ### Describe alternatives you've considered 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | ### Additional context 22 | 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates#about-the-dependabotyml-file 2 | version: 2 3 | 4 | updates: 5 | # Configure check for outdated GitHub Actions actions in workflows. 6 | # See: https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot 7 | - package-ecosystem: github-actions 8 | directory: / # Check the repository's workflows under /.github/workflows/ 9 | schedule: 10 | interval: daily 11 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | daysUntilStale: 60 4 | daysUntilClose: 14 5 | limitPerRun: 30 6 | staleLabel: stale 7 | exemptLabels: 8 | - pinned 9 | - security 10 | - "to be implemented" 11 | - "for reference" 12 | - "move to PR" 13 | - "enhancement" 14 | 15 | only: issues 16 | onlyLabels: [] 17 | exemptProjects: false 18 | exemptMilestones: false 19 | exemptAssignees: false 20 | 21 | markComment: > 22 | [STALE_SET] This issue has been automatically marked as stale because it has not had 23 | recent activity. It will be closed in 14 days if no further activity occurs. Thank you 24 | for your contributions. 25 | 26 | unmarkComment: > 27 | [STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it opening the future. 28 | 29 | closeComment: > 30 | [STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/auto-github-actions.yml: -------------------------------------------------------------------------------- 1 | name: auto-github-actions 2 | on: [push] 3 | jobs: 4 | check-bats-version: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v3 8 | - uses: actions/setup-node@v3 9 | with: 10 | node-version: '14' 11 | - run: npm install -g bats 12 | - run: bats -v 13 | -------------------------------------------------------------------------------- /.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report Size Deltas 2 | 3 | on: 4 | schedule: 5 | - cron: '*/5 * * * *' 6 | 7 | jobs: 8 | report: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Comment size deltas reports to PRs 13 | uses: arduino/report-size-deltas@v1 14 | with: 15 | # The name of the workflow artifact created by the "Compile Examples" workflow 16 | sketches-reports-source: sketches-reports 17 | -------------------------------------------------------------------------------- /.github/workflows/spell-check.yml: -------------------------------------------------------------------------------- 1 | name: Spell Check 2 | 3 | on: 4 | pull_request: 5 | push: 6 | schedule: 7 | # run every Tuesday at 3 AM UTC 8 | - cron: "0 3 * * 2" 9 | workflow_dispatch: 10 | repository_dispatch: 11 | 12 | jobs: 13 | spellcheck: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v3 19 | 20 | # See: https://github.com/codespell-project/actions-codespell/blob/master/README.md 21 | - name: Spell check 22 | uses: codespell-project/actions-codespell@master 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Visual Studio folder and files 35 | .vs 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to ESP_WiFiManager 2 | 3 | ### Reporting Bugs 4 | 5 | Please report bugs in ESP_WiFiManager if you find them. 6 | 7 | However, before reporting a bug please check through the following: 8 | 9 | * [Existing Open Issues](https://github.com/khoih-prog/ESP_WiFiManager/issues) - someone might have already encountered this. 10 | 11 | If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ESP_WiFiManager/issues/new). 12 | 13 | ### How to submit a bug report 14 | 15 | Please ensure to specify the following, or your post will be ignored and deleted: 16 | 17 | * Arduino IDE version (e.g. 1.8.19) or Platform.io version 18 | * `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v3.0.2 or ESP32 v2.0.5) 19 | * Contextual information (e.g. what you were trying to achieve) 20 | * Simplest possible steps to reproduce 21 | * Anything that might be relevant in your opinion, such as: 22 | * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` 23 | * Network configuration 24 | 25 | 26 | ### Example 27 | 28 | ``` 29 | Arduino IDE version: 1.8.19 30 | ESP8266 Core Version 3.0.2 31 | OS: Ubuntu 20.04 LTS 32 | Linux xy-Inspiron-3593 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 33 | 34 | Context: 35 | I encountered a crash when using this library 36 | 37 | Steps to reproduce: 38 | 1. ... 39 | 2. ... 40 | 3. ... 41 | 4. ... 42 | ``` 43 | --- 44 | 45 | ### Sending Feature Requests 46 | 47 | Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. 48 | 49 | There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 50 | 51 | --- 52 | 53 | ### Sending Pull Requests 54 | 55 | Pull Requests with changes and fixes are also welcome! 56 | 57 | Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) 58 | 59 | 1. Change directory to the library GitHub 60 | 61 | ``` 62 | xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP_WifiManager_GitHub/ 63 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WifiManager_GitHub$ 64 | ``` 65 | 66 | 2. Issue astyle command 67 | 68 | ``` 69 | xy@xy-Inspiron-3593:~/Arduino/xy/ESP_WifiManager_GitHub$ bash utils/restyle.sh 70 | ``` 71 | 72 | 73 | -------------------------------------------------------------------------------- /Images/Configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration.png -------------------------------------------------------------------------------- /Images/Configuration_1-0-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration_1-0-11.png -------------------------------------------------------------------------------- /Images/Configuration_1-0-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration_1-0-8.png -------------------------------------------------------------------------------- /Images/Configuration_1-0-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration_1-0-9.png -------------------------------------------------------------------------------- /Images/Configuration_Simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration_Simple.png -------------------------------------------------------------------------------- /Images/Configuration_Standard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Configuration_Standard.png -------------------------------------------------------------------------------- /Images/Info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Info.png -------------------------------------------------------------------------------- /Images/Info_Short.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Info_Short.png -------------------------------------------------------------------------------- /Images/Info_Short_1-0-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Info_Short_1-0-5.png -------------------------------------------------------------------------------- /Images/Main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Main.png -------------------------------------------------------------------------------- /Images/Main_1-0-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Main_1-0-5.png -------------------------------------------------------------------------------- /Images/Saved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/Images/Saved.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Khoi Hoang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # ESP_WiFiManager 2 | 3 | [![arduino-library-badge](https://www.ardu-badge.com/badge/ESP_WiFiManager.svg?)](https://www.ardu-badge.com/ESP_WiFiManager) 4 | [![GitHub release](https://img.shields.io/github/release/khoih-prog/ESP_WiFiManager.svg)](https://github.com/khoih-prog/ESP_WiFiManager/releases) 5 | [![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/ESP_WiFiManager/blob/master/LICENSE) 6 | [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) 7 | [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ESP_WiFiManager.svg)](http://github.com/khoih-prog/ESP_WiFiManager/issues) 8 | [![star this repo](https://githubbadges.com/star.svg?user=khoih-prog&repo=ESP_WiFiManager&style=default)](https://github.com/khoih-prog/ESP_WiFiManager) 9 | 10 | Donate to my libraries using BuyMeACoffee 11 | 12 | 13 | --- 14 | --- 15 | 16 | ## Table of Contents 17 | 18 | * [Changelog](#changelog) 19 | * [Releases v1.12.1](#releases-v1121) 20 | * [Releases v1.12.0](#releases-v1120) 21 | * [Releases v1.11.0](#releases-v1110) 22 | * [Releases v1.10.2](#releases-v1102) 23 | * [Releases v1.10.1](#releases-v1101) 24 | * [Releases v1.10.0](#releases-v1100) 25 | * [Releases v1.9.0](#releases-v190) 26 | * [Releases v1.8.0](#releases-v180) 27 | * [Releases v1.7.8](#releases-v178) 28 | * [Releases v1.7.7](#releases-v177) 29 | * [Releases v1.7.6](#releases-v176) 30 | * [Releases v1.7.5](#releases-v175) 31 | * [Releases v1.7.4](#releases-v174) 32 | * [Releases v1.7.3](#releases-v173) 33 | * [Releases v1.7.2](#releases-v172) 34 | * [Releases v1.7.1](#releases-v171) 35 | * [Major Releases v1.7.0](#major-releases-v170) 36 | * [Releases v1.6.1](#releases-v161) 37 | * [Releases v1.6.0](#releases-v160) 38 | * [Releases v1.5.3](#releases-v153) 39 | * [Releases v1.5.2](#releases-v152) 40 | * [Releases v1.5.1](#releases-v151) 41 | * [Releases v1.5.0](#releases-v150) 42 | * [Releases v1.4.3](#releases-v143) 43 | * [Releases v1.4.2](#releases-v142) 44 | * [Major Releases v1.4.1](#major-releases-v141) 45 | * [Releases v1.3.0](#releases-v130) 46 | * [Releases v1.2.0](#releases-v120) 47 | * [Releases v1.1.2](#releases-v112) 48 | * [Releases v1.1.1](#releases-v111) 49 | * [Major Releases v1.1.0](#major-releases-v110) 50 | * [Releases v1.0.11](#releases-v1011) 51 | * [Releases v1.0.10](#releases-v1010) 52 | * [Releases v1.0.9](#releases-v109) 53 | * [Releases v1.0.8](#releases-v108) 54 | * [Releases v1.0.7](#releases-v107) 55 | * [Releases v1.0.6](#releases-v106) 56 | 57 | --- 58 | --- 59 | 60 | 61 | ## Changelog 62 | 63 | ### Releases v1.12.1 64 | 65 | 1. Using random channel for softAP without password. Check [fix: using random CH for non-password use too #118](https://github.com/khoih-prog/ESPAsync_WiFiManager/pull/118) 66 | 2. Add astyle using `allman` style. Restyle the library 67 | 68 | ### Releases v1.12.0 69 | 70 | 1. Optionally display Credentials (SSIDs, PWDs) in Config Portal. Check [Populate portal wifi with saved credentials #91](https://github.com/khoih-prog/ESP_WiFiManager/discussions/91) 71 | 2. Display `Credentials` Hint on Config Portal 72 | 3. Periodic code clean-up 73 | 74 | ### Releases v1.11.0 75 | 76 | 1. Fix ESP32 chipID. Check [Help for storing variables in memory (non-volatile) #87](https://github.com/khoih-prog/ESP_WiFiManager/discussions/87#discussioncomment-3593028) 77 | 2. Add ESP32 ESP_getChipOUI() function 78 | 3. Display new info on Config Portal for ESP32 79 | 4. Remove dependency on `LittleFS_esp32` library to prevent PIO error when using new ESP32 core v1.0.6+ 80 | 81 | ### Releases v1.10.2 82 | 83 | 1. Send CORS header in handleWifiSave() function. Check [Cors header not sent when saving wifi details, even when cors is enabled #80](https://github.com/khoih-prog/ESP_WiFiManager/issues/80) 84 | 2. Optimize code by using passing by `reference` instead of by `value` 85 | 3. Delete all confusing, function-lacking `minimal` examples 86 | 4. Display informational warnings only when `_WIFIMGR_LOGLEVEL_ > 3` 87 | 88 | ### Releases v1.10.1 89 | 90 | 1. Add LittleFS support to `ESP32-C3`. 91 | 2. Use ESP32-core's LittleFS library instead of Lorol's LITTLEFS library for v2.0.0+ 92 | 93 | ### Releases v1.10.0 94 | 95 | 1. Add support to `ESP32-S3` (`ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3`, etc.) using [ESP32 core, esp32-s3-support branch, v2.0.2+](https://github.com/espressif/arduino-esp32/tree/esp32-s3-support) 96 | 97 | ### Releases v1.9.0 98 | 99 | 1. Reduce the breaking effect of v1.8.0 by enabling compatibility with old code to include only `ESP_WiFiManager.h`. Check [Important Breaking Change from v1.8.0](https://github.com/khoih-prog/ESP_WiFiManager#Important-Breaking-Change-from-v180) 100 | 101 | 102 | ### Releases v1.8.0 103 | 104 | 1. Fix `multiple-definitions` linker error and weird bug related to `src_cpp`. Check [Different behaviour using the src_cpp or src_h lib #80](https://github.com/khoih-prog/ESPAsync_WiFiManager/discussions/80) 105 | 2. Optimize library code by using `reference-passing` instead of `value-passing` 106 | 107 | ### Releases v1.7.8 108 | 109 | 1. To permit using HTTP port different from 80. Check [WiFiManager works only on port 80 #75](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/75) 110 | 2. Fix bug returning IP `255.255.255.255` in core v2.0.0+ when using `hostname` 111 | 112 | 113 | ### Releases v1.7.7 114 | 115 | 1. Fix compile error for ESP32 core v1.0.5- 116 | 117 | ### Releases v1.7.6 118 | 119 | 1. Auto detect ESP32 core and use either built-in LittleFS or [LITTLEFS](https://github.com/lorol/LITTLEFS) library 120 | 2. Update `library.json` to use new `headers` for PIO 121 | 122 | ### Releases v1.7.5 123 | 124 | 1. Update `platform.ini` and `library.json` to use original `khoih-prog` instead of `khoih.prog` after PIO fix 125 | 126 | ### Releases v1.7.4 127 | 128 | 1. Add WiFi scanning of hidden SSIDs. Check [Add support for Wifi hidden SSID scanning. #66](https://github.com/khoih-prog/ESP_WiFiManager/pull/66) 129 | 130 | ### Releases v1.7.3 131 | 132 | 1. Fix MultiWiFi connection issue with ESP32 core v2.0.0-rc1+ 133 | 2. Verify compatibility with new ESP32 core v2.0.0-rc1+ 134 | 3. Verify compatibility with new ESP8266 core v3.0.2 135 | 136 | ### Releases v1.7.2 137 | 138 | 1. Fix warnings and Verify compatibility with new ESP8266 core v3.0.0 139 | 140 | ### Releases v1.7.1 141 | 142 | 1. Fix Json bug in /scan. Check [Invalid Json generated #60](https://github.com/khoih-prog/ESP_WiFiManager/issues/60) 143 | 2. Fix timezoneName not displayed in Info page. 144 | 145 | ### Major Releases v1.7.0 146 | 147 | 1. Add auto-Timezone feature with variable `_timezoneName` (e.g. `America/New_York`) and function to retrieve TZ (e.g. `EST5EDT,M3.2.0,M11.1.0`) to use directly to configure ESP32/ESP8266 timezone. Check [How to retrieve timezone? #51](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/51) for more info. 148 | 2. Store those `_timezoneName` and `TZ` in LittleFS or SPIFFS config file. 149 | 3. Using these new timezone feature is optional. 150 | 4. Add checksum in config file to validate data read from LittleFS or SPIFFS config file. 151 | 5. Update examples to show how to use the new TZ feature. 152 | 153 | ### Releases v1.6.1 154 | 155 | 1. Fix captive-portal bug if Config Portal AP address is not default 192.168.4.1. Check [In AP, DNS server always redirects to 192.168.4.1 no matter what APStaticIP is set to. #58](https://github.com/khoih-prog/ESP_WiFiManager/issues/58) 156 | 2. Fix MultiWiFi bug. 157 | 158 | ### Releases v1.6.0 159 | 160 | 1. Add **EEPROM and SPIFFS** support to new **ESP32-C3** boards (**Arduino ESP32C3_DEV**). Check [HOWTO Install esp32 core for ESP32-S2 (Saola, AI-Thinker ESP-12K) and ESP32-C3 boards into Arduino IDE](#howto-install-esp32-core-for-esp32-s2-saola-ai-thinker-esp-12k-and-esp32-c3-boards-into-arduino-ide). 161 | 162 | 163 | ### Releases v1.5.3 164 | 165 | 1. Add `dnsServer can't allocate` and `dnsServer can't start` error messages 166 | 167 | ### Releases v1.5.2 168 | 169 | 1. Fix example misleading messages. Check [**Minor: examples/Async_ESP32_FSWebServer/ wrongly uses FileFS.begin(true)** #47](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/47) 170 | 2. Tested with [**ESP32 Core 1.0.6**](https://github.com/espressif/arduino-esp32) and [**LittleFS_esp32 v1.0.6**](https://github.com/lorol/LITTLEFS) 171 | 172 | ### Releases v1.5.1 173 | 174 | 1. Fix compiler error if setting `Compiler Warnings` to `All`. 175 | 2. Modify multiWiFi-related timings to work with latest esp32 core v1.0.6 176 | 177 | ### Releases v1.5.0 178 | 179 | 1. Add support to **ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, ESP32S2 Dev Module, UM FeatherS2, UM ProS2, microS2, etc.)** 180 | 2. Add [**Instructions to install ESP32-S2 core**](#howto-install-esp32-s2-core-for-esp32-s2-saola-ai-thinker-esp-12k-boards-into-arduino-ide) 181 | 182 | ### Releases v1.4.3 183 | 184 | 1. Fix examples' bug not saving Static IP in certain cases. 185 | 2. Add feature to warn if using examples with old library versions 186 | 187 | ### Releases v1.4.2 188 | 189 | 1. Fix examples' bug not using saved WiFi Credentials after losing all WiFi connections. 190 | 2. Fix compiler warnings. 191 | 192 | ### Major Releases v1.4.1 193 | 194 | 1. Fix staticIP not saved in examples. See [ESP32 static IP not saved after restarting the device](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/19) 195 | 2. Add structures and functions to handle AP and STA IPs. 196 | 3. Add complex examples 197 | * [ConfigOnDRD_FS_MQTT_Ptr_Complex](examples/ConfigOnDRD_FS_MQTT_Ptr_Complex) to demo usage of std::map 198 | * [ConfigOnDRD_FS_MQTT_Ptr_Medium](examples/ConfigOnDRD_FS_MQTT_Ptr_Medium). 199 | 4. Add simple minimal examples 200 | * [ConfigOnDRD_ESP32_minimal](examples/ConfigOnDRD_ESP32_minimal) 201 | * [ConfigOnDRD_ESP8266_minimal](examples/ConfigOnDRD_ESP8266_minimal) 202 | * [AutoConnect_ESP32_minimal](examples/AutoConnect_ESP32_minimal) 203 | * [AutoConnect_ESP8266_minimal](examples/AutoConnect_ESP8266_minimal) 204 | 5. Fix bug. 205 | 6. Fix compiler warnings. 206 | 7. Modify Version String 207 | 8. Add Table of Contents 208 | 209 | 210 | ### Releases v1.3.0 211 | 212 | 1. Add LittleFS support to ESP32-related examples to use [LittleFS_esp32 Library](https://github.com/lorol/LITTLEFS) 213 | 2. Add Version String 214 | 215 | ### Releases v1.2.0 216 | 217 | 1. Restore cpp code besides Impl.h code to use in case of `multiple definition` linker error. See [`Change Implementation to separate *.h and *.cpp file instead of *.h and *-Impl.h`](https://github.com/khoih-prog/ESP_WiFiManager/issues/38) and [`Support building in PlatformIO PR`](https://github.com/khoih-prog/ESP_WiFiManager/pull/20). Also have a look at [**HOWTO Fix Multiple Definitions Linker Error**](https://github.com/khoih-prog/ESP_WiFiManager#HOWTO-Fix-Multiple-Definitions-Linker-Error) 218 | 2. Fix bug [/close does not close the config portal](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/16). 219 | 220 | ### Releases v1.1.2 221 | 222 | 1. Fix bug in examples. 223 | 2. Add example. 224 | 225 | ### Releases v1.1.1 226 | 227 | 1. Add setCORSHeader function to allow **configurable CORS Header**. See [Using CORS feature](https://github.com/khoih-prog/ESP_WiFiManager#15-using-cors-cross-origin-resource-sharing-feature) 228 | 2. Fix typo and minor improvement. 229 | 3. Shorten MultiWiFi connection time. 230 | 231 | ### Major Releases v1.1.0 232 | 233 | 1. Add **MultiWiFi feature to auto(Re)connect to the best WiFi at runtime** 234 | 2. Fix bug. 235 | 3. Completely enhanced examples to use new MultiWiFi feature. 236 | 237 | #### Releases v1.0.11 238 | 239 | 1. Add optional **CORS (Cross-Origin Resource Sharing)** feature. Thanks to [AlesSt](https://github.com/AlesSt). See more in [Issue #27: CORS protection fires up with AJAX](https://github.com/khoih-prog/ESP_WiFiManager/issues/27) and [Cross Origin Resource Sharing](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing). To use, you must explicitly use `#define USING_CORS_FEATURE true` 240 | 2. Solve issue softAP with custom IP sometimes not working. Thanks to [AlesSt](https://github.com/AlesSt). See [Issue #26: softAP with custom IP not working](https://github.com/khoih-prog/ESP_WiFiManager/issues/26) and [Wifi.softAPConfig() sometimes set the wrong IP address](https://github.com/espressif/arduino-esp32/issues/985). 241 | 3. Temporary fix for issue of not clearing WiFi SSID/PW from flash of ESP32. Thanks to [AlesSt](https://github.com/AlesSt). See more in [Issue #25: API call /r doesn't clear credentials](https://github.com/khoih-prog/ESP_WiFiManager/issues/25) and [WiFi.disconnect(true) problem](https://github.com/espressif/arduino-esp32/issues/400). 242 | 4. Fix autoConnect() feature to permit autoConnect() to use STA static IP or DHCP IP. Remove from deprecated function list. 243 | 5. Enhance README.md with more instructions and illustrations. 244 | 245 | 246 | #### Releases v1.0.10 247 | 248 | 1. Don't need to reinput already working SSID in Config Port to update other parameters, such as StaticIP. 249 | 2. Disable/Enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used. 250 | 3. Change HTTP_XYZ constants to WM_HTTP_XYZ to avoid conflicts with future releases of ESP32 and ESP8266 cores. 251 | 4. Add feature to change WiFi AP channel (fixed or random) to avoid conflict in AP-overcrowded environments. 252 | 5. Enhance Config Portal GUI and get the item out of the bucket list. 253 | 6. Enhance README.md with more instructions and illustrations. 254 | 255 | #### Releases v1.0.9 256 | 257 | 1. Fix ESP32 STAstaticIP bug. 258 | 2. Enable changing from DHCP <-> static IP using Config Portal. 259 | 3. Enable NTP configuration from sketch (USE_ESP_WIFIMANAGER_NTP, USE_CLOUDFLARE_NTP). See Issue #21: [CloudFlare link in the default portal](https://github.com/khoih-prog/ESP_WiFiManager/issues/21). 260 | 4. Add, enhance examples (fix MDNS for ESP32 examples, add DRD feature). 261 | 262 | #### Releases v1.0.8 263 | 264 | 1. Fix setSTAStaticIPConfig issue. See [Static Station IP doesn't work](https://github.com/khoih-prog/ESP_WiFiManager/issues/17) 265 | 2. Add LittleFS support for ESP8266 core 2.7.1+ in examples to replace deprecated SPIFFS. 266 | 3. Restructure code. 267 | 268 | #### Releases v1.0.7 269 | 270 | 1. Use `just-in-time` scanWiFiNetworks() to reduce connection time necessary for battery-operated DeepSleep application. Thanks to [CrispinP](https://github.com/CrispinP) for identifying, requesting and testing. See [Starting WiFIManger is very slow (2000ms)](https://github.com/khoih-prog/ESP_WiFiManager/issues/6) 271 | 2. Fix bug relating SPIFFS in examples : 272 | - [ConfigOnSwitchFS](examples/ConfigOnSwitchFS) 273 | - [ConfigPortalParamsOnSwitch](examples/ConfigPortalParamsOnSwitch) (now support ArduinoJson 6.0.0+ as well as 5.13.5-) 274 | - [AutoConnectWithFSParameters](examples/AutoConnectWithFSParameters) 275 | See [Having issue to read the SPIFF file](https://github.com/khoih-prog/ESP_WiFiManager/issues/14), Thanks to [OttoKlaasen](https://github.com/OttoKlaasen) to report. 276 | 3. Fix [README](README.md). See [Accessing manager after connection](https://github.com/khoih-prog/ESP_WiFiManager/issues/15) 277 | 278 | #### Releases v1.0.6 279 | 280 | 1. Add function getConfigPortalPW() 281 | 2. Add 4 new complicated examples compatible with ArduinoJson 6.0.0+ :[AutoConnect](examples/AutoConnect), [AutoConnectWithFeedback](examples/AutoConnectWithFeedback), [AutoConnectWithFeedbackLED](examples/AutoConnectWithFeedbackLED) and [AutoConnectWithFSParameters](examples/AutoConnectWithFSParameters) 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /esp32s2_WebServer_Patch/WebServer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | WebServer.cpp - Dead simple web-server. 3 | Supports only one simultaneous client, knows how to handle GET and POST. 4 | 5 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) 21 | */ 22 | 23 | // KH, Using "WebServer.handleClient delay" (https://github.com/espressif/arduino-esp32/pull/4350) 24 | 25 | #include 26 | #include 27 | #include 28 | #include "WiFiServer.h" 29 | #include "WiFiClient.h" 30 | #include "WebServer.h" 31 | #include "FS.h" 32 | #include "detail/RequestHandlersImpl.h" 33 | #include "mbedtls/md5.h" 34 | 35 | 36 | static const char AUTHORIZATION_HEADER[] = "Authorization"; 37 | static const char qop_auth[] = "qop=\"auth\""; 38 | static const char WWW_Authenticate[] = "WWW-Authenticate"; 39 | static const char Content_Length[] = "Content-Length"; 40 | 41 | 42 | WebServer::WebServer(IPAddress addr, int port) 43 | : _corsEnabled(false) 44 | , _server(addr, port) 45 | , _currentMethod(HTTP_ANY) 46 | , _currentVersion(0) 47 | , _currentStatus(HC_NONE) 48 | , _statusChange(0) 49 | , _nullDelay(true) 50 | , _currentHandler(nullptr) 51 | , _firstHandler(nullptr) 52 | , _lastHandler(nullptr) 53 | , _currentArgCount(0) 54 | , _currentArgs(nullptr) 55 | , _postArgsLen(0) 56 | , _postArgs(nullptr) 57 | , _headerKeysCount(0) 58 | , _currentHeaders(nullptr) 59 | , _contentLength(0) 60 | , _chunked(false) 61 | { 62 | } 63 | 64 | WebServer::WebServer(int port) 65 | : _corsEnabled(false) 66 | , _server(port) 67 | , _currentMethod(HTTP_ANY) 68 | , _currentVersion(0) 69 | , _currentStatus(HC_NONE) 70 | , _statusChange(0) 71 | , _nullDelay(true) 72 | , _currentHandler(nullptr) 73 | , _firstHandler(nullptr) 74 | , _lastHandler(nullptr) 75 | , _currentArgCount(0) 76 | , _currentArgs(nullptr) 77 | , _postArgsLen(0) 78 | , _postArgs(nullptr) 79 | , _headerKeysCount(0) 80 | , _currentHeaders(nullptr) 81 | , _contentLength(0) 82 | , _chunked(false) 83 | { 84 | } 85 | 86 | WebServer::~WebServer() 87 | { 88 | _server.close(); 89 | 90 | if (_currentHeaders) 91 | delete[]_currentHeaders; 92 | 93 | RequestHandler* handler = _firstHandler; 94 | 95 | while (handler) 96 | { 97 | RequestHandler* next = handler->next(); 98 | delete handler; 99 | handler = next; 100 | } 101 | } 102 | 103 | void WebServer::begin() 104 | { 105 | close(); 106 | _server.begin(); 107 | _server.setNoDelay(true); 108 | } 109 | 110 | void WebServer::begin(uint16_t port) 111 | { 112 | close(); 113 | _server.begin(port); 114 | _server.setNoDelay(true); 115 | } 116 | 117 | String WebServer::_extractParam(String& authReq, const String& param, const char delimit) 118 | { 119 | int _begin = authReq.indexOf(param); 120 | 121 | if (_begin == -1) 122 | return ""; 123 | 124 | return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length())); 125 | } 126 | 127 | static String md5str(String &in) 128 | { 129 | char out[33] = {0}; 130 | mbedtls_md5_context _ctx; 131 | uint8_t i; 132 | uint8_t * _buf = (uint8_t*)malloc(16); 133 | 134 | if (_buf == NULL) 135 | return String(out); 136 | 137 | memset(_buf, 0x00, 16); 138 | mbedtls_md5_init(&_ctx); 139 | mbedtls_md5_starts(&_ctx); 140 | mbedtls_md5_update(&_ctx, (const uint8_t *)in.c_str(), in.length()); 141 | mbedtls_md5_finish(&_ctx, _buf); 142 | 143 | for (i = 0; i < 16; i++) 144 | { 145 | sprintf(out + (i * 2), "%02x", _buf[i]); 146 | } 147 | 148 | out[32] = 0; 149 | free(_buf); 150 | return String(out); 151 | } 152 | 153 | bool WebServer::authenticate(const char * username, const char * password) 154 | { 155 | if (hasHeader(FPSTR(AUTHORIZATION_HEADER))) 156 | { 157 | String authReq = header(FPSTR(AUTHORIZATION_HEADER)); 158 | 159 | if (authReq.startsWith(F("Basic"))) 160 | { 161 | authReq = authReq.substring(6); 162 | authReq.trim(); 163 | char toencodeLen = strlen(username) + strlen(password) + 1; 164 | char *toencode = new char[toencodeLen + 1]; 165 | 166 | if (toencode == NULL) 167 | { 168 | authReq = ""; 169 | return false; 170 | } 171 | 172 | char *encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; 173 | 174 | if (encoded == NULL) 175 | { 176 | authReq = ""; 177 | delete[] toencode; 178 | return false; 179 | } 180 | 181 | sprintf(toencode, "%s:%s", username, password); 182 | 183 | if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) 184 | { 185 | authReq = ""; 186 | delete[] toencode; 187 | delete[] encoded; 188 | return true; 189 | } 190 | 191 | delete[] toencode; 192 | delete[] encoded; 193 | } 194 | else if (authReq.startsWith(F("Digest"))) 195 | { 196 | authReq = authReq.substring(7); 197 | log_v("%s", authReq.c_str()); 198 | String _username = _extractParam(authReq, F("username=\""), '\"'); 199 | 200 | if (!_username.length() || _username != String(username)) 201 | { 202 | authReq = ""; 203 | return false; 204 | } 205 | 206 | // extracting required parameters for RFC 2069 simpler Digest 207 | String _realm = _extractParam(authReq, F("realm=\""), '\"'); 208 | String _nonce = _extractParam(authReq, F("nonce=\""), '\"'); 209 | String _uri = _extractParam(authReq, F("uri=\""), '\"'); 210 | String _response = _extractParam(authReq, F("response=\""), '\"'); 211 | String _opaque = _extractParam(authReq, F("opaque=\""), '\"'); 212 | 213 | if ((!_realm.length()) || (!_nonce.length()) || (!_uri.length()) || (!_response.length()) || (!_opaque.length())) 214 | { 215 | authReq = ""; 216 | return false; 217 | } 218 | 219 | if ((_opaque != _sopaque) || (_nonce != _snonce) || (_realm != _srealm)) 220 | { 221 | authReq = ""; 222 | return false; 223 | } 224 | 225 | // parameters for the RFC 2617 newer Digest 226 | String _nc, _cnonce; 227 | 228 | if (authReq.indexOf(FPSTR(qop_auth)) != -1) 229 | { 230 | _nc = _extractParam(authReq, F("nc="), ','); 231 | _cnonce = _extractParam(authReq, F("cnonce=\""), '\"'); 232 | } 233 | 234 | String _H1 = md5str(String(username) + ':' + _realm + ':' + String(password)); 235 | log_v("Hash of user:realm:pass=%s", _H1.c_str()); 236 | String _H2 = ""; 237 | 238 | if (_currentMethod == HTTP_GET) 239 | { 240 | _H2 = md5str(String(F("GET:")) + _uri); 241 | } 242 | else if (_currentMethod == HTTP_POST) 243 | { 244 | _H2 = md5str(String(F("POST:")) + _uri); 245 | } 246 | else if (_currentMethod == HTTP_PUT) 247 | { 248 | _H2 = md5str(String(F("PUT:")) + _uri); 249 | } 250 | else if (_currentMethod == HTTP_DELETE) 251 | { 252 | _H2 = md5str(String(F("DELETE:")) + _uri); 253 | } 254 | else 255 | { 256 | _H2 = md5str(String(F("GET:")) + _uri); 257 | } 258 | 259 | log_v("Hash of GET:uri=%s", _H2.c_str()); 260 | String _responsecheck = ""; 261 | 262 | if (authReq.indexOf(FPSTR(qop_auth)) != -1) 263 | { 264 | _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2); 265 | } 266 | else 267 | { 268 | _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _H2); 269 | } 270 | 271 | log_v("The Proper response=%s", _responsecheck.c_str()); 272 | 273 | if (_response == _responsecheck) 274 | { 275 | authReq = ""; 276 | return true; 277 | } 278 | } 279 | 280 | authReq = ""; 281 | } 282 | 283 | return false; 284 | } 285 | 286 | String WebServer::_getRandomHexString() 287 | { 288 | char buffer[33]; // buffer to hold 32 Hex Digit + /0 289 | int i; 290 | 291 | for (i = 0; i < 4; i++) 292 | { 293 | sprintf (buffer + (i * 8), "%08x", esp_random()); 294 | } 295 | 296 | return String(buffer); 297 | } 298 | 299 | void WebServer::requestAuthentication(HTTPAuthMethod mode, const char* realm, const String& authFailMsg) 300 | { 301 | if (realm == NULL) 302 | { 303 | _srealm = String(F("Login Required")); 304 | } 305 | else 306 | { 307 | _srealm = String(realm); 308 | } 309 | 310 | if (mode == BASIC_AUTH) 311 | { 312 | sendHeader(String(FPSTR(WWW_Authenticate)), String(F("Basic realm=\"")) + _srealm + String(F("\""))); 313 | } 314 | else 315 | { 316 | _snonce = _getRandomHexString(); 317 | _sopaque = _getRandomHexString(); 318 | sendHeader(String(FPSTR(WWW_Authenticate)), 319 | String(F("Digest realm=\"")) + _srealm + String(F("\", qop=\"auth\", nonce=\"")) + _snonce + String( 320 | F("\", opaque=\"")) + _sopaque + String(F("\""))); 321 | } 322 | 323 | using namespace mime; 324 | send(401, String(FPSTR(mimeTable[html].mimeType)), authFailMsg); 325 | } 326 | 327 | void WebServer::on(const Uri &uri, WebServer::THandlerFunction handler) 328 | { 329 | on(uri, HTTP_ANY, handler); 330 | } 331 | 332 | void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn) 333 | { 334 | on(uri, method, fn, _fileUploadHandler); 335 | } 336 | 337 | void WebServer::on(const Uri &uri, HTTPMethod method, WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn) 338 | { 339 | _addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method)); 340 | } 341 | 342 | void WebServer::addHandler(RequestHandler* handler) 343 | { 344 | _addRequestHandler(handler); 345 | } 346 | 347 | void WebServer::_addRequestHandler(RequestHandler* handler) 348 | { 349 | if (!_lastHandler) 350 | { 351 | _firstHandler = handler; 352 | _lastHandler = handler; 353 | } 354 | else 355 | { 356 | _lastHandler->next(handler); 357 | _lastHandler = handler; 358 | } 359 | } 360 | 361 | void WebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) 362 | { 363 | _addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header)); 364 | } 365 | 366 | void WebServer::handleClient() 367 | { 368 | if (_currentStatus == HC_NONE) 369 | { 370 | WiFiClient client = _server.available(); 371 | 372 | if (!client) 373 | { 374 | if (_nullDelay) 375 | { 376 | delay(1); 377 | } 378 | 379 | return; 380 | } 381 | 382 | log_v("New client"); 383 | 384 | _currentClient = client; 385 | _currentStatus = HC_WAIT_READ; 386 | _statusChange = millis(); 387 | } 388 | 389 | bool keepCurrentClient = false; 390 | bool callYield = false; 391 | 392 | if (_currentClient.connected()) 393 | { 394 | switch (_currentStatus) 395 | { 396 | case HC_NONE: 397 | // No-op to avoid C++ compiler warning 398 | break; 399 | 400 | case HC_WAIT_READ: 401 | 402 | // Wait for data from client to become available 403 | if (_currentClient.available()) 404 | { 405 | if (_parseRequest(_currentClient)) 406 | { 407 | // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, 408 | // it must be divided by 1000 409 | _currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); 410 | _contentLength = CONTENT_LENGTH_NOT_SET; 411 | _handleRequest(); 412 | 413 | // Fix for issue with Chrome based browsers: https://github.com/espressif/arduino-esp32/issues/3652 414 | // if (_currentClient.connected()) { 415 | // _currentStatus = HC_WAIT_CLOSE; 416 | // _statusChange = millis(); 417 | // keepCurrentClient = true; 418 | // } 419 | } 420 | } 421 | else // !_currentClient.available() 422 | { 423 | if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) 424 | { 425 | keepCurrentClient = true; 426 | } 427 | 428 | callYield = true; 429 | } 430 | 431 | break; 432 | 433 | case HC_WAIT_CLOSE: 434 | 435 | // Wait for client to close the connection 436 | if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) 437 | { 438 | keepCurrentClient = true; 439 | callYield = true; 440 | } 441 | } 442 | } 443 | 444 | if (!keepCurrentClient) 445 | { 446 | _currentClient = WiFiClient(); 447 | _currentStatus = HC_NONE; 448 | _currentUpload.reset(); 449 | } 450 | 451 | if (callYield) 452 | { 453 | yield(); 454 | } 455 | } 456 | 457 | void WebServer::close() 458 | { 459 | _server.close(); 460 | _currentStatus = HC_NONE; 461 | 462 | if (!_headerKeysCount) 463 | collectHeaders(0, 0); 464 | } 465 | 466 | void WebServer::stop() 467 | { 468 | close(); 469 | } 470 | 471 | void WebServer::sendHeader(const String& name, const String& value, bool first) 472 | { 473 | String headerLine = name; 474 | headerLine += F(": "); 475 | headerLine += value; 476 | headerLine += "\r\n"; 477 | 478 | if (first) 479 | { 480 | _responseHeaders = headerLine + _responseHeaders; 481 | } 482 | else 483 | { 484 | _responseHeaders += headerLine; 485 | } 486 | } 487 | 488 | void WebServer::setContentLength(const size_t contentLength) 489 | { 490 | _contentLength = contentLength; 491 | } 492 | 493 | void WebServer::enableDelay(boolean value) 494 | { 495 | _nullDelay = value; 496 | } 497 | 498 | void WebServer::enableCORS(boolean value) 499 | { 500 | _corsEnabled = value; 501 | } 502 | 503 | void WebServer::enableCrossOrigin(boolean value) 504 | { 505 | enableCORS(value); 506 | } 507 | 508 | void WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) 509 | { 510 | response = String(F("HTTP/1.")) + String(_currentVersion) + ' '; 511 | response += String(code); 512 | response += ' '; 513 | response += _responseCodeToString(code); 514 | response += "\r\n"; 515 | 516 | using namespace mime; 517 | 518 | if (!content_type) 519 | content_type = mimeTable[html].mimeType; 520 | 521 | sendHeader(String(F("Content-Type")), String(FPSTR(content_type)), true); 522 | 523 | if (_contentLength == CONTENT_LENGTH_NOT_SET) 524 | { 525 | sendHeader(String(FPSTR(Content_Length)), String(contentLength)); 526 | } 527 | else if (_contentLength != CONTENT_LENGTH_UNKNOWN) 528 | { 529 | sendHeader(String(FPSTR(Content_Length)), String(_contentLength)); 530 | } 531 | else if (_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion) //HTTP/1.1 or above client 532 | { 533 | //let's do chunked 534 | _chunked = true; 535 | sendHeader(String(F("Accept-Ranges")), String(F("none"))); 536 | sendHeader(String(F("Transfer-Encoding")), String(F("chunked"))); 537 | } 538 | 539 | if (_corsEnabled) 540 | { 541 | sendHeader(String(FPSTR("Access-Control-Allow-Origin")), String("*")); 542 | } 543 | 544 | sendHeader(String(F("Connection")), String(F("close"))); 545 | 546 | response += _responseHeaders; 547 | response += "\r\n"; 548 | _responseHeaders = ""; 549 | } 550 | 551 | void WebServer::send(int code, const char* content_type, const String& content) 552 | { 553 | String header; 554 | // Can we assume the following? 555 | //if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET) 556 | // _contentLength = CONTENT_LENGTH_UNKNOWN; 557 | _prepareHeader(header, code, content_type, content.length()); 558 | _currentClientWrite(header.c_str(), header.length()); 559 | 560 | if (content.length()) 561 | sendContent(content); 562 | } 563 | 564 | void WebServer::send_P(int code, PGM_P content_type, PGM_P content) 565 | { 566 | size_t contentLength = 0; 567 | 568 | if (content != NULL) 569 | { 570 | contentLength = strlen_P(content); 571 | } 572 | 573 | String header; 574 | char type[64]; 575 | memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); 576 | _prepareHeader(header, code, (const char* )type, contentLength); 577 | _currentClientWrite(header.c_str(), header.length()); 578 | sendContent_P(content); 579 | } 580 | 581 | void WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) 582 | { 583 | String header; 584 | char type[64]; 585 | memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type)); 586 | _prepareHeader(header, code, (const char* )type, contentLength); 587 | sendContent(header); 588 | sendContent_P(content, contentLength); 589 | } 590 | 591 | void WebServer::send(int code, char* content_type, const String& content) 592 | { 593 | send(code, (const char*)content_type, content); 594 | } 595 | 596 | void WebServer::send(int code, const String& content_type, const String& content) 597 | { 598 | send(code, (const char*)content_type.c_str(), content); 599 | } 600 | 601 | void WebServer::sendContent(const String& content) 602 | { 603 | sendContent(content.c_str(), content.length()); 604 | } 605 | 606 | void WebServer::sendContent(const char* content, size_t contentLength) 607 | { 608 | const char * footer = "\r\n"; 609 | 610 | if (_chunked) 611 | { 612 | char * chunkSize = (char *)malloc(11); 613 | 614 | if (chunkSize) 615 | { 616 | sprintf(chunkSize, "%x%s", contentLength, footer); 617 | _currentClientWrite(chunkSize, strlen(chunkSize)); 618 | free(chunkSize); 619 | } 620 | } 621 | 622 | _currentClientWrite(content, contentLength); 623 | 624 | if (_chunked) 625 | { 626 | _currentClient.write(footer, 2); 627 | 628 | if (contentLength == 0) 629 | { 630 | _chunked = false; 631 | } 632 | } 633 | } 634 | 635 | void WebServer::sendContent_P(PGM_P content) 636 | { 637 | sendContent_P(content, strlen_P(content)); 638 | } 639 | 640 | void WebServer::sendContent_P(PGM_P content, size_t size) 641 | { 642 | const char * footer = "\r\n"; 643 | 644 | if (_chunked) 645 | { 646 | char * chunkSize = (char *)malloc(11); 647 | 648 | if (chunkSize) 649 | { 650 | sprintf(chunkSize, "%x%s", size, footer); 651 | _currentClientWrite(chunkSize, strlen(chunkSize)); 652 | free(chunkSize); 653 | } 654 | } 655 | 656 | _currentClientWrite_P(content, size); 657 | 658 | if (_chunked) 659 | { 660 | _currentClient.write(footer, 2); 661 | 662 | if (size == 0) 663 | { 664 | _chunked = false; 665 | } 666 | } 667 | } 668 | 669 | 670 | void WebServer::_streamFileCore(const size_t fileSize, const String & fileName, const String & contentType) 671 | { 672 | using namespace mime; 673 | setContentLength(fileSize); 674 | 675 | if (fileName.endsWith(String(FPSTR(mimeTable[gz].endsWith))) && 676 | contentType != String(FPSTR(mimeTable[gz].mimeType)) && 677 | contentType != String(FPSTR(mimeTable[none].mimeType))) 678 | { 679 | sendHeader(F("Content-Encoding"), F("gzip")); 680 | } 681 | 682 | send(200, contentType, ""); 683 | } 684 | 685 | String WebServer::pathArg(unsigned int i) 686 | { 687 | if (_currentHandler != nullptr) 688 | return _currentHandler->pathArg(i); 689 | 690 | return ""; 691 | } 692 | 693 | String WebServer::arg(String name) 694 | { 695 | for (int j = 0; j < _postArgsLen; ++j) 696 | { 697 | if ( _postArgs[j].key == name ) 698 | return _postArgs[j].value; 699 | } 700 | 701 | for (int i = 0; i < _currentArgCount; ++i) 702 | { 703 | if ( _currentArgs[i].key == name ) 704 | return _currentArgs[i].value; 705 | } 706 | 707 | return ""; 708 | } 709 | 710 | String WebServer::arg(int i) 711 | { 712 | if (i < _currentArgCount) 713 | return _currentArgs[i].value; 714 | 715 | return ""; 716 | } 717 | 718 | String WebServer::argName(int i) 719 | { 720 | if (i < _currentArgCount) 721 | return _currentArgs[i].key; 722 | 723 | return ""; 724 | } 725 | 726 | int WebServer::args() 727 | { 728 | return _currentArgCount; 729 | } 730 | 731 | bool WebServer::hasArg(String name) 732 | { 733 | for (int j = 0; j < _postArgsLen; ++j) 734 | { 735 | if (_postArgs[j].key == name) 736 | return true; 737 | } 738 | 739 | for (int i = 0; i < _currentArgCount; ++i) 740 | { 741 | if (_currentArgs[i].key == name) 742 | return true; 743 | } 744 | 745 | return false; 746 | } 747 | 748 | 749 | String WebServer::header(String name) 750 | { 751 | for (int i = 0; i < _headerKeysCount; ++i) 752 | { 753 | if (_currentHeaders[i].key.equalsIgnoreCase(name)) 754 | return _currentHeaders[i].value; 755 | } 756 | 757 | return ""; 758 | } 759 | 760 | void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) 761 | { 762 | _headerKeysCount = headerKeysCount + 1; 763 | 764 | if (_currentHeaders) 765 | delete[]_currentHeaders; 766 | 767 | _currentHeaders = new RequestArgument[_headerKeysCount]; 768 | _currentHeaders[0].key = FPSTR(AUTHORIZATION_HEADER); 769 | 770 | for (int i = 1; i < _headerKeysCount; i++) 771 | { 772 | _currentHeaders[i].key = headerKeys[i - 1]; 773 | } 774 | } 775 | 776 | String WebServer::header(int i) 777 | { 778 | if (i < _headerKeysCount) 779 | return _currentHeaders[i].value; 780 | 781 | return ""; 782 | } 783 | 784 | String WebServer::headerName(int i) 785 | { 786 | if (i < _headerKeysCount) 787 | return _currentHeaders[i].key; 788 | 789 | return ""; 790 | } 791 | 792 | int WebServer::headers() 793 | { 794 | return _headerKeysCount; 795 | } 796 | 797 | bool WebServer::hasHeader(String name) 798 | { 799 | for (int i = 0; i < _headerKeysCount; ++i) 800 | { 801 | if ((_currentHeaders[i].key.equalsIgnoreCase(name)) && (_currentHeaders[i].value.length() > 0)) 802 | return true; 803 | } 804 | 805 | return false; 806 | } 807 | 808 | String WebServer::hostHeader() 809 | { 810 | return _hostHeader; 811 | } 812 | 813 | void WebServer::onFileUpload(THandlerFunction fn) 814 | { 815 | _fileUploadHandler = fn; 816 | } 817 | 818 | void WebServer::onNotFound(THandlerFunction fn) 819 | { 820 | _notFoundHandler = fn; 821 | } 822 | 823 | void WebServer::_handleRequest() 824 | { 825 | bool handled = false; 826 | 827 | if (!_currentHandler) 828 | { 829 | log_e("request handler not found"); 830 | } 831 | else 832 | { 833 | handled = _currentHandler->handle(*this, _currentMethod, _currentUri); 834 | 835 | if (!handled) 836 | { 837 | log_e("request handler failed to handle request"); 838 | } 839 | } 840 | 841 | if (!handled && _notFoundHandler) 842 | { 843 | _notFoundHandler(); 844 | handled = true; 845 | } 846 | 847 | if (!handled) 848 | { 849 | using namespace mime; 850 | send(404, String(FPSTR(mimeTable[html].mimeType)), String(F("Not found: ")) + _currentUri); 851 | handled = true; 852 | } 853 | 854 | if (handled) 855 | { 856 | _finalizeResponse(); 857 | } 858 | 859 | _currentUri = ""; 860 | } 861 | 862 | 863 | void WebServer::_finalizeResponse() 864 | { 865 | if (_chunked) 866 | { 867 | sendContent(""); 868 | } 869 | } 870 | 871 | String WebServer::_responseCodeToString(int code) 872 | { 873 | switch (code) 874 | { 875 | case 100: 876 | return F("Continue"); 877 | 878 | case 101: 879 | return F("Switching Protocols"); 880 | 881 | case 200: 882 | return F("OK"); 883 | 884 | case 201: 885 | return F("Created"); 886 | 887 | case 202: 888 | return F("Accepted"); 889 | 890 | case 203: 891 | return F("Non-Authoritative Information"); 892 | 893 | case 204: 894 | return F("No Content"); 895 | 896 | case 205: 897 | return F("Reset Content"); 898 | 899 | case 206: 900 | return F("Partial Content"); 901 | 902 | case 300: 903 | return F("Multiple Choices"); 904 | 905 | case 301: 906 | return F("Moved Permanently"); 907 | 908 | case 302: 909 | return F("Found"); 910 | 911 | case 303: 912 | return F("See Other"); 913 | 914 | case 304: 915 | return F("Not Modified"); 916 | 917 | case 305: 918 | return F("Use Proxy"); 919 | 920 | case 307: 921 | return F("Temporary Redirect"); 922 | 923 | case 400: 924 | return F("Bad Request"); 925 | 926 | case 401: 927 | return F("Unauthorized"); 928 | 929 | case 402: 930 | return F("Payment Required"); 931 | 932 | case 403: 933 | return F("Forbidden"); 934 | 935 | case 404: 936 | return F("Not Found"); 937 | 938 | case 405: 939 | return F("Method Not Allowed"); 940 | 941 | case 406: 942 | return F("Not Acceptable"); 943 | 944 | case 407: 945 | return F("Proxy Authentication Required"); 946 | 947 | case 408: 948 | return F("Request Time-out"); 949 | 950 | case 409: 951 | return F("Conflict"); 952 | 953 | case 410: 954 | return F("Gone"); 955 | 956 | case 411: 957 | return F("Length Required"); 958 | 959 | case 412: 960 | return F("Precondition Failed"); 961 | 962 | case 413: 963 | return F("Request Entity Too Large"); 964 | 965 | case 414: 966 | return F("Request-URI Too Large"); 967 | 968 | case 415: 969 | return F("Unsupported Media Type"); 970 | 971 | case 416: 972 | return F("Requested range not satisfiable"); 973 | 974 | case 417: 975 | return F("Expectation Failed"); 976 | 977 | case 500: 978 | return F("Internal Server Error"); 979 | 980 | case 501: 981 | return F("Not Implemented"); 982 | 983 | case 502: 984 | return F("Bad Gateway"); 985 | 986 | case 503: 987 | return F("Service Unavailable"); 988 | 989 | case 504: 990 | return F("Gateway Time-out"); 991 | 992 | case 505: 993 | return F("HTTP Version not supported"); 994 | 995 | default: 996 | return F(""); 997 | } 998 | } 999 | -------------------------------------------------------------------------------- /esp32s2_WebServer_Patch/WebServer.h: -------------------------------------------------------------------------------- 1 | /* 2 | WebServer.h - Dead simple web-server. 3 | Supports only one simultaneous client, knows how to handle GET and POST. 4 | 5 | Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) 21 | */ 22 | 23 | 24 | #ifndef WEBSERVER_H 25 | #define WEBSERVER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include "HTTP_Method.h" 31 | #include "Uri.h" 32 | 33 | enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, 34 | UPLOAD_FILE_ABORTED 35 | }; 36 | enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE }; 37 | enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH }; 38 | 39 | #define HTTP_DOWNLOAD_UNIT_SIZE 1436 40 | 41 | #ifndef HTTP_UPLOAD_BUFLEN 42 | #define HTTP_UPLOAD_BUFLEN 1436 43 | #endif 44 | 45 | #define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request 46 | #define HTTP_MAX_POST_WAIT 5000 //ms to wait for POST data to arrive 47 | #define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed 48 | #define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection 49 | 50 | #define CONTENT_LENGTH_UNKNOWN ((size_t) -1) 51 | #define CONTENT_LENGTH_NOT_SET ((size_t) -2) 52 | 53 | class WebServer; 54 | 55 | typedef struct 56 | { 57 | HTTPUploadStatus status; 58 | String filename; 59 | String name; 60 | String type; 61 | size_t totalSize; // file size 62 | size_t currentSize; // size of data currently in buf 63 | uint8_t buf[HTTP_UPLOAD_BUFLEN]; 64 | } HTTPUpload; 65 | 66 | #include "detail/RequestHandler.h" 67 | 68 | namespace fs 69 | { 70 | class FS; 71 | } 72 | 73 | class WebServer 74 | { 75 | public: 76 | WebServer(IPAddress addr, int port = 80); 77 | WebServer(int port = 80); 78 | virtual ~WebServer(); 79 | 80 | virtual void begin(); 81 | virtual void begin(uint16_t port); 82 | virtual void handleClient(); 83 | 84 | virtual void close(); 85 | void stop(); 86 | 87 | bool authenticate(const char * username, const char * password); 88 | void requestAuthentication(HTTPAuthMethod mode = BASIC_AUTH, const char* realm = NULL, 89 | const String& authFailMsg = String("") ); 90 | 91 | typedef std::function THandlerFunction; 92 | void on(const Uri &uri, THandlerFunction handler); 93 | void on(const Uri &uri, HTTPMethod method, THandlerFunction fn); 94 | void on(const Uri &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn); 95 | void addHandler(RequestHandler* handler); 96 | void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL ); 97 | void onNotFound(THandlerFunction fn); //called when handler is not assigned 98 | void onFileUpload(THandlerFunction fn); //handle file uploads 99 | 100 | String uri() 101 | { 102 | return _currentUri; 103 | } 104 | HTTPMethod method() 105 | { 106 | return _currentMethod; 107 | } 108 | virtual WiFiClient client() 109 | { 110 | return _currentClient; 111 | } 112 | HTTPUpload& upload() 113 | { 114 | return *_currentUpload; 115 | } 116 | 117 | String pathArg(unsigned int i); // get request path argument by number 118 | String arg(String name); // get request argument value by name 119 | String arg(int i); // get request argument value by number 120 | String argName(int i); // get request argument name by number 121 | int args(); // get arguments count 122 | bool hasArg(String name); // check if argument exists 123 | void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect 124 | String header(String name); // get request header value by name 125 | String header(int i); // get request header value by number 126 | String headerName(int i); // get request header name by number 127 | int headers(); // get header count 128 | bool hasHeader(String name); // check if header exists 129 | 130 | String hostHeader(); // get request host header if available or empty String if not 131 | 132 | // send response to the client 133 | // code - HTTP response code, can be 200 or 404 134 | // content_type - HTTP content type, like "text/plain" or "image/png" 135 | // content - actual content body 136 | void send(int code, const char* content_type = NULL, const String& content = String("")); 137 | void send(int code, char* content_type, const String& content); 138 | void send(int code, const String& content_type, const String& content); 139 | void send_P(int code, PGM_P content_type, PGM_P content); 140 | void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength); 141 | 142 | void enableDelay(boolean value); 143 | void enableCORS(boolean value = true); 144 | void enableCrossOrigin(boolean value = true); 145 | 146 | void setContentLength(const size_t contentLength); 147 | void sendHeader(const String& name, const String& value, bool first = false); 148 | void sendContent(const String& content); 149 | void sendContent(const char* content, size_t contentLength); 150 | void sendContent_P(PGM_P content); 151 | void sendContent_P(PGM_P content, size_t size); 152 | 153 | static String urlDecode(const String& text); 154 | 155 | template 156 | size_t streamFile(T &file, const String& contentType) 157 | { 158 | _streamFileCore(file.size(), file.name(), contentType); 159 | return _currentClient.write(file); 160 | } 161 | 162 | protected: 163 | virtual size_t _currentClientWrite(const char* b, size_t l) 164 | { 165 | return _currentClient.write( b, l ); 166 | } 167 | virtual size_t _currentClientWrite_P(PGM_P b, size_t l) 168 | { 169 | return _currentClient.write_P( b, l ); 170 | } 171 | void _addRequestHandler(RequestHandler* handler); 172 | void _handleRequest(); 173 | void _finalizeResponse(); 174 | bool _parseRequest(WiFiClient& client); 175 | void _parseArguments(String data); 176 | static String _responseCodeToString(int code); 177 | bool _parseForm(WiFiClient& client, String boundary, uint32_t len); 178 | bool _parseFormUploadAborted(); 179 | void _uploadWriteByte(uint8_t b); 180 | int _uploadReadByte(WiFiClient& client); 181 | void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength); 182 | bool _collectHeader(const char* headerName, const char* headerValue); 183 | 184 | void _streamFileCore(const size_t fileSize, const String & fileName, const String & contentType); 185 | 186 | String _getRandomHexString(); 187 | // for extracting Auth parameters 188 | String _extractParam(String& authReq, const String& param, const char delimit = '"'); 189 | 190 | struct RequestArgument 191 | { 192 | String key; 193 | String value; 194 | }; 195 | 196 | boolean _corsEnabled; 197 | WiFiServer _server; 198 | 199 | WiFiClient _currentClient; 200 | HTTPMethod _currentMethod; 201 | String _currentUri; 202 | uint8_t _currentVersion; 203 | HTTPClientStatus _currentStatus; 204 | unsigned long _statusChange; 205 | bool _nullDelay; 206 | 207 | RequestHandler* _currentHandler; 208 | RequestHandler* _firstHandler; 209 | RequestHandler* _lastHandler; 210 | THandlerFunction _notFoundHandler; 211 | THandlerFunction _fileUploadHandler; 212 | 213 | int _currentArgCount; 214 | RequestArgument* _currentArgs; 215 | int _postArgsLen; 216 | RequestArgument* _postArgs; 217 | 218 | std::unique_ptr _currentUpload; 219 | 220 | int _headerKeysCount; 221 | RequestArgument* _currentHeaders; 222 | size_t _contentLength; 223 | String _responseHeaders; 224 | 225 | String _hostHeader; 226 | bool _chunked; 227 | 228 | String _snonce; // Store noance and opaque for future comparison 229 | String _sopaque; 230 | String _srealm; // Store the Auth realm between Calls 231 | 232 | }; 233 | 234 | 235 | #endif //ESP8266WEBSERVER_H 236 | -------------------------------------------------------------------------------- /examples/AutoConnect/AutoConnect.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | AutoConnect.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy 6 | configuration and reconfiguration of WiFi credentials using a Captive Portal. 7 | 8 | Modified from Tzapu https://github.com/tzapu/WiFiManager 9 | and from Ken Taylor https://github.com/kentaylor 10 | 11 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 12 | Licensed under MIT license 13 | *****************************************************************************************************************************/ 14 | #if !( defined(ESP8266) || defined(ESP32) ) 15 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 16 | #endif 17 | 18 | #define ESP_WIFIMANAGER_VERSION_MIN_TARGET "ESP_WiFiManager v1.12.0" 19 | #define ESP_WIFIMANAGER_VERSION_MIN 1012000 20 | 21 | // Use from 0 to 4. Higher number, more debugging messages and memory usage. 22 | #define _WIFIMGR_LOGLEVEL_ 1 23 | 24 | // To not display stored SSIDs and PWDs on Config Portal, select false. Default is true 25 | // Even the stored Credentials are not display, just leave them all blank to reconnect and reuse the stored Credentials 26 | //#define DISPLAY_STORED_CREDENTIALS_IN_CP false 27 | 28 | //Ported to ESP32 29 | #ifdef ESP32 30 | #include 31 | #include 32 | #include 33 | 34 | // From v1.1.0 35 | #include 36 | WiFiMulti wifiMulti; 37 | 38 | // LittleFS has higher priority than SPIFFS 39 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 40 | #define USE_LITTLEFS true 41 | #define USE_SPIFFS false 42 | #elif defined(ARDUINO_ESP32C3_DEV) 43 | // For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS 44 | #define USE_LITTLEFS false 45 | #define USE_SPIFFS true 46 | #endif 47 | 48 | #if USE_LITTLEFS 49 | // Use LittleFS 50 | #include "FS.h" 51 | 52 | // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h 53 | //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) 54 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 55 | #if (_WIFIMGR_LOGLEVEL_ > 3) 56 | #warning Using ESP32 Core 1.0.6 or 2.0.0+ 57 | #endif 58 | 59 | // The library has been merged into esp32 core from release 1.0.6 60 | #include // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS 61 | 62 | FS* filesystem = &LittleFS; 63 | #define FileFS LittleFS 64 | #define FS_Name "LittleFS" 65 | #else 66 | #if (_WIFIMGR_LOGLEVEL_ > 3) 67 | #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library 68 | #endif 69 | 70 | // The library has been merged into esp32 core from release 1.0.6 71 | #include // https://github.com/lorol/LITTLEFS 72 | 73 | FS* filesystem = &LITTLEFS; 74 | #define FileFS LITTLEFS 75 | #define FS_Name "LittleFS" 76 | #endif 77 | 78 | #elif USE_SPIFFS 79 | #include 80 | FS* filesystem = &SPIFFS; 81 | #define FileFS SPIFFS 82 | #define FS_Name "SPIFFS" 83 | #else 84 | // Use FFat 85 | #include 86 | FS* filesystem = &FFat; 87 | #define FileFS FFat 88 | #define FS_Name "FFat" 89 | #endif 90 | ////// 91 | 92 | #define LED_BUILTIN 2 93 | #define LED_ON HIGH 94 | #define LED_OFF LOW 95 | 96 | #else 97 | 98 | #include //https://github.com/esp8266/Arduino 99 | //needed for library 100 | #include 101 | #include 102 | 103 | // From v1.1.0 104 | #include 105 | ESP8266WiFiMulti wifiMulti; 106 | 107 | #include 108 | 109 | #define USE_LITTLEFS true 110 | 111 | #if USE_LITTLEFS 112 | #include 113 | FS* filesystem = &LittleFS; 114 | #define FileFS LittleFS 115 | #define FS_Name "LittleFS" 116 | #else 117 | FS* filesystem = &SPIFFS; 118 | #define FileFS SPIFFS 119 | #define FS_Name "SPIFFS" 120 | #endif 121 | ////// 122 | 123 | #define ESP_getChipId() (ESP.getChipId()) 124 | 125 | #define LED_ON LOW 126 | #define LED_OFF HIGH 127 | #endif 128 | 129 | // You only need to format the filesystem once 130 | //#define FORMAT_FILESYSTEM true 131 | #define FORMAT_FILESYSTEM false 132 | 133 | // SSID and PW for your Router 134 | String Router_SSID; 135 | String Router_Pass; 136 | 137 | // From v1.1.0 138 | #define MIN_AP_PASSWORD_SIZE 8 139 | 140 | #define SSID_MAX_LEN 32 141 | //From v1.0.10, WPA2 passwords can be up to 63 characters long. 142 | #define PASS_MAX_LEN 64 143 | 144 | typedef struct 145 | { 146 | char wifi_ssid[SSID_MAX_LEN]; 147 | char wifi_pw [PASS_MAX_LEN]; 148 | } WiFi_Credentials; 149 | 150 | typedef struct 151 | { 152 | String wifi_ssid; 153 | String wifi_pw; 154 | } WiFi_Credentials_String; 155 | 156 | #define NUM_WIFI_CREDENTIALS 2 157 | 158 | // Assuming max 491 chars 159 | #define TZNAME_MAX_LEN 50 160 | #define TIMEZONE_MAX_LEN 50 161 | 162 | typedef struct 163 | { 164 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 165 | char TZ_Name[TZNAME_MAX_LEN]; // "America/Toronto" 166 | char TZ[TIMEZONE_MAX_LEN]; // "EST5EDT,M3.2.0,M11.1.0" 167 | uint16_t checksum; 168 | } WM_Config; 169 | 170 | WM_Config WM_config; 171 | 172 | #define CONFIG_FILENAME F("/wifi_cred.dat") 173 | 174 | // Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected 175 | bool initialConfig = false; 176 | ////// 177 | 178 | // Use false if you don't like to display Available Pages in Information Page of Config Portal 179 | // Comment out or use true to display Available Pages in Information Page of Config Portal 180 | // Must be placed before #include 181 | #define USE_AVAILABLE_PAGES false 182 | 183 | // From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used. 184 | // You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa 185 | // You have to explicitly specify false to disable the feature. 186 | //#define USE_STATIC_IP_CONFIG_IN_CP false 187 | 188 | // Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal. 189 | // See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23) 190 | #define USE_ESP_WIFIMANAGER_NTP true 191 | 192 | // Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen 193 | // if using too much memory 194 | #define USING_AFRICA false 195 | #define USING_AMERICA true 196 | #define USING_ANTARCTICA false 197 | #define USING_ASIA false 198 | #define USING_ATLANTIC false 199 | #define USING_AUSTRALIA false 200 | #define USING_EUROPE false 201 | #define USING_INDIAN false 202 | #define USING_PACIFIC false 203 | #define USING_ETC_GMT false 204 | 205 | // Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare 206 | // See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21) 207 | #define USE_CLOUDFLARE_NTP false 208 | 209 | // New in v1.0.11 210 | #define USING_CORS_FEATURE true 211 | 212 | //////////////////////////////////////////// 213 | 214 | // Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network 215 | #if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP) 216 | // Force DHCP to be true 217 | #if defined(USE_DHCP_IP) 218 | #undef USE_DHCP_IP 219 | #endif 220 | #define USE_DHCP_IP true 221 | #else 222 | // You can select DHCP or Static IP here 223 | #define USE_DHCP_IP true 224 | //#define USE_DHCP_IP false 225 | #endif 226 | 227 | #if ( USE_DHCP_IP ) 228 | // Use DHCP 229 | 230 | #if (_WIFIMGR_LOGLEVEL_ > 3) 231 | #warning Using DHCP IP 232 | #endif 233 | 234 | IPAddress stationIP = IPAddress(0, 0, 0, 0); 235 | IPAddress gatewayIP = IPAddress(192, 168, 2, 1); 236 | IPAddress netMask = IPAddress(255, 255, 255, 0); 237 | 238 | #else 239 | // Use static IP 240 | 241 | #if (_WIFIMGR_LOGLEVEL_ > 3) 242 | #warning Using static IP 243 | #endif 244 | 245 | #ifdef ESP32 246 | IPAddress stationIP = IPAddress(192, 168, 2, 232); 247 | #else 248 | IPAddress stationIP = IPAddress(192, 168, 2, 186); 249 | #endif 250 | 251 | IPAddress gatewayIP = IPAddress(192, 168, 2, 1); 252 | IPAddress netMask = IPAddress(255, 255, 255, 0); 253 | #endif 254 | 255 | //////////////////////////////////////////// 256 | 257 | #define USE_CONFIGURABLE_DNS true 258 | 259 | IPAddress dns1IP = gatewayIP; 260 | IPAddress dns2IP = IPAddress(8, 8, 8, 8); 261 | 262 | #define USE_CUSTOM_AP_IP false 263 | 264 | // New in v1.4.0 265 | IPAddress APStaticIP = IPAddress(192, 168, 100, 1); 266 | IPAddress APStaticGW = IPAddress(192, 168, 100, 1); 267 | IPAddress APStaticSN = IPAddress(255, 255, 255, 0); 268 | ////// 269 | 270 | // Must be placed before #include , or default port 80 will be used 271 | //#define HTTP_PORT 8080 272 | 273 | #include //https://github.com/khoih-prog/ESP_WiFiManager 274 | 275 | // Redundant, for v1.8.0 only 276 | //#include //https://github.com/khoih-prog/ESP_WiFiManager 277 | 278 | // Function Prototypes 279 | uint8_t connectMultiWiFi(); 280 | 281 | /////////////////////////////////////////// 282 | // New in v1.4.0 283 | /****************************************** 284 | * // Defined in ESPAsync_WiFiManager.h 285 | typedef struct 286 | { 287 | IPAddress _ap_static_ip; 288 | IPAddress _ap_static_gw; 289 | IPAddress _ap_static_sn; 290 | 291 | } WiFi_AP_IPConfig; 292 | 293 | typedef struct 294 | { 295 | IPAddress _sta_static_ip; 296 | IPAddress _sta_static_gw; 297 | IPAddress _sta_static_sn; 298 | #if USE_CONFIGURABLE_DNS 299 | IPAddress _sta_static_dns1; 300 | IPAddress _sta_static_dns2; 301 | #endif 302 | } WiFi_STA_IPConfig; 303 | ******************************************/ 304 | 305 | WiFi_AP_IPConfig WM_AP_IPconfig; 306 | WiFi_STA_IPConfig WM_STA_IPconfig; 307 | 308 | void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig) 309 | { 310 | in_WM_AP_IPconfig._ap_static_ip = APStaticIP; 311 | in_WM_AP_IPconfig._ap_static_gw = APStaticGW; 312 | in_WM_AP_IPconfig._ap_static_sn = APStaticSN; 313 | } 314 | 315 | void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig) 316 | { 317 | in_WM_STA_IPconfig._sta_static_ip = stationIP; 318 | in_WM_STA_IPconfig._sta_static_gw = gatewayIP; 319 | in_WM_STA_IPconfig._sta_static_sn = netMask; 320 | #if USE_CONFIGURABLE_DNS 321 | in_WM_STA_IPconfig._sta_static_dns1 = dns1IP; 322 | in_WM_STA_IPconfig._sta_static_dns2 = dns2IP; 323 | #endif 324 | } 325 | 326 | void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig) 327 | { 328 | LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip, ", gatewayIP =", in_WM_STA_IPconfig._sta_static_gw); 329 | LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn); 330 | #if USE_CONFIGURABLE_DNS 331 | LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1, ", dns2IP =", in_WM_STA_IPconfig._sta_static_dns2); 332 | #endif 333 | } 334 | 335 | void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig) 336 | { 337 | #if USE_CONFIGURABLE_DNS 338 | // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5 339 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2); 340 | #else 341 | // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2. 342 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn); 343 | #endif 344 | } 345 | 346 | /////////////////////////////////////////// 347 | 348 | uint8_t connectMultiWiFi() 349 | { 350 | #if ESP32 351 | // For ESP32, this better be 0 to shorten the connect time. 352 | // For ESP32-S2/C3, must be > 500 353 | #if ( USING_ESP32_S2 || USING_ESP32_C3 ) 354 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 500L 355 | #else 356 | // For ESP32 core v1.0.6, must be >= 500 357 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 800L 358 | #endif 359 | #else 360 | // For ESP8266, this better be 2200 to enable connect the 1st time 361 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L 362 | #endif 363 | 364 | #define WIFI_MULTI_CONNECT_WAITING_MS 500L 365 | 366 | uint8_t status; 367 | 368 | //WiFi.mode(WIFI_STA); 369 | 370 | LOGERROR(F("ConnectMultiWiFi with :")); 371 | 372 | if ( (Router_SSID != "") && (Router_Pass != "") ) 373 | { 374 | LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass ); 375 | LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass ); 376 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 377 | } 378 | 379 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 380 | { 381 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 382 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 383 | { 384 | LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 385 | } 386 | } 387 | 388 | LOGERROR(F("Connecting MultiWifi...")); 389 | 390 | //WiFi.mode(WIFI_STA); 391 | 392 | #if !USE_DHCP_IP 393 | // New in v1.4.0 394 | configWiFi(WM_STA_IPconfig); 395 | ////// 396 | #endif 397 | 398 | int i = 0; 399 | 400 | status = wifiMulti.run(); 401 | delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS); 402 | 403 | while ( ( i++ < 20 ) && ( status != WL_CONNECTED ) ) 404 | { 405 | status = WiFi.status(); 406 | 407 | if ( status == WL_CONNECTED ) 408 | break; 409 | else 410 | delay(WIFI_MULTI_CONNECT_WAITING_MS); 411 | } 412 | 413 | if ( status == WL_CONNECTED ) 414 | { 415 | LOGERROR1(F("WiFi connected after time: "), i); 416 | LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI()); 417 | LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() ); 418 | } 419 | else 420 | { 421 | LOGERROR(F("WiFi not connected")); 422 | 423 | #if ESP8266 424 | ESP.reset(); 425 | #else 426 | ESP.restart(); 427 | #endif 428 | } 429 | 430 | return status; 431 | } 432 | 433 | #if USE_ESP_WIFIMANAGER_NTP 434 | 435 | void printLocalTime() 436 | { 437 | #if ESP8266 438 | static time_t now; 439 | 440 | now = time(nullptr); 441 | 442 | if ( now > 1451602800 ) 443 | { 444 | Serial.print("Local Date/Time: "); 445 | Serial.print(ctime(&now)); 446 | } 447 | #else 448 | struct tm timeinfo; 449 | 450 | getLocalTime( &timeinfo ); 451 | 452 | // Valid only if year > 2000. 453 | // You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec 454 | if (timeinfo.tm_year > 100 ) 455 | { 456 | Serial.print("Local Date/Time: "); 457 | Serial.print( asctime( &timeinfo ) ); 458 | } 459 | #endif 460 | } 461 | 462 | #endif 463 | 464 | void heartBeatPrint() 465 | { 466 | #if USE_ESP_WIFIMANAGER_NTP 467 | printLocalTime(); 468 | #else 469 | static int num = 1; 470 | 471 | if (WiFi.status() == WL_CONNECTED) 472 | Serial.print(F("H")); // H means connected to WiFi 473 | else 474 | Serial.print(F("F")); // F means not connected to WiFi 475 | 476 | if (num == 80) 477 | { 478 | Serial.println(); 479 | num = 1; 480 | } 481 | else if (num++ % 10 == 0) 482 | { 483 | Serial.print(F(" ")); 484 | } 485 | #endif 486 | } 487 | 488 | void check_WiFi() 489 | { 490 | if ( (WiFi.status() != WL_CONNECTED) ) 491 | { 492 | Serial.println(F("\nWiFi lost. Call connectMultiWiFi in loop")); 493 | connectMultiWiFi(); 494 | } 495 | } 496 | 497 | void check_status() 498 | { 499 | static ulong checkstatus_timeout = 0; 500 | static ulong checkwifi_timeout = 0; 501 | 502 | static ulong current_millis; 503 | 504 | #define WIFICHECK_INTERVAL 1000L 505 | 506 | #if USE_ESP_WIFIMANAGER_NTP 507 | #define HEARTBEAT_INTERVAL 60000L 508 | #else 509 | #define HEARTBEAT_INTERVAL 10000L 510 | #endif 511 | 512 | current_millis = millis(); 513 | 514 | // Check WiFi every WIFICHECK_INTERVAL (1) seconds. 515 | if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0)) 516 | { 517 | check_WiFi(); 518 | checkwifi_timeout = current_millis + WIFICHECK_INTERVAL; 519 | } 520 | 521 | // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds. 522 | if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0)) 523 | { 524 | heartBeatPrint(); 525 | checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL; 526 | } 527 | } 528 | 529 | int calcChecksum(uint8_t* address, uint16_t sizeToCalc) 530 | { 531 | uint16_t checkSum = 0; 532 | 533 | for (uint16_t index = 0; index < sizeToCalc; index++) 534 | { 535 | checkSum += * ( ( (byte*) address ) + index); 536 | } 537 | 538 | return checkSum; 539 | } 540 | 541 | bool loadConfigData() 542 | { 543 | File file = FileFS.open(CONFIG_FILENAME, "r"); 544 | LOGERROR(F("LoadWiFiCfgFile ")); 545 | 546 | memset((void *) &WM_config, 0, sizeof(WM_config)); 547 | 548 | // New in v1.4.0 549 | memset((void *) &WM_STA_IPconfig, 0, sizeof(WM_STA_IPconfig)); 550 | ////// 551 | 552 | if (file) 553 | { 554 | file.readBytes((char *) &WM_config, sizeof(WM_config)); 555 | 556 | // New in v1.4.0 557 | file.readBytes((char *) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 558 | ////// 559 | 560 | file.close(); 561 | LOGERROR(F("OK")); 562 | 563 | if ( WM_config.checksum != calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ) ) 564 | { 565 | LOGERROR(F("WM_config checksum wrong")); 566 | 567 | return false; 568 | } 569 | 570 | // New in v1.4.0 571 | displayIPConfigStruct(WM_STA_IPconfig); 572 | ////// 573 | 574 | return true; 575 | } 576 | else 577 | { 578 | LOGERROR(F("failed")); 579 | 580 | return false; 581 | } 582 | } 583 | 584 | void saveConfigData() 585 | { 586 | File file = FileFS.open(CONFIG_FILENAME, "w"); 587 | LOGERROR(F("SaveWiFiCfgFile ")); 588 | 589 | if (file) 590 | { 591 | WM_config.checksum = calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ); 592 | 593 | file.write((uint8_t*) &WM_config, sizeof(WM_config)); 594 | 595 | displayIPConfigStruct(WM_STA_IPconfig); 596 | 597 | // New in v1.4.0 598 | file.write((uint8_t*) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 599 | ////// 600 | 601 | file.close(); 602 | LOGERROR(F("OK")); 603 | } 604 | else 605 | { 606 | LOGERROR(F("failed")); 607 | } 608 | } 609 | 610 | void setup() 611 | { 612 | // put your setup code here, to run once: 613 | Serial.begin(115200); 614 | while (!Serial); 615 | 616 | delay(200); 617 | 618 | Serial.print(F("\nStarting AutoConnectAP using ")); Serial.print(FS_Name); 619 | Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD); 620 | Serial.println(ESP_WIFIMANAGER_VERSION); 621 | 622 | #if defined(ESP_WIFIMANAGER_VERSION_MIN) 623 | if (ESP_WIFIMANAGER_VERSION_INT < ESP_WIFIMANAGER_VERSION_MIN) 624 | { 625 | Serial.print("Warning. Must use this example on Version later than : "); 626 | Serial.println(ESP_WIFIMANAGER_VERSION_MIN_TARGET); 627 | } 628 | #endif 629 | 630 | if (FORMAT_FILESYSTEM) 631 | FileFS.format(); 632 | 633 | // Format FileFS if not yet 634 | #ifdef ESP32 635 | if (!FileFS.begin(true)) 636 | #else 637 | if (!FileFS.begin()) 638 | #endif 639 | { 640 | #ifdef ESP8266 641 | FileFS.format(); 642 | #endif 643 | 644 | Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting.")); 645 | 646 | if (!FileFS.begin()) 647 | { 648 | // prevents debug info from the library to hide err message. 649 | delay(100); 650 | 651 | #if USE_LITTLEFS 652 | Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever")); 653 | #else 654 | Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever")); 655 | #endif 656 | 657 | while (true) 658 | { 659 | delay(1); 660 | } 661 | } 662 | } 663 | 664 | unsigned long startedAt = millis(); 665 | 666 | // New in v1.4.0 667 | initAPIPConfigStruct(WM_AP_IPconfig); 668 | initSTAIPConfigStruct(WM_STA_IPconfig); 669 | ////// 670 | 671 | // Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX 672 | //ESP_WiFiManager ESP_wifiManager; 673 | // Use this to personalize DHCP hostname (RFC952 conformed) 674 | ESP_WiFiManager ESP_wifiManager("AutoConnectAP"); 675 | 676 | ESP_wifiManager.setDebugOutput(true); 677 | 678 | //reset settings - for testing 679 | //ESP_wifiManager.resetSettings(); 680 | 681 | #if USE_CUSTOM_AP_IP 682 | //set custom ip for portal 683 | // New in v1.4.0 684 | ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig); 685 | ////// 686 | #endif 687 | 688 | ESP_wifiManager.setMinimumSignalQuality(-1); 689 | 690 | // From v1.0.10 only 691 | // Set config portal channel, default = 1. Use 0 => random channel from 1-13 692 | ESP_wifiManager.setConfigPortalChannel(0); 693 | ////// 694 | 695 | #if !USE_DHCP_IP 696 | // Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5 697 | // New in v1.4.0 698 | ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig); 699 | ////// 700 | #endif 701 | 702 | // New from v1.1.1 703 | #if USING_CORS_FEATURE 704 | ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin"); 705 | #endif 706 | 707 | // We can't use WiFi.SSID() in ESP32 as it's only valid after connected. 708 | // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot 709 | // Have to create a new function to store in EEPROM/SPIFFS for this purpose 710 | Router_SSID = ESP_wifiManager.WiFi_SSID(); 711 | Router_Pass = ESP_wifiManager.WiFi_Pass(); 712 | 713 | //Remove this line if you do not want to see WiFi password printed 714 | Serial.println("ESP Self-Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass); 715 | 716 | bool configDataLoaded = false; 717 | 718 | // From v1.1.0, Don't permit NULL password 719 | if ( (Router_SSID != "") && (Router_Pass != "") ) 720 | { 721 | LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass); 722 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 723 | 724 | ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout. 725 | Serial.println(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal")); 726 | } 727 | 728 | if (loadConfigData()) 729 | { 730 | configDataLoaded = true; 731 | 732 | ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout. 733 | Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal")); 734 | 735 | #if USE_ESP_WIFIMANAGER_NTP 736 | if ( strlen(WM_config.TZ_Name) > 0 ) 737 | { 738 | LOGERROR3(F("Current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ); 739 | 740 | #if ESP8266 741 | configTime(WM_config.TZ, "pool.ntp.org"); 742 | #else 743 | //configTzTime(WM_config.TZ, "pool.ntp.org" ); 744 | configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); 745 | #endif 746 | } 747 | else 748 | { 749 | Serial.println(F("Current Timezone is not set. Enter Config Portal to set.")); 750 | } 751 | #endif 752 | } 753 | else 754 | { 755 | // Enter CP only if no stored SSID on flash and file 756 | Serial.println(F("Open Config Portal without Timeout: No stored Credentials.")); 757 | initialConfig = true; 758 | } 759 | 760 | String chipID = String(ESP_getChipId(), HEX); 761 | chipID.toUpperCase(); 762 | 763 | // SSID and PW for Config Portal 764 | String AP_SSID = "ESP_" + chipID + "_AutoConnectAP"; 765 | String AP_PASS = "MyESP_" + chipID; 766 | 767 | if (initialConfig) 768 | { 769 | Serial.print(F("Starting configuration portal @ ")); 770 | 771 | #if USE_CUSTOM_AP_IP 772 | Serial.print(APStaticIP); 773 | #else 774 | Serial.print(F("192.168.4.1")); 775 | #endif 776 | 777 | #if defined(HTTP_PORT_TO_USE) 778 | Serial.print(F(":")); Serial.print(HTTP_PORT_TO_USE); 779 | #endif 780 | 781 | Serial.print(F(", SSID = ")); 782 | Serial.print(AP_SSID); 783 | Serial.print(F(", PWD = ")); 784 | Serial.println(AP_PASS); 785 | 786 | initialConfig = true; 787 | 788 | #if DISPLAY_STORED_CREDENTIALS_IN_CP 789 | // New. Update Credentials, got from loadConfigData(), to display on CP 790 | ESP_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw, 791 | WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw); 792 | #endif 793 | 794 | // Starts an access point 795 | //if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password)) 796 | if ( !ESP_wifiManager.startConfigPortal(AP_SSID.c_str(), AP_PASS.c_str()) ) 797 | Serial.println(F("Not connected to WiFi but continuing anyway.")); 798 | else 799 | Serial.println(F("WiFi connected...yeey :)")); 800 | 801 | // Stored for later usage, from v1.1.0, but clear first 802 | memset(&WM_config, 0, sizeof(WM_config)); 803 | 804 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 805 | { 806 | String tempSSID = ESP_wifiManager.getSSID(i); 807 | String tempPW = ESP_wifiManager.getPW(i); 808 | 809 | if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1) 810 | strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str()); 811 | else 812 | strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1); 813 | 814 | if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1) 815 | strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str()); 816 | else 817 | strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1); 818 | 819 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 820 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 821 | { 822 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 823 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 824 | } 825 | } 826 | 827 | #if USE_ESP_WIFIMANAGER_NTP 828 | String tempTZ = ESP_wifiManager.getTimezoneName(); 829 | 830 | if (strlen(tempTZ.c_str()) < sizeof(WM_config.TZ_Name) - 1) 831 | strcpy(WM_config.TZ_Name, tempTZ.c_str()); 832 | else 833 | strncpy(WM_config.TZ_Name, tempTZ.c_str(), sizeof(WM_config.TZ_Name) - 1); 834 | 835 | const char * TZ_Result = ESP_wifiManager.getTZ(WM_config.TZ_Name); 836 | 837 | if (strlen(TZ_Result) < sizeof(WM_config.TZ) - 1) 838 | strcpy(WM_config.TZ, TZ_Result); 839 | else 840 | strncpy(WM_config.TZ, TZ_Result, sizeof(WM_config.TZ_Name) - 1); 841 | 842 | if ( strlen(WM_config.TZ_Name) > 0 ) 843 | { 844 | LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ); 845 | 846 | #if ESP8266 847 | configTime(WM_config.TZ, "pool.ntp.org"); 848 | #else 849 | //configTzTime(WM_config.TZ, "pool.ntp.org" ); 850 | configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); 851 | #endif 852 | } 853 | else 854 | { 855 | LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set.")); 856 | } 857 | #endif 858 | 859 | // New in v1.4.0 860 | ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig); 861 | ////// 862 | 863 | saveConfigData(); 864 | } 865 | else 866 | { 867 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 868 | } 869 | 870 | startedAt = millis(); 871 | 872 | if (!initialConfig) 873 | { 874 | // Load stored data, the addAP ready for MultiWiFi reconnection 875 | if (!configDataLoaded) 876 | loadConfigData(); 877 | 878 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 879 | { 880 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 881 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 882 | { 883 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 884 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 885 | } 886 | } 887 | 888 | if ( WiFi.status() != WL_CONNECTED ) 889 | { 890 | Serial.println(F("ConnectMultiWiFi in setup")); 891 | 892 | connectMultiWiFi(); 893 | } 894 | } 895 | 896 | Serial.print(F("After waiting ")); 897 | Serial.print((float) (millis() - startedAt) / 1000L); 898 | Serial.print(F(" secs more in setup(), connection result is ")); 899 | 900 | if (WiFi.status() == WL_CONNECTED) 901 | { 902 | Serial.print(F("connected. Local IP: ")); 903 | Serial.println(WiFi.localIP()); 904 | } 905 | else 906 | Serial.println(ESP_wifiManager.getStatus(WiFi.status())); 907 | } 908 | 909 | void loop() 910 | { 911 | // put your main code here, to run repeatedly 912 | check_status(); 913 | } 914 | -------------------------------------------------------------------------------- /examples/ConfigOnDoubleReset_Multi/ConfigOnDoubleReset_Multi.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnDoubleReset_Multi.cpp 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy 6 | configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by: 7 | http://www.esp8266.com/viewtopic.php?f=29&t=2520 8 | https://github.com/chriscook8/esp-arduino-apboot 9 | https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ 10 | 11 | Modified from Tzapu https://github.com/tzapu/WiFiManager 12 | and from Ken Taylor https://github.com/kentaylor 13 | 14 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 15 | Licensed under MIT license 16 | *****************************************************************************************************************************/ 17 | /**************************************************************************************************************************** 18 | This example will open a configuration portal when the reset button is pressed twice. 19 | This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal. 20 | 21 | How It Works 22 | 1) ESP8266 23 | Save data in RTC memory 24 | 2) ESP32 25 | Save data in EEPROM from address 256, size 512 bytes (both configurable) 26 | 27 | So when the device starts up it checks this region of ram for a flag to see if it has been recently reset. 28 | If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that 29 | it will only launch the configuration portal in response to closely spaced resets. 30 | 31 | Settings 32 | There are two values to be set in the sketch. 33 | 34 | DRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example. 35 | DRD_ADDRESS - The address in ESP8266 RTC RAM to store the flag. This memory must not be used for other purposes in the same sketch. Set to 0 in the example. 36 | 37 | This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector 38 | To support ESP32, use ESP_DoubleResetDetector library from //https://github.com/khoih-prog/ESP_DoubleResetDetector 39 | *****************************************************************************************************************************/ 40 | 41 | #if !( defined(ESP8266) || defined(ESP32) ) 42 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 43 | #endif 44 | 45 | #include "ConfigOnDoubleReset_Multi.h" 46 | 47 | //Ported to ESP32 48 | #ifdef ESP32 49 | WiFiMulti wifiMulti; 50 | 51 | #if USE_LITTLEFS 52 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 53 | FS* filesystem = &LittleFS; 54 | #else 55 | FS* filesystem = &LITTLEFS; 56 | #endif 57 | 58 | #elif USE_SPIFFS 59 | FS* filesystem = &SPIFFS; 60 | #else 61 | FS* filesystem = &FFat; 62 | #endif 63 | ////// 64 | 65 | #else 66 | 67 | ESP8266WiFiMulti wifiMulti; 68 | 69 | #if USE_LITTLEFS 70 | FS* filesystem = &LittleFS; 71 | #else 72 | FS* filesystem = &SPIFFS; 73 | #endif 74 | ////// 75 | 76 | #endif 77 | 78 | DoubleResetDetector* drd; 79 | 80 | // Onboard LED I/O pin on NodeMCU board 81 | const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED. 82 | 83 | // SSID and PW for Config Portal 84 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 85 | String password; 86 | 87 | // SSID and PW for your Router 88 | String Router_SSID; 89 | String Router_Pass; 90 | 91 | WM_Config WM_config; 92 | 93 | // Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected 94 | bool initialConfig = false; 95 | 96 | #if ( USE_DHCP_IP ) 97 | // Use DHCP 98 | 99 | #if (_WIFIMGR_LOGLEVEL_ > 3) 100 | #warning Using DHCP IP 101 | #endif 102 | 103 | IPAddress stationIP = IPAddress(0, 0, 0, 0); 104 | IPAddress gatewayIP = IPAddress(192, 168, 1, 1); 105 | IPAddress netMask = IPAddress(255, 255, 255, 0); 106 | #else 107 | // Use static IP 108 | 109 | #if (_WIFIMGR_LOGLEVEL_ > 3) 110 | #warning Using static IP 111 | #endif 112 | 113 | #ifdef ESP32 114 | IPAddress stationIP = IPAddress(192, 168, 2, 232); 115 | #else 116 | IPAddress stationIP = IPAddress(192, 168, 2, 186); 117 | #endif 118 | 119 | IPAddress gatewayIP = IPAddress(192, 168, 2, 1); 120 | IPAddress netMask = IPAddress(255, 255, 255, 0); 121 | #endif 122 | 123 | IPAddress dns1IP = gatewayIP; 124 | IPAddress dns2IP = IPAddress(8, 8, 8, 8); 125 | 126 | IPAddress APStaticIP = IPAddress(192, 168, 100, 1); 127 | IPAddress APStaticGW = IPAddress(192, 168, 100, 1); 128 | IPAddress APStaticSN = IPAddress(255, 255, 255, 0); 129 | 130 | /////////////////////////////////////////// 131 | // New in v1.4.0 132 | /****************************************** 133 | * // Defined in ESP_WiFiManager.h 134 | typedef struct 135 | { 136 | IPAddress _ap_static_ip; 137 | IPAddress _ap_static_gw; 138 | IPAddress _ap_static_sn; 139 | 140 | } WiFi_AP_IPConfig; 141 | 142 | typedef struct 143 | { 144 | IPAddress _sta_static_ip; 145 | IPAddress _sta_static_gw; 146 | IPAddress _sta_static_sn; 147 | #if USE_CONFIGURABLE_DNS 148 | IPAddress _sta_static_dns1; 149 | IPAddress _sta_static_dns2; 150 | #endif 151 | } WiFi_STA_IPConfig; 152 | ******************************************/ 153 | 154 | WiFi_AP_IPConfig WM_AP_IPconfig; 155 | WiFi_STA_IPConfig WM_STA_IPconfig; 156 | 157 | void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig) 158 | { 159 | in_WM_AP_IPconfig._ap_static_ip = APStaticIP; 160 | in_WM_AP_IPconfig._ap_static_gw = APStaticGW; 161 | in_WM_AP_IPconfig._ap_static_sn = APStaticSN; 162 | } 163 | 164 | void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig) 165 | { 166 | in_WM_STA_IPconfig._sta_static_ip = stationIP; 167 | in_WM_STA_IPconfig._sta_static_gw = gatewayIP; 168 | in_WM_STA_IPconfig._sta_static_sn = netMask; 169 | #if USE_CONFIGURABLE_DNS 170 | in_WM_STA_IPconfig._sta_static_dns1 = dns1IP; 171 | in_WM_STA_IPconfig._sta_static_dns2 = dns2IP; 172 | #endif 173 | } 174 | 175 | void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig) 176 | { 177 | LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip, ", gatewayIP =", in_WM_STA_IPconfig._sta_static_gw); 178 | LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn); 179 | #if USE_CONFIGURABLE_DNS 180 | LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1, ", dns2IP =", in_WM_STA_IPconfig._sta_static_dns2); 181 | #endif 182 | } 183 | 184 | void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig) 185 | { 186 | #if USE_CONFIGURABLE_DNS 187 | // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5 188 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2); 189 | #else 190 | // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2. 191 | WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn); 192 | #endif 193 | } 194 | 195 | /////////////////////////////////////////// 196 | 197 | uint8_t connectMultiWiFi() 198 | { 199 | #if ESP32 200 | // For ESP32, this better be 0 to shorten the connect time. 201 | // For ESP32-S2/C3, must be > 500 202 | #if ( USING_ESP32_S2 || USING_ESP32_C3 ) 203 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 500L 204 | #else 205 | // For ESP32 core v1.0.6, must be >= 500 206 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 800L 207 | #endif 208 | #else 209 | // For ESP8266, this better be 2200 to enable connect the 1st time 210 | #define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L 211 | #endif 212 | 213 | #define WIFI_MULTI_CONNECT_WAITING_MS 500L 214 | 215 | uint8_t status; 216 | 217 | //WiFi.mode(WIFI_STA); 218 | 219 | LOGERROR(F("ConnectMultiWiFi with :")); 220 | 221 | if ( (Router_SSID != "") && (Router_Pass != "") ) 222 | { 223 | LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass ); 224 | LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass ); 225 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 226 | } 227 | 228 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 229 | { 230 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 231 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 232 | { 233 | LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 234 | } 235 | } 236 | 237 | LOGERROR(F("Connecting MultiWifi...")); 238 | 239 | //WiFi.mode(WIFI_STA); 240 | 241 | #if !USE_DHCP_IP 242 | // New in v1.4.0 243 | configWiFi(WM_STA_IPconfig); 244 | ////// 245 | #endif 246 | 247 | int i = 0; 248 | 249 | status = wifiMulti.run(); 250 | delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS); 251 | 252 | while ( ( i++ < 20 ) && ( status != WL_CONNECTED ) ) 253 | { 254 | status = WiFi.status(); 255 | 256 | if ( status == WL_CONNECTED ) 257 | break; 258 | else 259 | delay(WIFI_MULTI_CONNECT_WAITING_MS); 260 | } 261 | 262 | if ( status == WL_CONNECTED ) 263 | { 264 | LOGERROR1(F("WiFi connected after time: "), i); 265 | LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI()); 266 | LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() ); 267 | } 268 | else 269 | { 270 | LOGERROR(F("WiFi not connected")); 271 | 272 | // To avoid unnecessary DRD 273 | drd->loop(); 274 | 275 | #if ESP8266 276 | ESP.reset(); 277 | #else 278 | ESP.restart(); 279 | #endif 280 | } 281 | 282 | return status; 283 | } 284 | 285 | #if USE_ESP_WIFIMANAGER_NTP 286 | 287 | void printLocalTime() 288 | { 289 | #if ESP8266 290 | static time_t now; 291 | 292 | now = time(nullptr); 293 | 294 | if ( now > 1451602800 ) 295 | { 296 | Serial.print("Local Date/Time: "); 297 | Serial.print(ctime(&now)); 298 | } 299 | #else 300 | struct tm timeinfo; 301 | 302 | getLocalTime( &timeinfo ); 303 | 304 | // Valid only if year > 2000. 305 | // You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec 306 | if (timeinfo.tm_year > 100 ) 307 | { 308 | Serial.print("Local Date/Time: "); 309 | Serial.print( asctime( &timeinfo ) ); 310 | } 311 | #endif 312 | } 313 | 314 | #endif 315 | 316 | void heartBeatPrint() 317 | { 318 | #if USE_ESP_WIFIMANAGER_NTP 319 | printLocalTime(); 320 | #else 321 | static int num = 1; 322 | 323 | if (WiFi.status() == WL_CONNECTED) 324 | Serial.print(F("H")); // H means connected to WiFi 325 | else 326 | Serial.print(F("F")); // F means not connected to WiFi 327 | 328 | if (num == 80) 329 | { 330 | Serial.println(); 331 | num = 1; 332 | } 333 | else if (num++ % 10 == 0) 334 | { 335 | Serial.print(F(" ")); 336 | } 337 | #endif 338 | } 339 | 340 | void check_WiFi() 341 | { 342 | if ( (WiFi.status() != WL_CONNECTED) ) 343 | { 344 | Serial.println(F("\nWiFi lost. Call connectMultiWiFi in loop")); 345 | connectMultiWiFi(); 346 | } 347 | } 348 | 349 | void check_status() 350 | { 351 | static ulong checkstatus_timeout = 0; 352 | static ulong checkwifi_timeout = 0; 353 | 354 | static ulong current_millis; 355 | 356 | #define WIFICHECK_INTERVAL 1000L 357 | 358 | #if USE_ESP_WIFIMANAGER_NTP 359 | #define HEARTBEAT_INTERVAL 60000L 360 | #else 361 | #define HEARTBEAT_INTERVAL 10000L 362 | #endif 363 | 364 | current_millis = millis(); 365 | 366 | // Check WiFi every WIFICHECK_INTERVAL (1) seconds. 367 | if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0)) 368 | { 369 | check_WiFi(); 370 | checkwifi_timeout = current_millis + WIFICHECK_INTERVAL; 371 | } 372 | 373 | // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds. 374 | if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0)) 375 | { 376 | heartBeatPrint(); 377 | checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL; 378 | } 379 | } 380 | 381 | int calcChecksum(uint8_t* address, uint16_t sizeToCalc) 382 | { 383 | uint16_t checkSum = 0; 384 | 385 | for (uint16_t index = 0; index < sizeToCalc; index++) 386 | { 387 | checkSum += * ( ( (byte*) address ) + index); 388 | } 389 | 390 | return checkSum; 391 | } 392 | 393 | bool loadConfigData() 394 | { 395 | File file = FileFS.open(CONFIG_FILENAME, "r"); 396 | LOGERROR(F("LoadWiFiCfgFile ")); 397 | 398 | memset((void*) &WM_config, 0, sizeof(WM_config)); 399 | 400 | // New in v1.4.0 401 | memset((void*) &WM_STA_IPconfig, 0, sizeof(WM_STA_IPconfig)); 402 | ////// 403 | 404 | if (file) 405 | { 406 | file.readBytes((char *) &WM_config, sizeof(WM_config)); 407 | 408 | // New in v1.4.0 409 | file.readBytes((char *) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 410 | ////// 411 | 412 | file.close(); 413 | LOGERROR(F("OK")); 414 | 415 | if ( WM_config.checksum != calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ) ) 416 | { 417 | LOGERROR(F("WM_config checksum wrong")); 418 | 419 | return false; 420 | } 421 | 422 | // New in v1.4.0 423 | displayIPConfigStruct(WM_STA_IPconfig); 424 | ////// 425 | 426 | return true; 427 | } 428 | else 429 | { 430 | LOGERROR(F("failed")); 431 | 432 | return false; 433 | } 434 | } 435 | 436 | void saveConfigData() 437 | { 438 | File file = FileFS.open(CONFIG_FILENAME, "w"); 439 | LOGERROR(F("SaveWiFiCfgFile ")); 440 | 441 | if (file) 442 | { 443 | WM_config.checksum = calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ); 444 | 445 | file.write((uint8_t*) &WM_config, sizeof(WM_config)); 446 | 447 | displayIPConfigStruct(WM_STA_IPconfig); 448 | 449 | // New in v1.4.0 450 | file.write((uint8_t*) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig)); 451 | ////// 452 | 453 | file.close(); 454 | LOGERROR(F("OK")); 455 | } 456 | else 457 | { 458 | LOGERROR(F("failed")); 459 | } 460 | } 461 | -------------------------------------------------------------------------------- /examples/ConfigOnDoubleReset_Multi/ConfigOnDoubleReset_Multi.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnDoubleReset_Multi.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy 6 | configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by: 7 | http://www.esp8266.com/viewtopic.php?f=29&t=2520 8 | https://github.com/chriscook8/esp-arduino-apboot 9 | https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ 10 | 11 | Modified from Tzapu https://github.com/tzapu/WiFiManager 12 | and from Ken Taylor https://github.com/kentaylor 13 | 14 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 15 | Licensed under MIT license 16 | *****************************************************************************************************************************/ 17 | /**************************************************************************************************************************** 18 | This example will open a configuration portal when the reset button is pressed twice. 19 | This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal. 20 | 21 | How It Works 22 | 1) ESP8266 23 | Save data in RTC memory 24 | 2) ESP32 25 | Save data in EEPROM from address 256, size 512 bytes (both configurable) 26 | 27 | So when the device starts up it checks this region of ram for a flag to see if it has been recently reset. 28 | If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that 29 | it will only launch the configuration portal in response to closely spaced resets. 30 | 31 | Settings 32 | There are two values to be set in the sketch. 33 | 34 | DRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example. 35 | DRD_ADDRESS - The address in ESP8266 RTC RAM to store the flag. This memory must not be used for other purposes in the same sketch. Set to 0 in the example. 36 | 37 | This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector 38 | To support ESP32, use ESP_DoubleResetDetector library from //https://github.com/khoih-prog/ESP_DoubleResetDetector 39 | *****************************************************************************************************************************/ 40 | 41 | #if !( defined(ESP8266) || defined(ESP32) ) 42 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 43 | #endif 44 | 45 | // Use from 0 to 4. Higher number, more debugging messages and memory usage. 46 | #define _WIFIMGR_LOGLEVEL_ 3 47 | 48 | #include 49 | 50 | //Ported to ESP32 51 | #ifdef ESP32 52 | #include 53 | #include 54 | #include 55 | 56 | // From v1.1.0 57 | #include 58 | extern WiFiMulti wifiMulti; 59 | 60 | // LittleFS has higher priority than SPIFFS 61 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 62 | #define USE_LITTLEFS true 63 | #define USE_SPIFFS false 64 | #elif defined(ARDUINO_ESP32C3_DEV) 65 | // For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS 66 | #define USE_LITTLEFS false 67 | #define USE_SPIFFS true 68 | #endif 69 | 70 | #if USE_LITTLEFS 71 | // Use LittleFS 72 | #include "FS.h" 73 | 74 | // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h 75 | //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) 76 | #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) 77 | #if (_WIFIMGR_LOGLEVEL_ > 3) 78 | #warning Using ESP32 Core 1.0.6 or 2.0.0+ 79 | #endif 80 | 81 | // The library has been merged into esp32 core from release 1.0.6 82 | #include // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS 83 | 84 | extern FS* filesystem; // = &LittleFS; 85 | #define FileFS LittleFS 86 | #define FS_Name "LittleFS" 87 | #else 88 | #if (_WIFIMGR_LOGLEVEL_ > 3) 89 | #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library 90 | #endif 91 | 92 | // The library has been merged into esp32 core from release 1.0.6 93 | #include // https://github.com/lorol/LITTLEFS 94 | 95 | extern FS* filesystem; // = &LITTLEFS; 96 | #define FileFS LITTLEFS 97 | #define FS_Name "LittleFS" 98 | #endif 99 | 100 | #elif USE_SPIFFS 101 | #include 102 | extern FS* filesystem; // = &SPIFFS; 103 | #define FileFS SPIFFS 104 | #define FS_Name "SPIFFS" 105 | #else 106 | // +Use FFat 107 | #include 108 | extern FS* filesystem; // = &FFat; 109 | #define FileFS FFat 110 | #define FS_Name "FFat" 111 | #endif 112 | ////// 113 | 114 | #define LED_BUILTIN 2 115 | #define LED_ON HIGH 116 | #define LED_OFF LOW 117 | 118 | #else 119 | #include //https://github.com/esp8266/Arduino 120 | //needed for library 121 | #include 122 | #include 123 | 124 | // From v1.1.0 125 | #include 126 | extern ESP8266WiFiMulti wifiMulti; 127 | 128 | #define USE_LITTLEFS true 129 | 130 | #if USE_LITTLEFS 131 | #include 132 | extern FS* filesystem; // = &LittleFS; 133 | #define FileFS LittleFS 134 | #define FS_Name "LittleFS" 135 | #else 136 | extern FS* filesystem; // = &SPIFFS; 137 | #define FileFS SPIFFS 138 | #define FS_Name "SPIFFS" 139 | #endif 140 | ////// 141 | 142 | #define ESP_getChipId() (ESP.getChipId()) 143 | 144 | #define LED_ON LOW 145 | #define LED_OFF HIGH 146 | #endif 147 | 148 | // These defines must be put before #include 149 | // to select where to store DoubleResetDetector's variable. 150 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 151 | // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) 152 | // Otherwise, library will use default EEPROM storage 153 | #ifdef ESP32 154 | 155 | // These defines must be put before #include 156 | // to select where to store DoubleResetDetector's variable. 157 | // For ESP32, You must select one to be true (EEPROM or SPIFFS) 158 | // Otherwise, library will use default EEPROM storage 159 | #if USE_LITTLEFS 160 | #define ESP_DRD_USE_LITTLEFS true 161 | #define ESP_DRD_USE_SPIFFS false 162 | #define ESP_DRD_USE_EEPROM false 163 | #elif USE_SPIFFS 164 | #define ESP_DRD_USE_LITTLEFS false 165 | #define ESP_DRD_USE_SPIFFS true 166 | #define ESP_DRD_USE_EEPROM false 167 | #else 168 | #define ESP_DRD_USE_LITTLEFS false 169 | #define ESP_DRD_USE_SPIFFS false 170 | #define ESP_DRD_USE_EEPROM true 171 | #endif 172 | 173 | #else //ESP8266 174 | 175 | // For DRD 176 | // These defines must be put before #include 177 | // to select where to store DoubleResetDetector's variable. 178 | // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) 179 | // Otherwise, library will use default EEPROM storage 180 | #if USE_LITTLEFS 181 | #define ESP_DRD_USE_LITTLEFS true 182 | #define ESP_DRD_USE_SPIFFS false 183 | #else 184 | #define ESP_DRD_USE_LITTLEFS false 185 | #define ESP_DRD_USE_SPIFFS true 186 | #endif 187 | 188 | #define ESP_DRD_USE_EEPROM false 189 | #define ESP8266_DRD_USE_RTC false 190 | #endif 191 | 192 | #define DOUBLERESETDETECTOR_DEBUG true //false 193 | 194 | #include //https://github.com/khoih-prog/ESP_DoubleResetDetector 195 | 196 | // Number of seconds after reset during which a 197 | // subseqent reset will be considered a double reset. 198 | #define DRD_TIMEOUT 10 199 | 200 | // RTC Memory Address for the DoubleResetDetector to use 201 | #define DRD_ADDRESS 0 202 | 203 | //DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS); 204 | extern DoubleResetDetector* drd;////// 205 | 206 | // Onboard LED I/O pin on NodeMCU board 207 | extern const int PIN_LED; // = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED. 208 | 209 | // SSID and PW for Config Portal 210 | //String ssid = "ESP_" + String(ESP_getChipId(), HEX); 211 | extern String ssid; 212 | extern String password; 213 | //extern const char* password; // = "your_password"; 214 | 215 | // SSID and PW for your Router 216 | extern String Router_SSID; 217 | extern String Router_Pass; 218 | 219 | // From v1.1.0 220 | // You only need to format the filesystem once 221 | //#define FORMAT_FILESYSTEM true 222 | #define FORMAT_FILESYSTEM false 223 | 224 | #define MIN_AP_PASSWORD_SIZE 8 225 | 226 | #define SSID_MAX_LEN 32 227 | //From v1.0.10, WPA2 passwords can be up to 63 characters long. 228 | #define PASS_MAX_LEN 64 229 | 230 | typedef struct 231 | { 232 | char wifi_ssid[SSID_MAX_LEN]; 233 | char wifi_pw [PASS_MAX_LEN]; 234 | } WiFi_Credentials; 235 | 236 | typedef struct 237 | { 238 | String wifi_ssid; 239 | String wifi_pw; 240 | } WiFi_Credentials_String; 241 | 242 | #define NUM_WIFI_CREDENTIALS 2 243 | 244 | // Assuming max 491 chars 245 | #define TZNAME_MAX_LEN 50 246 | #define TIMEZONE_MAX_LEN 50 247 | 248 | typedef struct 249 | { 250 | WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; 251 | char TZ_Name[TZNAME_MAX_LEN]; // "America/Toronto" 252 | char TZ[TIMEZONE_MAX_LEN]; // "EST5EDT,M3.2.0,M11.1.0" 253 | uint16_t checksum; 254 | } WM_Config; 255 | 256 | extern WM_Config WM_config; 257 | 258 | #define CONFIG_FILENAME F("/wifi_cred.dat") 259 | ////// 260 | 261 | // Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected 262 | extern bool initialConfig; // = false; 263 | 264 | // Use false if you don't like to display Available Pages in Information Page of Config Portal 265 | // Comment out or use true to display Available Pages in Information Page of Config Portal 266 | // Must be placed before #include 267 | #define USE_AVAILABLE_PAGES true //false 268 | 269 | // From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used. 270 | // You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa 271 | // You have to explicitly specify false to disable the feature. 272 | //#define USE_STATIC_IP_CONFIG_IN_CP false 273 | 274 | // Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal. 275 | // See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23) 276 | #define USE_ESP_WIFIMANAGER_NTP true 277 | 278 | // Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen 279 | // if using too much memory 280 | #define USING_AFRICA false 281 | #define USING_AMERICA true 282 | #define USING_ANTARCTICA false 283 | #define USING_ASIA false 284 | #define USING_ATLANTIC false 285 | #define USING_AUSTRALIA false 286 | #define USING_EUROPE false 287 | #define USING_INDIAN false 288 | #define USING_PACIFIC false 289 | #define USING_ETC_GMT false 290 | 291 | // Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare 292 | // See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21) 293 | #define USE_CLOUDFLARE_NTP false 294 | 295 | // New in v1.0.11 296 | #define USING_CORS_FEATURE true 297 | 298 | ////// 299 | 300 | // Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network 301 | #if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP) 302 | // Force DHCP to be true 303 | #if defined(USE_DHCP_IP) 304 | #undef USE_DHCP_IP 305 | #endif 306 | #define USE_DHCP_IP true 307 | #else 308 | // You can select DHCP or Static IP here 309 | #define USE_DHCP_IP true 310 | //#define USE_DHCP_IP false 311 | #endif 312 | 313 | #if ( USE_DHCP_IP ) 314 | // Use DHCP 315 | 316 | #if (_WIFIMGR_LOGLEVEL_ > 3) 317 | #warning Using DHCP IP 318 | #endif 319 | 320 | extern IPAddress stationIP; // = IPAddress(0, 0, 0, 0); 321 | extern IPAddress gatewayIP; // = IPAddress(192, 168, 1, 1); 322 | extern IPAddress netMask; // = IPAddress(255, 255, 255, 0); 323 | #else 324 | // Use static IP 325 | 326 | #if (_WIFIMGR_LOGLEVEL_ > 3) 327 | #warning Using static IP 328 | #endif 329 | 330 | #ifdef ESP32 331 | extern IPAddress stationIP; // = IPAddress(192, 168, 2, 232); 332 | #else 333 | extern IPAddress stationIP; // = IPAddress(192, 168, 2, 186); 334 | #endif 335 | 336 | extern IPAddress gatewayIP; // = IPAddress(192, 168, 2, 1); 337 | extern IPAddress netMask; // = IPAddress(255, 255, 255, 0); 338 | #endif 339 | 340 | #define USE_CONFIGURABLE_DNS true 341 | 342 | extern IPAddress dns1IP; // = gatewayIP; 343 | extern IPAddress dns2IP; // = IPAddress(8, 8, 8, 8); 344 | 345 | #define USE_CUSTOM_AP_IP false 346 | 347 | extern IPAddress APStaticIP; // = IPAddress(192, 168, 100, 1); 348 | extern IPAddress APStaticGW; // = IPAddress(192, 168, 100, 1); 349 | extern IPAddress APStaticSN; // = IPAddress(255, 255, 255, 0); 350 | 351 | // Must be placed before #include , or default port 80 will be used 352 | //#define HTTP_PORT 8080 353 | 354 | #include //https://github.com/khoih-prog/ESP_WiFiManager 355 | 356 | // Function Prototypes 357 | uint8_t connectMultiWiFi(); 358 | 359 | /////////////////////////////////////////// 360 | // New in v1.4.0 361 | /****************************************** 362 | * // Defined in ESP_WiFiManager.h 363 | typedef struct 364 | { 365 | IPAddress _ap_static_ip; 366 | IPAddress _ap_static_gw; 367 | IPAddress _ap_static_sn; 368 | 369 | } WiFi_AP_IPConfig; 370 | 371 | typedef struct 372 | { 373 | IPAddress _sta_static_ip; 374 | IPAddress _sta_static_gw; 375 | IPAddress _sta_static_sn; 376 | #if USE_CONFIGURABLE_DNS 377 | IPAddress _sta_static_dns1; 378 | IPAddress _sta_static_dns2; 379 | #endif 380 | } WiFi_STA_IPConfig; 381 | ******************************************/ 382 | 383 | extern WiFi_AP_IPConfig WM_AP_IPconfig; 384 | extern WiFi_STA_IPConfig WM_STA_IPconfig; 385 | 386 | void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig); 387 | void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig); 388 | void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig); 389 | void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig); 390 | 391 | uint8_t connectMultiWiFi(); 392 | 393 | 394 | #if USE_ESP_WIFIMANAGER_NTP 395 | void printLocalTime(); 396 | #endif 397 | 398 | void heartBeatPrint(); 399 | 400 | void check_WiFi(); 401 | void check_status(); 402 | int calcChecksum(uint8_t* address, uint16_t sizeToCalc); 403 | bool loadConfigData(); 404 | void saveConfigData(); 405 | 406 | /////////////////////////////////////////// 407 | -------------------------------------------------------------------------------- /examples/ConfigOnDoubleReset_Multi/ConfigOnDoubleReset_Multi.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ConfigOnDoubleReset_Multi.ino 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy 6 | configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by: 7 | http://www.esp8266.com/viewtopic.php?f=29&t=2520 8 | https://github.com/chriscook8/esp-arduino-apboot 9 | https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ 10 | 11 | Modified from Tzapu https://github.com/tzapu/WiFiManager 12 | and from Ken Taylor https://github.com/kentaylor 13 | 14 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 15 | Licensed under MIT license 16 | *****************************************************************************************************************************/ 17 | /**************************************************************************************************************************** 18 | This example will open a configuration portal when the reset button is pressed twice. 19 | This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal. 20 | 21 | How It Works 22 | 1) ESP8266 23 | Save data in RTC memory 24 | 2) ESP32 25 | Save data in EEPROM from address 256, size 512 bytes (both configurable) 26 | 27 | So when the device starts up it checks this region of ram for a flag to see if it has been recently reset. 28 | If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that 29 | it will only launch the configuration portal in response to closely spaced resets. 30 | 31 | Settings 32 | There are two values to be set in the sketch. 33 | 34 | DRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example. 35 | DRD_ADDRESS - The address in ESP8266 RTC RAM to store the flag. This memory must not be used for other purposes in the same sketch. Set to 0 in the example. 36 | 37 | This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector 38 | To support ESP32, use ESP_DoubleResetDetector library from //https://github.com/khoih-prog/ESP_DoubleResetDetector 39 | *****************************************************************************************************************************/ 40 | 41 | #if !( defined(ESP8266) || defined(ESP32) ) 42 | #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. 43 | #endif 44 | 45 | #define ESP_WIFIMANAGER_VERSION_MIN_TARGET "ESP_WiFiManager v1.12.0" 46 | #define ESP_WIFIMANAGER_VERSION_MIN 1012000 47 | 48 | // Use from 0 to 4. Higher number, more debugging messages and memory usage. 49 | #define _WIFIMGR_LOGLEVEL_ 1 50 | 51 | // To not display stored SSIDs and PWDs on Config Portal, select false. Default is true 52 | // Even the stored Credentials are not display, just leave them all blank to reconnect and reuse the stored Credentials 53 | //#define DISPLAY_STORED_CREDENTIALS_IN_CP false 54 | 55 | // These definitions must be placed before #include 56 | #include "ConfigOnDoubleReset_Multi.h" 57 | 58 | #include //https://github.com/khoih-prog/ESP_WiFiManager 59 | 60 | // Redundant, for v1.8.0 only 61 | //#include //https://github.com/khoih-prog/ESP_WiFiManager 62 | 63 | void setup() 64 | { 65 | // put your setup code here, to run once: 66 | // initialize the LED digital pin as an output. 67 | pinMode(PIN_LED, OUTPUT); 68 | 69 | Serial.begin(115200); 70 | while (!Serial); 71 | 72 | delay(200); 73 | 74 | Serial.print(F("\nStarting ConfigOnDoubleReset_Multi with DoubleResetDetect using ")); Serial.print(FS_Name); 75 | Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD); 76 | Serial.println(ESP_WIFIMANAGER_VERSION); 77 | Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION); 78 | 79 | #if defined(ESP_WIFIMANAGER_VERSION_MIN) 80 | if (ESP_WIFIMANAGER_VERSION_INT < ESP_WIFIMANAGER_VERSION_MIN) 81 | { 82 | Serial.print("Warning. Must use this example on Version equal or later than : "); 83 | Serial.println(ESP_WIFIMANAGER_VERSION_MIN_TARGET); 84 | } 85 | #endif 86 | 87 | Serial.setDebugOutput(false); 88 | 89 | if (FORMAT_FILESYSTEM) 90 | FileFS.format(); 91 | 92 | // Format FileFS if not yet 93 | #ifdef ESP32 94 | if (!FileFS.begin(true)) 95 | #else 96 | if (!FileFS.begin()) 97 | #endif 98 | { 99 | #ifdef ESP8266 100 | FileFS.format(); 101 | #endif 102 | 103 | Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting.")); 104 | 105 | if (!FileFS.begin()) 106 | { 107 | // prevents debug info from the library to hide err message. 108 | delay(100); 109 | 110 | #if USE_LITTLEFS 111 | Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever")); 112 | #else 113 | Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever")); 114 | #endif 115 | 116 | while (true) 117 | { 118 | delay(1); 119 | } 120 | } 121 | } 122 | 123 | drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS); 124 | 125 | unsigned long startedAt = millis(); 126 | 127 | // New in v1.4.0 128 | initAPIPConfigStruct(WM_AP_IPconfig); 129 | initSTAIPConfigStruct(WM_STA_IPconfig); 130 | ////// 131 | 132 | //Local intialization. Once its business is done, there is no need to keep it around 133 | // Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX 134 | //ESP_WiFiManager ESP_wifiManager; 135 | // Use this to personalize DHCP hostname (RFC952 conformed) 136 | ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset"); 137 | 138 | #if USE_CUSTOM_AP_IP 139 | //set custom ip for portal 140 | // New in v1.4.0 141 | ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig); 142 | ////// 143 | #endif 144 | 145 | ESP_wifiManager.setMinimumSignalQuality(-1); 146 | 147 | // From v1.0.10 only 148 | // Set config portal channel, default = 1. Use 0 => random channel from 1-13 149 | ESP_wifiManager.setConfigPortalChannel(0); 150 | ////// 151 | 152 | #if !USE_DHCP_IP 153 | // Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5 154 | // New in v1.4.0 155 | ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig); 156 | ////// 157 | #endif 158 | 159 | // New from v1.1.1 160 | #if USING_CORS_FEATURE 161 | ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin"); 162 | #endif 163 | 164 | // We can't use WiFi.SSID() in ESP32 as it's only valid after connected. 165 | // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot 166 | // Have to create a new function to store in EEPROM/SPIFFS for this purpose 167 | Router_SSID = ESP_wifiManager.WiFi_SSID(); 168 | Router_Pass = ESP_wifiManager.WiFi_Pass(); 169 | 170 | //Remove this line if you do not want to see WiFi password printed 171 | Serial.println("ESP Self-Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass); 172 | 173 | // SSID/PWD to uppercase 174 | ssid.toUpperCase(); 175 | password = "My" + ssid; 176 | 177 | bool configDataLoaded = false; 178 | 179 | // From v1.1.0, Don't permit NULL password 180 | if ( (Router_SSID != "") && (Router_Pass != "") ) 181 | { 182 | LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass); 183 | wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); 184 | 185 | ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout. 186 | Serial.println(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal")); 187 | } 188 | 189 | if (loadConfigData()) 190 | { 191 | configDataLoaded = true; 192 | 193 | ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout. 194 | Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal")); 195 | 196 | #if USE_ESP_WIFIMANAGER_NTP 197 | if ( strlen(WM_config.TZ_Name) > 0 ) 198 | { 199 | LOGERROR3(F("Current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ); 200 | 201 | #if ESP8266 202 | configTime(WM_config.TZ, "pool.ntp.org"); 203 | #else 204 | //configTzTime(WM_config.TZ, "pool.ntp.org" ); 205 | configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); 206 | #endif 207 | } 208 | else 209 | { 210 | Serial.println(F("Current Timezone is not set. Enter Config Portal to set.")); 211 | } 212 | #endif 213 | } 214 | else 215 | { 216 | // Enter CP only if no stored SSID on flash and file 217 | Serial.println(F("Open Config Portal without Timeout: No stored Credentials.")); 218 | initialConfig = true; 219 | } 220 | 221 | if (drd->detectDoubleReset()) 222 | { 223 | // DRD, disable timeout. 224 | ESP_wifiManager.setConfigPortalTimeout(0); 225 | 226 | Serial.println(F("Open Config Portal without Timeout: Double Reset Detected")); 227 | initialConfig = true; 228 | } 229 | 230 | if (initialConfig) 231 | { 232 | Serial.print(F("Starting configuration portal @ ")); 233 | 234 | #if USE_CUSTOM_AP_IP 235 | Serial.print(APStaticIP); 236 | #else 237 | Serial.print(F("192.168.4.1")); 238 | #endif 239 | 240 | #if defined(HTTP_PORT_TO_USE) 241 | Serial.print(F(":")); Serial.print(HTTP_PORT_TO_USE); 242 | #endif 243 | 244 | Serial.print(F(", SSID = ")); 245 | Serial.print(ssid); 246 | Serial.print(F(", PWD = ")); 247 | Serial.println(password); 248 | 249 | digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode. 250 | 251 | //sets timeout in seconds until configuration portal gets turned off. 252 | //If not specified device will remain in configuration mode until 253 | //switched off via webserver or device is restarted. 254 | //ESP_wifiManager.setConfigPortalTimeout(600); 255 | 256 | #if DISPLAY_STORED_CREDENTIALS_IN_CP 257 | // New. Update Credentials, got from loadConfigData(), to display on CP 258 | ESP_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw, 259 | WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw); 260 | #endif 261 | 262 | // Starts an access point 263 | if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), (const char *) password.c_str())) 264 | Serial.println(F("Not connected to WiFi but continuing anyway.")); 265 | else 266 | { 267 | Serial.println(F("WiFi connected...yeey :)")); 268 | } 269 | 270 | // Stored for later usage, from v1.1.0, but clear first 271 | memset(&WM_config, 0, sizeof(WM_config)); 272 | 273 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 274 | { 275 | String tempSSID = ESP_wifiManager.getSSID(i); 276 | String tempPW = ESP_wifiManager.getPW(i); 277 | 278 | if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1) 279 | strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str()); 280 | else 281 | strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1); 282 | 283 | if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1) 284 | strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str()); 285 | else 286 | strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1); 287 | 288 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 289 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 290 | { 291 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 292 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 293 | } 294 | } 295 | 296 | #if USE_ESP_WIFIMANAGER_NTP 297 | String tempTZ = ESP_wifiManager.getTimezoneName(); 298 | 299 | if (strlen(tempTZ.c_str()) < sizeof(WM_config.TZ_Name) - 1) 300 | strcpy(WM_config.TZ_Name, tempTZ.c_str()); 301 | else 302 | strncpy(WM_config.TZ_Name, tempTZ.c_str(), sizeof(WM_config.TZ_Name) - 1); 303 | 304 | const char * TZ_Result = ESP_wifiManager.getTZ(WM_config.TZ_Name); 305 | 306 | if (strlen(TZ_Result) < sizeof(WM_config.TZ) - 1) 307 | strcpy(WM_config.TZ, TZ_Result); 308 | else 309 | strncpy(WM_config.TZ, TZ_Result, sizeof(WM_config.TZ_Name) - 1); 310 | 311 | if ( strlen(WM_config.TZ_Name) > 0 ) 312 | { 313 | LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ); 314 | 315 | #if ESP8266 316 | configTime(WM_config.TZ, "pool.ntp.org"); 317 | #else 318 | //configTzTime(WM_config.TZ, "pool.ntp.org" ); 319 | configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); 320 | #endif 321 | } 322 | else 323 | { 324 | LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set.")); 325 | } 326 | #endif 327 | 328 | // New in v1.4.0 329 | ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig); 330 | ////// 331 | 332 | saveConfigData(); 333 | } 334 | 335 | digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode. 336 | 337 | startedAt = millis(); 338 | 339 | if (!initialConfig) 340 | { 341 | // Load stored data, the addAP ready for MultiWiFi reconnection 342 | if (!configDataLoaded) 343 | loadConfigData(); 344 | 345 | for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++) 346 | { 347 | // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) 348 | if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) 349 | { 350 | LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw ); 351 | wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); 352 | } 353 | } 354 | 355 | if ( WiFi.status() != WL_CONNECTED ) 356 | { 357 | Serial.println(F("ConnectMultiWiFi in setup")); 358 | 359 | connectMultiWiFi(); 360 | } 361 | } 362 | 363 | Serial.print(F("After waiting ")); 364 | Serial.print((float) (millis() - startedAt) / 1000); 365 | Serial.print(F(" secs more in setup(), connection result is ")); 366 | 367 | if (WiFi.status() == WL_CONNECTED) 368 | { 369 | Serial.print(F("connected. Local IP: ")); 370 | Serial.println(WiFi.localIP()); 371 | } 372 | else 373 | Serial.println(ESP_wifiManager.getStatus(WiFi.status())); 374 | } 375 | 376 | void loop() 377 | { 378 | // Call the double reset detector loop method every so often, 379 | // so that it can recognise when the timeout expires. 380 | // You can also call drd.stop() when you wish to no longer 381 | // consider the next reset as a double reset. 382 | drd->loop(); 383 | 384 | // put your main code here, to run repeatedly 385 | check_status(); 386 | 387 | } 388 | -------------------------------------------------------------------------------- /examples/ConfigOnSwitch/README.md: -------------------------------------------------------------------------------- 1 | # The Config On Switch Example 2 | In this example we initiate the configuration portal to connect an ESP8266 to WiFi by pushing a button. The example requires this version of WiFi Manager. It will not work with the tzapu version. 3 | 4 | ## Why Have A Button To Initiate Configuration? 5 | Once the ESP device contains network credentials it will always try to connect to that network in the background and succeed whenever that network becomes visible. The application continues to function and because WiFi networks tend to be flaky only a human has the knowledge of whether a new network is required or it is better to wait for the network to become visible again. Therefore, providing a configuration portal must be human initiated and requiring a button push is a good way to get human input. 6 | 7 | The alternative of automatically going into configuration mode every time a WiFi network becomes invisible will cause the application to stop and the device will sit in configuration mode forever. This is undesirable when a network is temporarily unavailable. 8 | 9 | ## Issues With Automatically Going Into Configuration Mode 10 | Providing a timeout on configuration mode is one way to get the application running again when a network becomes temporarily unavailable and no one is around to reboot. However, the application will still not function while waiting for the timeout and the device is vulnerable to sabotage when in config mode. With a push button it will also be vulnerable to sabotage whenever the saboteur has physical access but then it is vulnerable in other ways as well. An assumption that saboteurs will not have physical access to the device is sufficient for most applications. 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/README.md: -------------------------------------------------------------------------------- 1 | # ESP_FSWebServer Example 2 | 3 | ## First, how Config Portal works? 4 | In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples): 5 | 6 | ```cpp 7 | // SSID and PW for Config Portal 8 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 9 | const char* password = "your_password"; 10 | ``` 11 | After you connected, please, go to http://192.168.4.1, you'll see this `Main` page: 12 | 13 |

14 | 15 |

16 | 17 | Select `Information` to enter the Info page where the board info will be shown (long page) 18 | 19 |

20 | 21 |

22 | 23 | or short page (default) 24 | 25 |

26 | 27 |

28 | 29 | Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials 30 | 31 |

32 | 33 |

34 | 35 | Enter your credentials, then click `Save`. The WiFi Credentials will be saved and the board reboots to connect to the selected WiFi AP. 36 | 37 | If you're already connected to a listed WiFi AP and don't want to change anything, just select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact. 38 | 39 | 40 | ## How to use this ESP_FSWebServer example? 41 | 42 | This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes) 43 | 44 | 1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g., 45 | 46 | ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 47 | 48 | 1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) 49 | 2. or upload the contents of a folder by running the following commands: 50 | - Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 51 | - Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done 52 | 3. Access the sample web page at http://esp8266fs.local 53 | 54 |

55 | 56 |

57 | 58 | 4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit 59 | 60 |

61 | 62 |

63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/CanadaFlag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/CanadaFlag_1.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/CanadaFlag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/CanadaFlag_2.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/CanadaFlag_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/CanadaFlag_3.jpg -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/edit.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/edit.htm.gz -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/favicon.ico -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/graphs.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/data/graphs.js.gz -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/data/index.htm: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | ESP Monitor 23 | 24 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 |
93 |
94 |
95 |
96 | 97 | -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/pics/esp8266fs.local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/pics/esp8266fs.local.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer/pics/esp8266fs.local_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer/pics/esp8266fs.local_edit.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/README.md: -------------------------------------------------------------------------------- 1 | # ESP_FSWebServer Example 2 | 3 | ## First, how Config Portal works? 4 | In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples): 5 | 6 | ```cpp 7 | // SSID and PW for Config Portal 8 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 9 | const char* password = "your_password"; 10 | ``` 11 | After you connected, please, go to http://192.168.4.1, you'll see this `Main` page: 12 | 13 |

14 | 15 |

16 | 17 | Select `Information` to enter the Info page where the board info will be shown (long page) 18 | 19 |

20 | 21 |

22 | 23 | or short page (default) 24 | 25 |

26 | 27 |

28 | 29 | Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials 30 | 31 |

32 | 33 |

34 | 35 | Enter your credentials, then click `Save`. The WiFi Credentials will be saved and the board reboots to connect to the selected WiFi AP. 36 | 37 | If you're already connected to a listed WiFi AP and don't want to change anything, just select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact. 38 | 39 | 40 | ## How to use this ESP_FSWebServer example? 41 | 42 | This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes) 43 | 44 | 1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g., 45 | 46 | ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 47 | 48 | 1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) 49 | 2. or upload the contents of a folder by running the following commands: 50 | - Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 51 | - Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done 52 | 3. Access the sample web page at http://esp8266fs.local 53 | 54 |

55 | 56 |

57 | 58 | 4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit 59 | 60 |

61 | 62 |

63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/CanadaFlag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/CanadaFlag_1.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/CanadaFlag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/CanadaFlag_2.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/CanadaFlag_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/CanadaFlag_3.jpg -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/edit.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/edit.htm.gz -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/favicon.ico -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/graphs.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/data/graphs.js.gz -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/data/index.htm: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | ESP Monitor 23 | 24 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 |
93 |
94 |
95 |
96 | 97 | -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/pics/esp8266fs.local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/pics/esp8266fs.local.png -------------------------------------------------------------------------------- /examples/ESP32_FSWebServer_DRD/pics/esp8266fs.local_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP32_FSWebServer_DRD/pics/esp8266fs.local_edit.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/README.md: -------------------------------------------------------------------------------- 1 | # ESP_FSWebServer Example 2 | 3 | ## First, how Config Portal works? 4 | In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples): 5 | 6 | ```cpp 7 | // SSID and PW for Config Portal 8 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 9 | const char* password = "your_password"; 10 | ``` 11 | After you connected, please, go to http://192.168.4.1, you'll see this `Main` page: 12 | 13 |

14 | 15 |

16 | 17 | Select `Information` to enter the Info page where the board info will be shown (long page) 18 | 19 |

20 | 21 |

22 | 23 | or short page (default) 24 | 25 |

26 | 27 |

28 | 29 | Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials 30 | 31 |

32 | 33 |

34 | 35 | Enter your credentials, then click `Save`. The WiFi Credentials will be saved and the board reboots to connect to the selected WiFi AP. 36 | 37 | If you're already connected to a listed WiFi AP and don't want to change anything, just select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact. 38 | 39 | 40 | ## How to use this ESP_FSWebServer example? 41 | 42 | This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes) 43 | 44 | 1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g., 45 | 46 | ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 47 | 48 | 1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) 49 | 2. or upload the contents of a folder by running the following commands: 50 | - Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 51 | - Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done 52 | 3. Access the sample web page at http://esp8266fs.local 53 | 54 |

55 | 56 |

57 | 58 | 4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit 59 | 60 |

61 | 62 |

63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/CanadaFlag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/CanadaFlag_1.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/CanadaFlag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/CanadaFlag_2.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/CanadaFlag_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/CanadaFlag_3.jpg -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/edit.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/edit.htm.gz -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/favicon.ico -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/graphs.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/data/graphs.js.gz -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/data/index.htm: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | ESP Monitor 23 | 24 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 |
93 |
94 |
95 |
96 | 97 | -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/pics/esp8266fs.local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/pics/esp8266fs.local.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/README.md: -------------------------------------------------------------------------------- 1 | # ESP_FSWebServer Example 2 | 3 | ## First, how Config Portal works? 4 | In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples): 5 | 6 | ```cpp 7 | // SSID and PW for Config Portal 8 | String ssid = "ESP_" + String(ESP_getChipId(), HEX); 9 | const char* password = "your_password"; 10 | ``` 11 | After you connected, please, go to http://192.168.4.1, you'll see this `Main` page: 12 | 13 |

14 | 15 |

16 | 17 | Select `Information` to enter the Info page where the board info will be shown (long page) 18 | 19 |

20 | 21 |

22 | 23 | or short page (default) 24 | 25 |

26 | 27 |

28 | 29 | Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials 30 | 31 |

32 | 33 |

34 | 35 | Enter your credentials, then click `Save`. The WiFi Credentials will be saved and the board reboots to connect to the selected WiFi AP. 36 | 37 | If you're already connected to a listed WiFi AP and don't want to change anything, just select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact. 38 | 39 | 40 | ## How to use this ESP_FSWebServer example? 41 | 42 | This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes) 43 | 44 | 1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g., 45 | 46 | ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 47 | 48 | 1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) 49 | 2. or upload the contents of a folder by running the following commands: 50 | - Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data 51 | - Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done 52 | 3. Access the sample web page at http://esp8266fs.local 53 | 54 |

55 | 56 |

57 | 58 | 4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit 59 | 60 |

61 | 62 |

63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/CanadaFlag_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/CanadaFlag_1.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/CanadaFlag_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/CanadaFlag_2.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/CanadaFlag_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/CanadaFlag_3.jpg -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/edit.htm.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/edit.htm.gz -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/favicon.ico -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/graphs.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/data/graphs.js.gz -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/data/index.htm: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | ESP Monitor 23 | 24 | 85 | 86 | 87 |
88 | 89 | 90 | 91 | 92 |
93 |
94 |
95 |
96 | 97 | -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/pics/esp8266fs.local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/pics/esp8266fs.local.png -------------------------------------------------------------------------------- /examples/ESP_FSWebServer_DRD/pics/esp8266fs.local_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khoih-prog/ESP_WiFiManager/aeee669702f13058a47f34ddfd5a5937ff1df250/examples/ESP_FSWebServer_DRD/pics/esp8266fs.local_edit.png -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################## 2 | # Syntax Coloring Map For ESP_WifiManager 3 | ########################################## 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ESP_WiFiManager KEYWORD1 10 | ESP_WMParameter KEYWORD1 11 | 12 | WiFi_AP_IPConfig KEYWORD1 13 | WiFi_STA_IPConfig KEYWORD1 14 | 15 | WiFiResult KEYWORD1 16 | wifi_ssid_count_t KEYWORD1 17 | 18 | ####################################### 19 | # Methods and Functions (KEYWORD2) 20 | ####################################### 21 | 22 | getID KEYWORD2 23 | getValue KEYWORD2 24 | getPlaceholder KEYWORD2 25 | getValueLength KEYWORD2 26 | getLabelPlacement KEYWORD2 27 | getCustomHTML KEYWORD2 28 | autoConnect KEYWORD2 29 | startConfigPortal KEYWORD2 30 | getConfigPortalSSID KEYWORD2 31 | getConfigPortalPW KEYWORD2 32 | resetSettings KEYWORD2 33 | setConfigPortalTimeout KEYWORD2 34 | setTimeout KEYWORD2 35 | setConnectTimeout KEYWORD2 36 | setDebugOutput KEYWORD2 37 | setMinimumSignalQuality KEYWORD2 38 | setConfigPortalChannel KEYWORD2 39 | setAPStaticIPConfig KEYWORD2 40 | getAPStaticIPConfig KEYWORD2 41 | setSTAStaticIPConfig KEYWORD2 42 | getSTAStaticIPConfig KEYWORD2 43 | setAPCallback KEYWORD2 44 | setSaveConfigCallback KEYWORD2 45 | addParameter KEYWORD2 46 | setBreakAfterConfig KEYWORD2 47 | setCustomHeadElement KEYWORD2 48 | setRemoveDuplicateAPs KEYWORD2 49 | scanWifiNetworks KEYWORD2 50 | setCredentials KEYWORD2 51 | getSSID KEYWORD2 52 | getPW KEYWORD2 53 | getSSID1 KEYWORD2 54 | getPW1 KEYWORD2 55 | setCORSHeader KEYWORD2 56 | getCORSHeader KEYWORD2 57 | getParameters KEYWORD2 58 | getParametersCount KEYWORD2 59 | getStatus KEYWORD2 60 | getStoredWiFiSSID KEYWORD2 61 | getStoredWiFiPass KEYWORD2 62 | WiFi_SSID KEYWORD2 63 | WiFi_Pass KEYWORD2 64 | setHostname KEYWORD2 65 | getTimezoneName KEYWORD2 66 | setTimezoneName KEYWORD2 67 | getTZ KEYWORD2 68 | 69 | ####################################### 70 | 71 | getChipID KEYWORD2 72 | getChipOUI KEYWORD2 73 | 74 | ESP_getChipId KEYWORD2 75 | ESP_getChipOUI KEYWORD2 76 | 77 | ####################################### 78 | # Constants (LITERAL1) 79 | ####################################### 80 | 81 | # LITERAL1 82 | 83 | ESP_WIFIMANAGER_VERSION LITERAL1 84 | ESP_WIFIMANAGER_VERSION_MAJOR LITERAL1 85 | ESP_WIFIMANAGER_VERSION_MINOR LITERAL1 86 | ESP_WIFIMANAGER_VERSION_PATCH LITERAL1 87 | ESP_WIFIMANAGER_VERSION_INT LITERAL1 88 | 89 | WM_HTTP_200 LITERAL1 90 | WM_HTTP_HEAD_START LITERAL1 91 | WM_HTTP_STYLE LITERAL1 92 | WM_HTTP_SCRIPT LITERAL1 93 | WM_HTTP_SCRIPT_NTP_MSG LITERAL1 94 | WM_HTTP_SCRIPT_NTP_HIDDEN LITERAL1 95 | WM_HTTP_SCRIPT_NTP LITERAL1 96 | WM_HTTP_HEAD_END LITERAL1 97 | WM_FLDSET_START LITERAL1 98 | WM_FLDSET_END LITERAL1 99 | WM_HTTP_PORTAL_OPTIONS LITERAL1 100 | WM_HTTP_ITEM LITERAL1 101 | JSON_ITEM LITERAL1 102 | WM_HTTP_FORM_LABEL_BEFORE LITERAL1 103 | WM_HTTP_FORM_LABEL_AFTER LITERAL1 104 | WM_HTTP_FORM_LABEL LITERAL1 105 | WM_HTTP_FORM_PARAM LITERAL1 106 | WM_HTTP_FORM_END LITERAL1 107 | WM_HTTP_SAVED LITERAL1 108 | WM_HTTP_END LITERAL1 109 | WM_HTTP_HEAD_CL LITERAL1 110 | WM_HTTP_HEAD_CT LITERAL1 111 | WM_HTTP_HEAD_CT2 LITERAL1 112 | WM_HTTP_CACHE_CONTROL LITERAL1 113 | WM_HTTP_PRAGMA LITERAL1 114 | WM_HTTP_NO_CACHE LITERAL1 115 | WM_HTTP_EXPIRES LITERAL1 116 | WM_HTTP_CORS LITERAL1 117 | WM_HTTP_CORS_ALLOW_ALL LITERAL1 118 | WM_HTTP_AVAILABLE_PAGES LITERAL1 119 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP_WifiManager", 3 | "version": "1.12.1", 4 | "keywords": "wifi, wi-fi, MultiWiFi, multi-wifi, WiFiManager, esp8266, esp32, esp32-s2, esp32-s3, esp32-c3, Communication, iot, credentials, persistent, config-portal, DoubleReset, MultiReset, DoubleResetDetector, littlefs, spiffs, eeprom, dns-server", 5 | "description": "Library to configure MultiWiFi/Credentials at runtime for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. With enhanced GUI and fallback web ConfigPortal. This Library is used for configuring ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 MultiWiFi Credentials at runtime. You can also specify static DNS servers, personalized HostName, DHCP HostName, static AP and STA IP, fixed or random AP channel. Now with MultiWiFi auto(Re)connect, configurable CORS Header and auto-Timezone features. Auto detect ESP32 core and use either built-in LittleFS or external LITTLEFS library. Now using correct ESP32 chipIP and optional display Credentials on Config Portal", 6 | "authors": 7 | { 8 | "name": "Khoi Hoang", 9 | "url": "https://github.com/khoih-prog", 10 | "maintainer": true 11 | }, 12 | "repository": 13 | { 14 | "type": "git", 15 | "url": "https://github.com/khoih-prog/ESP_WiFiManager" 16 | }, 17 | "homepage": "https://github.com/khoih-prog/ESP_WiFiManager", 18 | "export": { 19 | "exclude": [ 20 | "linux", 21 | "extras", 22 | "tests" 23 | ] 24 | }, 25 | "dependencies": 26 | [ 27 | { 28 | "owner": "khoih-prog", 29 | "name": "ESP_DoubleResetDetector", 30 | "version": ">=1.3.2", 31 | "platforms": ["espressif8266", "espressif32"] 32 | } 33 | ], 34 | "license": "MIT", 35 | "frameworks": "*", 36 | "platforms": ["espressif8266", "espressif32"], 37 | "examples": "examples/*/*/*.ino", 38 | "headers": ["ESP_WiFiManager.h", "ESP_WiFiManager.hpp"] 39 | } 40 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ESP_WiFiManager 2 | version=1.12.1 3 | author=Khoi Hoang 4 | maintainer=Khoi Hoang 5 | license=MIT 6 | sentence=Library to configure MultiWiFi/Credentials at runtime for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. With enhanced GUI and fallback web ConfigPortal. 7 | paragraph=Library to configure MultiWiFi/Credentials at runtime for ESP32 (including ESP32-S2, ESP32-S3 and ESP32-C3) and ESP8266 boards. With enhanced GUI and fallback web ConfigPortal. This Library is used for configuring ESP32 and ESP8266 MultiWiFi Credentials at runtime. You can also specify static DNS servers, personalized HostName, DHCP HostName, static AP and STA IP, fixed or random AP channel. Now with MultiWiFi auto(Re)connect, configurable CORS Header and auto-Timezone features. Auto detect ESP32 core and use either built-in LittleFS or external LITTLEFS library. Now using correct ESP32 chipIP and optional display Credentials on Config Portal 8 | category=Communication 9 | url=https://github.com/khoih-prog/ESP_WiFiManager 10 | architectures=esp8266,esp32 11 | depends=ESP_DoubleResetDetector 12 | includes=ESP_WiFiManager.h,ESP_WiFiManager.hpp 13 | -------------------------------------------------------------------------------- /platformio/platformio.ini: -------------------------------------------------------------------------------- 1 | ;PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; ============================================================ 13 | ; chose environment: 14 | ; ESP8266 15 | ; ESP32 16 | ; ============================================================ 17 | default_envs = ESP8266 18 | ;default_envs = ESP32 19 | 20 | [env] 21 | ; ============================================================ 22 | ; Serial configuration 23 | ; choose upload speed, serial-monitor speed 24 | ; ============================================================ 25 | upload_speed = 921600 26 | ;upload_port = COM11 27 | ;monitor_speed = 9600 28 | ;monitor_port = COM11 29 | 30 | ; Checks for the compatibility with frameworks and dev/platforms 31 | lib_compat_mode = strict 32 | lib_ldf_mode = chain+ 33 | ;lib_ldf_mode = deep+ 34 | 35 | lib_deps = 36 | ; PlatformIO 4.x 37 | ; ESP_DoubleResetDetector@>=1.3.2 38 | ; PlatformIO 5.x 39 | khoih-prog/ESP_DoubleResetDetector@>=1.3.2 40 | 41 | build_flags = 42 | ; set your debug output (default=Serial) 43 | -D DEBUG_ESP_PORT=Serial 44 | ; comment the following line to enable WiFi debugging 45 | -D NDEBUG 46 | 47 | [env:ESP8266] 48 | platform = espressif8266 49 | framework = arduino 50 | ; ============================================================ 51 | ; Board configuration 52 | ; choose your board by uncommenting one of the following lines 53 | ; ============================================================ 54 | ;board = gen4iod 55 | ;board = huzzah 56 | ;board = oak 57 | ;board = esp_wroom_02 58 | ;board = espduino 59 | ;board = espectro 60 | ;board = espino 61 | ;board = espresso_lite_v1 62 | ;board = espresso_lite_v2 63 | ;board = esp12e 64 | ;board = esp01_1m 65 | ;board = esp01 66 | ;board = esp07 67 | ;board = esp8285 68 | ;board = heltec_wifi_kit_8 69 | ;board = inventone 70 | ;board = nodemcu 71 | board = nodemcuv2 72 | ;board = modwifi 73 | ;board = phoenix_v1 74 | ;board = phoenix_v2 75 | ;board = sparkfunBlynk 76 | ;board = thing 77 | ;board = thingdev 78 | ;board = esp210 79 | ;board = espinotee 80 | ;board = d1 81 | ;board = d1_mini 82 | ;board = d1_mini_lite 83 | ;board = d1_mini_pro 84 | ;board = wifi_slot 85 | ;board = wifiduino 86 | ;board = wifinfo 87 | ;board = wio_link 88 | ;board = wio_node 89 | ;board = xinabox_cw01 90 | ;board = esp32doit-devkit-v1 91 | 92 | [env:ESP32] 93 | platform = espressif32 94 | framework = arduino 95 | ; ============================================================ 96 | ; Board configuration 97 | ; choose your board by uncommenting one of the following lines 98 | ; ============================================================ 99 | ;board = esp32cam 100 | ;board = alksesp32 101 | ;board = featheresp32 102 | ;board = espea32 103 | ;board = bpi-bit 104 | ;board = d-duino-32 105 | board = esp32doit-devkit-v1 106 | ;board = pocket_32 107 | ;board = fm-devkit 108 | ;board = pico32 109 | ;board = esp32-evb 110 | ;board = esp32-gateway 111 | ;board = esp32-pro 112 | ;board = esp32-poe 113 | ;board = oroca_edubot 114 | ;board = onehorse32dev 115 | ;board = lopy 116 | ;board = lopy4 117 | ;board = wesp32 118 | ;board = esp32thing 119 | ;board = sparkfun_lora_gateway_1-channel 120 | ;board = ttgo-lora32-v1 121 | ;board = ttgo-t-beam 122 | ;board = turta_iot_node 123 | ;board = lolin_d32 124 | ;board = lolin_d32_pro 125 | ;board = lolin32 126 | ;board = wemosbat 127 | ;board = widora-air 128 | ;board = xinabox_cw02 129 | ;board = iotbusio 130 | ;board = iotbusproteus 131 | ;board = nina_w10 132 | -------------------------------------------------------------------------------- /src/ESP_WiFiManager.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_WiFiManager.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/Arduino platform 6 | (https://github.com/esp8266/Arduino) to enable easy 7 | configuration and reconfiguration of WiFi credentials using a Captive Portal 8 | inspired by: 9 | http://www.esp8266.com/viewtopic.php?f=29&t=2520 10 | https://github.com/chriscook8/esp-arduino-apboot 11 | https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ 12 | 13 | Modified from Tzapu https://github.com/tzapu/WiFiManager 14 | and from Ken Taylor https://github.com/kentaylor 15 | 16 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 17 | Licensed under MIT license 18 | 19 | Version: 1.12.1 20 | 21 | Version Modified By Date Comments 22 | ------- ----------- ---------- ----------- 23 | 1.0.0 K Hoang 07/10/2019 Initial coding 24 | ... 25 | 1.8.0 K Hoang 29/12/2021 Fix `multiple-definitions` linker error and weird bug related to src_cpp 26 | 1.9.0 K Hoang 17/01/2022 Enable compatibility with old code to include only ESP_WiFiManager.h 27 | 1.10.0 K Hoang 10/02/2022 Add support to new ESP32-S3 28 | 1.10.1 K Hoang 11/02/2022 Add LittleFS support to ESP32-C3. Use core LittleFS instead of Lorol's LITTLEFS for v2.0.0+ 29 | 1.10.2 K Hoang 13/03/2022 Send CORS header in handleWifiSave() function 30 | 1.11.0 K Hoang 09/09/2022 Fix ESP32 chipID and add ESP_getChipOUI() 31 | 1.12.0 K Hoang 07/10/2022 Optional display Credentials (SSIDs, PWDs) in Config Portal 32 | 1.12.1 K Hoang 25/10/2022 Using random channel for softAP without password. Add astyle using allman style 33 | *****************************************************************************************************************************/ 34 | 35 | #pragma once 36 | 37 | #ifndef ESP_WiFiManager_h 38 | #define ESP_WiFiManager_h 39 | 40 | #include //https://github.com/khoih-prog/ESP_WiFiManager 41 | #include //https://github.com/khoih-prog/ESP_WiFiManager 42 | 43 | #endif // ESP_WiFiManager_h 44 | 45 | -------------------------------------------------------------------------------- /src/ESP_WiFiManager_Debug.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************************************************************** 2 | ESP_WiFiManager_Debug.h 3 | For ESP8266 / ESP32 boards 4 | 5 | ESP_WiFiManager is a library for the ESP8266/Arduino platform 6 | (https://github.com/esp8266/Arduino) to enable easy 7 | configuration and reconfiguration of WiFi credentials using a Captive Portal 8 | inspired by: 9 | http://www.esp8266.com/viewtopic.php?f=29&t=2520 10 | https://github.com/chriscook8/esp-arduino-apboot 11 | https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ 12 | 13 | Modified from Tzapu https://github.com/tzapu/WiFiManager 14 | and from Ken Taylor https://github.com/kentaylor 15 | 16 | Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager 17 | Licensed under MIT license 18 | 19 | Version: 1.12.1 20 | 21 | Version Modified By Date Comments 22 | ------- ----------- ---------- ----------- 23 | 1.0.0 K Hoang 07/10/2019 Initial coding 24 | ... 25 | 1.8.0 K Hoang 29/12/2021 Fix `multiple-definitions` linker error and weird bug related to src_cpp 26 | 1.9.0 K Hoang 17/01/2022 Enable compatibility with old code to include only ESP_WiFiManager.h 27 | 1.10.0 K Hoang 10/02/2022 Add support to new ESP32-S3 28 | 1.10.1 K Hoang 11/02/2022 Add LittleFS support to ESP32-C3. Use core LittleFS instead of Lorol's LITTLEFS for v2.0.0+ 29 | 1.10.2 K Hoang 13/03/2022 Send CORS header in handleWifiSave() function 30 | 1.11.0 K Hoang 09/09/2022 Fix ESP32 chipID and add ESP_getChipOUI() 31 | 1.12.0 K Hoang 07/10/2022 Optional display Credentials (SSIDs, PWDs) in Config Portal 32 | 1.12.1 K Hoang 25/10/2022 Using random channel for softAP without password. Add astyle using allman style 33 | *****************************************************************************************************************************/ 34 | 35 | #pragma once 36 | 37 | #ifndef ESP_WiFiManager_Debug_H 38 | #define ESP_WiFiManager_Debug_H 39 | 40 | ////////////////////////////////////////// 41 | 42 | #ifdef WIFIMGR_DEBUG_PORT 43 | #define WM_DBG_PORT WIFIMGR_DEBUG_PORT 44 | #else 45 | #define WM_DBG_PORT Serial 46 | #endif 47 | 48 | ////////////////////////////////////////// 49 | 50 | // Change _WIFIMGR_LOGLEVEL_ to set tracing and logging verbosity 51 | // 0: DISABLED: no logging 52 | // 1: ERROR: errors 53 | // 2: WARN: errors and warnings 54 | // 3: INFO: errors, warnings and informational (default) 55 | // 4: DEBUG: errors, warnings, informational and debug 56 | 57 | #ifndef _WIFIMGR_LOGLEVEL_ 58 | #define _WIFIMGR_LOGLEVEL_ 0 59 | #endif 60 | 61 | ////////////////////////////////////////// 62 | 63 | const char WM_MARK[] = "[WM] "; 64 | const char WM_SP[] = " "; 65 | 66 | #define WM_PRINT WM_DBG_PORT.print 67 | #define WM_PRINTLN WM_DBG_PORT.println 68 | 69 | #define WM_PRINT_MARK WM_PRINT(WM_MARK) 70 | #define WM_PRINT_SP WM_PRINT(WM_SP) 71 | 72 | //////////////////////////////////////////////////// 73 | 74 | #define LOGERROR(x) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINTLN(x); } 75 | #define LOGERROR0(x) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT(x); } 76 | #define LOGERROR1(x,y) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); } 77 | #define LOGERROR2(x,y,z) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); } 78 | #define LOGERROR3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>0) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); } 79 | 80 | //////////////////////////////////////////////////// 81 | 82 | #define LOGWARN(x) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINTLN(x); } 83 | #define LOGWARN0(x) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT(x); } 84 | #define LOGWARN1(x,y) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); } 85 | #define LOGWARN2(x,y,z) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); } 86 | #define LOGWARN3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>1) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); } 87 | 88 | //////////////////////////////////////////////////// 89 | 90 | #define LOGINFO(x) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINTLN(x); } 91 | #define LOGINFO0(x) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT(x); } 92 | #define LOGINFO1(x,y) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); } 93 | #define LOGINFO2(x,y,z) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); } 94 | #define LOGINFO3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>2) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); } 95 | 96 | //////////////////////////////////////////////////// 97 | 98 | #define LOGDEBUG(x) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINTLN(x); } 99 | #define LOGDEBUG0(x) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT(x); } 100 | #define LOGDEBUG1(x,y) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINTLN(y); } 101 | #define LOGDEBUG2(x,y,z) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINTLN(z); } 102 | #define LOGDEBUG3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>3) { WM_PRINT_MARK; WM_PRINT(x); WM_PRINT_SP; WM_PRINT(y); WM_PRINT_SP; WM_PRINT(z); WM_PRINT_SP; WM_PRINTLN(w); } 103 | 104 | //////////////////////////////////////////////////// 105 | 106 | #endif //ESP_WiFiManager_Debug_H 107 | -------------------------------------------------------------------------------- /travis/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function build_examples() 4 | { 5 | # track the exit code for this platform 6 | local exit_code=0 7 | # loop through results and add them to the array 8 | examples=($(find $PWD/examples/ -name "*.pde" -o -name "*.ino")) 9 | 10 | # get the last example in the array 11 | local last="${examples[@]:(-1)}" 12 | 13 | # loop through example sketches 14 | for example in "${examples[@]}"; do 15 | 16 | # store the full path to the example's sketch directory 17 | local example_dir=$(dirname $example) 18 | 19 | # store the filename for the example without the path 20 | local example_file=$(basename $example) 21 | 22 | echo "$example_file: " 23 | local sketch="$example_dir/$example_file" 24 | echo "$sketch" 25 | #arduino -v --verbose-build --verify $sketch 26 | 27 | # verify the example, and save stdout & stderr to a variable 28 | # we have to avoid reading the exit code of local: 29 | # "when declaring a local variable in a function, the local acts as a command in its own right" 30 | local build_stdout 31 | build_stdout=$(arduino --verify $sketch 2>&1) 32 | 33 | # echo output if the build failed 34 | if [ $? -ne 0 ]; then 35 | # heavy X 36 | echo -e "\xe2\x9c\x96" 37 | echo -e "----------------------------- DEBUG OUTPUT -----------------------------\n" 38 | echo "$build_stdout" 39 | echo -e "\n------------------------------------------------------------------------\n" 40 | 41 | # mark as fail 42 | exit_code=1 43 | 44 | else 45 | # heavy checkmark 46 | echo -e "\xe2\x9c\x93" 47 | fi 48 | done 49 | 50 | return $exit_code 51 | } 52 | -------------------------------------------------------------------------------- /utils/astyle_library.conf: -------------------------------------------------------------------------------- 1 | # Code formatting rules for Arduino libraries, modified from for KH libraries: 2 | # 3 | # https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf 4 | # 5 | 6 | # astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino 7 | 8 | --mode=c 9 | --lineend=linux 10 | --style=allman 11 | 12 | # -r or -R 13 | #--recursive 14 | 15 | # -c => Converts tabs into spaces 16 | convert-tabs 17 | 18 | # -s2 => 2 spaces indentation 19 | --indent=spaces=2 20 | 21 | # -t2 => tab =2 spaces 22 | #--indent=tab=2 23 | 24 | # -C 25 | --indent-classes 26 | 27 | # -S 28 | --indent-switches 29 | 30 | # -xW 31 | --indent-preproc-block 32 | 33 | # -Y => indent classes, switches (and cases), comments starting at column 1 34 | --indent-col1-comments 35 | 36 | # -M120 => maximum of 120 spaces to indent a continuation line 37 | --max-continuation-indent=120 38 | 39 | # -xC120 => max‑code‑length will break a line if the code exceeds # characters 40 | --max-code-length=120 41 | 42 | # -f => 43 | --break-blocks 44 | 45 | # -p => put a space around operators 46 | --pad-oper 47 | 48 | # -xg => Insert space padding after commas 49 | --pad-comma 50 | 51 | # -H => put a space after if/for/while 52 | pad-header 53 | 54 | # -xb => Break one line headers (e.g. if/for/while) 55 | --break-one-line-headers 56 | 57 | # -c => Converts tabs into spaces 58 | #--convert-tabs 59 | 60 | # if you like one-liners, keep them 61 | #keep-one-line-statements 62 | 63 | # -xV 64 | --attach-closing-while 65 | 66 | #unpad-paren 67 | 68 | # -xp 69 | remove-comment-prefix 70 | 71 | -------------------------------------------------------------------------------- /utils/restyle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for dir in . ; do 4 | find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \; 5 | done 6 | 7 | --------------------------------------------------------------------------------