CI: fixing the files to be complient with pre-commit hooks

This commit is contained in:
Suren Gabrielyan
2022-10-11 16:31:57 +02:00
parent 9d45d505d5
commit 945bd17701
205 changed files with 3130 additions and 3441 deletions

View File

@ -136,6 +136,5 @@ show_source = True
statistics = True statistics = True
per-file-ignores = exclude =
# Sphinx conf.py files use star imports to setup config variables components/asio/docs/conf_common.py
docs/conf_common.py: F405

2
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,2 @@
# Formating according pre-commit hooks
3e1c3cc647b6f6d4da20b3ab979879f60229bfee

View File

@ -8,7 +8,7 @@ jobs:
matrix: matrix:
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4"] idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4"]
example: ["pppos_client", "modem_console", "ap_to_pppos", "simple_cmux_client"] example: ["pppos_client", "modem_console", "ap_to_pppos", "simple_cmux_client"]
idf_target: ["esp32"] idf_target: ["esp32"]
exclude: exclude:
- idf_ver: "release-v4.1" - idf_ver: "release-v4.1"
example: modem_console example: modem_console
@ -57,30 +57,30 @@ jobs:
cat sdkconfig.ci.usb >> sdkconfig.defaults cat sdkconfig.ci.usb >> sdkconfig.defaults
idf.py build idf.py build
build_mdns: build_mdns:
strategy: strategy:
matrix: matrix:
idf_ver: ["latest"] idf_ver: ["latest"]
idf_target: ["esp32", "esp32s2", "esp32c3"] idf_target: ["esp32", "esp32s2", "esp32c3"]
config: ["eth_custom_netif", "eth_def", "eth_no_ipv6", "eth_socket"] config: ["eth_custom_netif", "eth_def", "eth_no_ipv6", "eth_socket"]
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }} container: espressif/idf:${{ matrix.idf_ver }}
steps: steps:
- name: Checkout esp-protocols - name: Checkout esp-protocols
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }} for ${{ matrix.config }} - name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }} for ${{ matrix.config }}
env: env:
IDF_TARGET: ${{ matrix.idf_target }} IDF_TARGET: ${{ matrix.idf_target }}
shell: bash shell: bash
working-directory: components/mdns/examples/ working-directory: components/mdns/examples/
run: | run: |
. ${IDF_PATH}/export.sh . ${IDF_PATH}/export.sh
rm -rf sdkconfig sdkconfig.defaults build build_${{ matrix.config }} rm -rf sdkconfig sdkconfig.defaults build build_${{ matrix.config }}
cat sdkconfig.ci.${{ matrix.config }} >> sdkconfig.defaults cat sdkconfig.ci.${{ matrix.config }} >> sdkconfig.defaults
idf.py set-target ${{ matrix.idf_target }} idf.py set-target ${{ matrix.idf_target }}
idf.py build idf.py build
mv build build_${{ matrix.config }} mv build build_${{ matrix.config }}
- name: Merge binaries with IDF-${{ matrix.idf_ver }} for ${{ matrix.config }} - name: Merge binaries with IDF-${{ matrix.idf_ver }} for ${{ matrix.config }}
working-directory: components/mdns/examples working-directory: components/mdns/examples
@ -118,7 +118,7 @@ jobs:
- name: Checkout esp-protocols - name: Checkout esp-protocols
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive
- name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }} - name: Build ${{ matrix.example }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
working-directory: components/asio/examples/${{ matrix.example }} working-directory: components/asio/examples/${{ matrix.example }}
env: env:
@ -234,9 +234,9 @@ jobs:
path: components/esp_websocket_client/examples/*.xml path: components/esp_websocket_client/examples/*.xml
run-target-mdns: run-target-mdns:
strategy: strategy:
matrix: matrix:
idf_ver: ["latest"] idf_ver: ["latest"]
idf_target: ["esp32"] idf_target: ["esp32"]
config: ["eth_custom_netif", "eth_def", "eth_no_ipv6", "eth_socket"] config: ["eth_custom_netif", "eth_def", "eth_no_ipv6", "eth_socket"]
name: Run mDNS Example Test on target name: Run mDNS Example Test on target
@ -267,7 +267,7 @@ jobs:
run: | run: |
rm -rf build rm -rf build
mv build_${{ matrix.config }} build mv build_${{ matrix.config }} build
cat sdkconfig.ci.${{ matrix.config }} >> sdkconfig.defaults cat sdkconfig.ci.${{ matrix.config }} >> sdkconfig.defaults
python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.config }}.xml --target=${{ matrix.idf_target }} python -m pytest --log-cli-level DEBUG --junit-xml=./examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.config }}.xml --target=${{ matrix.idf_target }}
rm -rf build sdkconfig.defaults rm -rf build sdkconfig.defaults
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
@ -277,9 +277,9 @@ jobs:
path: components/mdns/examples/*.xml path: components/mdns/examples/*.xml
run-target-asio: run-target-asio:
strategy: strategy:
matrix: matrix:
idf_ver: ["latest"] idf_ver: ["latest"]
idf_target: ["esp32"] idf_target: ["esp32"]
example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"] example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"]
name: Run ASIO Example Test on target name: Run ASIO Example Test on target

26
.mypy.ini Normal file
View File

@ -0,0 +1,26 @@
[mypy]
# Specifies the Python version used to parse and check the target program
python_version = 3.9
# Disallows defining functions without type annotations or with incomplete type annotations
# True => enforce type annotation in all function definitions
disallow_untyped_defs = True
# Shows a warning when returning a value with type Any from a function declared with a non- Any return type
warn_return_any = True
# Shows errors for missing return statements on some execution paths
warn_no_return = True
# Suppress error messages about imports that cannot be resolved
# True => ignore all import errors
ignore_missing_imports = True
# Disallows defining functions with incomplete type annotations
disallow_incomplete_defs = False
# Directs what to do with imports when the imported module is found as a .py file and not part of the files,
# modules and packages provided on the command line.
# SKIP -> mypy checks only single file, not included imports
follow_imports = skip

View File

@ -20,6 +20,10 @@ repos:
rev: v0.981 rev: v0.981
hooks: hooks:
- id: mypy - id: mypy
exclude: >
(?x)^(
.*.py
)$
- repo: https://github.com/myint/unify - repo: https://github.com/myint/unify
rev: v0.5 rev: v0.5
hooks: hooks:

View File

@ -46,9 +46,19 @@ asio_component:
- Apache-2.0 - Apache-2.0
- BSL-1.0 - BSL-1.0
slim_modem_examples:
include:
- 'examples/esp_netif/slip_custom_netif/**'
allowed_licenses:
- Apache-2.0
- Unlicense
- CC0-1.0
ignore: ignore:
perform_check: no perform_check: no
include: include:
- 'components/**/docs/**' - 'components/**/docs/**'
- 'components/esp_modem/port/linux/**' - 'components/esp_modem/port/linux/**'
- 'components/asio/examples/asio_chat/main/*' - 'components/asio/examples/**'
- 'components/mdns/**/esp_system_protocols_linux/**'
- 'common_components/protocol_examples_common/**'

View File

@ -26,7 +26,7 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad
do { do {
fgets(host_ip, HOST_IP_SIZE, stdin); fgets(host_ip, HOST_IP_SIZE, stdin);
len = strlen(host_ip); len = strlen(host_ip);
} while (len<=1 && host_ip[0] == '\n'); } while (len <= 1 && host_ip[0] == '\n');
host_ip[len - 1] = '\0'; host_ip[len - 1] = '\0';
struct addrinfo hints, *addr_list, *cur; struct addrinfo hints, *addr_list, *cur;
@ -36,16 +36,16 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = sock_type; hints.ai_socktype = sock_type;
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
if( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) { if ( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) {
return ESP_FAIL; return ESP_FAIL;
} }
for( cur = addr_list; cur != NULL; cur = cur->ai_next ) { for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr)); memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr));
if (cur->ai_family == AF_INET) { if (cur->ai_family == AF_INET) {
*ip_protocol = IPPROTO_IP; *ip_protocol = IPPROTO_IP;
*addr_family = AF_INET; *addr_family = AF_INET;
// add port number and return on first IPv4 match // add port number and return on first IPv4 match
((struct sockaddr_in*)dest_addr)->sin_port = htons(port); ((struct sockaddr_in *)dest_addr)->sin_port = htons(port);
freeaddrinfo( addr_list ); freeaddrinfo( addr_list );
return ESP_OK; return ESP_OK;
@ -55,8 +55,8 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad
*ip_protocol = IPPROTO_IPV6; *ip_protocol = IPPROTO_IPV6;
*addr_family = AF_INET6; *addr_family = AF_INET6;
// add port and interface number and return on first IPv6 match // add port and interface number and return on first IPv6 match
((struct sockaddr_in6*)dest_addr)->sin6_port = htons(port); ((struct sockaddr_in6 *)dest_addr)->sin6_port = htons(port);
((struct sockaddr_in6*)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE); ((struct sockaddr_in6 *)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
freeaddrinfo( addr_list ); freeaddrinfo( addr_list );
return ESP_OK; return ESP_OK;
} }

View File

@ -1,10 +1,11 @@
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <string.h> #include <string.h>

View File

@ -1,13 +1,14 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* Common utilities for socket address input interface: /* Common utilities for socket address input interface:
The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured). The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured).
This option is typically used in the CI, but could be enabled in the project configuration. This option is typically used in the CI, but could be enabled in the project configuration.
In that case this component is used to receive a string that is evaluated and processed to output In that case this component is used to receive a string that is evaluated and processed to output
socket structures to open a connectio socket structures to open a connectio
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -1,10 +1,11 @@
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -1,10 +1,11 @@
/* Common functions for protocol examples, to configure stdin and stdout. /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Common functions for protocol examples, to configure stdin and stdout.
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include "protocol_examples_common.h" #include "protocol_examples_common.h"
@ -19,7 +20,7 @@ esp_err_t example_configure_stdin_stdout(void)
setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdin, NULL, _IONBF, 0);
/* Install UART driver for interrupt-driven reads and writes */ /* Install UART driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM, ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) ); 256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */ /* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);

View File

@ -1,10 +1,11 @@
from esp_docs.conf_docs import * # noqa: F403,F401 from esp_docs.conf_docs import * # noqa: F403,F401
extensions += ['sphinx_copybutton', extensions += [
# Needed as a trigger for running doxygen 'sphinx_copybutton',
'esp_docs.esp_extensions.dummy_build_system', # Needed as a trigger for running doxygen
'esp_docs.esp_extensions.run_doxygen', 'esp_docs.esp_extensions.dummy_build_system',
] 'esp_docs.esp_extensions.run_doxygen',
]
# link roles config # link roles config
github_repo = 'espressif/esp-protocols' github_repo = 'espressif/esp-protocols'
@ -14,7 +15,7 @@ html_context['github_user'] = 'espressif'
html_context['github_repo'] = 'esp-protocols' html_context['github_repo'] = 'esp-protocols'
# Extra options required by sphinx_idf_theme # Extra options required by sphinx_idf_theme
project_slug = 'esp-idf' # >=5.0 project_slug = 'esp-idf' # >=5.0
versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js' versions_url = 'https://github.com/espressif/esp-protocols/docs/docs_versions.js'
idf_targets = ['esp32'] idf_targets = ['esp32']

View File

@ -13,7 +13,7 @@ window.onload =(function() {
mySpan.value = 'latest'; mySpan.value = 'latest';
mySpan.setAttribute('disabled', true); mySpan.setAttribute('disabled', true);
myAnchor.parentNode.replaceChild(mySpan, myAnchor); myAnchor.parentNode.replaceChild(mySpan, myAnchor);
var myAnchor = document.getElementById('target-select'); var myAnchor = document.getElementById('target-select');
var mySpan = document.createElement('input'); var mySpan = document.createElement('input');
mySpan.setAttribute('type', 'text'); mySpan.setAttribute('type', 'text');
@ -24,4 +24,3 @@ window.onload =(function() {
})(); })();
</script>" >> html/index.html </script>" >> html/index.html

View File

@ -1 +1 @@
.. include:: ../../../en/api-reference/protocols/asio.rst .. include:: ../../../en/api-reference/protocols/asio.rst

View File

@ -53,14 +53,15 @@ void start_client(void)
#ifdef CONFIG_EXAMPLE_CHAT_SERVER #ifdef CONFIG_EXAMPLE_CHAT_SERVER
std::lock_guard<std::mutex> guard(server_ready); std::lock_guard<std::mutex> guard(server_ready);
#endif #endif
std::thread t([&io_context]() { try { std::thread t([&io_context]() {
io_context.run(); try {
} catch (const std::exception &e) { io_context.run();
ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what()); } catch (const std::exception &e) {
} ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what());
catch (...) { } catch (...) {
ESP_LOGE(TAG, "Unknown exception"); ESP_LOGE(TAG, "Unknown exception");
}}); }
});
do { do {
ESP_LOGI(TAG, "CLIENT: Waiting for input"); ESP_LOGI(TAG, "CLIENT: Waiting for input");
get_string(line, sizeof(line)); get_string(line, sizeof(line));
@ -95,14 +96,14 @@ extern "C" void app_main(void)
asio::io_context io_context; asio::io_context io_context;
chat_server server(io_context, tcp::endpoint(tcp::v4(), std::atoi(CONFIG_EXAMPLE_CHAT_SERVER_BIND_PORT))); chat_server server(io_context, tcp::endpoint(tcp::v4(), std::atoi(CONFIG_EXAMPLE_CHAT_SERVER_BIND_PORT)));
std::thread t = std::thread([&io_context]() { // Chat server starting here std::thread t = std::thread([&io_context]() { // Chat server starting here
try { try {
io_context.run(); io_context.run();
} catch (const std::exception &e) { } catch (const std::exception &e) {
ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what()); ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what());
} } catch (...) {
catch (...) { ESP_LOGE(TAG, "Unknown exception");
ESP_LOGE(TAG, "Unknown exception"); }
}});; });;
#endif #endif
#ifdef CONFIG_EXAMPLE_CHAT_CLIENT #ifdef CONFIG_EXAMPLE_CHAT_CLIENT
start_client(); start_client();

View File

@ -15,77 +15,76 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
class chat_message class chat_message {
{
public: public:
static constexpr std::size_t header_length = 4; static constexpr std::size_t header_length = 4;
static constexpr std::size_t max_body_length = 512; static constexpr std::size_t max_body_length = 512;
chat_message() chat_message()
: body_length_(0) : body_length_(0)
{
}
const char* data() const
{
return data_;
}
char* data()
{
return data_;
}
std::size_t length() const
{
return header_length + body_length_;
}
const char* body() const
{
return data_ + header_length;
}
char* body()
{
return data_ + header_length;
}
std::size_t body_length() const
{
return body_length_;
}
void body_length(std::size_t new_length)
{
body_length_ = new_length;
if (body_length_ > max_body_length)
body_length_ = max_body_length;
}
bool decode_header()
{
char header[header_length + 1] = "";
std::strncat(header, data_, header_length);
body_length_ = std::atoi(header);
if (body_length_ > max_body_length)
{ {
body_length_ = 0;
return false;
} }
return true;
}
void encode_header() const char *data() const
{ {
char header[header_length + 1] = ""; return data_;
std::sprintf(header, "%4d", static_cast<int>(body_length_)); }
std::memcpy(data_, header, header_length);
} char *data()
{
return data_;
}
std::size_t length() const
{
return header_length + body_length_;
}
const char *body() const
{
return data_ + header_length;
}
char *body()
{
return data_ + header_length;
}
std::size_t body_length() const
{
return body_length_;
}
void body_length(std::size_t new_length)
{
body_length_ = new_length;
if (body_length_ > max_body_length) {
body_length_ = max_body_length;
}
}
bool decode_header()
{
char header[header_length + 1] = "";
std::strncat(header, data_, header_length);
body_length_ = std::atoi(header);
if (body_length_ > max_body_length) {
body_length_ = 0;
return false;
}
return true;
}
void encode_header()
{
char header[header_length + 1] = "";
std::sprintf(header, "%4d", static_cast<int>(body_length_));
std::memcpy(data_, header, header_length);
}
private: private:
char data_[header_length + max_body_length]; char data_[header_length + max_body_length];
std::size_t body_length_; std::size_t body_length_;
}; };
#endif // CHAT_MESSAGE_HPP #endif // CHAT_MESSAGE_HPP

View File

@ -17,107 +17,91 @@
typedef std::deque<chat_message> chat_message_queue; typedef std::deque<chat_message> chat_message_queue;
class chat_client class chat_client {
{
public: public:
chat_client(asio::io_context& io_context, chat_client(asio::io_context &io_context,
const asio::ip::tcp::resolver::results_type& endpoints) const asio::ip::tcp::resolver::results_type &endpoints)
: io_context_(io_context), : io_context_(io_context),
socket_(io_context) socket_(io_context)
{ {
do_connect(endpoints); do_connect(endpoints);
} }
void write(const chat_message& msg) void write(const chat_message &msg)
{ {
asio::post(io_context_, asio::post(io_context_,
[this, msg]() [this, msg]() {
{ bool write_in_progress = !write_msgs_.empty();
bool write_in_progress = !write_msgs_.empty(); write_msgs_.push_back(msg);
write_msgs_.push_back(msg); if (!write_in_progress) {
if (!write_in_progress) do_write();
{ }
do_write();
}
}); });
} }
void close() void close()
{ {
asio::post(io_context_, [this]() { socket_.close(); }); asio::post(io_context_, [this]() {
} socket_.close();
});
}
private: private:
void do_connect(const asio::ip::tcp::resolver::results_type& endpoints) void do_connect(const asio::ip::tcp::resolver::results_type &endpoints)
{ {
asio::async_connect(socket_, endpoints, asio::async_connect(socket_, endpoints,
[this](std::error_code ec, asio::ip::tcp::endpoint) [this](std::error_code ec, asio::ip::tcp::endpoint) {
{ if (!ec) {
if (!ec) do_read_header();
{
do_read_header();
} }
}); });
} }
void do_read_header() void do_read_header()
{ {
asio::async_read(socket_, asio::async_read(socket_,
asio::buffer(read_msg_.data(), chat_message::header_length), asio::buffer(read_msg_.data(), chat_message::header_length),
[this](std::error_code ec, std::size_t /*length*/) [this](std::error_code ec, std::size_t /*length*/) {
{ if (!ec && read_msg_.decode_header()) {
if (!ec && read_msg_.decode_header()) do_read_body();
{ } else {
do_read_body(); socket_.close();
} }
else });
{
socket_.close();
}
});
} }
void do_read_body() void do_read_body()
{ {
asio::async_read(socket_, asio::async_read(socket_,
asio::buffer(read_msg_.body(), read_msg_.body_length()), asio::buffer(read_msg_.body(), read_msg_.body_length()),
[this](std::error_code ec, std::size_t /*length*/) [this](std::error_code ec, std::size_t /*length*/) {
{ if (!ec) {
if (!ec) do_read_header();
{ } else {
do_read_header(); socket_.close();
} }
else });
{
socket_.close();
}
});
} }
void do_write() void do_write()
{ {
asio::async_write(socket_, asio::async_write(socket_,
asio::buffer(write_msgs_.front().data(), asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()), write_msgs_.front().length()),
[this](std::error_code ec, std::size_t /*length*/) [this](std::error_code ec, std::size_t /*length*/) {
{ if (!ec) {
if (!ec) write_msgs_.pop_front();
{ if (!write_msgs_.empty()) {
write_msgs_.pop_front(); do_write();
if (!write_msgs_.empty()) }
{ } else {
do_write(); socket_.close();
}
} }
else });
{ }
socket_.close();
}
});
}
private: private:
asio::io_context& io_context_; asio::io_context &io_context_;
asio::ip::tcp::socket socket_; asio::ip::tcp::socket socket_;
chat_message read_msg_; chat_message read_msg_;
chat_message_queue write_msgs_; chat_message_queue write_msgs_;

