Initial commit of Arduino libraries

This commit is contained in:
Sam
2025-05-23 10:47:41 +10:00
commit 5bfce5fc3e
2476 changed files with 1108481 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
## Contributing to AsyncTCP_SSL
### Reporting Bugs
Please report bugs in [AsyncTCP_SSL Issues](https://github.com/khoih-prog/AsyncTCP_SSL/issues) if you find them.
However, before reporting a bug please check through the following:
* [Existing Open Issues](https://github.com/khoih-prog/AsyncTCP_SSL/issues) - someone might have already encountered this.
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/AsyncTCP_SSL/issues/new).
### How to submit a bug report
Please ensure to specify the following:
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
* `ESP32` Core Version (e.g. ESP32 core v2.0.5)
* `ESP32` Board type (e.g. ESP32_DEV, ESP32_S2, ESP32_S3, ESP32_C3, etc.)
* Contextual information (e.g. what you were trying to achieve)
* Simplest possible steps to reproduce
* Anything that might be relevant in your opinion, such as:
* Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` for Linux / Ubuntu
* Network configuration
### Example
```
Arduino IDE version: 1.8.19
ESP32 core v2.0.5
ESP32_DEV Module
OS: Ubuntu 20.04 LTS
Linux xy-Inspiron-3593 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Context:
I encountered a crash while using TimerInterrupt.
Steps to reproduce:
1. ...
2. ...
3. ...
4. ...
```
### Sending Feature Requests
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/AsyncTCP_SSL/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
### Sending Pull Requests
Pull Requests with changes and fixes are also welcome!

165
AsyncTCP_SSL/LICENSE Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

625
AsyncTCP_SSL/README.md Normal file
View File

@@ -0,0 +1,625 @@
# AsyncTCP_SSL
[![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncTCP_SSL.svg?)](https://www.ardu-badge.com/AsyncTCP_SSL)
[![GitHub release](https://img.shields.io/github/release/khoih-prog/AsyncTCP_SSL.svg)](https://github.com/khoih-prog/AsyncTCP_SSL/releases)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncTCP_SSL.svg)](http://github.com/khoih-prog/AsyncTCP_SSL/issues)
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Donate to my libraries using BuyMeACoffee" style="height: 50px !important;width: 181px !important;" ></a>
<a href="https://www.buymeacoffee.com/khoihprog6" title="Donate to my libraries using BuyMeACoffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-orange.svg?logo=buy-me-a-coffee&logoColor=FFDD00" style="height: 20px !important;width: 200px !important;" ></a>
---
---
## Table of contents
* [Important Note for ESP32_S3](#Important-Note-for-ESP32_S3)
* [Important Change from v1.2.0](#Important-Change-from-v120)
* [Why do we need this AsyncTCP_SSL library](#why-do-we-need-this-AsyncTCP_SSL-library)
* [Features](#features)
* [Why Async is better](#why-async-is-better)
* [Currently supported Boards](#currently-supported-boards)
* [Changelog](changelog.md)
* [Prerequisites](#prerequisites)
* [Installation](#installation)
* [Use Arduino Library Manager](#use-arduino-library-manager)
* [Manual Install](#manual-install)
* [VS Code & PlatformIO](#vs-code--platformio)
* [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs)
* [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error)
* [Note for Platform IO using ESP32 LittleFS](#note-for-platform-io-using-esp32-littlefs)
* [HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)](#howto-use-analogread-with-esp32-running-wifi-andor-bluetooth-btble)
* [1. ESP32 has 2 ADCs, named ADC1 and ADC2](#1--esp32-has-2-adcs-named-adc1-and-adc2)
* [2. ESP32 ADCs functions](#2-esp32-adcs-functions)
* [3. ESP32 WiFi uses ADC2 for WiFi functions](#3-esp32-wifi-uses-adc2-for-wifi-functions)
* [Orignal documentation](#Orignal-documentation)
* [AsyncSSLClient](#AsyncSSLClient)
* [Examples](#examples)
* [1. multiFileProject](examples/multiFileProject)
* [Debug Terminal Output Samples](#debug-terminal-output-samples)
* [1. AsyncHTTPSRequest_ESP on ESP32_DEV](#1-AsyncHTTPSRequest_ESP-on-ESP32_DEV)
* [2. AsyncHTTPSRequest_ESP on ESP32S2_DEV](#2-AsyncHTTPSRequest_ESP-on-ESP32S2_DEV)
* [3. AsyncHTTPSRequest_ESP on ESP32C3_DEV](#3-AsyncHTTPSRequest_ESP-on-ESP32C3_DEV)
* [4. AsyncHTTPSRequest_ESP_WiFiManager on ESP32_DEV](#4-AsyncHTTPSRequest_ESP_WiFiManager-on-ESP32_DEV)
* [5. AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV](#5-AsyncHTTPSRequest_ESP_Multi-on-ESP32S3_DEV)
* [Debug](#debug)
* [Troubleshooting](#troubleshooting)
* [Issues](#issues)
* [TO DO](#to-do)
* [DONE](#done)
* [Contributions and Thanks](#contributions-and-thanks)
* [Contributing](#contributing)
* [License](#license)
* [Copyright](#copyright)
---
---
### Important Note for ESP32_S3
**Don't use `ESP32_S3` with core v2.0.4**. Check `already fixed` [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165)
**ESP32_S3 is OK now with core v2.0.5**
---
### Important Change from v1.2.0
Please have a look at [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error)
---
### Why do we need this [AsyncTCP_SSL library](https://github.com/khoih-prog/AsyncTCP_SSL)
#### Features
This library is based on, modified from:
1. [Hristo Gochkov's AsyncTCP](https://github.com/me-no-dev/AsyncTCP)
2. [Maarten Fremouw's AsyncTCP](https://github.com/fremouw/AsyncTCP).
3. [Thorsten von Eicken's AsyncTCP](https://github.com/tve/AsyncTCP)
to apply the better and faster **asynchronous** feature of the **powerful** [AsyncTCP Library](https://github.com/me-no-dev/AsyncTCP) with SSL, and will be the base for future and more advanced Async libraries for ESP32, such as AsyncSSLWebServer, AsyncHTTPSRequest, etc.
#### Why Async is better
- Using asynchronous network means that you can handle **more than one connection at the same time**
- **You are called once the request is ready and parsed**
- When you send the response, you are **immediately ready** to handle other connections while the server is taking care of sending the response in the background
- **Speed is OMG**
- **Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse**
- Easily extensible to handle **any type of content**
- Supports Continue 100
- **Async WebSocket plugin offering different locations without extra servers or ports**
- Async EventSource (Server-Sent Events) plugin to send events to the browser
- URL Rewrite plugin for conditional and permanent url rewrites
- ServeStatic plugin that supports cache, Last-Modified, default index and more
- Simple template processing engine to handle templates
### Currently supported Boards
1. `ESP32` boards, such as ESP32_DEV, etc.
2. `ESP32_S2`-based boards, such as ESP32S2_DEV, ESP32_S2 Saola, etc.
3. `ESP32_C3`-based boards, such as ESP32C3_DEV, etc.
4. `ESP32_S3`-based boards, such as ESP32S3_DEV, etc., using ESP32 core `v2.0.3` or `v2.0.5+`
---
---
## Prerequisites
1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest)
2. [`ESP32 Core 2.0.5+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) for ESP32, ESP32_S2, ESP32_C3
3. [`ESP32 Core 2.0.4`](https://github.com/espressif/arduino-esp32) can't be used for ESP32_S3-based boards. Check `already fixed` [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165)
---
---
## Installation
### Use Arduino Library Manager
The best and easiest way is to use `Arduino Library Manager`. Search for [**AsyncTCP_SSL**](https://github.com/khoih-prog/AsyncTCP_SSL), then select / install the latest version.
You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncTCP_SSL.svg?)](https://www.ardu-badge.com/AsyncTCP_SSL) for more detailed instructions.
### Manual Install
Another way to install is to:
1. Navigate to [**AsyncTCP_SSL**](https://github.com/khoih-prog/AsyncTCP_SSL) page.
2. Download the latest release `AsyncTCP_SSL-main.zip`.
3. Extract the zip file to `AsyncTCP_SSL-main` directory
4. Copy whole `AsyncTCP_SSL-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`.
### VS Code & PlatformIO
1. Install [VS Code](https://code.visualstudio.com/)
2. Install [PlatformIO](https://platformio.org/platformio-ide)
3. Install [**AsyncTCP_SSL** library](https://platformio.org/lib/show/12965/AsyncTCP_SSL) by using [Library Manager](https://platformio.org/lib/show/12965/AsyncTCP_SSL/installation). Search for **AsyncTCP_SSL** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22)
4. Use included [platformio.ini](platformio/platformio.ini) file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at [Project Configuration File](https://docs.platformio.org/page/projectconf.html)
---
---
### Note for Platform IO using ESP32 LittleFS
In Platform IO, to fix the error when using [`LittleFS_esp32 v1.0`](https://github.com/lorol/LITTLEFS) for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line
from
```
//#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */
```
to
```
#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */
```
It's advisable to use the latest [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) to avoid the issue.
Thanks to [Roshan](https://github.com/solroshan) to report the issue in [Error esp_littlefs.c 'utime_p'](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/28)
---
---
### HOWTO Fix `Multiple Definitions` Linker Error
The current library implementation, using `xyz-Impl.h` instead of standard `xyz.cpp`, possibly creates certain `Multiple Definitions` Linker error in certain use cases.
You can include this `.hpp` file
```
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
#include "AsyncTCP_SSL.hpp" //https://github.com/khoih-prog/AsyncTCP_SSL
```
in many files. But be sure to use the following `.h` file **in just 1 `.h`, `.cpp` or `.ino` file**, which must **not be included in any other file**, to avoid `Multiple Definitions` Linker Error
```
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "AsyncTCP_SSL.h" //https://github.com/khoih-prog/AsyncTCP_SSL
```
Check the new [**multiFileProject** example](examples/multiFileProject) for a `HOWTO` demo.
---
---
### Note for Platform IO using ESP32 LittleFS
In Platform IO, to fix the error when using [`LittleFS_esp32 v1.0`](https://github.com/lorol/LITTLEFS) for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line
from
```
//#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */
```
to
```
#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */
```
It's advisable to use the latest [`LittleFS_esp32 v1.0.5+`](https://github.com/lorol/LITTLEFS) to avoid the issue.
Thanks to [Roshan](https://github.com/solroshan) to report the issue in [Error esp_littlefs.c 'utime_p'](https://github.com/khoih-prog/ESPAsync_WiFiManager/issues/28)
---
---
### HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)
Please have a look at [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to have more detailed description and solution of the issue.
#### 1. ESP32 has 2 ADCs, named ADC1 and ADC2
#### 2. ESP32 ADCs functions
- ADC1 controls ADC function for pins **GPIO32-GPIO39**
- ADC2 controls ADC function for pins **GPIO0, 2, 4, 12-15, 25-27**
#### 3.. ESP32 WiFi uses ADC2 for WiFi functions
Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master/components/driver/adc_common.c#L61)
> In ADC2, there're two locks used for different cases:
> 1. lock shared with app and Wi-Fi:
> ESP32:
> When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.
> ESP32S2:
> The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
>
> 2. lock shared between tasks:
> when several tasks sharing the ADC2, we want to guarantee
> all the requests will be handled.
> Since conversions are short (about 31us), app returns the lock very soon,
> we use a spinlock to stand there waiting to do conversions one by one.
>
> adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
- In order to use ADC2 for other functions, we have to **acquire complicated firmware locks and very difficult to do**
- So, it's not advisable to use ADC2 with WiFi/BlueTooth (BT/BLE).
- Use ADC1, and pins GPIO32-GPIO39
- If somehow it's a must to use those pins serviced by ADC2 (**GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27**), use the **fix mentioned at the end** of [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to work with ESP32 WiFi/BlueTooth (BT/BLE).
---
---
## Orignal documentation
For ESP32, check [AsyncTCP Library](https://github.com/me-no-dev/AsyncTCP)
This is a fully asynchronous SSL TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs.
### AsyncSSLClient
The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use.
---
---
### Examples
1. [multiFileProject](examples/multiFileProject). **New**
---
---
### Debug Terminal Output Samples
#### 1. AsyncHTTPSRequest_ESP on ESP32_DEV
Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP) on ESP32_DEV to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL).
```
Starting AsyncHTTPSRequest_ESP using ESP32_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.1.2
Connecting to WiFi SSID: HueNet1
.......
AsyncHTTPSRequest @ IP : 192.168.2.133
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:35:32.451975-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663479332
utc_datetime: 2022-09-18T05:35:32.451975+00:00
utc_offset: -04:00
week_number: 37
**************************************
HHHHHH
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:36:31.992595-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663479391
utc_datetime: 2022-09-18T05:36:31.992595+00:00
utc_offset: -04:00
week_number: 37
```
---
#### 2. AsyncHTTPSRequest_ESP on ESP32S2_DEV
Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP) on ESP32S2_DEV to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL).
```
Starting AsyncHTTPSRequest_ESP using ESP32S2_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.1.2
Connecting to WiFi SSID: HueNet1
.......
AsyncHTTPSRequest @ IP : 192.168.2.79
[ATCP] _handle_async_event: LWIP_TCP_DNS = 0x3FFE4E24
[ATCP] _handle_async_event: LWIP_TCP_DNS, name = worldtimeapi.org , IP = 213.188.196.246
[ATCP] _handle_async_event: LWIP_TCP_CONNECTED = 0x3FFE4E24 0x3FFE5024
[ATCP] _handle_async_event: LWIP_TCP_CONNECTED = 0
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 305
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1436
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1436
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1242
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 107
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 6
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 45
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 51
[ATCP] _handle_async_event: LWIP_TCP_SENT = 0x3FFE5024
[ATCP] _sent: len = 106
[ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024
[ATCP] _recv: tot_len = 1016
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:46:31.858783-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663479991
utc_datetime: 2022-09-18T05:46:31.858783+00:00
utc_offset: -04:00
week_number: 37
**************************************
```
---
#### 3. AsyncHTTPSRequest_ESP on ESP32C3_DEV
Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP) on ESP32C3_DEV to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL).
```
Starting AsyncHTTPSRequest_ESP using ESP32C3_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.1.2
Connecting to WiFi SSID: HueNet1
.........
AsyncHTTPSRequest @ IP : 192.168.2.80
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:35:32.451975-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663479332
utc_datetime: 2022-09-18T05:35:32.451975+00:00
utc_offset: -04:00
week_number: 37
**************************************
```
---
#### 4. AsyncHTTPSRequest_ESP_WiFiManager on ESP32_DEV
Following is the debug terminal when running example [AsyncHTTPSRequest_ESP_WiFiManager](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP_WiFiManager) on ESP32_DEV to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL), and [ESPAsync_WiFiManager Library](https://github.com/khoih-prog/ESPAsync_WiFiManager)
```
Starting AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32_DEV
ESPAsync_WiFiManager v1.14.1
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.1.2
Stored: SSID = HueNet1, Pass = 12345678
Got stored Credentials. Timeout 120s
ConnectMultiWiFi in setup
After waiting 11.38 secs more in setup(), connection result is connected. Local IP: 192.168.2.232
H
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:36:31.992595-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663479391
utc_datetime: 2022-09-18T05:36:31.992595+00:00
utc_offset: -04:00
week_number: 37
**************************************
H
```
---
#### 5. AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV
Following is the debug terminal when running example [AsyncHTTPSRequest_ESP_Multi](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP_Multi) on **ESP32S3_DEV on ESP32 core v2.0.5** to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL)
```
Starting AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV
AsyncTCP_SSL v1.3.1
AsyncHTTPSRequest_Generic v2.1.2
Connecting to WiFi SSID: HueNet1
...
AsyncHTTPSRequest @ IP : 192.168.2.187
Sending request: https://worldtimeapi.org/api/timezone/Europe/Prague.txt
Sending request: https://www.myexternalip.com/raw
[AHTTPS] _onError handler SSL error = OK
[AHTTPS] _onError handler SSL error = OK
**************************************
[AHTTPS] Response Code = HTTP OK
**************************************
aaa.bbb.ccc.ddd
**************************************
**************************************
[AHTTPS] Response Code = HTTP OK
**************************************
abbreviation: CEST
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T07:50:04.395849+02:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-27T01:00:00+00:00
dst_offset: 3600
dst_until: 2022-10-30T01:00:00+00:00
raw_offset: 3600
timezone: Europe/Prague
unixtime: 1663480204
utc_datetime: 2022-09-18T05:50:04.395849+00:00
utc_offset: +02:00
week_number: 37
**************************************
Sending request: https://worldtimeapi.org/api/timezone/America/Toronto.txt
**************************************
[AHTTPS] Response Code = HTTP OK
**************************************
abbreviation: EDT
client_ip: aaa.bbb.ccc.ddd
datetime: 2022-09-18T01:50:05.382100-04:00
day_of_week: 0
day_of_year: 261
dst: true
dst_from: 2022-03-13T07:00:00+00:00
dst_offset: 3600
dst_until: 2022-11-06T06:00:00+00:00
raw_offset: -18000
timezone: America/Toronto
unixtime: 1663480205
utc_datetime: 2022-09-18T05:50:05.382100+00:00
utc_offset: -04:00
week_number: 37
**************************************
H
```
---
---
### Debug
Debug is enabled by default on Serial.
You can also change the debugging level `_ASYNC_TCP_SSL_LOGLEVEL_` from 0 to 4 in the sketch
```cpp
#define _ASYNC_TCP_SSL_LOGLEVEL_ 1
```
---
### Troubleshooting
If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.
Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.
---
---
### Issues
Submit issues to: [AsyncTCP_SSL issues](https://github.com/khoih-prog/AsyncTCP_SSL/issues)
---
## TO DO
1. Search for bug and improvement.
2. Similar Async SSL libraries for ESP8266, STM32, Portenta_H7 and many other boards
3. Permit both HTTP and HTTPS
---
## DONE
1. Add support to ESP32 using SSL
2. Add Table of Contents
3. Add debug feature
4. Fix `multiple-definitions` linker error
5. Add examples
6. Remove hard-code if possible
7. Improve debug messages by adding functions to display `error/state messages` instead of `cryptic error/state number`
8. Add support to `ESP32_S3`, using ESP32 core `v2.0.3` or `v2.0.5+`. **Don't use `ESP32_S3` with core v2.0.4**. Check `already fixed` [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165)
9. Increase `ASYNC_QUEUE_LENGTH` to default **512 from 32** and make it user-configurable
10. Increase `ASYNC_TCP_PRIORITY` to default **10 from 3**, and make it user-configurable
---
---
### Contributions and Thanks
Many thanks for everyone for bug reporting, new feature suggesting, testing and contributing to the development of this library.
### Contributions and Thanks
1. Based on and modified from [Hristo Gochkov's AsyncTCP](https://github.com/me-no-dev/AsyncTCP). Many thanks to [Hristo Gochkov](https://github.com/me-no-dev) for great [AsyncTCP Library](https://github.com/me-no-dev/AsyncTCP)
2. Based on [Maarten Fremouw's AsyncTCP Library](https://github.com/fremouw/AsyncTCP).
3. Based on [Thorsten von Eicken's AsyncTCP Library](https://github.com/tve/AsyncTCP).
<table>
<tr>
<td align="center"><a href="https://github.com/me-no-dev"><img src="https://github.com/me-no-dev.png" width="100px;" alt="me-no-dev"/><br /><sub><b>⭐️⭐️ Hristo Gochkov</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/fremouw"><img src="https://github.com/fremouw.png" width="100px;" alt="fremouw"/><br /><sub><b>Maarten Fremouw</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/tve"><img src="https://github.com/tve.png" width="100px;" alt="tve"/><br /><sub><b>Thorsten von Eicken</b></sub></a><br /></td>
</tr>
</table>
---
## Contributing
If you want to contribute to this project:
- Report bugs and errors
- Ask for enhancements
- Create issues and pull requests
- Tell other people about this library
---
### License
- The library is licensed under [LGPLv3](https://github.com/khoih-prog/AsyncTCP_SSL/blob/main/LICENSE)
---
## Copyright
- Copyright 2016- Hristo Gochkov
- Copyright 2019- Maarten Fremouw
- Copyright 2019- Thorsten von Eicken
- Copyright 2021- Khoi Hoang

54
AsyncTCP_SSL/changelog.md Normal file
View File

@@ -0,0 +1,54 @@
# AsyncTCP_SSL Library
[![arduino-library-badge](https://www.ardu-badge.com/badge/AsyncTCP_SSL.svg?)](https://www.ardu-badge.com/AsyncTCP_SSL)
[![GitHub release](https://img.shields.io/github/release/khoih-prog/AsyncTCP_SSL.svg)](https://github.com/khoih-prog/AsyncTCP_SSL/releases)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncTCP_SSL.svg)](http://github.com/khoih-prog/AsyncTCP_SSL/issues)
---
---
## Table of Contents
* [Changelog](#changelog)
* [Releases v1.3.1](#Releases-v131)
* [Releases v1.3.0](#Releases-v130)
* [Releases v1.2.0](#Releases-v120)
* [Releases v1.1.0](#Releases-v110)
* [Initial Releases v1.0.0](#Initial-Releases-v100)
---
---
## Changelog
### Releases v1.3.1
1. Increase `ASYNC_QUEUE_LENGTH` to default 512 from 32 and make it user-configurable
2. Increase `ASYNC_TCP_PRIORITY` to default 10 from 3, and make it user-configurable
### Releases v1.3.0
1. Remove hard-code if possible
2. Improve debug messages by adding functions to display `error/state messages` instead of `cryptic error/state number`
3. Clean up
4. Add support to `ESP32_S3`, using ESP32 core `v2.0.3`. **Don't use `ESP32_S3` with core v2.0.4**. Check [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165)
### Releases v1.2.0
1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
2. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project.
3. Add `platformio.ini`
### Releases v1.1.0
1. Fix duplication bug when using `src_h`
2. Enable coexistence with AsyncTCP
### Initial Releases v1.0.0
1. Initial coding to support **ESP32**

View File

@@ -0,0 +1,13 @@
/****************************************************************************************************************************
multiFileProject.cpp
For ESP32
AsyncTCP_SSL is a library for the ESP32
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
Licensed under MIT license
*****************************************************************************************************************************/
// To demo how to include files in multi-file Projects
#include "multiFileProject.h"

View File

@@ -0,0 +1,22 @@
/****************************************************************************************************************************
multiFileProject.h
For ESP32
AsyncTCP_SSL is a library for the ESP32
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
Licensed under MIT license
*****************************************************************************************************************************/
// To demo how to include files in multi-file Projects
#pragma once
// Use larger queue size if necessary for large data transfer. Default is 512 bytes if not defined here
#define ASYNC_QUEUE_LENGTH 512
// Use larger priority if necessary. Default is 10 if not defined here. Must be > 4 or adjusted to 4
#define CONFIG_ASYNC_TCP_PRIORITY (12)
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
#include "AsyncTCP_SSL.hpp"

View File

@@ -0,0 +1,49 @@
/****************************************************************************************************************************
multiFileProject.ino
For ESP32
AsyncTCP_SSL is a library for the ESP32
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
Licensed under MIT license
*****************************************************************************************************************************/
// To demo how to include files in multi-file Projects
#if !( defined(ESP32) )
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define ASYNC_TCP_SSL_VERSION_MIN_TARGET "AsyncTCP_SSL v1.3.1"
#define ASYNC_TCP_SSL_VERSION_MIN 1003001
#include "multiFileProject.h"
#include <WiFi.h>
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "AsyncTCP_SSL.h"
void setup()
{
Serial.begin(115200);
while (!Serial && millis() < 5000);
Serial.println("\nStart multiFileProject on "); Serial.println(ARDUINO_BOARD);
Serial.println(ASYNC_TCP_SSL_VERSION);
#if defined(ASYNC_TCP_SSL_VERSION_MIN)
if (ASYNC_TCP_SSL_VERSION_INT < ASYNC_TCP_SSL_VERSION_MIN)
{
Serial.print("Warning. Must use this example on Version equal or later than : ");
Serial.println(ASYNC_TCP_SSL_VERSION_MIN_TARGET);
}
#endif
Serial.print("You're OK now");
}
void loop()
{
// put your main code here, to run repeatedly:
}

45
AsyncTCP_SSL/library.json Normal file
View File

@@ -0,0 +1,45 @@
{
"name":"AsyncTCP_SSL",
"version": "1.3.1",
"keywords":"communication, async, tcp, ssl, tls, mbed, free-rtos",
"description":"Asynchronous SSL TCP Library for ESP32. This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest, etc",
"authors":
[
{
"name": "Hristo Gochkov",
"url": "https://github.com/me-no-dev"
},
{
"name": "Maarten Fremouw",
"url": "https://github.com/fremouw"
},
{
"name": "Thorsten von Eicken",
"url": "https://github.com/tve"
},
{
"name": "Khoi Hoang",
"url": "https://github.com/khoih-prog",
"email": "khoih.prog@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/khoih-prog/AsyncTCP_SSL.git"
},
"homepage": "https://github.com/khoih-prog/AsyncTCP_SSL",
"export": {
"exclude": [
"linux",
"extras",
"tests"
]
},
"license": "LGPL-3.0",
"frameworks": "*",
"platforms": "espressif32",
"examples": "examples/*/*/*.ino",
"headers": ["AsyncTCP_SSL.h", "AsyncTCP_SSL.hpp"]
}

View File

@@ -0,0 +1,12 @@
name=AsyncTCP_SSL
version=1.3.1
author=Hristo Gochkov, Maarten Fremouw, Thorsten von Eicken, Khoi Hoang
maintainer=Khoi Hoang <khoih.prog@gmail.com>
sentence=Asynchronous SSL TCP Library for ESP32.
paragraph=This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest, etc.
category=Communication
url=https://github.com/khoih-prog/AsyncTCP_SSL
architectures=esp32
repository=https://github.com/khoih-prog/AsyncTCP_SSL
license=LGPLv3
includes=AsyncTCP_SSL.h,AsyncTCP_SSL.hpp

View File

@@ -0,0 +1,339 @@
;PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
; ============================================================
; chose environment:
; ESP8266
; ESP32
; SAMD
; NRF52
; STM32
; ============================================================
;default_envs = ESP8266
default_envs = ESP32
;default_envs = SAMD
;default_envs = NRF52
;default_envs = STM32
[env]
; ============================================================
; Serial configuration
; choose upload speed, serial-monitor speed
; ============================================================
upload_speed = 921600
;upload_port = COM11
;monitor_speed = 9600
;monitor_port = COM11
; Checks for the compatibility with frameworks and dev/platforms
lib_compat_mode = strict
lib_ldf_mode = chain+
;lib_ldf_mode = deep+
lib_deps =
build_flags =
; set your debug output (default=Serial)
; -D DEBUG_ESP_PORT=Serial
; comment the folowing line to enable WiFi debugging
; -D NDEBUG
[env:ESP8266]
platform = espressif8266
framework = arduino
; ============================================================
; Board configuration
; choose your board by uncommenting one of the following lines
; ============================================================
;board = gen4iod
;board = huzzah
;board = oak
;board = esp_wroom_02
;board = espduino
;board = espectro
;board = espino
;board = espresso_lite_v1
;board = espresso_lite_v2
;board = esp12e
;board = esp01_1m
;board = esp01
;board = esp07
;board = esp8285
;board = heltec_wifi_kit_8
;board = inventone
;board = nodemcu
board = nodemcuv2
;board = modwifi
;board = phoenix_v1
;board = phoenix_v2
;board = sparkfunBlynk
;board = thing
;board = thingdev
;board = esp210
;board = espinotee
;board = d1
;board = d1_mini
;board = d1_mini_lite
;board = d1_mini_pro
;board = wifi_slot
;board = wifiduino
;board = wifinfo
;board = wio_link
;board = wio_node
;board = xinabox_cw01
;board = esp32doit-devkit-v1
[env:ESP32]
platform = espressif32
framework = arduino
; ============================================================
; Board configuration
; choose your board by uncommenting one of the following lines
; ============================================================
;board = esp32cam
;board = alksesp32
;board = featheresp32
;board = espea32
;board = bpi-bit
;board = d-duino-32
board = esp32doit-devkit-v1
;board = pocket_32
;board = fm-devkit
;board = pico32
;board = esp32-evb
;board = esp32-gateway
;board = esp32-pro
;board = esp32-poe
;board = oroca_edubot
;board = onehorse32dev
;board = lopy
;board = lopy4
;board = wesp32
;board = esp32thing
;board = sparkfun_lora_gateway_1-channel
;board = ttgo-lora32-v1
;board = ttgo-t-beam
;board = turta_iot_node
;board = lolin_d32
;board = lolin_d32_pro
;board = lolin32
;board = wemosbat
;board = widora-air
;board = xinabox_cw02
;board = iotbusio
;board = iotbusproteus
;board = nina_w10
[env:SAMD]
platform = atmelsam
framework = arduino
; ============================================================
; Choose your board by uncommenting one of the following lines
; ============================================================
; ============================================================
; Board configuration Adafruit SAMD
; ============================================================
;board = adafruit_feather_m0
;board = adafruit_feather_m0_express
;board = adafruit_metro_m0
;board = adafruit_circuitplayground_m0
;board = adafruit_gemma_m0
;board = adafruit_trinket_m0
;board = adafruit_itsybitsy_m0
;board = adafruit_pirkey
;board = adafruit_hallowing
;board = adafruit_crickit_m0
;board = adafruit_metro_m4
;board = adafruit_grandcentral_m4
board = adafruit_itsybitsy_m4
;board = adafruit_feather_m4
;board = adafruit_trellis_m4
;board = adafruit_pyportal_m4
;board = adafruit_pyportal_m4_titano
;board = adafruit_pybadge_m4
;board = adafruit_metro_m4_airliftlite
;board = adafruit_pygamer_m4
;board = adafruit_pygamer_advance_m4
;board = adafruit_pybadge_airlift_m4
;board = adafruit_monster_m4sk
;board = adafruit_hallowing_m4
; ============================================================
; Board configuration Arduino SAMD and SAM
; ============================================================
;board = arduino_zero_edbg
;board = arduino_zero_native
;board = mkr1000
;board = mkrzero
;board = mkrwifi1010
;board = nano_33_iot
;board = mkrfox1200
;board = mkrwan1300
;board = mkrwan1310
;board = mkrgsm1400
;board = mkrnb1500
;board = mkrvidor4000
;board = adafruit_circuitplayground_m0
;board = mzero_pro_bl_dbg
;board = mzero_pro_bl
;board = mzero_bl
;board = tian
;board = tian_cons
;board = arduino_due_x_dbg
;board = arduino_due_x
; ============================================================
; Board configuration Seeeduino SAMD
; ============================================================
;board = seeed_wio_terminal
;board = Seeed_femto_m0
;board = seeed_XIAO_m0
;board = Wio_Lite_MG126
;board = WioGPS
;board = zero
;board = rolawan
;board = seeed_grove_ui_wireless
[env:NRF52]
platform = nordicnrf52
framework = arduino
; ============================================================
; Board configuration Adafruit nRF52
; choose your board by uncommenting one of the following lines
; ============================================================
;board = feather52832
board = feather52840
;board = feather52840sense
;board = itsybitsy52840
;board = cplaynrf52840
;board = cluenrf52840
;board = metro52840
;board = pca10056
;board = particle_xenon
;board = mdbt50qrx
;board = ninab302
;board = ninab112
[env:STM32]
platform = ststm32
framework = arduino
; ============================================================
; Choose your board by uncommenting one of the following lines
; ============================================================
; ============================================================
; Board configuration Nucleo-144
; ============================================================
;board = nucleo_f207zg
;board = nucleo_f429zi
;board = nucleo_f746zg
;board = nucleo_f756zg
;board = nucleo_f767zi
;board = nucleo_h743zi
;board = nucleo_l496zg
;board = nucleo_l496zg-p
;board = nucleo_l4r5zi
;board = nucleo_l4r5zi-p
; ============================================================
; Board configuration Nucleo-64
; ============================================================
;board = nucleo_f030r8
;board = nucleo_f072rb
;board = nucleo_f091rc
;board = nucleo_f103rb
;board = nucleo_f302r8
;board = nucleo_f303re
;board = nucleo_f401re
;board = nucleo_f411re
;board = nucleo_f446re
;board = nucleo_g071rb
;board = nucleo_g431rb
;board = nucleo_g474re
;board = nucleo_l053r8
;board = nucleo_l073rz
;board = nucleo_l152re
;board = nucleo_l433rc_p
;board = nucleo_l452re
;board = nucleo_l452re-p
;board = nucleo_l476rg
;board = pnucleo_wb55rg
; ============================================================
; Board configuration Nucleo-32
; ============================================================
;board = nucleo_f031k6
;board = nucleo_l031k6
;board = nucleo_l412kb
;board = nucleo_l432lc
;board = nucleo_f303k8
;board = nucleo_g431kb
; ============================================================
; Board configuration Discovery Boards
; ============================================================
;board = disco_f030r8
;board = disco_f072rb
;board = disco_f030r8
;board = disco_f100rb
;board = disco_f407vg
;board = disco_f413zh
;board = disco_f746ng
;board = disco_g0316
;board = disco_l475vg_iot
;board = disco_f072cz-lrwan1
; ============================================================
; Board configuration STM32MP1 Boards
; ============================================================
;board = stm32mp157a-dk1
;board = stm32mp157c-dk2
; ============================================================
; Board configuration Generic Boards
; ============================================================
;board = bluepill_f103c6
;board = bluepill_f103c8
;board = blackpill_f103c8
;board = stm32f103cx
;board = stm32f103rx
;board = stm32f103tx
;board = stm32f103vx
;board = stm32f103zx
;board = stm32f103zet6
;board = maplemini_f103cb
;board = blackpill_f303cc
;board = black_f407ve
;board = black_f407vg
;board = black_f407ze
;board = black_f407zg
;board = blue_f407ve_mini
;board = blackpill_f401cc
;board = blackpill_f411ce
;board = coreboard_f401rc
;board = feather_f405
; ============================================================
; Board configuration Many more Boards to be filled
; ============================================================

View File

@@ -0,0 +1,56 @@
/****************************************************************************************************************************
AsyncTCP_SSL.h
AsyncTCP_SSL is a library for ESP32
Based on and modified from :
1) AsyncTCP (https://github.com/me-no-dev/ESPAsyncTCP)
2) AsyncTCP (https://github.com/tve/AsyncTCP)
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Version: 1.3.1
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32
1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP
1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error
1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible
1.3.1 K Hoang 18/09/2022 Improve stability. Make queue length user-configurable
*****************************************************************************************************************************/
/*
Asynchronous TCP library for Espressif MCUs
Copyright (c) 2016 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ASYNCTCP_SSL_H_
#define ASYNCTCP_SSL_H_
#include "AsyncTCP_SSL.hpp"
#include "AsyncTCP_SSL_Impl.h"
#endif /* ASYNCTCP_SSL_H_ */

View File

@@ -0,0 +1,381 @@
/****************************************************************************************************************************
AsyncTCP_SSL.hpp
AsyncTCP_SSL is a library for ESP32
Based on and modified from :
1) AsyncTCP (https://github.com/me-no-dev/ESPAsyncTCP)
2) AsyncTCP (https://github.com/tve/AsyncTCP)
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Version: 1.3.1
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32
1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP
1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error
1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible
1.3.1 K Hoang 18/09/2022 Improve stability. Make queue length user-configurable
*****************************************************************************************************************************/
/*
Asynchronous TCP library for Espressif MCUs
Copyright (c) 2016 Hristo Gochkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ASYNCTCP_SSL_HPP
#define ASYNCTCP_SSL_HPP
#if !defined(ESP32)
#error This AsyncTCP_SSL library is supporting only ESP32
#endif
/////////////////////////////////////////////////
#define ASYNC_TCP_SSL_VERSION "AsyncTCP_SSL v1.3.1"
#define ASYNC_TCP_SSL_VERSION_MAJOR 1
#define ASYNC_TCP_SSL_VERSION_MINOR 3
#define ASYNC_TCP_SSL_VERSION_PATCH 1
#define ASYNC_TCP_SSL_VERSION_INT 1003001
/////////////////////////////////////////////////
#include "Arduino.h"
#include "IPAddress.h"
#include "sdkconfig.h"
#include <functional>
#include <string>
// in ./libraries/WiFiClientSecure/src/ssl_client.h for ESP32
#include <ssl_client.h>
#include "tcp_mbedtls.h"
extern "C"
{
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "lwip/pbuf.h"
}
#include "AsyncTCP_SSL_Debug.h"
/*****************************************************
// Defined in tools/sdk/esp32s3/include/lwip/lwip/src/include/lwip/tcpbase.h
enum tcp_state
{
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
*****************************************************/
#define INVALID_CLOSED_SLOT -1
//////////////////////////////////////////////////////////////////////////////////////////
//If core is not defined, then we are running in Arduino or PIO
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core
#define CONFIG_ASYNC_TCP_USE_WDT 1 //if enabled, adds between 33us and 200us per event
#endif
/////////////////////////////////////////////////
// Make ASYNC_QUEUE_LENGTH adjustable in sketch. Default 512
#ifndef ASYNC_QUEUE_LENGTH
#define ASYNC_QUEUE_LENGTH 512
#endif
// Make ASYNC_TCP_PRIORITY user-adjustable in sketch. Default 10, can't be less than 4
#if !defined(CONFIG_ASYNC_TCP_PRIORITY)
#define CONFIG_ASYNC_TCP_PRIORITY (10)
#elif (CONFIG_ASYNC_TCP_PRIORITY < 4)
#undef CONFIG_ASYNC_TCP_PRIORITY
#define CONFIG_ASYNC_TCP_PRIORITY (4)
#warning Adjust CONFIG_ASYNC_TCP_PRIORITY to 4
#endif
/////////////////////////////////////////////////
#define ASYNC_MAX_ACK_TIME 5000
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.
#define SSL_HANDSHAKE_TIMEOUT 5000 // timeout to complete SSL handshake
//////////////////////////////////////////////////////////////////////////////////////////////
class AsyncSSLClient;
typedef std::function<void(void*, AsyncSSLClient*)> AcConnectHandlerSSL;
typedef std::function<void(void*, AsyncSSLClient*, size_t len, uint32_t time)> AcAckHandlerSSL;
typedef std::function<void(void*, AsyncSSLClient*, int8_t error)> AcErrorHandlerSSL;
typedef std::function<void(void*, AsyncSSLClient*, void *data, size_t len)> AcDataHandlerSSL;
typedef std::function<void(void*, AsyncSSLClient*, struct pbuf *pb)> AcPacketHandlerSSL;
typedef std::function<void(void*, AsyncSSLClient*, uint32_t time)> AcTimeoutHandlerSSL;
/////////////////////////////////////////////////
struct tcp_pcb;
struct ip_addr;
//////////////////////////////////////////////////////////////////////////////////////////////
class AsyncSSLClient
{
public:
AsyncSSLClient(tcp_pcb* pcb = 0);
virtual ~AsyncSSLClient();
AsyncSSLClient & operator=(const AsyncSSLClient &other);
AsyncSSLClient & operator+=(const AsyncSSLClient &other);
bool operator==(const AsyncSSLClient &other);
bool operator!=(const AsyncSSLClient &other)
{
return !(*this == other);
}
bool connect(IPAddress ip, uint16_t port, bool secure = false);
bool connect(const char* host, uint16_t port, bool secure = false);
void setRootCa(const char* rootca, const size_t len);
void setClientCert(const char* cli_cert, const size_t len);
void setClientKey(const char* cli_key, const size_t len);
void setPsk(const char* psk_ident, const char* psk);
void close(bool now = false);
void stop();
int8_t abort();
bool free();
bool canSend(); //ack is not pending
size_t add(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY); //add for sending
bool send(); //send all data added with the method above
virtual size_t space(); //space available in the TCP window
//write equals add()+send()
virtual size_t write(const char* data);
virtual size_t write(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY); //only when canSend() == true
uint8_t state();
bool connecting();
bool connected();
bool disconnecting();
bool disconnected();
bool freeable(); //disconnected or disconnecting
uint16_t getMss();
uint32_t getRxTimeout();
void setRxTimeout(uint32_t timeout); //no RX data timeout for the connection in seconds
uint32_t getAckTimeout();
void setAckTimeout(uint32_t timeout); //no ACK timeout for the last sent packet in milliseconds
void setNoDelay(bool nodelay);
bool getNoDelay();
uint32_t getRemoteAddress();
uint16_t getRemotePort();
uint32_t getLocalAddress();
uint16_t getLocalPort();
//compatibility
IPAddress remoteIP();
uint16_t remotePort();
IPAddress localIP();
uint16_t localPort();
void onConnect(AcConnectHandlerSSL cb, void* arg = 0); //on successful connect
void onDisconnect(AcConnectHandlerSSL cb, void* arg = 0); //disconnected
void onAck(AcAckHandlerSSL cb, void* arg = 0); //ack received
void onError(AcErrorHandlerSSL cb, void* arg = 0); //unsuccessful connect or error
void onData(AcDataHandlerSSL cb, void* arg = 0); //data received (called if onPacket is not used)
void onPacket(AcPacketHandlerSSL cb, void* arg = 0); //data received
void onTimeout(AcTimeoutHandlerSSL cb, void* arg = 0); //ack timeout
void onPoll(AcConnectHandlerSSL cb, void* arg = 0); //every 125ms when connected
void ackPacket(struct pbuf * pb);//ack pbuf from onPacket
size_t ack(size_t len); //ack data that you have not acked using the method below
void ackLater()
{
_ack_pcb = false; //will not ack the current packet. Call from onData
}
const char * errorToString(int8_t error);
const char * stateToString();
//Do not use any of the functions below!
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
static void _s_error(void *arg, int8_t err);
static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
static void _s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len);
static void _s_handshake(void *arg, struct tcp_pcb *tcp, struct tcp_ssl_pcb* ssl);
static void _s_ssl_error(void *arg, struct tcp_pcb *tcp, int8_t err);
int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err);
tcp_pcb * pcb()
{
return _pcb;
}
//KH
int8_t getClosed_Slot()
{
return _closed_slot;
}
//////
protected:
tcp_pcb* _pcb;
std::string _hostname;
int8_t _closed_slot;
AcConnectHandlerSSL _connect_cb;
void* _connect_cb_arg;
AcConnectHandlerSSL _discard_cb;
void* _discard_cb_arg;
AcAckHandlerSSL _sent_cb;
void* _sent_cb_arg;
AcErrorHandlerSSL _error_cb;
void* _error_cb_arg;
AcDataHandlerSSL _recv_cb;
void* _recv_cb_arg;
AcPacketHandlerSSL _pb_cb;
void* _pb_cb_arg;
AcTimeoutHandlerSSL _timeout_cb;
void* _timeout_cb_arg;
AcConnectHandlerSSL _poll_cb;
void* _poll_cb_arg;
bool _pcb_busy;
uint32_t _pcb_sent_at;
bool _ack_pcb;
uint32_t _rx_ack_len;
uint32_t _rx_last_packet;
uint32_t _rx_since_timeout;
uint32_t _ack_timeout;
uint16_t _connect_port;
////// SSL
size_t _root_ca_len;
char* _root_ca;
size_t _cli_cert_len;
char* _cli_cert;
size_t _cli_key_len;
char* _cli_key;
bool _pcb_secure;
bool _handshake_done;
const char* _psk_ident;
const char* _psk;
//////
int8_t _close();
void _free_closed_slot();
void _allocate_closed_slot();
int8_t _connected(void* pcb, int8_t err);
void _error(int8_t err);
int8_t _poll(tcp_pcb* pcb);
int8_t _sent(tcp_pcb* pcb, uint16_t len);
int8_t _fin(tcp_pcb* pcb, int8_t err);
int8_t _lwip_fin(tcp_pcb* pcb, int8_t err);
void _dns_found(struct ip_addr *ipaddr);
////// SSL
void _ssl_error(int8_t err);
//////
public:
AsyncSSLClient* prev;
AsyncSSLClient* next;
};
typedef std::function<int(void* arg, const char *filename, uint8_t **buf)> AcSSlFileHandlerSSL;
//////////////////////////////////////////////////////////////////////////////////////////////
class AsyncSSLServer
{
public:
AsyncSSLServer(IPAddress addr, uint16_t port);
AsyncSSLServer(uint16_t port);
~AsyncSSLServer();
void onClient(AcConnectHandlerSSL cb, void* arg);
// Dummy, so it compiles with ESP Async WebServer library enabled.
void onSslFileRequest(AcSSlFileHandlerSSL cb, void* arg) {};
void beginSecure(const char *cert, const char *private_key_file, const char *password) {};
void begin();
void end();
void setNoDelay(bool nodelay);
bool getNoDelay();
uint8_t status();
//Do not use any of the functions below!
static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err);
static int8_t _s_accepted(void *arg, AsyncSSLClient* client);
protected:
uint16_t _port;
IPAddress _addr;
bool _noDelay;
tcp_pcb* _pcb;
AcConnectHandlerSSL _connect_cb;
void* _connect_cb_arg;
int8_t _accept(tcp_pcb* newpcb, int8_t err);
int8_t _accepted(AsyncSSLClient* client);
};
//////////////////////////////////////////////////////////////////////////////////////////////
#endif /* ASYNCTCP_SSL_HPP */

View File

@@ -0,0 +1,106 @@
/****************************************************************************************************************************
AsyncTCP_SSL_Debug.h
AsyncTCP_SSL is a library for ESP32
Based on and modified from :
1) AsyncTCP (https://github.com/me-no-dev/ESPAsyncTCP)
2) AsyncTCP (https://github.com/tve/AsyncTCP)
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Version: 1.3.1
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32
1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP
1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error
1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible
1.3.1 K Hoang 18/09/2022 Improve stability. Make queue length user-configurable
*****************************************************************************************************************************/
#pragma once
#ifndef ASYNC_TCP_SSL_DEBUG_H
#define ASYNC_TCP_SSL_DEBUG_H
#ifdef ASYNC_TCP_SSL_DEBUG_PORT
#define DBG_PORT_ATCP ASYNC_TCP_SSL_DEBUG_PORT
#else
#define DBG_PORT_ATCP Serial
#endif
// Change _ASYNC_TCP_SSL_LOGLEVEL_ to set tracing and logging verbosity
// 0: DISABLED: no logging
// 1: ERROR: errors
// 2: WARN: errors and warnings
// 3: INFO: errors, warnings and informational (default)
// 4: DEBUG: errors, warnings, informational and debug
#ifndef _ASYNC_TCP_SSL_LOGLEVEL_
#define _ASYNC_TCP_SSL_LOGLEVEL_ 1
#endif
/////////////////////////////////////////////////////////
#define ATCP_PRINT_MARK ATCP_PRINT("[ATCP] ")
#define ATCP_PRINT_SP DBG_PORT_ATCP.print(" ")
#define ATCP_PRINT_SP0X DBG_PORT_ATCP.print(" 0x")
#define ATCP_PRINT DBG_PORT_ATCP.print
#define ATCP_PRINTLN DBG_PORT_ATCP.println
/////////////////////////////////////////////////////////
#define ATCP_LOGERROR(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); }
#define ATCP_LOGERROR0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT(x); }
#define ATCP_LOGERROR1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINTLN(y); }
#define ATCP_HEXLOGERROR1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINTLN(y, HEX); }
#define ATCP_LOGERROR2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); }
#define ATCP_HEXLOGERROR2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); }
#define ATCP_LOGERROR3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); }
#define ATCP_LOGERROR5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); }
/////////////////////////////////////////////////////////
#define ATCP_LOGWARN(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); }
#define ATCP_LOGWARN0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT(x); }
#define ATCP_LOGWARN1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINTLN(y); }
#define ATCP_HEXLOGWARN1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINTLN(y, HEX); }
#define ATCP_LOGWARN2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); }
#define ATCP_HEXLOGWARN2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); }
#define ATCP_LOGWARN3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); }
#define ATCP_LOGWARN5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); }
/////////////////////////////////////////////////////////
#define ATCP_LOGINFO(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); }
#define ATCP_LOGINFO0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT(x); }
#define ATCP_LOGINFO1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINTLN(y); }
#define ATCP_HEXLOGINFO1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINTLN(y, HEX); }
#define ATCP_LOGINFO2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); }
#define ATCP_HEXLOGINFO2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); }
#define ATCP_LOGINFO3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); }
#define ATCP_LOGINFO5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); }
/////////////////////////////////////////////////////////
#define ATCP_LOGDEBUG(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); }
#define ATCP_LOGDEBUG0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT(x); }
#define ATCP_LOGDEBUG1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINTLN(y); }
#define ATCP_HEXLOGDEBUG1(x,y) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINTLN(y, HEX); }
#define ATCP_LOGDEBUG2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); }
#define ATCP_HEXLOGDEBUG2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); }
#define ATCP_LOGDEBUG3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); }
#define ATCP_LOGDEBUG5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); }
/////////////////////////////////////////////////////////
#endif //ASYNC_TCP_SSL_DEBUG_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,912 @@
/****************************************************************************************************************************
tcp_mbedtls.c
AsyncTCP_SSL is a library for ESP32
Based on and modified from :
1) AsyncTCP (https://github.com/me-no-dev/ESPAsyncTCP)
2) AsyncTCP (https://github.com/tve/AsyncTCP)
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Version: 1.3.1
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32
1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP
1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error
1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible
1.3.1 K Hoang 18/09/2022 Improve stability. Make queue length user-configurable
*****************************************************************************************************************************/
#ifndef _ASYNC_TCP_SSL_LOGLEVEL_
#define _ASYNC_TCP_SSL_LOGLEVEL_ 1
#endif
#include "tcp_mbedtls.h"
#include "lwip/tcp.h"
#include "mbedtls/debug.h"
#include "mbedtls/esp_debug.h"
#include <string.h>
// stubs to call LwIP's tcp functions on the LwIP thread itself, implemented in AsyncTCP.cpp
extern esp_err_t _tcp_output4ssl(struct tcp_pcb * pcb, void* client);
extern esp_err_t _tcp_write4ssl(struct tcp_pcb * pcb, const char* data, size_t size, uint8_t apiflags, void* client);
#define TCP_SSL_DEBUG(...)
static const char pers[] = "esp32-tls";
static int handle_error(int err)
{
if (err == -30848)
{
return err;
}
#ifdef MBEDTLS_ERROR_C
char error_buf[100];
mbedtls_strerror(err, error_buf, 100);
#endif
return err;
}
/**
Certificate verification callback for mbed TLS
Here we only use it to display information on each cert in the chain
*/
// static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
// const uint32_t buf_size = 1024;
// char buf[buf_size];
// (void) data;
// mbedtls_printf("\nVerifying certificate at depth %d:\n", depth);
// mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt);
// mbedtls_printf("%s", buf);
// if (*flags == 0)
// mbedtls_printf("No verification issue for this certificate\n");
// else
// {
// mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags);
// mbedtls_printf("%s\n", buf);
// }
// return 0;
// }
static uint8_t _tcp_ssl_has_client = 0;
struct tcp_ssl_pcb
{
struct tcp_pcb *tcp;
int fd;
mbedtls_ssl_context ssl_ctx;
mbedtls_ssl_config ssl_conf;
mbedtls_x509_crt ca_cert;
bool has_ca_cert;
mbedtls_x509_crt client_cert;
bool has_client_cert;
mbedtls_pk_context client_key;
mbedtls_ctr_drbg_context drbg_ctx;
mbedtls_entropy_context entropy_ctx;
uint8_t type;
void *arg;
tcp_ssl_data_cb_t on_data;
tcp_ssl_handshake_cb_t on_handshake;
tcp_ssl_error_cb_t on_error;
size_t last_wr;
struct pbuf *tcp_pbuf;
int pbuf_offset;
struct tcp_ssl_pcb *next;
};
typedef struct tcp_ssl_pcb tcp_ssl_t;
static tcp_ssl_t * tcp_ssl_array = NULL;
static int tcp_ssl_next_fd = 0;
/////////////////////////////////////////////
// tcp_ssl_recv attempts to read up to len bytes into buf from data already received.
// It is called by mbedtls.
int tcp_ssl_recv(void *ctx, unsigned char *buf, size_t len)
{
tcp_ssl_t *tcp_ssl = (tcp_ssl_t*)ctx;
u16_t recv_len = 0;
if (tcp_ssl->tcp_pbuf == NULL || tcp_ssl->tcp_pbuf->tot_len == 0)
{
//TCP_SSL_DEBUG("tcp_ssl_recv: not yet ready to read: tcp_pbuf: 0x%X.\n", tcp_ssl->tcp_pbuf);
return MBEDTLS_ERR_SSL_WANT_READ;
}
recv_len = pbuf_copy_partial(tcp_ssl->tcp_pbuf, buf, len, tcp_ssl->pbuf_offset);
tcp_ssl->pbuf_offset += recv_len;
if (recv_len == 0)
{
return MBEDTLS_ERR_SSL_WANT_READ;
}
return recv_len;
}
/////////////////////////////////////////////
// tcp_ssl_send attempts to send len bytes from buf.
// It is called by mbedtls.
int tcp_ssl_send(void *ctx, const unsigned char *buf, size_t len)
{
//TCP_SSL_DEBUG("tcp_ssl_send: ctx: 0x%X, buf: 0x%X, len: %d\n", ctx, buf, len);
if (ctx == NULL)
{
//TCP_SSL_DEBUG("tcp_ssl_send: no context set\n");
return -1;
}
if (buf == NULL)
{
//TCP_SSL_DEBUG("tcp_ssl_send: buf not set\n");
return -1;
}
tcp_ssl_t *tcp_ssl = (tcp_ssl_t*)ctx;
size_t tcp_len = 0;
int err = ERR_OK;
if (tcp_sndbuf(tcp_ssl->tcp) < len)
{
tcp_len = tcp_sndbuf(tcp_ssl->tcp);
if (tcp_len == 0)
{
//TCP_SSL_DEBUG("tcp_ssl_send: tcp_sndbuf is zero: %d\n", len);
return ERR_MEM;
}
}
else
{
tcp_len = len;
}
if (tcp_len > 2 * tcp_ssl->tcp->mss)
{
tcp_len = 2 * tcp_ssl->tcp->mss;
}
//TCP_SSL_DEBUG("tcp_ssl_send: tcp_write(%x, %x, %d, %x)\n", tcp_ssl->tcp, (char *)buf, tcp_len, tcp_ssl->arg);
err = _tcp_write4ssl(tcp_ssl->tcp, (char *)buf, tcp_len, TCP_WRITE_FLAG_COPY, tcp_ssl->arg);
if (err < ERR_OK)
{
if (err == ERR_MEM)
{
//TCP_SSL_DEBUG("tcp_ssl_send: No memory %d (%d)\n", tcp_len, len);
return err;
}
//TCP_SSL_DEBUG("tcp_ssl_send: tcp_write error: %d\n", err);
return err;
}
else if (err == ERR_OK)
{
//TCP_SSL_DEBUG("tcp_ssl_send: tcp_output: %d / %d\n", tcp_len, len);
err = _tcp_output4ssl(tcp_ssl->tcp, tcp_ssl->arg);
if (err != ERR_OK)
{
//TCP_SSL_DEBUG("tcp_ssl_send: tcp_output err: %d\n", err);
return err;
}
}
tcp_ssl->last_wr += tcp_len;
return tcp_len;
}
/////////////////////////////////////////////
uint8_t tcp_ssl_has_client()
{
return _tcp_ssl_has_client;
}
/////////////////////////////////////////////
tcp_ssl_t * tcp_ssl_new(struct tcp_pcb *tcp, void* arg)
{
if (tcp_ssl_next_fd < 0)
{
tcp_ssl_next_fd = 0; //overflow
}
tcp_ssl_t * new_item = (tcp_ssl_t*)malloc(sizeof(tcp_ssl_t));
if (!new_item)
{
//TCP_SSL_DEBUG("tcp_ssl_new: failed to allocate tcp_ssl\n");
return NULL;
}
new_item->tcp = tcp;
new_item->arg = arg;
new_item->on_data = NULL;
new_item->on_handshake = NULL;
new_item->on_error = NULL;
new_item->tcp_pbuf = NULL;
new_item->pbuf_offset = 0;
new_item->next = NULL;
new_item->has_ca_cert = false;
new_item->has_client_cert = false;
if (tcp_ssl_array == NULL)
{
tcp_ssl_array = new_item;
}
else
{
tcp_ssl_t * item = tcp_ssl_array;
while (item->next != NULL)
item = item->next;
item->next = new_item;
}
return new_item;
}
/////////////////////////////////////////////
tcp_ssl_t* tcp_ssl_get(struct tcp_pcb *tcp)
{
if (tcp == NULL)
{
return NULL;
}
tcp_ssl_t * item = tcp_ssl_array;
while (item && item->tcp != tcp)
{
item = item->next;
}
return item;
}
/////////////////////////////////////////////
int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, const char* root_ca, const size_t root_ca_len,
const char* cli_cert, const size_t cli_cert_len, const char* cli_key, const size_t cli_key_len)
{
tcp_ssl_t* tcp_ssl;
if (tcp == NULL)
{
return -1;
}
if (tcp_ssl_get(tcp) != NULL)
{
return -1;
}
tcp_ssl = tcp_ssl_new(tcp, arg);
if (tcp_ssl == NULL)
{
return -1;
}
mbedtls_entropy_init(&tcp_ssl->entropy_ctx);
mbedtls_ctr_drbg_init(&tcp_ssl->drbg_ctx);
mbedtls_ssl_init(&tcp_ssl->ssl_ctx);
mbedtls_ssl_config_init(&tcp_ssl->ssl_conf);
if (root_ca != NULL)
{
mbedtls_x509_crt_init(&tcp_ssl->ca_cert);
tcp_ssl->has_ca_cert = true;
}
if (cli_cert != NULL && cli_key != NULL)
{
mbedtls_x509_crt_init(&tcp_ssl->client_cert);
mbedtls_pk_init(&tcp_ssl->client_key);
tcp_ssl->has_client_cert = true;
}
mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func,
&tcp_ssl->entropy_ctx, (const unsigned char*)pers, sizeof(pers));
if (mbedtls_ssl_config_defaults(&tcp_ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT))
{
//TCP_SSL_DEBUG("error setting SSL config.\n");
tcp_ssl_free(tcp);
return -1;
}
int ret = 0;
if (tcp_ssl->has_ca_cert)
{
//TCP_SSL_DEBUG("setting the root ca.\n");
mbedtls_x509_crt_init(&tcp_ssl->ca_cert);
mbedtls_ssl_conf_authmode(&tcp_ssl->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
ret = mbedtls_x509_crt_parse(&tcp_ssl->ca_cert, (const unsigned char *)root_ca, root_ca_len);
if ( ret < 0 )
{
//TCP_SSL_DEBUG(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
tcp_ssl_free(tcp);
return handle_error(ret);
}
mbedtls_ssl_conf_ca_chain(&tcp_ssl->ssl_conf, &tcp_ssl->ca_cert, NULL);
}
else
{
mbedtls_ssl_conf_authmode(&tcp_ssl->ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
}
if (tcp_ssl->has_client_cert)
{
//TCP_SSL_DEBUG("loading client cert");
ret = mbedtls_x509_crt_parse(&tcp_ssl->client_cert, (const unsigned char *) cli_cert, cli_cert_len);
if (ret < 0)
{
tcp_ssl_free(tcp);
return handle_error(ret);
}
//TCP_SSL_DEBUG("loading private key");
ret = mbedtls_pk_parse_key(&tcp_ssl->client_key, (const unsigned char *) cli_key, cli_key_len, NULL, 0);
if (ret != 0)
{
tcp_ssl_free(tcp);
return handle_error(ret);
}
mbedtls_ssl_conf_own_cert(&tcp_ssl->ssl_conf, &tcp_ssl->client_cert, &tcp_ssl->client_key);
}
if (hostname != NULL)
{
//TCP_SSL_DEBUG("setting the hostname: %s\n", hostname);
if ((ret = mbedtls_ssl_set_hostname(&tcp_ssl->ssl_ctx, hostname)) != 0)
{
tcp_ssl_free(tcp);
return handle_error(ret);
}
}
mbedtls_ssl_conf_rng(&tcp_ssl->ssl_conf, mbedtls_ctr_drbg_random, &tcp_ssl->drbg_ctx);
if ((ret = mbedtls_ssl_setup(&tcp_ssl->ssl_ctx, &tcp_ssl->ssl_conf)) != 0)
{
tcp_ssl_free(tcp);
return handle_error(ret);
}
mbedtls_ssl_set_bio(&tcp_ssl->ssl_ctx, (void*)tcp_ssl, tcp_ssl_send, tcp_ssl_recv, NULL);
// Start handshake.
ret = mbedtls_ssl_handshake(&tcp_ssl->ssl_ctx);
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
{
//TCP_SSL_DEBUG("handshake error!\n");
tcp_ssl_free(tcp);
return handle_error(ret);
}
return ERR_OK;
}
/////////////////////////////////////////////
// Open an SSL connection using a PSK (pre-shared-key) cipher suite.
int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident, const char* pskey)
{
tcp_ssl_t* tcp_ssl;
if (pskey == NULL || psk_ident == NULL)
{
//TCP_SSL_DEBUG(" failed\n ! pre-shared key or identity is NULL\n\n");
return -1;
}
if (tcp == NULL)
return -1;
if (tcp_ssl_get(tcp) != NULL)
return -1;
int pskey_len = strnlen(pskey, 2 * MBEDTLS_PSK_MAX_LEN + 1);
if ((pskey_len > 2 * MBEDTLS_PSK_MAX_LEN) || (pskey_len & 1) != 0)
{
//TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n");
return -1;
}
tcp_ssl = tcp_ssl_new(tcp, arg);
if (tcp_ssl == NULL)
return -1;
mbedtls_entropy_init(&tcp_ssl->entropy_ctx);
mbedtls_ctr_drbg_init(&tcp_ssl->drbg_ctx);
mbedtls_ssl_init(&tcp_ssl->ssl_ctx);
mbedtls_ssl_config_init(&tcp_ssl->ssl_conf);
mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func,
&tcp_ssl->entropy_ctx, (const uint8_t*)pers, sizeof(pers));
if (mbedtls_ssl_config_defaults(&tcp_ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT))
{
//TCP_SSL_DEBUG("error setting SSL config.\n");
tcp_ssl_free(tcp);
return -1;
}
//mbedtls_esp_enable_debug_log(&tcp_ssl->ssl_conf, 4); // 4=verbose
int ret = 0;
//TCP_SSL_DEBUG("setting the pre-shared key.\n");
// convert PSK from hex string to binary
//////
//if ((strlen(pskey) & 1) != 0 || strlen(pskey) > 2*MBEDTLS_PSK_MAX_LEN) {
// //TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n");
// return -1;
//}
//////
unsigned char psk[MBEDTLS_PSK_MAX_LEN];
size_t psk_len = strlen(pskey) / 2;
for (int j = 0; j < strlen(pskey); j += 2)
{
char c = pskey[j];
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'F')
c -= 'A' - 10;
else if (c >= 'a' && c <= 'f')
c -= 'a' - 10;
else
return -1;
psk[j / 2] = c << 4;
c = pskey[j + 1];
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'F')
c -= 'A' - 10;
else if (c >= 'a' && c <= 'f')
c -= 'a' - 10;
else
return -1;
psk[j / 2] |= c;
}
// set mbedtls config
ret = mbedtls_ssl_conf_psk(&tcp_ssl->ssl_conf, psk, psk_len, (const unsigned char *)psk_ident,
strnlen(psk_ident, 64));
if (ret != 0)
{
//TCP_SSL_DEBUG(" failed\n ! mbedtls_ssl_conf_psk returned -0x%x\n\n", -ret);
return handle_error(ret);
}
mbedtls_ssl_conf_rng(&tcp_ssl->ssl_conf, mbedtls_ctr_drbg_random, &tcp_ssl->drbg_ctx);
if ((ret = mbedtls_ssl_setup(&tcp_ssl->ssl_ctx, &tcp_ssl->ssl_conf)) != 0)
{
tcp_ssl_free(tcp);
return handle_error(ret);
}
mbedtls_ssl_set_bio(&tcp_ssl->ssl_ctx, (void*)tcp_ssl, tcp_ssl_send, tcp_ssl_recv, NULL);
// Start handshake.
ret = mbedtls_ssl_handshake(&tcp_ssl->ssl_ctx);
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
{
//TCP_SSL_DEBUG("handshake error!\n");
return handle_error(ret);
}
return ERR_OK;
}
/////////////////////////////////////////////
// tcp_ssl_write writes len bytes from data into the TLS connection. I.e., data is plaintext, gets
// encrypted, and then transmitted on the TCP connection.
int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len)
{
//TCP_SSL_DEBUG("tcp_ssl_write(%x, %x, len=%d)\n", tcp, data, len);
if (tcp == NULL)
{
return -1;
}
tcp_ssl_t * tcp_ssl = tcp_ssl_get(tcp);
if (tcp_ssl == NULL)
{
return 0;
}
tcp_ssl->last_wr = 0;
int rc = mbedtls_ssl_write(&tcp_ssl->ssl_ctx, data, len);
if (rc < 0)
{
if (rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE)
{
//TCP_SSL_DEBUG("about to call mbedtls_ssl_write\n");
return handle_error(rc);
}
if (rc != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
{
//TCP_SSL_DEBUG("tcp_ssl_write error: %d\r\n", rc);
}
return rc;
}
return tcp_ssl->last_wr;
}
/////////////////////////////////////////////
/*
typedef enum
{
MBEDTLS_SSL_HELLO_REQUEST,
MBEDTLS_SSL_CLIENT_HELLO,
MBEDTLS_SSL_SERVER_HELLO,
MBEDTLS_SSL_SERVER_CERTIFICATE,
MBEDTLS_SSL_SERVER_KEY_EXCHANGE,
MBEDTLS_SSL_CERTIFICATE_REQUEST,
MBEDTLS_SSL_SERVER_HELLO_DONE,
MBEDTLS_SSL_CLIENT_CERTIFICATE,
MBEDTLS_SSL_CLIENT_KEY_EXCHANGE,
MBEDTLS_SSL_CERTIFICATE_VERIFY,
MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC,
MBEDTLS_SSL_CLIENT_FINISHED,
MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC,
MBEDTLS_SSL_SERVER_FINISHED,
MBEDTLS_SSL_FLUSH_BUFFERS,
MBEDTLS_SSL_HANDSHAKE_WRAPUP,
MBEDTLS_SSL_HANDSHAKE_OVER,
MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET,
MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
}
mbedtls_ssl_states;
*/
/////////////////////////////////////////////
// tcp_ssl_read is a callback that reads from the TLS connection, i.e., it calls mbedtls, which then
// tries to read from the TCP connection and decrypts it, tcp_ssl_read then calls the application's
// onData callback with the decrypted data.
int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p)
{
//TCP_SSL_DEBUG("tcp_ssl_read(%x, %x)\n", tcp, p);
if (tcp == NULL)
{
return -1;
}
int read_bytes = 0;
int total_bytes = 0;
static const size_t read_buf_size = 1024;
uint8_t read_buf[read_buf_size];
tcp_ssl_t *tcp_ssl = tcp_ssl_get(tcp);
if (tcp_ssl == NULL)
{
return ERR_TCP_SSL_INVALID_CLIENTFD_DATA;
}
if (p == NULL)
{
return ERR_TCP_SSL_INVALID_DATA;
}
// TCP_SSL_DEBUG("READY TO READ SOME DATA\n");
tcp_ssl->tcp_pbuf = p;
tcp_ssl->pbuf_offset = 0;
bool debugPrinted = false;
do
{
if (tcp_ssl->ssl_ctx.state != MBEDTLS_SSL_HANDSHAKE_OVER)
{
//KH to print once
if (!debugPrinted)
{
//TCP_SSL_DEBUG("start handshake: %d\n", tcp_ssl->ssl_ctx.state);
debugPrinted = true;
}
int ret = mbedtls_ssl_handshake(&tcp_ssl->ssl_ctx);
//handle_error(ret);
if (ret == 0)
{
//TCP_SSL_DEBUG("Protocol is %s, Ciphersuite is %s\n", mbedtls_ssl_get_version(&tcp_ssl->ssl_ctx), mbedtls_ssl_get_ciphersuite(&tcp_ssl->ssl_ctx));
//////
//TCP_SSL_DEBUG("Verifying peer X.509 certificate...");
if ((mbedtls_ssl_get_verify_result(&tcp_ssl->ssl_ctx)) != 0)
{
//TCP_SSL_DEBUG("handshake error: %d\n", ret);
handle_error(ret);
if (tcp_ssl->on_error)
tcp_ssl->on_error(tcp_ssl->arg, tcp_ssl->tcp, ret);
}
else
{
//TCP_SSL_DEBUG("Certificate verified.");
}
//////
if (tcp_ssl->on_handshake)
tcp_ssl->on_handshake(tcp_ssl->arg, tcp_ssl->tcp, tcp_ssl);
}
else if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
{
//TCP_SSL_DEBUG("handshake error: %d\n", ret);
handle_error(ret);
if (tcp_ssl->on_error)
tcp_ssl->on_error(tcp_ssl->arg, tcp_ssl->tcp, ret);
break;
}
}
else
{
read_bytes = mbedtls_ssl_read(&tcp_ssl->ssl_ctx, (unsigned char *)&read_buf, read_buf_size);
//TCP_SSL_DEBUG("tcp_ssl_read: read_bytes: %d, total_bytes: %d, tot_len: %d, pbuf_offset: %d\r\n",
// read_bytes, total_bytes, p->tot_len, tcp_ssl->pbuf_offset);
if (read_bytes < 0)
{
// SSL_OK
if (read_bytes == MBEDTLS_ERR_SSL_WANT_READ)
{
break;
}
else if (read_bytes != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
{
//TCP_SSL_DEBUG("tcp_ssl_read: read error: %d\n", read_bytes);
}
total_bytes = read_bytes;
break;
}
else if (read_bytes > 0)
{
if (tcp_ssl->on_data)
{
tcp_ssl->on_data(tcp_ssl->arg, tcp, read_buf, read_bytes);
}
total_bytes += read_bytes;
}
}
//KH
vTaskDelay(1 / portTICK_PERIOD_MS);
//////
} while (p->tot_len - tcp_ssl->pbuf_offset > 0 || read_bytes > 0);
tcp_ssl->tcp_pbuf = NULL;
return (total_bytes >= 0 ? 0 : total_bytes); // return error code
}
/////////////////////////////////////////////
int tcp_ssl_free(struct tcp_pcb *tcp)
{
//TCP_SSL_DEBUG("tcp_ssl_free(%x)\n", tcp);
if (tcp == NULL)
{
return -1;
}
tcp_ssl_t * item = tcp_ssl_array;
if (item->tcp == tcp)
{
tcp_ssl_array = tcp_ssl_array->next;
if (item->tcp_pbuf != NULL)
{
pbuf_free(item->tcp_pbuf);
}
mbedtls_ssl_free(&item->ssl_ctx);
mbedtls_ssl_config_free(&item->ssl_conf);
mbedtls_ctr_drbg_free(&item->drbg_ctx);
mbedtls_entropy_free(&item->entropy_ctx);
if (item->has_ca_cert)
{
mbedtls_x509_crt_free(&item->ca_cert);
}
if (item->has_client_cert)
{
mbedtls_x509_crt_free(&item->client_cert);
mbedtls_pk_free(&item->client_key);
}
free(item);
return 0;
}
while (item->next && item->next->tcp != tcp)
item = item->next;
if (item->next == NULL)
{
return ERR_TCP_SSL_INVALID_CLIENTFD_DATA;//item not found
}
tcp_ssl_t * i = item->next;
item->next = i->next;
if (i->tcp_pbuf != NULL)
{
pbuf_free(i->tcp_pbuf);
}
mbedtls_ssl_free(&i->ssl_ctx);
mbedtls_ssl_config_free(&i->ssl_conf);
mbedtls_ctr_drbg_free(&i->drbg_ctx);
mbedtls_entropy_free(&i->entropy_ctx);
free(i);
return 0;
}
/////////////////////////////////////////////
bool tcp_ssl_has(struct tcp_pcb *tcp)
{
return tcp_ssl_get(tcp) != NULL;
}
/////////////////////////////////////////////
void tcp_ssl_arg(struct tcp_pcb *tcp, void * arg)
{
tcp_ssl_t * item = tcp_ssl_get(tcp);
if (item)
{
item->arg = arg;
}
}
/////////////////////////////////////////////
void tcp_ssl_data(struct tcp_pcb *tcp, tcp_ssl_data_cb_t arg)
{
tcp_ssl_t * item = tcp_ssl_get(tcp);
if (item)
{
item->on_data = arg;
}
}
/////////////////////////////////////////////
void tcp_ssl_handshake(struct tcp_pcb *tcp, tcp_ssl_handshake_cb_t arg)
{
tcp_ssl_t * item = tcp_ssl_get(tcp);
if (item)
{
item->on_handshake = arg;
}
}
/////////////////////////////////////////////
void tcp_ssl_err(struct tcp_pcb *tcp, tcp_ssl_error_cb_t arg)
{
tcp_ssl_t * item = tcp_ssl_get(tcp);
if (item)
{
item->on_error = arg;
}
}
/////////////////////////////////////////////
//#endif // ASYNC_TCP_SSL_ENABLED

View File

@@ -0,0 +1,89 @@
/****************************************************************************************************************************
tcp_mbedtls.h
AsyncTCP_SSL is a library for ESP32
Based on and modified from :
1) AsyncTCP (https://github.com/me-no-dev/ESPAsyncTCP)
2) AsyncTCP (https://github.com/tve/AsyncTCP)
Built by Khoi Hoang https://github.com/khoih-prog/AsyncTCP_SSL
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Version: 1.3.1
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32
1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP
1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error
1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible
1.3.1 K Hoang 18/09/2022 Improve stability. Make queue length user-configurable
*****************************************************************************************************************************/
#ifndef LWIPR_MBEDTLS_H
#define LWIPR_MBEDTLS_H
/////////////////////////////////////////////
#include "mbedtls/platform.h"
#include "mbedtls/net.h"
#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
/////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
#define ERR_TCP_SSL_INVALID_SSL -101
#define ERR_TCP_SSL_INVALID_TCP -102
#define ERR_TCP_SSL_INVALID_CLIENTFD -103
#define ERR_TCP_SSL_INVALID_CLIENTFD_DATA -104
#define ERR_TCP_SSL_INVALID_DATA -105
/////////////////////////////////////////////
struct tcp_pcb;
struct pbuf;
struct tcp_ssl_pcb;
/////////////////////////////////////////////
typedef void (* tcp_ssl_data_cb_t)(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len);
typedef void (* tcp_ssl_handshake_cb_t)(void *arg, struct tcp_pcb *tcp, struct tcp_ssl_pcb* ssl);
typedef void (* tcp_ssl_error_cb_t)(void *arg, struct tcp_pcb *tcp, int8_t error);
/////////////////////////////////////////////
uint8_t tcp_ssl_has_client();
int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, const char* root_ca, const size_t root_ca_len,
const char* cli_cert, const size_t cli_cert_len, const char* cli_key, const size_t cli_key_len);
int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident, const char* psk);
int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len);
int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p);
int tcp_ssl_handshake_step(struct tcp_pcb *tcp);
int tcp_ssl_free(struct tcp_pcb *tcp);
bool tcp_ssl_has(struct tcp_pcb *tcp);
void tcp_ssl_arg(struct tcp_pcb *tcp, void * arg);
void tcp_ssl_data(struct tcp_pcb *tcp, tcp_ssl_data_cb_t arg);
void tcp_ssl_handshake(struct tcp_pcb *tcp, tcp_ssl_handshake_cb_t arg);
void tcp_ssl_err(struct tcp_pcb *tcp, tcp_ssl_error_cb_t arg);
/////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif // LWIPR_MBEDTLS_H