Compare commits

...

4 Commits

16 changed files with 85 additions and 37 deletions

View File

@ -37,7 +37,7 @@ idf_component_register(SRCS "${srcs}"
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)

View File

@ -141,6 +141,7 @@ public:
int write(uint8_t *data, size_t len) override
{
ESP_LOGI("TAG", "%zd %.*s", len, len, (const char *)data);
return cmux->write(instance, data, len);
}
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override

View File

@ -31,9 +31,9 @@ namespace dce_commands {
* @param fail_phrase String to be present in the reply to fail this command
* @param timeout_ms Timeout in ms
*/
command_result generic_command(CommandableIf *t, const std::string &command,
const std::string &pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms);
command_result generic_command(CommandableIf *t, std::string_view command,
std::string_view pass_phrase,
std::string_view fail_phrase, uint32_t timeout_ms);
/**
* @brief Declaration of all commands is generated from esp_modem_command_declare.inc

View File

@ -6,6 +6,9 @@
#pragma once
#include <string_view>
#include <span>
namespace esp_modem::dce_commands {
/**
@ -17,9 +20,9 @@ namespace esp_modem::dce_commands {
* @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT)
*/
command_result generic_command(CommandableIf *t, const std::string &command,
const std::string &pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms);
command_result generic_command(CommandableIf *t, std::string_view command,
std::string_view pass_phrase,
std::string_view fail_phrase, uint32_t timeout_ms);
/**
* @brief Utility command to send command and return reply (after DCE says OK)
@ -30,7 +33,7 @@ command_result generic_command(CommandableIf *t, const std::string &command,
* @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT)
*/
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500);
command_result generic_get_string(CommandableIf *t, std::string_view command, std::string &output, uint32_t timeout_ms = 500);
/**
* @brief Generic command that passes on "OK" and fails on "ERROR"
@ -40,6 +43,6 @@ command_result generic_get_string(CommandableIf *t, const std::string &command,
* @param timeout_ms Command timeout in ms
* @return Generic command return type (OK, FAIL, TIMEOUT)
*/
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms = 500);
command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms = 500);
} // esp_modem::dce_commands

View File

@ -74,7 +74,7 @@ public:
return device.get();
}
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms)
command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms)
{
return dte->command(command, std::move(got_line), time_ms);
}

View File

@ -67,26 +67,35 @@ public:
{
if (mode == modem_mode::DATA_MODE) {
if (set_data_mode() != command_result::OK) {
return resume_data_mode() == command_result::OK;
const auto result = resume_data_mode() == command_result::OK;
ESP_LOGI("TAG", "result = %s", result?"true":"false");
return result;
}
ESP_LOGI("TAG", "result OK");
return true;
} else if (mode == modem_mode::COMMAND_MODE) {
Task::Delay(1000); // Mandatory 1s pause before
int retry = 0;
while (retry++ < 3) {
if (set_command_mode() == command_result::OK) {
ESP_LOGI("TAG", "result OK");
return true;
}
Task::Delay(1000); // Mandatory 1s pause after escape
if (sync() == command_result::OK) {
ESP_LOGI("TAG", "result OK");
return true;
}
Task::Delay(1000); // Mandatory 1s pause before escape
}
ESP_LOGI("TAG", "result NOT OK");
return false;
} else if (mode == modem_mode::CMUX_MODE) {
return set_cmux() == command_result::OK;
const auto result = set_cmux() == command_result::OK;
ESP_LOGI("TAG", "result = %s", result?"true":"false");
return result;
}
ESP_LOGI("TAG", "result OK");
return true;
}

View File

@ -101,12 +101,12 @@ public:
* @param time_ms Time in ms to wait for the answer
* @return OK, FAIL, TIMEOUT
*/
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) override;
command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) override;
/**
* @brief Sends the command (same as above) but with a specific separator
*/
command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, char separator) override;
command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, char separator) override;
protected:
/**

View File

@ -78,8 +78,8 @@ public:
* @param time_ms timeout in milliseconds
* @return OK, FAIL or TIMEOUT
*/
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0;
virtual command_result command(const std::string &command, got_line_cb got_line, uint32_t time_ms) = 0;
virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator) = 0;
virtual command_result command(std::string_view command, got_line_cb got_line, uint32_t time_ms) = 0;
virtual int write(uint8_t *data, size_t len) = 0;
virtual void on_read(got_line_cb on_data) = 0;