View File

@ -27,176 +27,159 @@ extern std::mutex server_ready;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class chat_participant class chat_participant {
{
public: public:
virtual ~chat_participant() {} virtual ~chat_participant() {}
virtual void deliver(const chat_message& msg) = 0; virtual void deliver(const chat_message &msg) = 0;
}; };
typedef std::shared_ptr<chat_participant> chat_participant_ptr; typedef std::shared_ptr<chat_participant> chat_participant_ptr;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class chat_room class chat_room {
{
public: public:
void join(chat_participant_ptr participant) void join(chat_participant_ptr participant)
{ {
participants_.insert(participant); participants_.insert(participant);
for (auto msg: recent_msgs_) for (auto msg : recent_msgs_) {
participant->deliver(msg); participant->deliver(msg);
} }
}
void leave(chat_participant_ptr participant) void leave(chat_participant_ptr participant)
{ {
participants_.erase(participant); participants_.erase(participant);
} }
void deliver(const chat_message& msg) void deliver(const chat_message &msg)
{ {
recent_msgs_.push_back(msg); recent_msgs_.push_back(msg);
while (recent_msgs_.size() > max_recent_msgs) while (recent_msgs_.size() > max_recent_msgs) {
recent_msgs_.pop_front(); recent_msgs_.pop_front();
}
for (auto participant: participants_) for (auto participant : participants_) {
participant->deliver(msg); participant->deliver(msg);
} }
}
private: private:
std::set<chat_participant_ptr> participants_; std::set<chat_participant_ptr> participants_;
enum { max_recent_msgs = 100 }; enum { max_recent_msgs = 100 };
chat_message_queue recent_msgs_; chat_message_queue recent_msgs_;
}; };
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class chat_session class chat_session
: public chat_participant, : public chat_participant,
public std::enable_shared_from_this<chat_session> public std::enable_shared_from_this<chat_session> {
{
public: public:
chat_session(asio::ip::tcp::socket socket, chat_room& room) chat_session(asio::ip::tcp::socket socket, chat_room &room)
: socket_(std::move(socket)), : socket_(std::move(socket)),
room_(room) room_(room)
{
}
void start()
{
room_.join(shared_from_this());
do_read_header();
}
void deliver(const chat_message& msg)
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{ {
do_write();
} }
}
void start()
{
room_.join(shared_from_this());
do_read_header();
}
void deliver(const chat_message &msg)
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress) {
do_write();
}
}
private: private:
void do_read_header() void do_read_header()
{ {
auto self(shared_from_this()); auto self(shared_from_this());
asio::async_read(socket_, asio::async_read(socket_,
asio::buffer(read_msg_.data(), chat_message::header_length), asio::buffer(read_msg_.data(), chat_message::header_length),
[this, self](std::error_code ec, std::size_t /*length*/) [this, self](std::error_code ec, std::size_t /*length*/) {
{ if (!ec && read_msg_.decode_header()) {
if (!ec && read_msg_.decode_header()) do_read_body();
{ } else {
do_read_body(); room_.leave(shared_from_this());
} }
else });
{ }
room_.leave(shared_from_this());
}
});
}
void do_read_body() void do_read_body()
{ {
auto self(shared_from_this()); auto self(shared_from_this());
asio::async_read(socket_, asio::async_read(socket_,
asio::buffer(read_msg_.body(), read_msg_.body_length()), asio::buffer(read_msg_.body(), read_msg_.body_length()),
[this, self](std::error_code ec, std::size_t /*length*/) [this, self](std::error_code ec, std::size_t /*length*/) {
{ if (!ec) {
if (!ec) ESP_LOGD("asio-chat:", "%s", read_msg_.body());
{ room_.deliver(read_msg_);
ESP_LOGD("asio-chat:", "%s", read_msg_.body()); do_read_header();
room_.deliver(read_msg_); } else {
do_read_header(); room_.leave(shared_from_this());
} }
else });
{ }
room_.leave(shared_from_this());
}
});
}
void do_write() void do_write()
{ {
auto self(shared_from_this()); auto self(shared_from_this());
asio::async_write(socket_, asio::async_write(socket_,
asio::buffer(write_msgs_.front().data(), asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()), write_msgs_.front().length()),
[this, self](std::error_code ec, std::size_t /*length*/) [this, self](std::error_code ec, std::size_t /*length*/) {
{ if (!ec) {
if (!ec) write_msgs_.pop_front();
{ if (!write_msgs_.empty()) {
write_msgs_.pop_front(); do_write();
if (!write_msgs_.empty()) }
{ } else {
do_write(); room_.leave(shared_from_this());
} }
} });
else }
{
room_.leave(shared_from_this());
}
});
}
asio::ip::tcp::socket socket_; asio::ip::tcp::socket socket_;
chat_room& room_; chat_room &room_;
chat_message read_msg_; chat_message read_msg_;
chat_message_queue write_msgs_; chat_message_queue write_msgs_;
}; };
//---------------------------------------------------------------------- //----------------------------------------------------------------------
class chat_server class chat_server {
{
public: public:
chat_server(asio::io_context& io_context, chat_server(asio::io_context &io_context,
const asio::ip::tcp::endpoint& endpoint) const asio::ip::tcp::endpoint &endpoint)
: acceptor_(io_context, endpoint) : acceptor_(io_context, endpoint)
{ {
do_accept(); do_accept();
} }
private: private:
void do_accept() void do_accept()
{ {
std::lock_guard<std::mutex> guard(server_ready); std::lock_guard<std::mutex> guard(server_ready);
acceptor_.async_accept( acceptor_.async_accept(
[this](std::error_code ec, asio::ip::tcp::socket socket) [this](std::error_code ec, asio::ip::tcp::socket socket) {
{ if (!ec) {
if (!ec) std::make_shared<chat_session>(std::move(socket), room_)->start();
{ }
std::make_shared<chat_session>(std::move(socket), room_)->start();
}
do_accept(); do_accept();
}); });
} }
asio::ip::tcp::acceptor acceptor_; asio::ip::tcp::acceptor acceptor_;
chat_room room_; chat_room room_;
}; };
#endif // CHAT_SERVER_HPP #endif // CHAT_SERVER_HPP

View File

@ -1,14 +1,9 @@
# This example code is in the Public Domain (or CC0 licensed, at your option.) # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
# Unless required by applicable law or agreed to in writing, this
# software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied.
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re import re
import pytest
from pytest_embedded import Dut
def test_examples_asio_chat(dut): def test_examples_asio_chat(dut):

View File