View File

@ -134,6 +134,7 @@ void CMux::data_available(uint8_t *data, size_t len)
sabm_ack = dlci;
} else if (data == nullptr) {
int virtual_term = dlci - 1;
ESP_LOGI("TAG", "%zd %.*s", total_payload_size, total_payload_size, payload_start);
if (virtual_term < MAX_TERMINALS_NUM && read_cb[virtual_term]) {
#ifdef DEFRAGMENT_CMUX_PAYLOAD
read_cb[virtual_term](payload_start, total_payload_size);

View File

@ -5,7 +5,8 @@
*/
#include <charconv>
#include <list>
#include <span>
#include "esp_log.h"
#include "cxx_include/esp_modem_dte.hpp"
#include "cxx_include/esp_modem_dce_module.hpp"
@ -16,12 +17,12 @@ namespace esp_modem::dce_commands {
static const char *TAG = "command_lib";
static command_result generic_command(CommandableIf *t, const std::string &command,
const std::list<std::string_view> &pass_phrase,
const std::list<std::string_view> &fail_phrase,
uint32_t timeout_ms)
command_result generic_command(CommandableIf *t, std::string_view command,
std::span<const std::string_view> pass_phrase,
std::span<const std::string_view> fail_phrase,
uint32_t timeout_ms)
{
ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str());
ESP_LOGD(TAG, "%s command %.*s\n", __func__, command.size(), command.data());
return t->command(command, [&](uint8_t *data, size_t len) {
std::string_view response((char *)data, len);
if (data == nullptr || len == 0 || response.empty()) {
@ -41,17 +42,17 @@ static command_result generic_command(CommandableIf *t, const std::string &comma
}
command_result generic_command(CommandableIf *t, const std::string &command,
const std::string &pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms)
command_result generic_command(CommandableIf *t, std::string_view command,
std::string_view pass_phrase,
std::string_view fail_phrase, uint32_t timeout_ms)
{
ESP_LOGV(TAG, "%s", __func__ );
const auto pass = std::list<std::string_view>({pass_phrase});
const auto fail = std::list<std::string_view>({fail_phrase});
const std::string_view pass[] { pass_phrase };
const std::string_view fail[] { fail_phrase };
return generic_command(t, command, pass, fail, timeout_ms);
}
static command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500)
static command_result generic_get_string(CommandableIf *t, std::string_view command, std::string_view &output, uint32_t timeout_ms = 500)
{
ESP_LOGV(TAG, "%s", __func__ );
return t->command(command, [&](uint8_t *data, size_t len) {
@ -78,7 +79,7 @@ static command_result generic_get_string(CommandableIf *t, const std::string &co
}, timeout_ms);
}
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms)
command_result generic_get_string(CommandableIf *t, std::string_view command, std::string &output, uint32_t timeout_ms)
{
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
@ -90,7 +91,7 @@ command_result generic_get_string(CommandableIf *t, const std::string &command,
}
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms)
command_result generic_command_common(CommandableIf *t, std::string_view command, uint32_t timeout_ms)
{
ESP_LOGV(TAG, "%s", __func__ );
return generic_command(t, command, "OK", "ERROR", timeout_ms);
@ -290,8 +291,8 @@ command_result resume_data_mode(CommandableIf *t)
command_result set_command_mode(CommandableIf *t)
{
ESP_LOGV(TAG, "%s", __func__ );
const auto pass = std::list<std::string_view>({"NO CARRIER", "OK"});
const auto fail = std::list<std::string_view>({"ERROR"});
const std::string_view pass[] {"NO CARRIER", "OK"};
const std::string_view fail[] {"ERROR"};
return generic_command(t, "+++", pass, fail, 5000);
}

View File

@ -52,13 +52,17 @@ static bool exit_data(DTE &dte, ModuleIf &device, Netif &netif)
static bool enter_data(DTE &dte, ModuleIf &device, Netif &netif)
{
ESP_LOGI("TAG", "hatschi3");
if (!device.setup_data_mode()) {
ESP_LOGW("TAG", "nix da 3");
return false;
}
if (!device.set_mode(modem_mode::DATA_MODE)) {
ESP_LOGW("TAG", "nix da 4");
return false;
}
if (!dte.set_mode(modem_mode::DATA_MODE)) {
ESP_LOGW("TAG", "nix da 5");
return false;
}
netif.start();
@ -119,13 +123,16 @@ bool DCE_Mode::set_unsafe(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m
mode = m;
return true;
case modem_mode::CMUX_MODE:
ESP_LOGI("TAG", "switching to CMUX_MODE");
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE || mode >= modem_mode::CMUX_MANUAL_MODE) {
ESP_LOGW("TAG", "nix da 1 %i", std::to_underlying(mode));
return false;
}
device->set_mode(modem_mode::CMUX_MODE); // switch the device into CMUX mode
usleep(100'000); // some devices need a few ms to switch
if (!dte->set_mode(modem_mode::CMUX_MODE)) {
ESP_LOGW("TAG", "nix da 2");
return false;
}
mode = modem_mode::CMUX_MODE;

View File

@ -34,7 +34,7 @@ DTE::DTE(std::unique_ptr<Terminal> t, std::unique_ptr<Terminal> s):
cmux_term(nullptr), primary_term(std::move(t)), secondary_term(std::move(s)),
mode(modem_mode::DUAL_MODE) {}
command_result DTE::command(const std::string &command, got_line_cb got_line, uint32_t time_ms, const char separator)
command_result DTE::command(std::string_view command, got_line_cb got_line, uint32_t time_ms, const char separator)
{
Scoped<Lock> l(internal_lock);
result = command_result::TIMEOUT;
@ -56,7 +56,7 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui
buffer.consumed += len;
return false;
});
primary_term->write((uint8_t *)command.c_str(), command.length());
primary_term->write((uint8_t *)command.data(), command.length());
auto got_lf = signal.wait(GOT_LINE, time_ms);
if (got_lf && result == command_result::TIMEOUT) {
ESP_MODEM_THROW_IF_ERROR(ESP_ERR_INVALID_STATE);
@ -66,8 +66,9 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui
return result;
}
command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32_t time_ms)
command_result DTE::command(std::string_view cmd, got_line_cb got_line, uint32_t time_ms)
{
ESP_LOGI("TAG", "cmd=%.*s", cmd.size(), cmd.data());
return command(cmd, got_line, time_ms, '\n');
}
@ -103,14 +104,17 @@ bool DTE::setup_cmux()
bool DTE::set_mode(modem_mode m)
{
ESP_LOGI("TAG", "hatschi2");
// transitions (COMMAND|UNDEF) -> CMUX
if (m == modem_mode::CMUX_MODE) {
if (mode == modem_mode::UNDEF || mode == modem_mode::COMMAND_MODE) {
if (setup_cmux()) {
mode = m;
ESP_LOGI("TAG", "gut 1");
return true;
}
mode = modem_mode::UNDEF;
ESP_LOGW("TAG", "schlecht 1");
return false;
}
}
@ -122,6 +126,7 @@ bool DTE::set_mode(modem_mode m)
} else {
mode = m;
}
ESP_LOGI("TAG", "gut 2");
return true;
}
// transitions (DATA|DUAL|CMUX|UNDEF) -> COMMAND
@ -129,14 +134,18 @@ bool DTE::set_mode(modem_mode m)
if (mode == modem_mode::CMUX_MODE) {
if (exit_cmux()) {
mode = m;
ESP_LOGI("TAG", "gut 3");
return true;
}
mode = modem_mode::UNDEF;
ESP_LOGW("TAG", "schlecht 2");
return false;
} if (mode == modem_mode::CMUX_MANUAL_MODE || mode == modem_mode::DUAL_MODE) {
ESP_LOGI("TAG", "gut 4");
return true;
} else {
mode = m;
ESP_LOGI("TAG", "gut 5");
return true;
}
}
@ -144,26 +153,32 @@ bool DTE::set_mode(modem_mode m)
if (m == modem_mode::CMUX_MANUAL_MODE) {
if (setup_cmux()) {
mode = m;
ESP_LOGI("TAG", "gut 6");
return true;
}
mode = modem_mode::UNDEF;
ESP_LOGW("TAG", "schlecht 3");
return false;
}
// manual CMUX transitions: Exit CMUX
if (m == modem_mode::CMUX_MANUAL_EXIT && mode == modem_mode::CMUX_MANUAL_MODE) {
if (exit_cmux()) {
mode = modem_mode::COMMAND_MODE;
ESP_LOGI("TAG", "gut 7");
return true;
}
mode = modem_mode::UNDEF;
ESP_LOGW("TAG", "schlecht 4");
return false;
}
// manual CMUX transitions: Swap terminals
if (m == modem_mode::CMUX_MANUAL_SWAP && mode == modem_mode::CMUX_MANUAL_MODE) {
secondary_term.swap(primary_term);
ESP_LOGI("TAG", "gut 8");
return true;
}
mode = modem_mode::UNDEF;
ESP_LOGW("TAG", "schlecht 5");
return false;
}

View File

@ -147,6 +147,7 @@ int FdTerminal::read(uint8_t *data, size_t len)
int FdTerminal::write(uint8_t *data, size_t len)
{
ESP_LOGI("TAG", "%zd %.*s", len, len, (const char *)data);
int size = ::write(f.fd, data, len);
if (size < 0) {
ESP_LOGE(TAG, "Error occurred during read: %d", errno);

View File

@ -124,6 +124,7 @@ void UartTerminal::task()
switch (event.type) {
case UART_DATA:
uart_get_buffered_data_len(uart.port, &len);
ESP_LOGD("TAG", "%zd aber ohne data ptr", len);
if (len && on_read) {
on_read(nullptr, len);
}
@ -174,13 +175,17 @@ int UartTerminal::read(uint8_t *data, size_t len)
uart_get_buffered_data_len(uart.port, &length);
length = std::min(len, length);
if (length > 0) {
return uart_read_bytes(uart.port, data, length, portMAX_DELAY);
const auto really_gelesen = uart_read_bytes(uart.port, data, length, portMAX_DELAY);
ESP_LOGI("TAG", "%p %zd", data, really_gelesen);
ESP_LOGI("TAG", "%zd %.*s", really_gelesen, really_gelesen, data);
return really_gelesen;
}
return 0;
}
int UartTerminal::write(uint8_t *data, size_t len)
{
ESP_LOGI("TAG", "%zd %.*s", len, len, (const char *)data);
return uart_write_bytes_compat(uart.port, data, len);
}

View File

@ -90,6 +90,7 @@ typedef struct {
size_t client_cert_len;
const char *client_key;
size_t client_key_len;
bool skip_server_verification;
bool use_global_ca_store;
bool skip_cert_common_name_check;
esp_err_t (*crt_bundle_attach)(void *conf);
@ -492,7 +493,9 @@ static esp_err_t esp_websocket_client_create_transport(esp_websocket_client_hand
esp_transport_set_default_port(ssl, WEBSOCKET_SSL_DEFAULT_PORT);
esp_transport_list_add(client->transport_list, ssl, "_ssl"); // need to save to transport list, for cleanup
if (client->config->use_global_ca_store == true) {
if (client->config->skip_server_verification == true) {
esp_transport_ssl_skip_server_verification(ssl);
} else if (client->config->use_global_ca_store == true) {
esp_transport_ssl_enable_global_ca_store(ssl);
} else if (client->config->cert) {
if (!client->config->cert_len) {
@ -591,6 +594,7 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
}
// configure ssl related parameters
client->config->skip_server_verification = config->skip_server_verification;
client->config->use_global_ca_store = config->use_global_ca_store;
client->config->cert = config->cert_pem;
client->config->cert_len = config->cert_len;

View File

@ -119,6 +119,7 @@ typedef struct {
bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which this bool is set. */
esp_err_t (*crt_bundle_attach)(void *conf); /*!< Function pointer to esp_crt_bundle_attach. Enables the use of certification bundle for server verification, MBEDTLS_CERTIFICATE_BUNDLE must be enabled in menuconfig. Include esp_crt_bundle.h, and use `esp_crt_bundle_attach` here to include bundled CA certificates. */
bool skip_cert_common_name_check;/*!< Skip any validation of server certificate CN field */
bool skip_server_verification; /*!< Skip server verification completely. Should only be used for debugging */
bool keep_alive_enable; /*!< Enable keep-alive timeout */
int keep_alive_idle; /*!< Keep-alive idle time. Default is 5 (second) */
int keep_alive_interval; /*!< Keep-alive interval time. Default is 5 (second) */