@ -9,7 +9,7 @@ The application aims to show how to compose async operations using ASIO to build
# Configure and Building example # Configure and Building example
This example doesn't require any configuration, just build it with This example doesn't require any configuration, just build it with
``` ```
idf.py build idf.py build
@ -17,12 +17,12 @@ idf.py build
# Async operations composition and automatic lifetime control # Async operations composition and automatic lifetime control
On this example we compose the operation by starting the next step in the chain inside the completion handler of the On this example we compose the operation by starting the next step in the chain inside the completion handler of the
previous operation. Also we pass the `Connection` class itself as the parameter of its final handler to be owned by previous operation. Also we pass the `Connection` class itself as the parameter of its final handler to be owned by
the following operation. This is possible due to the control of lifetime by the usage of `std::shared_ptr`. the following operation. This is possible due to the control of lifetime by the usage of `std::shared_ptr`.
The control of lifetime of the class, done by `std::shared_ptr` usage, guarantee that the data will be available for The control of lifetime of the class, done by `std::shared_ptr` usage, guarantee that the data will be available for
async operations until it's not needed any more. This makes necessary that all of the async operation class must start async operations until it's not needed any more. This makes necessary that all of the async operation class must start
its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from_this`. its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from_this`.
@ -48,5 +48,5 @@ its lifetime as a `std::shared_ptr` due to the usage of `std::enable_shared_from
└────►Completion Handler() └────►Completion Handler()
The previous diagram shows the process and the life span of each of the tasks in this examples. At each stage the The previous diagram shows the process and the life span of each of the tasks in this examples. At each stage the
object responsible for the last action inject itself to the completion handler of the next stage for reuse. object responsible for the last action inject itself to the completion handler of the next stage for reuse.

View File

@ -5,64 +5,64 @@
(See the README.md file in the upper level 'examples' directory for more information about examples.) (See the README.md file in the upper level 'examples' directory for more information about examples.)
The application aims to show how to connect to a Socks4 proxy using async operations with ASIO. The SOCKS protocol is The application aims to show how to connect to a Socks4 proxy using async operations with ASIO. The SOCKS protocol is
briefly described by the diagram below. briefly described by the diagram below.
┌──────┐ ┌─────┐ ┌──────┐ ┌──────┐ ┌─────┐ ┌──────┐
│Client│ │Proxy│ │Target│ │Client│ │Proxy│ │Target│
└──┬───┘ └──┬──┘ └──┬───┘ └──┬───┘ └──┬──┘ └──┬───┘
│ │ │ │ │ │
│ ╔═╧══════════════╗ │ │ ╔═╧══════════════╗ │
══════════════════════╪════════════════════════╣ Initialization ╠═══╪════════════════════════════════════════════ ══════════════════════╪════════════════════════╣ Initialization ╠═══╪════════════════════════════════════════════
│ ╚═╤══════════════╝ │ │ ╚═╤══════════════╝ │
│ │ │ │ │ │
╔══════════════════╗│ │ │ ╔══════════════════╗│ │ │
║We establish a ░║│ Socket Connection │ │ ║We establish a ░║│ Socket Connection │ │
║TCP connection ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ > │ ║TCP connection ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ > │
║and get a socket ║│ │ │ ║and get a socket ║│ │ │
╚══════════════════╝│ │ │ ╚══════════════════╝│ │ │
│ │ │ │ │ │
│ ╔═╧══════════════╗ │ │ ╔═╧══════════════╗ │
══════════════════════╪════════════════════════╣ Socks Protocol ╠═══╪════════════════════════════════════════════ ══════════════════════╪════════════════════════╣ Socks Protocol ╠═══╪════════════════════════════════════════════
│ ╚═╤══════════════╝ │ │ ╚═╤══════════════╝ │
│ │ │ │ │ │
│ Client Connection Request│ │ │ Client Connection Request│ │
│ ─────────────────────────> │ │ ─────────────────────────> │
│ │ │ │ │ │
│ │ │ │ │ │
│ ╔════════════╪═══════╤══════════╪════════════════════════════════╗ │ ╔════════════╪═══════╤══════════╪════════════════════════════════╗
│ ║ TARGET CONNECTION │ │ ║ │ ║ TARGET CONNECTION │ │ ║
│ ╟────────────────────┘ │ ╔═══════════════════╗ ║ │ ╟────────────────────┘ │ ╔═══════════════════╗ ║
│ ║ │ Socket Connection│ ║Proxy establishes ░║ ║ │ ║ │ Socket Connection│ ║Proxy establishes ░║ ║
│ ║ │ <─ ─ ─ ─ ─ ─ ─ ─ > ║ TCPconnection ║ ║ │ ║ │ <─ ─ ─ ─ ─ ─ ─ ─ > ║ TCPconnection ║ ║
│ ║ │ │ ║ with target host ║ ║ │ ║ │ │ ║ with target host ║ ║
│ ╚════════════╪══════════════════╪══╚═══════════════════╝═════════╝ │ ╚════════════╪══════════════════╪══╚═══════════════════╝═════════╝
│ │ │ │ │ │
│ Response packet │ │ │ Response packet │ │
<───────────────────────── │ <───────────────────────── │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ ╔═══════╗ │ │ │ ╔═══════╗ │
══════════════════════╪══════════════════════════╪══╣ Usage ╠═══════╪════════════════════════════════════════════ ══════════════════════╪══════════════════════════╪══╣ Usage ╠═══════╪════════════════════════════════════════════
│ │ ╚═══════╝ │ │ │ ╚═══════╝ │
│ │ │ │ │ │
╔═════════════════╗│ │ │ ╔═════════════════╗│ │ │
║Client uses the ░║│ │ │ ║Client uses the ░║│ │ │
║ socket opened ║│ │ │ ║ socket opened ║│ │ │
║ with proxy ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─> ║ with proxy ║│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─>
║to communicate ║│ │ │ ║to communicate ║│ │ │
║ ║│ │ │ ║ ║│ │ │
╚═════════════════╝┴───┐ ┌──┴──┐ ┌──┴───┐ ╚═════════════════╝┴───┐ ┌──┴──┐ ┌──┴───┐
│Client│ │Proxy│ │Target│ │Client│ │Proxy│ │Target│
└──────┘ └─────┘ └──────┘ └──────┘ └─────┘ └──────┘
# Configure and Building example # Configure and Building example
This example requires the proxy address to be configured. You can do this using the menuconfig option. This example requires the proxy address to be configured. You can do this using the menuconfig option.
Proxy address and port must be configured in order for this example to work. Proxy address and port must be configured in order for this example to work.
If using Linux ssh can be used as a proxy for testing. If using Linux ssh can be used as a proxy for testing.
``` ```
ssh -N -v -D 0.0.0.0:1080 localhost ssh -N -v -D 0.0.0.0:1080 localhost
@ -70,4 +70,3 @@ ssh -N -v -D 0.0.0.0:1080 localhost
# Async operations composition and automatic lifetime control # Async operations composition and automatic lifetime control
For documentation about the structure of this example look into [async\_request README](../async_request/README.md). For documentation about the structure of this example look into [async\_request README](../async_request/README.md).

View File

@ -183,7 +183,7 @@ void async_connect(asio::io_context &context, std::string proxy, std::string pro
std::make_shared<Connection>(context)->start(proxy_resolution, std::make_shared<Connection>(context)->start(proxy_resolution,
[resolver, host_resolution, completion_handler](std::shared_ptr<Connection> connection) { [resolver, host_resolution, completion_handler](std::shared_ptr<Connection> connection) {
auto connect_data = std::make_shared<ConnectionData>(socks4::request::connect, *host_resolution, ""); auto connect_data = std::make_shared<ConnectionData>(socks4::request::connect, *host_resolution, "");
ESP_LOGI(TAG, "Sending Request to proxy for host connection."); ESP_LOGI(TAG, "Sending Request to proxy for host connection.");
connection->write_async(connect_data->request.buffers(), [connection, connect_data, completion_handler](std::error_code error, std::size_t bytes_received) { connection->write_async(connect_data->request.buffers(), [connection, connect_data, completion_handler](std::error_code error, std::size_t bytes_received) {
if (error) { if (error) {
ESP_LOGE(TAG, "Proxy request write error: %s", error.message().c_str()); ESP_LOGE(TAG, "Proxy request write error: %s", error.message().c_str());

View File

@ -20,122 +20,115 @@ namespace socks4 {
const unsigned char version = 0x04; const unsigned char version = 0x04;
class request class request {
{
public: public:
enum command_type enum command_type {
{ connect = 0x01,
connect = 0x01, bind = 0x02
bind = 0x02 };
};
request(command_type cmd, const asio::ip::tcp::endpoint& endpoint, request(command_type cmd, const asio::ip::tcp::endpoint &endpoint,
const std::string& user_id) const std::string &user_id)
: version_(version), : version_(version),
command_(cmd), command_(cmd),
user_id_(user_id), user_id_(user_id),
null_byte_(0) null_byte_(0)
{
// Only IPv4 is supported by the SOCKS 4 protocol.
if (endpoint.protocol() != asio::ip::tcp::v4())
{ {
throw asio::system_error( // Only IPv4 is supported by the SOCKS 4 protocol.
asio::error::address_family_not_supported); if (endpoint.protocol() != asio::ip::tcp::v4()) {
throw asio::system_error(
asio::error::address_family_not_supported);
}
// Convert port number to network byte order.
unsigned short port = endpoint.port();
port_high_byte_ = (port >> 8) & 0xff;
port_low_byte_ = port & 0xff;
// Save IP address in network byte order.
address_ = endpoint.address().to_v4().to_bytes();
} }
// Convert port number to network byte order. std::array<asio::const_buffer, 7> buffers() const
unsigned short port = endpoint.port();
port_high_byte_ = (port >> 8) & 0xff;
port_low_byte_ = port & 0xff;
// Save IP address in network byte order.
address_ = endpoint.address().to_v4().to_bytes();
}
std::array<asio::const_buffer, 7> buffers() const
{
return
{ {
{ return {
asio::buffer(&version_, 1), {
asio::buffer(&command_, 1), asio::buffer(&version_, 1),
asio::buffer(&port_high_byte_, 1), asio::buffer(&command_, 1),
asio::buffer(&port_low_byte_, 1), asio::buffer(&port_high_byte_, 1),
asio::buffer(address_), asio::buffer(&port_low_byte_, 1),
asio::buffer(user_id_), asio::buffer(address_),
asio::buffer(&null_byte_, 1) asio::buffer(user_id_),
} asio::buffer(&null_byte_, 1)
}; }
} };
}
private: private:
unsigned char version_; unsigned char version_;
unsigned char command_; unsigned char command_;
unsigned char port_high_byte_; unsigned char port_high_byte_;
unsigned char port_low_byte_; unsigned char port_low_byte_;
asio::ip::address_v4::bytes_type address_; asio::ip::address_v4::bytes_type address_;
std::string user_id_; std::string user_id_;
unsigned char null_byte_; unsigned char null_byte_;
}; };
class reply class reply {
{
public: public:
enum status_type enum status_type {
{ request_granted = 0x5a,
request_granted = 0x5a, request_failed = 0x5b,
request_failed = 0x5b, request_failed_no_identd = 0x5c,
request_failed_no_identd = 0x5c, request_failed_bad_user_id = 0x5d
request_failed_bad_user_id = 0x5d
};
reply()
: null_byte_(0),
status_()
{
}
std::array<asio::mutable_buffer, 5> buffers()
{
return
{
{
asio::buffer(&null_byte_, 1),
asio::buffer(&status_, 1),
asio::buffer(&port_high_byte_, 1),
asio::buffer(&port_low_byte_, 1),
asio::buffer(address_)
}
}; };
}
bool success() const reply()
{ : null_byte_(0),
return null_byte_ == 0 && status_ == request_granted; status_()
} {
}
unsigned char status() const std::array<asio::mutable_buffer, 5> buffers()
{ {
return status_; return {
} {
asio::buffer(&null_byte_, 1),
asio::buffer(&status_, 1),
asio::buffer(&port_high_byte_, 1),
asio::buffer(&port_low_byte_, 1),
asio::buffer(address_)
}
};
}
asio::ip::tcp::endpoint endpoint() const bool success() const
{ {
unsigned short port = port_high_byte_; return null_byte_ == 0 && status_ == request_granted;
port = (port << 8) & 0xff00; }
port = port | port_low_byte_;
asio::ip::address_v4 address(address_); unsigned char status() const
{
return status_;
}
return asio::ip::tcp::endpoint(address, port); asio::ip::tcp::endpoint endpoint() const
} {
unsigned short port = port_high_byte_;
port = (port << 8) & 0xff00;
port = port | port_low_byte_;
asio::ip::address_v4 address(address_);
return asio::ip::tcp::endpoint(address, port);
}
private: private:
unsigned char null_byte_; unsigned char null_byte_;
unsigned char status_; unsigned char status_;
unsigned char port_high_byte_; unsigned char port_high_byte_;
unsigned char port_low_byte_; unsigned char port_low_byte_;
asio::ip::address_v4::bytes_type address_; asio::ip::address_v4::bytes_type address_;
}; };
} // namespace socks4 } // namespace socks4

View File

@ -1,8 +1,7 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
from __future__ import unicode_literals from __future__ import unicode_literals
import pytest
from pytest_embedded import Dut
def test_examples_asio_ssl(dut): def test_examples_asio_ssl(dut):
dut.expect('Reply: GET / HTTP/1.1') dut.expect('Reply: GET / HTTP/1.1')

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "asio.hpp" #include "asio.hpp"
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -8,78 +13,70 @@
using asio::ip::tcp; using asio::ip::tcp;
class session class session
: public std::enable_shared_from_this<session> : public std::enable_shared_from_this<session> {
{
public: public:
session(tcp::socket socket) session(tcp::socket socket)
: socket_(std::move(socket)) : socket_(std::move(socket))
{ {
} }
void start() void start()
{ {
do_read(); do_read();
} }
private: private:
void do_read() void do_read()
{ {
auto self(shared_from_this()); auto self(shared_from_this());
socket_.async_read_some(asio::buffer(data_, max_length), socket_.async_read_some(asio::buffer(data_, max_length),
[this, self](std::error_code ec, std::size_t length) [this, self](std::error_code ec, std::size_t length) {
{ if (!ec) {
if (!ec) data_[length] = 0;
{ std::cout << data_ << std::endl;
data_[length] = 0; do_write(length);
std::cout << data_ << std::endl; }
do_write(length);
}
}); });
} }
void do_write(std::size_t length) void do_write(std::size_t length)
{ {
auto self(shared_from_this()); auto self(shared_from_this());
asio::async_write(socket_, asio::buffer(data_, length), asio::async_write(socket_, asio::buffer(data_, length),
[this, self](std::error_code ec, std::size_t length) [this, self](std::error_code ec, std::size_t length) {
{ if (!ec) {
if (!ec) do_read();
{ }
do_read();
}
}); });
} }
tcp::socket socket_; tcp::socket socket_;
enum { max_length = 1024 }; enum { max_length = 1024 };
char data_[max_length]; char data_[max_length];
}; };
class server class server {
{
public: public:
server(asio::io_context& io_context, short port) server(asio::io_context &io_context, short port)
: acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) : acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
{ {
do_accept(); do_accept();
} }
private: private:
void do_accept() void do_accept()
{ {
acceptor_.async_accept( acceptor_.async_accept(
[this](std::error_code ec, tcp::socket socket) [this](std::error_code ec, tcp::socket socket) {
{ if (!ec) {
if (!ec) std::make_shared<session>(std::move(socket))->start();
{ }
std::make_shared<session>(std::move(socket))->start();
}
do_accept(); do_accept();
}); });
} }
tcp::acceptor acceptor_; tcp::acceptor acceptor_;
}; };

View File

@ -1,7 +1,7 @@
import os # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import re import re
import socket import socket
from pytest_embedded import Dut
def test_examples_protocol_asio_tcp_server(dut): def test_examples_protocol_asio_tcp_server(dut):
@ -15,7 +15,10 @@ def test_examples_protocol_asio_tcp_server(dut):
""" """
test_msg = b'echo message from client to server' test_msg = b'echo message from client to server'
# 2. get the server IP address # 2. get the server IP address
data = dut.expect(re.compile(b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30).group(1).decode() data = dut.expect(
re.compile(
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
timeout=30).group(1).decode()
# 3. create tcp client and connect to server # 3. create tcp client and connect to server
dut.expect('ASIO engine is up and running', timeout=1) dut.expect('ASIO engine is up and running', timeout=1)
cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -29,7 +32,8 @@ def test_examples_protocol_asio_tcp_server(dut):
pass pass
else: else:
print('Failure!') print('Failure!')
raise ValueError('Wrong data received from asi tcp server: {} (expected:{})'.format(data, test_msg)) raise ValueError(
'Wrong data received from asi tcp server: {} (expected:{})'.format(
data, test_msg))
# 5. check the client message appears also on server terminal # 5. check the client message appears also on server terminal
dut.expect(test_msg.decode()) dut.expect(test_msg.decode())

View File

@ -20,49 +20,43 @@
using asio::ip::udp; using asio::ip::udp;
class server class server {
{
public: public:
server(asio::io_context& io_context, short port) server(asio::io_context &io_context, short port)
: socket_(io_context, udp::endpoint(udp::v4(), port)) : socket_(io_context, udp::endpoint(udp::v4(), port))
{ {
do_receive(); do_receive();
} }
void do_receive() void do_receive()
{ {
socket_.async_receive_from( socket_.async_receive_from(
asio::buffer(data_, max_length), sender_endpoint_, asio::buffer(data_, max_length), sender_endpoint_,
[this](std::error_code ec, std::size_t bytes_recvd) [this](std::error_code ec, std::size_t bytes_recvd) {
{ if (!ec && bytes_recvd > 0) {
if (!ec && bytes_recvd > 0) data_[bytes_recvd] = 0;
{ std::cout << data_ << std::endl;
data_[bytes_recvd] = 0; do_send(bytes_recvd);
std::cout << data_ << std::endl; } else {
do_send(bytes_recvd); do_receive();
} }
else });
{ }
void do_send(std::size_t length)
{
socket_.async_send_to(
asio::buffer(data_, length), sender_endpoint_,
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/) {
do_receive(); do_receive();
}
}); });
} }
void do_send(std::size_t length)
{
socket_.async_send_to(
asio::buffer(data_, length), sender_endpoint_,
[this](std::error_code /*ec*/, std::size_t bytes /*bytes_sent*/)
{
do_receive();
});
}
private: private:
udp::socket socket_; udp::socket socket_;
udp::endpoint sender_endpoint_; udp::endpoint sender_endpoint_;
enum { max_length = 1024 }; enum { max_length = 1024 };
char data_[max_length]; char data_[max_length];
}; };
extern "C" void app_main(void) extern "C" void app_main(void)

View File

@ -1,9 +1,8 @@
import os # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import re import re
import socket import socket
import pytest
from pytest_embedded import Dut
def test_examples_protocol_asio_udp_server(dut): def test_examples_protocol_asio_udp_server(dut):
""" """
@ -15,7 +14,10 @@ def test_examples_protocol_asio_udp_server(dut):
5. Test evaluates received test message on server stdout 5. Test evaluates received test message on server stdout
""" """
test_msg = b'echo message from client to server' test_msg = b'echo message from client to server'
data = dut.expect(re.compile(b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30).group(1).decode() data = dut.expect(
re.compile(
b' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), # noqa: W605
timeout=30).group(1).decode()
dut.expect('ASIO engine is up and running', timeout=1) dut.expect('ASIO engine is up and running', timeout=1)
cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cli.settimeout(30) cli.settimeout(30)
@ -28,6 +30,8 @@ def test_examples_protocol_asio_udp_server(dut):
pass pass
else: else:
print('Failure!') print('Failure!')
raise ValueError('Wrong data received from asio udp server: {} (expected:{})'.format(data, test_msg)) raise ValueError(
'Wrong data received from asio udp server: {} (expected:{})'.
format(data, test_msg))
# 5. check the client message appears also on server terminal # 5. check the client message appears also on server terminal
dut.expect(test_msg.decode()) dut.expect(test_msg.decode())

View File

@ -19,12 +19,13 @@
namespace asio { namespace asio {
namespace detail { namespace detail {
template <typename Exception> template <typename Exception>
void throw_exception(const Exception& e) void throw_exception(const Exception &e)
{ {
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what()); ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
abort(); abort();
}
}
} }
}}
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS) #endif // CONFIG_COMPILER_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
#endif // _ESP_EXCEPTION_H_ #endif // _ESP_EXCEPTION_H_

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
@ -16,9 +16,9 @@
#define SSL_OP_SINGLE_DH_USE 0 #define SSL_OP_SINGLE_DH_USE 0
#define SSL_OP_NO_COMPRESSION 0 #define SSL_OP_NO_COMPRESSION 0
#define SSL_OP_NO_SSLv2 0x01000000L #define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_OP_NO_SSLv3 0x02000000L #define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_TLSv1 0x04000000L #define SSL_OP_NO_TLSv1 0x04000000L
#define SSL_VERIFY_NONE 0x00 #define SSL_VERIFY_NONE 0x00
#define SSL_VERIFY_PEER 0x01 #define SSL_VERIFY_PEER 0x01
@ -35,12 +35,14 @@ namespace mbedtls {
class engine; class engine;
class bio; class bio;
class shared_ctx; class shared_ctx;
} } } // namespace asio::ssl::mbedtls }
}
} // namespace asio::ssl::mbedtls
// //
// Supply OpenSSL types as aliases to mbedtls classes // Supply OpenSSL types as aliases to mbedtls classes
// //
using X509_STORE_CTX=void; using X509_STORE_CTX = void;
using BIO=asio::ssl::mbedtls::bio; using BIO = asio::ssl::mbedtls::bio;
using SSL_CTX=asio::ssl::mbedtls::shared_ctx; using SSL_CTX = asio::ssl::mbedtls::shared_ctx;
using SSL=asio::ssl::mbedtls::engine; using SSL = asio::ssl::mbedtls::engine;

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
@ -87,7 +87,7 @@ public:
return flags_ & BIO_FLAGS_READ; return flags_ & BIO_FLAGS_READ;
} }
static std::pair<std::shared_ptr<bio>, std::shared_ptr<bio>> new_pair(const char* error_location) static std::pair<std::shared_ptr<bio>, std::shared_ptr<bio>> new_pair(const char *error_location)
{ {
auto b1 = std::shared_ptr<bio>(new (std::nothrow) bio); auto b1 = std::shared_ptr<bio>(new (std::nothrow) bio);
auto b2 = std::shared_ptr<bio>(new (std::nothrow) bio); auto b2 = std::shared_ptr<bio>(new (std::nothrow) bio);
@ -110,4 +110,6 @@ private:
size_t flags_ {0}; size_t flags_ {0};
}; };
} } } // namespace asio::ssl::mbedtls }
}
} // namespace asio::ssl::mbedtls

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
@ -11,13 +11,13 @@
namespace asio { namespace asio {
namespace error { namespace error {
const asio::error_category& get_mbedtls_category(); const asio::error_category &get_mbedtls_category();
} // namespace error } // namespace error
namespace ssl { namespace ssl {
namespace mbedtls { namespace mbedtls {
void throw_alloc_failure(const char* location); void throw_alloc_failure(const char *location);
const char *error_message(int error_code); const char *error_message(int error_code);
@ -26,11 +26,10 @@ enum class container {
}; };
template <typename T, typename... Args> template <typename T, typename... Args>
inline T* create(const char * location, Args &&... args) inline T *create(const char *location, Args &&... args)
{ {
T* t = new (std::nothrow) T(std::forward<Args>(args)...); T *t = new (std::nothrow) T(std::forward<Args>(args)...);
if (t == nullptr) if (t == nullptr) {
{
throw_alloc_failure(location); throw_alloc_failure(location);
} }
return t; return t;
@ -43,12 +42,12 @@ public:
const unsigned char *data(container c) const const unsigned char *data(container c) const
{ {
switch (c) { switch (c) {
case container::CERT: case container::CERT:
return static_cast<const unsigned char *>(cert_chain_.data()); return static_cast<const unsigned char *>(cert_chain_.data());
case container::CA_CERT: case container::CA_CERT:
return static_cast<const unsigned char *>(ca_cert_.data()); return static_cast<const unsigned char *>(ca_cert_.data());
case container::PRIVKEY: case container::PRIVKEY:
return static_cast<const unsigned char *>(private_key_.data()); return static_cast<const unsigned char *>(private_key_.data());
} }
return nullptr; return nullptr;
} }
@ -56,12 +55,12 @@ public:
std::size_t size(container c) const std::size_t size(container c) const
{ {
switch (c) { switch (c) {
case container::CERT: case container::CERT:
return cert_chain_.size(); return cert_chain_.size();
case container::CA_CERT: case container::CA_CERT:
return ca_cert_.size(); return ca_cert_.size();
case container::PRIVKEY: case container::PRIVKEY:
return private_key_.size(); return private_key_.size();
} }
return 0; return 0;
} }
@ -80,11 +79,10 @@ public:
*/ */
class shared_ctx { class shared_ctx {
public: public:
static SSL_CTX *create(const char* location, context_base::method m) static SSL_CTX *create(const char *location, context_base::method m)
{ {
auto wrapped = asio::ssl::mbedtls::create<shared_ctx>(location, m); auto wrapped = asio::ssl::mbedtls::create<shared_ctx>(location, m);
if (wrapped->ctx_ == nullptr) if (wrapped->ctx_ == nullptr) {
{
throw_alloc_failure(location); throw_alloc_failure(location);
} }
return wrapped; return wrapped;
@ -96,10 +94,12 @@ public:
} }
explicit shared_ctx(context_base::method m) explicit shared_ctx(context_base::method m)
:ctx_(std::shared_ptr<context>(new (std::nothrow) context(m))) { } : ctx_(std::shared_ptr<context>(new (std::nothrow) context(m))) { }
private: private:
std::shared_ptr<mbedtls::context> ctx_; std::shared_ptr<mbedtls::context> ctx_;
}; };
} } } // namespace asio::ssl::mbedtls }
}
} // namespace asio::ssl::mbedtls

View File

@ -23,7 +23,7 @@ const char *error_message(int error_code)
return error_buf; return error_buf;
} }
void throw_alloc_failure(const char* location) void throw_alloc_failure(const char *location)
{ {
asio::error_code ec( MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category()); asio::error_code ec( MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category());
asio::detail::throw_error(ec, location); asio::detail::throw_error(ec, location);
@ -62,7 +62,7 @@ public:
verify_mode_ = mode; verify_mode_ = mode;
} }
bio* ext_bio() const bio *ext_bio() const
{ {
return bio_.second.get(); return bio_.second.get();
} }
@ -95,14 +95,14 @@ public:
int write(const void *buffer, int len) int write(const void *buffer, int len)
{ {
int ret = impl_.write(buffer, len); int ret = impl_.write(buffer, len);
state_ = ret == len ? IDLE: WRITING; state_ = ret == len ? IDLE : WRITING;
return ret; return ret;
} }
int read(void *buffer, int len) int read(void *buffer, int len)
{ {
int ret = impl_.read(buffer, len); int ret = impl_.read(buffer, len);
state_ = ret == len ? IDLE: READING; state_ = ret == len ? IDLE : READING;
return ret; return ret;
} }
@ -117,7 +117,7 @@ private:
static int bio_read(void *ctx, unsigned char *buf, size_t len) static int bio_read(void *ctx, unsigned char *buf, size_t len)
{ {
auto bio = static_cast<BIO*>(ctx); auto bio = static_cast<BIO *>(ctx);
int read = bio->read(buf, len); int read = bio->read(buf, len);
if (read <= 0 && bio->should_read()) { if (read <= 0 && bio->should_read()) {
return MBEDTLS_ERR_SSL_WANT_READ; return MBEDTLS_ERR_SSL_WANT_READ;
@ -127,7 +127,7 @@ private:
static int bio_write(void *ctx, const unsigned char *buf, size_t len) static int bio_write(void *ctx, const unsigned char *buf, size_t len)
{ {
auto bio = static_cast<BIO*>(ctx); auto bio = static_cast<BIO *>(ctx);
int written = bio->write(buf, len); int written = bio->write(buf, len);
if (written <= 0 && bio->should_write()) { if (written <= 0 && bio->should_write()) {
return MBEDTLS_ERR_SSL_WANT_WRITE; return MBEDTLS_ERR_SSL_WANT_WRITE;
@ -163,25 +163,27 @@ private:
{ {
int mode = MBEDTLS_SSL_VERIFY_UNSET; int mode = MBEDTLS_SSL_VERIFY_UNSET;
if (is_client_not_server) { if (is_client_not_server) {
if (verify_mode_ & SSL_VERIFY_PEER) if (verify_mode_ & SSL_VERIFY_PEER) {
mode = MBEDTLS_SSL_VERIFY_REQUIRED; mode = MBEDTLS_SSL_VERIFY_REQUIRED;
else if (verify_mode_ == SSL_VERIFY_NONE) } else if (verify_mode_ == SSL_VERIFY_NONE) {
mode = MBEDTLS_SSL_VERIFY_NONE; mode = MBEDTLS_SSL_VERIFY_NONE;
}
} else { } else {
if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
mode = MBEDTLS_SSL_VERIFY_REQUIRED; mode = MBEDTLS_SSL_VERIFY_REQUIRED;
else if (verify_mode_ & SSL_VERIFY_PEER) } else if (verify_mode_ & SSL_VERIFY_PEER) {
mode = MBEDTLS_SSL_VERIFY_OPTIONAL; mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
else if (verify_mode_ == SSL_VERIFY_NONE) } else if (verify_mode_ == SSL_VERIFY_NONE) {
mode = MBEDTLS_SSL_VERIFY_NONE; mode = MBEDTLS_SSL_VERIFY_NONE;
}
} }
return mode; return mode;
} }
struct impl { struct impl {
static void print_error(const char* function, int error_code) static void print_error(const char *function, int error_code)
{ {
constexpr const char *TAG="mbedtls-engine-impl"; constexpr const char *TAG = "mbedtls-engine-impl";
ESP_LOGE(TAG, "%s() returned -0x%04X", function, -error_code); ESP_LOGE(TAG, "%s() returned -0x%04X", function, -error_code);
ESP_LOGI(TAG, "-0x%04X: %s", -error_code, error_message(error_code)); ESP_LOGI(TAG, "-0x%04X: %s", -error_code, error_message(error_code));
} }
@ -230,7 +232,7 @@ private:
mbedtls_x509_crt_init(&public_cert_); mbedtls_x509_crt_init(&public_cert_);
mbedtls_pk_init(&pk_key_); mbedtls_pk_init(&pk_key_);
mbedtls_x509_crt_init(&ca_cert_); mbedtls_x509_crt_init(&ca_cert_);
int ret = mbedtls_ssl_config_defaults(&conf_, is_client_not_server ? MBEDTLS_SSL_IS_CLIENT: MBEDTLS_SSL_IS_SERVER, int ret = mbedtls_ssl_config_defaults(&conf_, is_client_not_server ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
if (ret) { if (ret) {
print_error("mbedtls_ssl_config_defaults", ret); print_error("mbedtls_ssl_config_defaults", ret);
@ -290,4 +292,6 @@ private:
asio::ssl::verify_mode verify_mode_; asio::ssl::verify_mode verify_mode_;
}; };
} } } // namespace asio::ssl::mbedtls }
}
} // namespace asio::ssl::mbedtls

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
@ -14,30 +14,29 @@ namespace asio {
namespace error { namespace error {
namespace detail { namespace detail {
class mbedtls_category : public asio::error_category class mbedtls_category : public asio::error_category {
{
public: public:
const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT const char *name() const ASIO_ERROR_CATEGORY_NOEXCEPT
{ {
return "asio.ssl"; return "asio.ssl";
} }
std::string message(int value) const std::string message(int value) const
{ {
const char* s = asio::ssl::mbedtls::error_message(value); const char *s = asio::ssl::mbedtls::error_message(value);
return s ? s : "asio.mbedtls error"; return s ? s : "asio.mbedtls error";
} }
}; };
} // namespace detail } // namespace detail
const asio::error_category& get_mbedtls_category() const asio::error_category &get_mbedtls_category()
{ {
static detail::mbedtls_category instance; static detail::mbedtls_category instance;
return instance; return instance;
} }
const asio::error_category& get_ssl_category() const asio::error_category &get_ssl_category()
{ {
return asio::error::get_mbedtls_category(); return asio::error::get_mbedtls_category();
} }
@ -47,9 +46,11 @@ const asio::error_category& get_ssl_category()
namespace ssl { namespace ssl {
namespace error { namespace error {
const asio::error_category& get_stream_category() const asio::error_category &get_stream_category()
{ {
return asio::error::get_mbedtls_category(); return asio::error::get_mbedtls_category();
} }
} } } // namespace asio::ssl::error }
}
} // namespace asio::ssl::error

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //

View File

@ -4,7 +4,7 @@
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
@ -22,19 +22,19 @@ namespace ssl {
context::context(context::method m) context::context(context::method m)
: handle_(0) : handle_(0)
{ {
handle_ = mbedtls::shared_ctx::create("mbedtls-context", m); handle_ = mbedtls::shared_ctx::create("mbedtls-context", m);
set_options(no_compression); set_options(no_compression);
} }
context::context(context&& other) context::context(context &&other)
{ {
handle_ = other.handle_; handle_ = other.handle_;
other.handle_ = 0; other.handle_ = 0;
} }
context& context::operator=(context&& other) context &context::operator=(context &&other)
{ {
context tmp(ASIO_MOVE_CAST(context)(*this)); context tmp(ASIO_MOVE_CAST(context)(*this));
handle_ = other.handle_; handle_ = other.handle_;
@ -60,14 +60,14 @@ void context::set_options(context::options o)
} }
ASIO_SYNC_OP_VOID context::set_options( ASIO_SYNC_OP_VOID context::set_options(
context::options o, asio::error_code& ec) context::options o, asio::error_code &ec)
{ {
handle_->get()->options_ = o; handle_->get()->options_ = o;
ec = asio::error_code(); ec = asio::error_code();
ASIO_SYNC_OP_VOID_RETURN(ec); ASIO_SYNC_OP_VOID_RETURN(ec);
} }
void context::add_certificate_authority(const const_buffer& ca) void context::add_certificate_authority(const const_buffer &ca)
{ {
asio::error_code ec; asio::error_code ec;
add_certificate_authority(ca, ec); add_certificate_authority(ca, ec);
@ -75,13 +75,13 @@ void context::add_certificate_authority(const const_buffer& ca)
} }
ASIO_SYNC_OP_VOID context::add_certificate_authority( ASIO_SYNC_OP_VOID context::add_certificate_authority(
const const_buffer& ca, asio::error_code& ec) const const_buffer &ca, asio::error_code &ec)
{ {
handle_->get()->ca_cert_ = ca; handle_->get()->ca_cert_ = ca;
ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); ASIO_SYNC_OP_VOID_RETURN(asio::error_code());
} }
void context::use_certificate_chain(const const_buffer& chain) void context::use_certificate_chain(const const_buffer &chain)
{ {
asio::error_code ec; asio::error_code ec;
use_certificate_chain(chain, ec); use_certificate_chain(chain, ec);
@ -89,14 +89,14 @@ void context::use_certificate_chain(const const_buffer& chain)
} }
ASIO_SYNC_OP_VOID context::use_certificate_chain( ASIO_SYNC_OP_VOID context::use_certificate_chain(
const const_buffer& chain, asio::error_code& ec) const const_buffer &chain, asio::error_code &ec)
{ {
handle_->get()->cert_chain_ = chain; handle_->get()->cert_chain_ = chain;
ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); ASIO_SYNC_OP_VOID_RETURN(asio::error_code());
} }
void context::use_private_key( void context::use_private_key(
const const_buffer& private_key, context::file_format format) const const_buffer &private_key, context::file_format format)
{ {
asio::error_code ec; asio::error_code ec;
use_private_key(private_key, format, ec); use_private_key(private_key, format, ec);
@ -104,8 +104,8 @@ void context::use_private_key(
} }
ASIO_SYNC_OP_VOID context::use_private_key( ASIO_SYNC_OP_VOID context::use_private_key(
const const_buffer& private_key, context::file_format format, const const_buffer &private_key, context::file_format format,
asio::error_code& ec) asio::error_code &ec)
{ {
handle_->get()->private_key_ = private_key; handle_->get()->private_key_ = private_key;
ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); ASIO_SYNC_OP_VOID_RETURN(asio::error_code());

View File

@ -3,7 +3,7 @@
// //
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// //
// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileContributor: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
@ -24,8 +24,8 @@ namespace ssl {
namespace detail { namespace detail {
engine::engine(SSL_CTX* context) engine::engine(SSL_CTX *context)
: ssl_(nullptr) : ssl_(nullptr)
{ {
ssl_ = mbedtls::create<mbedtls::engine>("mbedtls-engine", context->get()); ssl_ = mbedtls::create<mbedtls::engine>("mbedtls-engine", context->get());
} }
@ -35,49 +35,47 @@ engine::~engine()
delete ssl_; delete ssl_;
} }
SSL* engine::native_handle() SSL *engine::native_handle()
{ {
return ssl_; return ssl_;
} }
asio::error_code engine::set_verify_mode( asio::error_code engine::set_verify_mode(
verify_mode v, asio::error_code& ec) verify_mode v, asio::error_code &ec)
{ {
ssl_->set_verify_mode(v); ssl_->set_verify_mode(v);
return {}; return {};
} }
engine::want engine::handshake( engine::want engine::handshake(
stream_base::handshake_type type, asio::error_code& ec) stream_base::handshake_type type, asio::error_code &ec)
{ {
return perform((type == asio::ssl::stream_base::client) return perform((type == asio::ssl::stream_base::client)
? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0); ? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0);
} }
engine::want engine::shutdown(asio::error_code& ec) engine::want engine::shutdown(asio::error_code &ec)
{ {
return perform(&engine::do_shutdown, 0, 0, ec, 0); return perform(&engine::do_shutdown, 0, 0, ec, 0);
} }
engine::want engine::write(const asio::const_buffer& data, engine::want engine::write(const asio::const_buffer &data,
asio::error_code& ec, std::size_t& bytes_transferred) asio::error_code &ec, std::size_t &bytes_transferred)
{ {
if (data.size() == 0) if (data.size() == 0) {
{
ec = asio::error_code(); ec = asio::error_code();
return engine::want_nothing; return engine::want_nothing;
} }
return perform(&engine::do_write, return perform(&engine::do_write,
const_cast<void*>(data.data()), const_cast<void *>(data.data()),
data.size(), ec, &bytes_transferred); data.size(), ec, &bytes_transferred);
} }
engine::want engine::read(const asio::mutable_buffer& data, engine::want engine::read(const asio::mutable_buffer &data,
asio::error_code& ec, std::size_t& bytes_transferred) asio::error_code &ec, std::size_t &bytes_transferred)
{ {
if (data.size() == 0) if (data.size() == 0) {
{
ec = asio::error_code(); ec = asio::error_code();
return engine::want_nothing; return engine::want_nothing;
} }
@ -87,7 +85,7 @@ engine::want engine::read(const asio::mutable_buffer& data,
} }
asio::mutable_buffer engine::get_output( asio::mutable_buffer engine::get_output(
const asio::mutable_buffer& data) const asio::mutable_buffer &data)
{ {
int length = ssl_->ext_bio()->read(data.data(), static_cast<int>(data.size())); int length = ssl_->ext_bio()->read(data.data(), static_cast<int>(data.size()));
@ -96,7 +94,7 @@ asio::mutable_buffer engine::get_output(
} }
asio::const_buffer engine::put_input( asio::const_buffer engine::put_input(
const asio::const_buffer& data) const asio::const_buffer &data)
{ {
int length = ssl_->ext_bio()->write(data.data(), static_cast<int>(data.size())); int length = ssl_->ext_bio()->write(data.data(), static_cast<int>(data.size()));
@ -104,23 +102,22 @@ asio::const_buffer engine::put_input(
(length > 0 ? static_cast<std::size_t>(length) : 0)); (length > 0 ? static_cast<std::size_t>(length) : 0));
} }
const asio::error_code& engine::map_error_code( const asio::error_code &engine::map_error_code(
asio::error_code& ec) const asio::error_code &ec) const
{ {
// We only want to map the error::eof code. // We only want to map the error::eof code.
if (ec != asio::error::eof) if (ec != asio::error::eof) {
return ec; return ec;
}
// If there's data yet to be read, it's an error. // If there's data yet to be read, it's an error.
if (ssl_->ext_bio()->wpending()) if (ssl_->ext_bio()->wpending()) {
{
ec = asio::ssl::error::stream_truncated; ec = asio::ssl::error::stream_truncated;
return ec; return ec;
} }
// Otherwise, the peer should have negotiated a proper shutdown. // Otherwise, the peer should have negotiated a proper shutdown.
if (ssl_->shutdown() != 0) if (ssl_->shutdown() != 0) {
{
ec = asio::ssl::error::stream_truncated; ec = asio::ssl::error::stream_truncated;
} }
@ -129,47 +126,39 @@ const asio::error_code& engine::map_error_code(
// This is a simplified implementation of a generic ssl io operation // This is a simplified implementation of a generic ssl io operation
// original implementation using openssl's SSL object is in asio/include/asio/ssl/detail/impl/engine.ipp // original implementation using openssl's SSL object is in asio/include/asio/ssl/detail/impl/engine.ipp
engine::want engine::perform(int (engine::* op)(void*, std::size_t), engine::want engine::perform(int (engine::* op)(void *, std::size_t),
void* data, std::size_t length, asio::error_code& ec, void *data, std::size_t length, asio::error_code &ec,
std::size_t* bytes_transferred) std::size_t *bytes_transferred)
{ {
std::size_t pending_output_before = ssl_->ext_bio()->ctrl_pending(); std::size_t pending_output_before = ssl_->ext_bio()->ctrl_pending();
int result = (this->*op)(data, length); int result = (this->*op)(data, length);
std::size_t pending_output_after = ssl_->ext_bio()->ctrl_pending(); std::size_t pending_output_after = ssl_->ext_bio()->ctrl_pending();
if (mbedtls::error_codes::is_error(result)) if (mbedtls::error_codes::is_error(result)) {
{
ec = asio::error_code(result, asio::error::get_mbedtls_category()); ec = asio::error_code(result, asio::error::get_mbedtls_category());
return pending_output_after > pending_output_before ? want_output : want_nothing; return pending_output_after > pending_output_before ? want_output : want_nothing;
} }
if (result == 0) if (result == 0) {
{
return pending_output_after > pending_output_before return pending_output_after > pending_output_before
? want_output : want_nothing; ? want_output : want_nothing;
} }
if (result > 0 && bytes_transferred) if (result > 0 && bytes_transferred) {
*bytes_transferred = static_cast<std::size_t>(result); *bytes_transferred = static_cast<std::size_t>(result);
}
if (mbedtls::error_codes::want_write(result)) if (mbedtls::error_codes::want_write(result)) {
{
ec = asio::error_code(); ec = asio::error_code();
return want_output_and_retry; return want_output_and_retry;
} } else if (pending_output_after > pending_output_before) {
else if (pending_output_after > pending_output_before)
{
ec = asio::error_code(); ec = asio::error_code();
return result > 0 ? want_output : want_output_and_retry; return result > 0 ? want_output : want_output_and_retry;
} } else if (mbedtls::error_codes::want_read(result)) {
else if (mbedtls::error_codes::want_read(result))
{
ec = asio::error_code(); ec = asio::error_code();
return want_input_and_retry; return want_input_and_retry;
} } else if (ssl_->get_state() == mbedtls::CLOSED) {
else if (ssl_->get_state() == mbedtls::CLOSED)
{
ec = asio::error::eof; ec = asio::error::eof;
return want_nothing; return want_nothing;
} }
@ -178,27 +167,27 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
return want_nothing; return want_nothing;
} }
int engine::do_accept(void*, std::size_t) int engine::do_accept(void *, std::size_t)
{ {
return ssl_->accept(); return ssl_->accept();
} }
int engine::do_connect(void*, std::size_t) int engine::do_connect(void *, std::size_t)
{ {
return ssl_->connect(); return ssl_->connect();
} }
int engine::do_shutdown(void*, std::size_t) int engine::do_shutdown(void *, std::size_t)
{ {
return ssl_->shutdown(); return ssl_->shutdown();
} }
int engine::do_read(void* data, std::size_t length) int engine::do_read(void *data, std::size_t length)
{ {
return ssl_->read(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX); return ssl_->read(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX);
} }
int engine::do_write(void* data, std::size_t length) int engine::do_write(void *data, std::size_t length)
{ {
return ssl_->write(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX); return ssl_->write(data, length < INT_MAX ? static_cast<int>(length) : INT_MAX);
} }

View File

@ -1,5 +1,5 @@
// //
// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD // SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
@ -17,4 +17,6 @@ asio::detail::shared_ptr<openssl_init_base::do_init> openssl_init_base::instance
return nullptr; return nullptr;
} }
} } } // namespace asio::ssl::detail }
}
} // namespace asio::ssl::detail

View File

@ -93,4 +93,4 @@ dependencies.lock
docs/html docs/html
# esp-idf managed components # esp-idf managed components
**/managed_components/** **/managed_components/**

View File

@ -2522,4 +2522,3 @@ DOT_CLEANUP = YES
#DOT_GRAPH_MAX_NODES = 100 #DOT_GRAPH_MAX_NODES = 100
#MAX_DOT_GRAPH_DEPTH = 0 #MAX_DOT_GRAPH_DEPTH = 0
#DOT_TRANSPARENT = YES #DOT_TRANSPARENT = YES

View File

@ -1,14 +1,14 @@
# ESP MODEM # ESP MODEM
This component is used to communicate with modems in the command mode (using AT commands), as well as the data mode This component is used to communicate with modems in the command mode (using AT commands), as well as the data mode
(over PPPoS protocol). (over PPPoS protocol).
The modem device is modeled with a DCE (Data Communication Equipment) object, which is composed of: The modem device is modeled with a DCE (Data Communication Equipment) object, which is composed of:
* DTE (Data Terminal Equipment), which abstracts the terminal (currently only UART implemented). * DTE (Data Terminal Equipment), which abstracts the terminal (currently only UART implemented).
* PPP Netif representing a network interface communicating with the DTE using PPP protocol. * PPP Netif representing a network interface communicating with the DTE using PPP protocol.
* Module abstracting the specific device model and its commands. * Module abstracting the specific device model and its commands.
``` ```
+-----+ +-----+
| DTE |--+ | DTE |--+
+-----+ | +-------+ +-----+ | +-------+
+-->| DCE | +-->| DCE |
@ -16,17 +16,17 @@ The modem device is modeled with a DCE (Data Communication Equipment) object, wh
| Module|--->| | | Module|--->| |
+-------+ | |o--- send_commands +-------+ | |o--- send_commands
+->| | +->| |
+------+ | +-------+ +------+ | +-------+
| PPP |--+ | PPP |--+
| netif|------------------> network events | netif|------------------> network events
+------+ +------+
``` ```
## Modem components ## Modem components
### DCE ### DCE
This is the basic operational unit of the esp_modem component, abstracting a specific module in software, This is the basic operational unit of the esp_modem component, abstracting a specific module in software,
which is basically configured by which is basically configured by
* the I/O communication media (UART), defined by the DTE configuration * the I/O communication media (UART), defined by the DTE configuration
* the specific command library supported by the device model, defined with the module type * the specific command library supported by the device model, defined with the module type
* network interface configuration (PPPoS config in lwip) * network interface configuration (PPPoS config in lwip)
@ -52,7 +52,7 @@ Users interact with the esp-modem using the DCE's interface, to basically
* Switch between command and data mode to connect to the internet via cellular network. * Switch between command and data mode to connect to the internet via cellular network.
* Send various commands to the device (e.g. send SMS) * Send various commands to the device (e.g. send SMS)
The applications typically register handlers for network events to receive notification on the network availability and The applications typically register handlers for network events to receive notification on the network availability and
IP address changes. IP address changes.
Common use cases of the esp-modem are also listed as the examples: Common use cases of the esp-modem are also listed as the examples:

View File

@ -46,4 +46,3 @@ a custom DTE object and supply it into :ref:`the DCE factory<dce_factory>`. The
- Create the DTE which uses the custom Terminal - Create the DTE which uses the custom Terminal
Please refer to the implementation of the existing UART DTE. Please refer to the implementation of the existing UART DTE.

View File

@ -6,7 +6,7 @@ C API Documentation
The C API is very simple and consist of these two basic parts: The C API is very simple and consist of these two basic parts:
- :ref:`lifecycle_api` - :ref:`lifecycle_api`
- :ref:`modem_commands` - :ref:`modem_commands`
The Typical application workflow is to: The Typical application workflow is to:
@ -54,4 +54,4 @@ Configuration structures
.. doxygengroup:: ESP_MODEM_CONFIG .. doxygengroup:: ESP_MODEM_CONFIG
:members: :members:

View File

@ -2,11 +2,6 @@
# #
# English Language RTD & Sphinx config file # English Language RTD & Sphinx config file
# #
import os
import os.path
import re
import subprocess
import sys
# General information about the project. # General information about the project.
project = u'esp-modem' project = u'esp-modem'
@ -18,11 +13,12 @@ language = 'en'
extensions = ['breathe', 'recommonmark'] extensions = ['breathe', 'recommonmark']
breathe_projects = {'esp_modem': 'xml'} breathe_projects = {'esp_modem': 'xml'}
breathe_default_project = "esp_modem" breathe_default_project = 'esp_modem'
source_suffix = ['.rst', '.md'] source_suffix = ['.rst', '.md']
source_parsers = {'.md': 'recommonmark.parser.CommonMarkParser', } source_parsers = {
'.md': 'recommonmark.parser.CommonMarkParser',
}

View File

@ -41,4 +41,4 @@ Destroy the DCE
--------------- ---------------
The DCE object is created as ``std::unique_ptr`` by default and as such doesn't have to be explicitly destroyed. The DCE object is created as ``std::unique_ptr`` by default and as such doesn't have to be explicitly destroyed.
It simply gets destroyed and cleaned-up automatically if the object goes out of the block scope. It simply gets destroyed and cleaned-up automatically if the object goes out of the block scope.

View File

@ -5,16 +5,16 @@
* Use C++ with additional C API * Use C++ with additional C API
* Use exceptions * Use exceptions
- Use macro wrapper over `try-catch` blocks when exceptions off (use `abort()` if `THROW()`) - Use macro wrapper over `try-catch` blocks when exceptions off (use `abort()` if `THROW()`)
* Initializes and allocates in the constructor (might throw) * Initializes and allocates in the constructor (might throw)
- easier code with exceptions ON, with exceptions OFF alloc/init failures are not treated as runtime error (program aborts) - easier code with exceptions ON, with exceptions OFF alloc/init failures are not treated as runtime error (program aborts)
- break down long initialization in constructor into more private methods - break down long initialization in constructor into more private methods
* Implements different devices using inheritance from `GenericModule`, which is the most general implementation of a common modem * Implements different devices using inheritance from `GenericModule`, which is the most general implementation of a common modem
- Internally uses templates with device specialization (modeled as `DCE<SpecificModule>`) which could be used as well for some special cases, - Internally uses templates with device specialization (modeled as `DCE<SpecificModule>`) which could be used as well for some special cases,
such as implantation of a minimal device (ModuleIf), add new AT commands (oOnly in compile time), or using the Module with DTE only (no DCE, no Netif) for sending AT commands without network such as implantation of a minimal device (ModuleIf), add new AT commands (oOnly in compile time), or using the Module with DTE only (no DCE, no Netif) for sending AT commands without network
## DCE collaboration model ## DCE collaboration model
The diagram describes how the DCE class collaborates with DTE, PPP and the device abstraction The diagram describes how the DCE class collaborates with DTE, PPP and the device abstraction

View File

@ -115,8 +115,3 @@ Modem types
.. doxygengroup:: ESP_MODEM_TYPES .. doxygengroup:: ESP_MODEM_TYPES
:members: :members:

View File

@ -18,4 +18,4 @@ Also, to demonstrate the dce_factory functionality, a new `NetDCE_Factory` is im
### Supported IDF versions ### Supported IDF versions
This example is only supported from `v4.2`, since is uses NAPT feature. This example is only supported from `v4.2`, since is uses NAPT feature.

View File

@ -1,10 +1,11 @@
/* softAP to PPPoS Example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* softAP to PPPoS Example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <string.h> #include <string.h>
#include "esp_system.h" #include "esp_system.h"
@ -18,8 +19,8 @@
#include "freertos/event_groups.h" #include "freertos/event_groups.h"
#include "network_dce.h" #include "network_dce.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "esp_mac.h" #include "esp_mac.h"
#include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver.h"
#endif #endif
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
@ -77,15 +78,15 @@ static esp_err_t set_dhcps_dns(esp_netif_t *netif, uint32_t addr)
return ESP_OK; return ESP_OK;
} }
static void wifi_event_handler(void* arg, esp_event_base_t event_base, static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) int32_t event_id, void *event_data)
{ {
if (event_id == WIFI_EVENT_AP_STACONNECTED) { if (event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
MAC2STR(event->mac), event->aid); MAC2STR(event->mac), event->aid);
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data;
ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
MAC2STR(event->mac), event->aid); MAC2STR(event->mac), event->aid);
} }
@ -98,10 +99,10 @@ void wifi_init_softap(void)
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID, ESP_EVENT_ANY_ID,
&wifi_event_handler, &wifi_event_handler,
NULL, NULL,
NULL)); NULL));
wifi_config_t wifi_config = { wifi_config_t wifi_config = {
.ap = { .ap = {
@ -162,8 +163,8 @@ void app_main(void)
// Initialize NVS // Initialize NVS
esp_err_t ret = nvs_flash_init(); esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init(); ret = nvs_flash_init();
} }
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);

View File

@ -1,10 +1,11 @@
/* softAP to PPPoS Example (network_dce) /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* softAP to PPPoS Example (network_dce)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <string.h> #include <string.h>

View File

@ -1,10 +1,11 @@
/* softAP to PPPoS Example (network_dce) /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* softAP to PPPoS Example (network_dce)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dte.hpp"
@ -92,8 +93,9 @@ public:
bool check_signal() bool check_signal()
{ {
int rssi, ber; int rssi, ber;
if (dce_commands::get_signal_quality(dte.get(), rssi, ber) != command_result::OK) if (dce_commands::get_signal_quality(dte.get(), rssi, ber) != command_result::OK) {
return false; return false;
}
return rssi != 99 && rssi > 5; return rssi != 99 && rssi > 5;
} }
@ -215,4 +217,4 @@ extern "C" bool modem_check_signal()
return dce->get_module()->check_signal(); return dce->get_module()->check_signal();
} }
} }

View File

@ -1,10 +1,11 @@
/* softAP to PPPoS Example (network_dce) /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* softAP to PPPoS Example (network_dce)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -20,4 +20,4 @@ over PPPoS, i.e. over the modem serial line.
### Supported IDF versions ### Supported IDF versions
This example (using the default CMake IDF build system) is only supported from `v4.4`, since is uses `idf.py`'s linux target. This example (using the default CMake IDF build system) is only supported from `v4.4`, since is uses `idf.py`'s linux target.

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <memory> #include <memory>
#include <cassert> #include <cassert>
#include <unistd.h> #include <unistd.h>
@ -79,4 +84,4 @@ int main()
usleep(15'000'000); usleep(15'000'000);
esp_netif_destroy(tun_netif); esp_netif_destroy(tun_netif);
} }

View File

@ -8,4 +8,3 @@ PROJECT_NAME := modem-console
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk include $(IDF_PATH)/make/project.mk

View File

@ -30,4 +30,4 @@ You must send a character to it (via idf.py monitor), so it unblocks and properl
This example is only supported from `v4.2`, due to support of the console repl mode. This example is only supported from `v4.2`, due to support of the console repl mode.
USB example is supported from `v4.4`. USB example is supported from `v4.4`.

View File

@ -83,7 +83,7 @@ menu "Example Configuration"
default EXAMPLE_FLOW_CONTROL_NONE default EXAMPLE_FLOW_CONTROL_NONE
help help
Set the modem's preferred control flow Set the modem's preferred control flow
config EXAMPLE_FLOW_CONTROL_NONE config EXAMPLE_FLOW_CONTROL_NONE
bool "No control flow" bool "No control flow"
config EXAMPLE_FLOW_CONTROL_SW config EXAMPLE_FLOW_CONTROL_SW

View File

@ -1,10 +1,11 @@
/* Modem console example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Modem console example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include "console_helper.hpp" #include "console_helper.hpp"

View File

@ -1,10 +1,11 @@
/* Modem console example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Modem console example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -1,10 +1,12 @@
/* Modem console example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Modem console example
Unless required by applicable law or agreed to in writing, this *
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <stdio.h> #include <stdio.h>
@ -19,34 +21,34 @@ static const char *TAG = "modem_console_httpget";
static esp_err_t http_event_handler(esp_http_client_event_t *evt) static esp_err_t http_event_handler(esp_http_client_event_t *evt)
{ {
switch(evt->event_id) { switch (evt->event_id) {
case HTTP_EVENT_ERROR: case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break; break;
case HTTP_EVENT_ON_CONNECTED: case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break; break;
case HTTP_EVENT_HEADER_SENT: case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break; break;
case HTTP_EVENT_ON_HEADER: case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break; break;
case HTTP_EVENT_ON_DATA: case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if ((bool)evt->user_data && if ((bool)evt->user_data &&
!esp_http_client_is_chunked_response(evt->client)) { !esp_http_client_is_chunked_response(evt->client)) {
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->data, evt->data_len, ESP_LOG_INFO); ESP_LOG_BUFFER_HEXDUMP(TAG, evt->data, evt->data_len, ESP_LOG_INFO);
} }
break; break;
case HTTP_EVENT_ON_FINISH: case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break; break;
case HTTP_EVENT_DISCONNECTED: case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED"); ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
break; break;
default: break; default: break;
} }
return ESP_OK; return ESP_OK;
} }
@ -65,7 +67,7 @@ static int do_http_client(int argc, char **argv)
return 1; return 1;
} }
esp_http_client_config_t config = { esp_http_client_config_t config = {
.event_handler = http_event_handler, .event_handler = http_event_handler,
}; };
if (http_args.host->count > 0) { if (http_args.host->count > 0) {
@ -76,11 +78,11 @@ static int do_http_client(int argc, char **argv)
if (http_args.hex->count > 0) { if (http_args.hex->count > 0) {
// show hex data from http-get // show hex data from http-get
config.user_data = (void*)true; config.user_data = (void *)true;
} }
esp_http_client_handle_t client = esp_http_client_init(&config); esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_perform(client); esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) { if (err == ESP_OK) {
@ -99,11 +101,11 @@ void modem_console_register_http(void)
http_args.hex = arg_litn("p", "print-hex", 0, 1, "print hex output"), http_args.hex = arg_litn("p", "print-hex", 0, 1, "print hex output"),
http_args.end = arg_end(1); http_args.end = arg_end(1);
const esp_console_cmd_t http_cmd = { const esp_console_cmd_t http_cmd = {
.command = "httpget", .command = "httpget",
.help = "http get command to test data mode", .help = "http get command to test data mode",
.hint = NULL, .hint = NULL,
.func = &do_http_client, .func = &do_http_client,
.argtable = &http_args .argtable = &http_args
}; };
ESP_ERROR_CHECK(esp_console_cmd_register(&http_cmd)); ESP_ERROR_CHECK(esp_console_cmd_register(&http_cmd));
} }

View File

@ -9,4 +9,4 @@ dependencies:
version: "^1.0.0" version: "^1.0.0"
rules: rules:
- if: "idf_version >=4.4" - if: "idf_version >=4.4"
- if: "target in [esp32s2, esp32s3]" - if: "target in [esp32s2, esp32s3]"

View File

@ -1,10 +1,11 @@
/* Modem console example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Modem console example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <cstdio> #include <cstdio>

View File

@ -1,10 +1,11 @@
/* Modem console example: Custom DCE /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* Modem console example: Custom DCE
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -1,10 +1,10 @@
/* Ping handle example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
This example code is in the Public Domain (or CC0 licensed, at your option.) *
* SPDX-License-Identifier: Unlicense OR CC0-1.0
Unless required by applicable law or agreed to in writing, this */
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR /*
CONDITIONS OF ANY KIND, either express or implied. * Ping handle example
*/ */
#include <stdio.h> #include <stdio.h>
@ -29,7 +29,7 @@ static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len)); esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time)); esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
ESP_LOGI(TAG, "%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", ESP_LOGI(TAG, "%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n",
recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time); recv_len, inet_ntoa(target_addr.u_addr.ip4), seqno, ttl, elapsed_time);
} }
static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args) static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
@ -58,7 +58,7 @@ static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
ESP_LOGI(TAG, "\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr))); ESP_LOGI(TAG, "\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
} }
ESP_LOGI(TAG, "%d packets transmitted, %d received, %d%% packet loss, time %dms\n", ESP_LOGI(TAG, "%d packets transmitted, %d received, %d%% packet loss, time %dms\n",
transmitted, received, loss, total_time_ms); transmitted, received, loss, total_time_ms);
// delete the ping sessions, so that we clean up all resources and can create a new ping session // delete the ping sessions, so that we clean up all resources and can create a new ping session
// we don't have to call delete function in the callback, instead we can call delete function from other tasks // we don't have to call delete function in the callback, instead we can call delete function from other tasks
esp_ping_delete_session(hdl); esp_ping_delete_session(hdl);
@ -112,10 +112,10 @@ static int do_ping_cmd(int argc, char **argv)
/* set callback functions */ /* set callback functions */
esp_ping_callbacks_t cbs = { esp_ping_callbacks_t cbs = {
.on_ping_success = cmd_ping_on_ping_success, .on_ping_success = cmd_ping_on_ping_success,
.on_ping_timeout = cmd_ping_on_ping_timeout, .on_ping_timeout = cmd_ping_on_ping_timeout,
.on_ping_end = cmd_ping_on_ping_end, .on_ping_end = cmd_ping_on_ping_end,
.cb_args = NULL .cb_args = NULL
}; };
esp_ping_handle_t ping; esp_ping_handle_t ping;
esp_ping_new_session(&config, &cbs, &ping); esp_ping_new_session(&config, &cbs, &ping);
@ -131,11 +131,11 @@ void modem_console_register_ping(void)
ping_args.host = arg_str1(NULL, NULL, "<host>", "Host address"); ping_args.host = arg_str1(NULL, NULL, "<host>", "Host address");
ping_args.end = arg_end(1); ping_args.end = arg_end(1);
const esp_console_cmd_t ping_cmd = { const esp_console_cmd_t ping_cmd = {
.command = "ping", .command = "ping",
.help = "send ICMP ECHO_REQUEST to network hosts", .help = "send ICMP ECHO_REQUEST to network hosts",
.hint = NULL, .hint = NULL,
.func = &do_ping_cmd, .func = &do_ping_cmd,
.argtable = &ping_args .argtable = &ping_args
}; };
ESP_ERROR_CHECK(esp_console_cmd_register(&ping_cmd)); ESP_ERROR_CHECK(esp_console_cmd_register(&ping_cmd));
} }

View File

@ -1 +1 @@
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -6,5 +6,3 @@ set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(pppos_client) project(pppos_client)

View File

@ -21,6 +21,6 @@ This example supports USB modem hot-plugging and reconnection.
### Supported IDF versions ### Supported IDF versions
This example is only supported from `v4.1`, as this is the default dependency of `esp-modem` component. This example is only supported from `v4.1`, as this is the default dependency of `esp-modem` component.
USB example is supported from `v4.4`. USB example is supported from `v4.4`.

View File

@ -9,4 +9,4 @@ dependencies:
version: "^1.0.0" version: "^1.0.0"
rules: rules:
- if: "idf_version >=4.4" - if: "idf_version >=4.4"
- if: "target in [esp32s2, esp32s3]" - if: "target in [esp32s2, esp32s3]"

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* PPPoS Client Example /* PPPoS Client Example
This example code is in the Public Domain (or CC0 licensed, at your option.) This example code is in the Public Domain (or CC0 licensed, at your option.)
@ -181,7 +186,7 @@ void app_main(void)
while (1) { while (1) {
ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module..."); ESP_LOGI(TAG, "Initializing esp_modem for the BG96 module...");
struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296, 2); // VID, PID and interface num of BG96 modem struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296, 2); // VID, PID and interface num of BG96 modem
const esp_modem_dte_config_t dte_usb_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config); const esp_modem_dte_config_t dte_usb_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config);
ESP_LOGI(TAG, "Waiting for USB device connection..."); ESP_LOGI(TAG, "Waiting for USB device connection...");
esp_modem_dce_t *dce = esp_modem_new_dev_usb(ESP_MODEM_DCE_BG96, &dte_usb_config, &dce_config, esp_netif); esp_modem_dce_t *dce = esp_modem_new_dev_usb(ESP_MODEM_DCE_BG96, &dte_usb_config, &dce_config, esp_netif);
esp_modem_set_error_cb(dce, usb_terminal_error_handler); esp_modem_set_error_cb(dce, usb_terminal_error_handler);
@ -244,7 +249,7 @@ void app_main(void)
}; };
#else #else
esp_mqtt_client_config_t mqtt_config = { esp_mqtt_client_config_t mqtt_config = {
.uri = BROKER_URL, .uri = BROKER_URL,
}; };
#endif #endif
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config); esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
@ -269,11 +274,11 @@ void app_main(void)
ESP_LOGI(TAG, "IMSI=%s", imsi); ESP_LOGI(TAG, "IMSI=%s", imsi);
#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) #if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
// USB example runs in a loop to demonstrate hot-plugging and sudden disconnection features. // USB example runs in a loop to demonstrate hot-plugging and sudden disconnection features.
ESP_LOGI(TAG, "USB demo finished. Disconnect and connect the modem to run it again"); ESP_LOGI(TAG, "USB demo finished. Disconnect and connect the modem to run it again");
xEventGroupWaitBits(event_group, USB_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY); xEventGroupWaitBits(event_group, USB_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
CHECK_USB_DISCONNECTION(event_group); // dce will be destroyed here CHECK_USB_DISCONNECTION(event_group); // dce will be destroyed here
} // while (1) } // while (1)
#else #else
// UART DTE clean-up // UART DTE clean-up
esp_modem_destroy(dce); esp_modem_destroy(dce);

View File

@ -1 +1 @@
CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y CONFIG_EXAMPLE_SERIAL_CONFIG_USB=y

View File

@ -6,5 +6,3 @@ set(EXTRA_COMPONENT_DIRS "../.." $ENV{IDF_PATH}/examples/cxx/experimental/experi
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(simple_cmux_client) project(simple_cmux_client)

View File

@ -18,4 +18,4 @@ Please check the component [README](../../README.md)
### Supported IDF versions ### Supported IDF versions
This example is only supported from `v4.3`, since is uses an experimental `esp_event_cxx` component. This example is only supported from `v4.3`, since is uses an experimental `esp_event_cxx` component.

View File

@ -90,7 +90,7 @@ menu "Example Configuration"
help help
Pin number of UART CTS. Pin number of UART CTS.
endmenu endmenu
config EXAMPLE_USE_VFS_TERM config EXAMPLE_USE_VFS_TERM
bool "Use VFS terminal" bool "Use VFS terminal"
default n default n

View File

@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* PPPoS Client Example /* PPPoS Client Example
This example code is in the Public Domain (or CC0 licensed, at your option.) This example code is in the Public Domain (or CC0 licensed, at your option.)
@ -96,8 +101,7 @@ extern "C" void app_main(void)
#endif #endif
assert(dce); assert(dce);
if(dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
{
if (command_result::OK != dce->set_flow_control(2, 2)) { if (command_result::OK != dce->set_flow_control(2, 2)) {
ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
return; return;

View File

@ -1,10 +1,11 @@
/* PPPoS Client Example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* PPPoS Client Example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#include <memory> #include <memory>

View File

@ -1,10 +1,11 @@
/* PPPoS Client Example /*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.) /*
* PPPoS Client Example
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/ */
#pragma once #pragma once

View File

@ -9,4 +9,4 @@ CONFIG_PARTITION_TABLE_TWO_OTA=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y
CONFIG_MAIN_TASK_STACK_SIZE=8192 CONFIG_MAIN_TASK_STACK_SIZE=8192

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2022 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -22,15 +14,15 @@ namespace esp_modem {
*/ */
struct unique_buffer { struct unique_buffer {
explicit unique_buffer(size_t size); explicit unique_buffer(size_t size);
unique_buffer (unique_buffer const&) = delete; unique_buffer (unique_buffer const &) = delete;
unique_buffer& operator=(unique_buffer const&) = delete; unique_buffer &operator=(unique_buffer const &) = delete;
unique_buffer(unique_buffer&& other) noexcept unique_buffer(unique_buffer &&other) noexcept
{ {
data = std::move(other.data); data = std::move(other.data);
size = other.size; size = other.size;
consumed = 0; consumed = 0;
} }
unique_buffer& operator=(unique_buffer&& other) noexcept unique_buffer &operator=(unique_buffer &&other) noexcept
{ {
if (&other == this) { if (&other == this) {
return *this; return *this;
@ -40,7 +32,10 @@ struct unique_buffer {
consumed = 0; consumed = 0;
return *this; return *this;
} }
[[nodiscard]] uint8_t *get() const { return data.get(); } [[nodiscard]] uint8_t *get() const
{
return data.get();
}
std::unique_ptr<uint8_t[]> data; std::unique_ptr<uint8_t[]> data;
size_t size{}; size_t size{};

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -55,7 +47,7 @@ class CMuxInstance;
*/ */
class CMux { class CMux {
public: public:
explicit CMux(std::shared_ptr<Terminal> t, unique_buffer&& b): explicit CMux(std::shared_ptr<Terminal> t, unique_buffer &&b):
term(std::move(t)), payload_start(nullptr), total_payload_size(0), buffer(std::move(b)) {} term(std::move(t)), payload_start(nullptr), total_payload_size(0), buffer(std::move(b)) {}
~CMux() = default; ~CMux() = default;

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -47,7 +39,7 @@ command_result get_battery_status_sim7xxx(CommandableIf *t, int &voltage, int &b
command_result set_gnss_power_mode_sim76xx(CommandableIf *t, int mode); command_result set_gnss_power_mode_sim76xx(CommandableIf *t, int mode);
command_result power_down_sim76xx(CommandableIf *t); command_result power_down_sim76xx(CommandableIf *t);
command_result power_down_sim70xx(CommandableIf *t); command_result power_down_sim70xx(CommandableIf *t);
command_result set_network_bands_sim76xx(CommandableIf *t, const std::string& mode, const int* bands, int size); command_result set_network_bands_sim76xx(CommandableIf *t, const std::string &mode, const int *bands, int size);
command_result power_down_sim8xx(CommandableIf *t); command_result power_down_sim8xx(CommandableIf *t);
command_result set_data_mode_sim8xx(CommandableIf *t); command_result set_data_mode_sim8xx(CommandableIf *t);

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
#include "esp_log.h" #include "esp_log.h"

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -82,11 +74,13 @@ public:
Task::Delay(1000); // Mandatory 1s pause before Task::Delay(1000); // Mandatory 1s pause before
int retry = 0; int retry = 0;
while (retry++ < 3) { while (retry++ < 3) {
if (set_command_mode() == command_result::OK) if (set_command_mode() == command_result::OK) {
return true; return true;
}
Task::Delay(1000); // Mandatory 1s pause after escape Task::Delay(1000); // Mandatory 1s pause after escape
if (sync() == command_result::OK) if (sync() == command_result::OK) {
return true; return true;
}
Task::Delay(1000); // Mandatory 1s pause before escape Task::Delay(1000); // Mandatory 1s pause before escape
} }
return false; return false;
@ -107,7 +101,7 @@ public:
/** /**
* @brief Simplified version of operator name (without the ACT, which is included in the command library) * @brief Simplified version of operator name (without the ACT, which is included in the command library)
*/ */
command_result get_operator_name(std::string& name) command_result get_operator_name(std::string &name)
{ {
int dummy_act; int dummy_act;
return get_operator_name(name, dummy_act); return get_operator_name(name, dummy_act);
@ -140,7 +134,7 @@ public:
command_result get_battery_status(int &voltage, int &bcs, int &bcl) override; command_result get_battery_status(int &voltage, int &bcs, int &bcl) override;
command_result power_down() override; command_result power_down() override;
command_result set_gnss_power_mode(int mode) override; command_result set_gnss_power_mode(int mode) override;
command_result set_network_bands(const std::string& mode, const int* bands, int size) override; command_result set_network_bands(const std::string &mode, const int *bands, int size) override;
}; };
/** /**

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -106,8 +98,14 @@ protected:
/** /**
* @brief Allows for locking the DTE * @brief Allows for locking the DTE
*/ */
void lock() { internal_lock.lock(); } void lock()
void unlock() { internal_lock.unlock(); } {
internal_lock.lock();
}
void unlock()
{
internal_lock.unlock();
}
friend class Scoped<DTE>; /*!< Declaring "Scoped<DTE> lock(dte)" locks this instance */ friend class Scoped<DTE>; /*!< Declaring "Scoped<DTE> lock(dte)" locks this instance */
private: private:
static const size_t GOT_LINE = SignalGroup::bit0; /*!< Bit indicating response available */ static const size_t GOT_LINE = SignalGroup::bit0; /*!< Bit indicating response available */

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -51,35 +43,44 @@ private:
#define ESP_MODEM_THROW(exception) do { exception; abort(); } while(0) #define ESP_MODEM_THROW(exception) do { exception; abort(); } while(0)
class esp_err_exception { class esp_err_exception {
void print(std::string msg) { ESP_LOGE("ESP_MODEM_THROW", "%s\n", msg.c_str()); } void print(std::string msg)
{
ESP_LOGE("ESP_MODEM_THROW", "%s\n", msg.c_str());
}
public: public:
explicit esp_err_exception(std::string msg) { print(std::move(msg)); } explicit esp_err_exception(std::string msg)
explicit esp_err_exception(std::string msg, esp_err_t err) { print(std::move(msg)); } {
print(std::move(msg));
}
explicit esp_err_exception(std::string msg, esp_err_t err)
{
print(std::move(msg));
}
}; };
#endif #endif
static inline std::string make_message(const std::string& filename, int line, const std::string& message = "ERROR") static inline std::string make_message(const std::string &filename, int line, const std::string &message = "ERROR")
{ {
std::string text = filename + ":" + std::to_string(line) + " " + message; std::string text = filename + ":" + std::to_string(line) + " " + message;
return text; return text;
} }
static inline void throw_if_false(const std::string& filename, int line, bool condition, const std::string& message) static inline void throw_if_false(const std::string &filename, int line, bool condition, const std::string &message)
{ {
if (!condition) { if (!condition) {
ESP_MODEM_THROW(esp_err_exception(make_message(filename, line, message))); ESP_MODEM_THROW(esp_err_exception(make_message(filename, line, message)));
} }
} }
static inline void throw_if_error(const std::string& filename, int line, esp_err_t err, const std::string& message) static inline void throw_if_error(const std::string &filename, int line, esp_err_t err, const std::string &message)
{ {
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_MODEM_THROW(esp_err_exception(make_message(filename, line, message), err)); ESP_MODEM_THROW(esp_err_exception(make_message(filename, line, message), err));
} }
} }
static inline void throw_if_error(const std::string& filename, int line, esp_err_t err) static inline void throw_if_error(const std::string &filename, int line, esp_err_t err)
{ {
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_MODEM_THROW(esp_err_exception(make_message(filename, line), err)); ESP_MODEM_THROW(esp_err_exception(make_message(filename, line), err));

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -68,10 +60,10 @@ struct PdpContext {
class CommandableIf { class CommandableIf {
public: public:
CommandableIf() = default; CommandableIf() = default;
CommandableIf(const CommandableIf&) = delete; CommandableIf(const CommandableIf &) = delete;
CommandableIf& operator=(const CommandableIf&) = delete; CommandableIf &operator=(const CommandableIf &) = delete;
CommandableIf(CommandableIf&&) = delete; CommandableIf(CommandableIf &&) = delete;
CommandableIf& operator=(CommandableIf&&) = delete; CommandableIf &operator=(CommandableIf &&) = delete;
virtual ~CommandableIf() = default; virtual ~CommandableIf() = default;
/** /**
* @brief Sends custom AT command * @brief Sends custom AT command
@ -90,10 +82,10 @@ public:
class ModuleIf { class ModuleIf {
public: public:
ModuleIf() = default; ModuleIf() = default;
ModuleIf(const ModuleIf&) = delete; ModuleIf(const ModuleIf &) = delete;
ModuleIf& operator=(const ModuleIf&) = delete; ModuleIf &operator=(const ModuleIf &) = delete;
ModuleIf(ModuleIf&&) = delete; ModuleIf(ModuleIf &&) = delete;
ModuleIf& operator=(ModuleIf&&) = delete; ModuleIf &operator=(ModuleIf &&) = delete;
virtual ~ModuleIf() = default; virtual ~ModuleIf() = default;
/** /**
* @brief Sets the data mode up (provides the necessary configuration to connect to the cellular network) * @brief Sets the data mode up (provides the necessary configuration to connect to the cellular network)

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -26,7 +18,7 @@ extern "C" {
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ #define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
esp_err_t esp_modem_ ## name(esp_modem_dce_t *dce, ##__VA_ARGS__); esp_err_t esp_modem_ ## name(esp_modem_dce_t *dce, ##__VA_ARGS__);
DECLARE_ALL_COMMAND_APIS(declares esp_modem_<API>(esp_modem_t * dce, ...);) DECLARE_ALL_COMMAND_APIS(declares esp_modem_<API>(esp_modem_t *dce, ...);)
#undef ESP_MODEM_DECLARE_DCE_COMMAND #undef ESP_MODEM_DECLARE_DCE_COMMAND

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -40,8 +32,7 @@ typedef struct esp_modem_PdpContext_t {
/** /**
* @brief DCE mode: This enum is used to set desired operation mode of the DCE * @brief DCE mode: This enum is used to set desired operation mode of the DCE
*/ */
typedef enum esp_modem_dce_mode typedef enum esp_modem_dce_mode {
{
ESP_MODEM_MODE_COMMAND, /**< Default mode after modem startup, used for sending AT commands */ ESP_MODEM_MODE_COMMAND, /**< Default mode after modem startup, used for sending AT commands */
ESP_MODEM_MODE_DATA, /**< Used for switching to PPP mode for the modem to connect to a network */ ESP_MODEM_MODE_DATA, /**< Used for switching to PPP mode for the modem to connect to a network */
ESP_MODEM_MODE_CMUX, /**< Multiplexed terminal mode */ ESP_MODEM_MODE_CMUX, /**< Multiplexed terminal mode */
@ -50,8 +41,7 @@ typedef enum esp_modem_dce_mode
/** /**
* @brief DCE devices: Enum list of supported devices * @brief DCE devices: Enum list of supported devices
*/ */
typedef enum esp_modem_dce_device typedef enum esp_modem_dce_device {
{
ESP_MODEM_DCE_GENETIC, /**< The most generic device */ ESP_MODEM_DCE_GENETIC, /**< The most generic device */
ESP_MODEM_DCE_SIM7600, ESP_MODEM_DCE_SIM7600,
ESP_MODEM_DCE_SIM7070, ESP_MODEM_DCE_SIM7070,
@ -63,8 +53,7 @@ typedef enum esp_modem_dce_device
/** /**
* @brief Terminal errors * @brief Terminal errors
*/ */
typedef enum esp_modem_terminal_error typedef enum esp_modem_terminal_error {
{
ESP_MODEM_TERMINAL_BUFFER_OVERFLOW, ESP_MODEM_TERMINAL_BUFFER_OVERFLOW,
ESP_MODEM_TERMINAL_CHECKSUM_ERROR, ESP_MODEM_TERMINAL_CHECKSUM_ERROR,
ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW, ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW,
@ -105,16 +94,16 @@ esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_mode
* *
* @param dce DCE to destroy * @param dce DCE to destroy
*/ */
void esp_modem_destroy(esp_modem_dce_t * dce); void esp_modem_destroy(esp_modem_dce_t *dce);
/** /**
* @brief Set DTE's error callback * @brief Set DTE's error callback
* *
* @param dce Modem DCE handle * @param dce Modem DCE handle
* @param[in] err_cb Error callback * @param[in] err_cb Error callback
* @return ESP_OK on success, ESP_FAIL on failure * @return ESP_OK on success, ESP_FAIL on failure
*/ */
esp_err_t esp_modem_set_error_cb(esp_modem_dce_t * dce, esp_modem_terminal_error_cbt err_cb); esp_err_t esp_modem_set_error_cb(esp_modem_dce_t *dce, esp_modem_terminal_error_cbt err_cb);
/** /**
* @brief Set operation mode for this DCE * @brief Set operation mode for this DCE
@ -122,7 +111,7 @@ esp_err_t esp_modem_set_error_cb(esp_modem_dce_t * dce, esp_modem_terminal_error
* @param mode Desired MODE * @param mode Desired MODE
* @return ESP_OK on success, ESP_FAIL on failure * @return ESP_OK on success, ESP_FAIL on failure
*/ */
esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce, esp_modem_dce_mode_t mode); esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce, esp_modem_dce_mode_t mode);
/** /**
* @} * @}

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -70,7 +62,7 @@ struct esp_modem_vfs_resource;
*/ */
struct esp_modem_vfs_term_config { struct esp_modem_vfs_term_config {
int fd; /*!< Already created file descriptor */ int fd; /*!< Already created file descriptor */
void (*deleter)(int, struct esp_modem_vfs_resource*); /*!< Custom close function for the fd */ void (*deleter)(int, struct esp_modem_vfs_resource *); /*!< Custom close function for the fd */
struct esp_modem_vfs_resource *resource; /*!< Resource attached to the VFS (need for clenaup) */ struct esp_modem_vfs_resource *resource; /*!< Resource attached to the VFS (need for clenaup) */
}; };

View File

@ -1,16 +1,8 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once #pragma once
@ -37,7 +29,7 @@ typedef struct esp_modem_dce_config esp_modem_dce_config_t;
* @brief DCE configuration structure * @brief DCE configuration structure
*/ */
struct esp_modem_dce_config { struct esp_modem_dce_config {
const char* apn; /*!< APN: Logical name of the Access point */ const char *apn; /*!< APN: Logical name of the Access point */
}; };
/** /**

View File

@ -1,87 +1,79 @@
// Copyright 2022 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// You may obtain a copy of the License at */
// http://www.apache.org/licenses/LICENSE-2.0 /**
// * @file c_api_wrapper.hpp
// Unless required by applicable law or agreed to in writing, software * @brief Collection of C API wrappers
// distributed under the License is distributed on an "AS IS" BASIS, *
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * This file is located in include/esp_private because it is not intended for users,
// See the License for the specific language governing permissions and * but rather for esp_modem C extension developers.
// limitations under the License. *
* The C extension API must provide a 'factory function' that returns initialized pointer to esp_modem_dce_wrap.
/** * Helper functions provided below, can be used for conversion between C++ enum classes and standard C enums.
* @file c_api_wrapper.hpp */
* @brief Collection of C API wrappers
* #pragma once
* This file is located in include/esp_private because it is not intended for users,
* but rather for esp_modem C extension developers. #include "cxx_include/esp_modem_dce_factory.hpp"
* #include "esp_modem_c_api_types.h"
* The C extension API must provide a 'factory function' that returns initialized pointer to esp_modem_dce_wrap.
* Helper functions provided below, can be used for conversion between C++ enum classes and standard C enums. using namespace esp_modem;
*/
struct esp_modem_dce_wrap { // need to mimic the polymorphic dispatch as CPP uses templated dispatch
#pragma once enum class modem_wrap_dte_type { UART, VFS, USB } dte_type;
dce_factory::ModemType modem_type;
#include "cxx_include/esp_modem_dce_factory.hpp" DCE *dce;
#include "esp_modem_c_api_types.h" std::shared_ptr<DTE> dte;
esp_modem_dce_wrap() : dce(nullptr), dte(nullptr) {}
using namespace esp_modem; };
struct esp_modem_dce_wrap { // need to mimic the polymorphic dispatch as CPP uses templated dispatch inline dce_factory::ModemType convert_modem_enum(esp_modem_dce_device_t module)
enum class modem_wrap_dte_type { UART, VFS, USB } dte_type; {
dce_factory::ModemType modem_type; switch (module) {
DCE *dce; case ESP_MODEM_DCE_SIM7600:
std::shared_ptr<DTE> dte; return esp_modem::dce_factory::ModemType::SIM7600;
esp_modem_dce_wrap() : dce(nullptr), dte(nullptr) {} case ESP_MODEM_DCE_SIM7070:
}; return esp_modem::dce_factory::ModemType::SIM7070;
case ESP_MODEM_DCE_SIM7000:
inline dce_factory::ModemType convert_modem_enum(esp_modem_dce_device_t module) return esp_modem::dce_factory::ModemType::SIM7000;
{ case ESP_MODEM_DCE_BG96:
switch (module) { return esp_modem::dce_factory::ModemType::BG96;
case ESP_MODEM_DCE_SIM7600: case ESP_MODEM_DCE_SIM800:
return esp_modem::dce_factory::ModemType::SIM7600; return esp_modem::dce_factory::ModemType::SIM800;
case ESP_MODEM_DCE_SIM7070: default:
return esp_modem::dce_factory::ModemType::SIM7070; case ESP_MODEM_DCE_GENETIC:
case ESP_MODEM_DCE_SIM7000: return esp_modem::dce_factory::ModemType::GenericModule;
return esp_modem::dce_factory::ModemType::SIM7000; }
case ESP_MODEM_DCE_BG96: }
return esp_modem::dce_factory::ModemType::BG96;
case ESP_MODEM_DCE_SIM800: inline esp_modem_terminal_error_t convert_terminal_error_enum(terminal_error err)
return esp_modem::dce_factory::ModemType::SIM800; {
default: switch (err) {
case ESP_MODEM_DCE_GENETIC: case terminal_error::BUFFER_OVERFLOW:
return esp_modem::dce_factory::ModemType::GenericModule; return ESP_MODEM_TERMINAL_BUFFER_OVERFLOW;
} case terminal_error::CHECKSUM_ERROR:
} return ESP_MODEM_TERMINAL_CHECKSUM_ERROR;
case terminal_error::UNEXPECTED_CONTROL_FLOW:
inline esp_modem_terminal_error_t convert_terminal_error_enum(terminal_error err) return ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW;
{ case terminal_error::DEVICE_GONE:
switch (err) { return ESP_MODEM_TERMINAL_DEVICE_GONE;
case terminal_error::BUFFER_OVERFLOW: default:
return ESP_MODEM_TERMINAL_BUFFER_OVERFLOW; return ESP_MODEM_TERMINAL_UNKNOWN_ERROR;
case terminal_error::CHECKSUM_ERROR: }
return ESP_MODEM_TERMINAL_CHECKSUM_ERROR; }
case terminal_error::UNEXPECTED_CONTROL_FLOW:
return ESP_MODEM_TERMINAL_UNEXPECTED_CONTROL_FLOW; inline esp_err_t command_response_to_esp_err(command_result res)
case terminal_error::DEVICE_GONE: {
return ESP_MODEM_TERMINAL_DEVICE_GONE; switch (res) {
default: case command_result::OK:
return ESP_MODEM_TERMINAL_UNKNOWN_ERROR; return ESP_OK;
} case command_result::FAIL:
} return ESP_FAIL;
case command_result::TIMEOUT:
inline esp_err_t command_response_to_esp_err(command_result res) return ESP_ERR_TIMEOUT;
{ }
switch (res) { return ESP_ERR_INVALID_ARG;
case command_result::OK: }
return ESP_OK;
case command_result::FAIL:
return ESP_FAIL;
case command_result::TIMEOUT:
return ESP_ERR_TIMEOUT;
}
return ESP_ERR_INVALID_ARG;
}

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