mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-20 14:02:21 +02:00
VFS Terminal cleanup
This commit is contained in:
@ -19,6 +19,9 @@ int main()
|
|||||||
// init the DTE
|
// init the DTE
|
||||||
esp_modem_dte_config_t dte_config = {
|
esp_modem_dte_config_t dte_config = {
|
||||||
.dte_buffer_size = 512,
|
.dte_buffer_size = 512,
|
||||||
|
.task_stack_size = 1024,
|
||||||
|
.task_priority = 10,
|
||||||
|
.uart_config = { },
|
||||||
.vfs_config = { }
|
.vfs_config = { }
|
||||||
};
|
};
|
||||||
dte_config.vfs_config.dev_name = "/dev/ttyUSB0";
|
dte_config.vfs_config.dev_name = "/dev/ttyUSB0";
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "cxx_include/esp_modem_api.hpp"
|
#include "cxx_include/esp_modem_api.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "esp_https_ota.h"
|
#include "esp_https_ota.h"
|
||||||
#include "esp_app_trace.h"
|
#include "esp_vfs_dev.h"
|
||||||
|
|
||||||
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
|
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
|
||||||
|
|
||||||
@ -130,18 +130,22 @@ extern "C" void app_main(void)
|
|||||||
|
|
||||||
/* Configure the DTE */
|
/* Configure the DTE */
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
esp_modem_dte_config_t dte_config2 = {
|
// dte_config.task_stack_size = 8192;
|
||||||
.dte_buffer_size = 512,
|
dte_config.vfs_config.dev_name = "/dev/uart/1";
|
||||||
.vfs_config = {.port_num = UART_NUM_1,
|
dte_config.uart_config.event_queue_size = 0;
|
||||||
.dev_name = "/dev/uart/1",
|
|
||||||
.rx_buffer_size = 1024,
|
// esp_modem_dte_config_t dte_config2 = {
|
||||||
.tx_buffer_size = 512,
|
// .dte_buffer_size = 512,
|
||||||
.baud_rate = 115200,
|
// .vfs_config = {.port_num = UART_NUM_1,
|
||||||
.tx_io_num = 25,
|
// .dev_name = "/dev/uart/1",
|
||||||
.rx_io_num = 26,
|
// .rx_buffer_size = 1024,
|
||||||
.task_stack_size = 4096,
|
// .tx_buffer_size = 512,
|
||||||
.task_prio = 5}
|
// .baud_rate = 115200,
|
||||||
};
|
// .tx_io_num = 25,
|
||||||
|
// .rx_io_num = 26,
|
||||||
|
// .task_stack_size = 4096,
|
||||||
|
// .task_prio = 5}
|
||||||
|
// };
|
||||||
|
|
||||||
/* Configure the DCE */
|
/* Configure the DCE */
|
||||||
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
|
||||||
@ -149,13 +153,11 @@ extern "C" void app_main(void)
|
|||||||
/* Configure the PPP netif */
|
/* Configure the PPP netif */
|
||||||
esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
|
esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
|
||||||
|
|
||||||
dte_config.dte_buffer_size = 512;
|
// dte_config.dte_buffer_size = 512;
|
||||||
dte_config.uart_config.port_num = UART_NUM_2;
|
// dte_config.uart_config.port_num = UART_NUM_2;
|
||||||
auto uart_dte = create_uart_dte(&dte_config);
|
// auto uart_dte = create_uart_dte(&dte_config);
|
||||||
|
auto uart_dte = create_vfs_dte(&dte_config);
|
||||||
|
esp_vfs_dev_uart_use_driver(dte_config.uart_config.port_num);
|
||||||
|
|
||||||
// auto uart_dte = create_vfs_dte(&dte_config2);
|
|
||||||
|
|
||||||
esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config);
|
esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config);
|
||||||
assert(esp_netif);
|
assert(esp_netif);
|
||||||
|
@ -53,29 +53,30 @@ struct esp_modem_uart_term_config {
|
|||||||
int cts_io_num; /*!< CTS Pin Number */
|
int cts_io_num; /*!< CTS Pin Number */
|
||||||
int rx_buffer_size; /*!< UART RX Buffer Size */
|
int rx_buffer_size; /*!< UART RX Buffer Size */
|
||||||
int tx_buffer_size; /*!< UART TX Buffer Size */
|
int tx_buffer_size; /*!< UART TX Buffer Size */
|
||||||
int event_queue_size; /*!< UART Event Queue Size */
|
int event_queue_size; /*!< UART Event Queue Size, set to 0 if no event queue needed */
|
||||||
uint32_t event_task_stack_size; /*!< UART Event Task Stack size */
|
|
||||||
int event_task_priority; /*!< UART Event Task Priority */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resources used by VFS terminal
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_MODEM_VFS_IS_EXTERN = 0, /*!< External resource: internal VFS terminal takes no action to setup this */
|
||||||
|
ESP_MODEM_VFS_IS_UART, /*!< VFS uses UART: internal VFS initializes UART based on esp_modem_uart_term_config */
|
||||||
|
} esp_modem_vfs_resource_t;
|
||||||
|
|
||||||
|
|
||||||
struct esp_modem_vfs_term_config {
|
struct esp_modem_vfs_term_config {
|
||||||
int port_num;
|
const char* dev_name; /*!< VFS device name, e.g. /dev/uart/n */
|
||||||
const char* dev_name;
|
esp_modem_vfs_resource_t resource; /*!< Underlying device which gets initialized during VFS init */
|
||||||
int rx_buffer_size;
|
|
||||||
int tx_buffer_size;
|
|
||||||
int baud_rate;
|
|
||||||
int tx_io_num;
|
|
||||||
int rx_io_num;
|
|
||||||
uint32_t task_stack_size;
|
|
||||||
int task_prio;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct esp_modem_dte_config {
|
struct esp_modem_dte_config {
|
||||||
size_t dte_buffer_size;
|
size_t dte_buffer_size; /*!< DTE buffer size */
|
||||||
union {
|
uint32_t task_stack_size; /*!< Terminal task stack size */
|
||||||
struct esp_modem_uart_term_config uart_config;
|
int task_priority; /*!< Terminal task priority */
|
||||||
struct esp_modem_vfs_term_config vfs_config;
|
struct esp_modem_uart_term_config uart_config; /*!< Configuration for UART Terminal */
|
||||||
};
|
struct esp_modem_vfs_term_config vfs_config; /*!< Configuration for VFS Terminal */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -86,6 +87,8 @@ struct esp_modem_dte_config {
|
|||||||
#define ESP_MODEM_DTE_DEFAULT_CONFIG() \
|
#define ESP_MODEM_DTE_DEFAULT_CONFIG() \
|
||||||
{ \
|
{ \
|
||||||
.dte_buffer_size = 512, \
|
.dte_buffer_size = 512, \
|
||||||
|
.task_stack_size = 4096, \
|
||||||
|
.task_priority = 5, \
|
||||||
.uart_config = { \
|
.uart_config = { \
|
||||||
.port_num = UART_NUM_1, \
|
.port_num = UART_NUM_1, \
|
||||||
.data_bits = UART_DATA_8_BITS, \
|
.data_bits = UART_DATA_8_BITS, \
|
||||||
@ -100,9 +103,10 @@ struct esp_modem_dte_config {
|
|||||||
.rx_buffer_size = 4096, \
|
.rx_buffer_size = 4096, \
|
||||||
.tx_buffer_size = 512, \
|
.tx_buffer_size = 512, \
|
||||||
.event_queue_size = 30, \
|
.event_queue_size = 30, \
|
||||||
.event_task_stack_size = 4096, \
|
}, \
|
||||||
.event_task_priority = 20, \
|
.vfs_config = { \
|
||||||
} \
|
.dev_name = "/null", \
|
||||||
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct esp_modem_dte_config esp_modem_dte_config_t;
|
typedef struct esp_modem_dte_config esp_modem_dte_config_t;
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
struct esp_modem_dte_config;
|
struct esp_modem_dte_config;
|
||||||
|
|
||||||
namespace esp_modem::terminal {
|
namespace esp_modem {
|
||||||
|
|
||||||
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config);
|
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config);
|
||||||
|
|
||||||
} // namespace esp_modem::terminal
|
} // namespace esp_modem
|
||||||
|
|
||||||
#endif // _VFS_TERMINAL_HPP_
|
#endif // _VFS_TERMINAL_HPP_
|
||||||
|
@ -39,7 +39,7 @@ std::shared_ptr<DTE> create_uart_dte(const dte_config *config) {
|
|||||||
|
|
||||||
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config) {
|
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config) {
|
||||||
TRY_CATCH_RET_NULL(
|
TRY_CATCH_RET_NULL(
|
||||||
auto term = terminal::create_vfs_terminal(config);
|
auto term = create_vfs_terminal(config);
|
||||||
return std::make_shared<DTE>(config, std::move(term));
|
return std::make_shared<DTE>(config, std::move(term));
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,18 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cxx_include/esp_modem_cmux.hpp>
|
#include <cxx_include/esp_modem_cmux.hpp>
|
||||||
//#include "esp_app_trace.h"
|
|
||||||
#include "cxx_include/esp_modem_dte.hpp"
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
using namespace esp_modem;
|
using namespace esp_modem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define this to defragment partially received data of CMUX payload
|
||||||
|
* This is useful if upper layers expect the entire payload available
|
||||||
|
* for parsing.
|
||||||
|
*/
|
||||||
|
#define DEFRAGMENT_CMUX_PAYLOAD
|
||||||
|
|
||||||
#define EA 0x01 /* Extension bit */
|
#define EA 0x01 /* Extension bit */
|
||||||
#define CR 0x02 /* Command / Response */
|
#define CR 0x02 /* Command / Response */
|
||||||
#define PF 0x10 /* Poll / Final */
|
#define PF 0x10 /* Poll / Final */
|
||||||
@ -72,11 +78,11 @@ uint8_t CMux::fcs_crc(const uint8_t frame[6])
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMux::send_sabm(size_t dlci)
|
void CMux::send_sabm(size_t i)
|
||||||
{
|
{
|
||||||
uint8_t frame[6];
|
uint8_t frame[6];
|
||||||
frame[0] = SOF_MARKER;
|
frame[0] = SOF_MARKER;
|
||||||
frame[1] = (dlci << 2) | 0x3;
|
frame[1] = (i << 2) | 0x3;
|
||||||
frame[2] = FT_SABM | PF;
|
frame[2] = FT_SABM | PF;
|
||||||
frame[3] = 1;
|
frame[3] = 1;
|
||||||
frame[4] = 0xFF - fcs_crc(frame);
|
frame[4] = 0xFF - fcs_crc(frame);
|
||||||
@ -90,14 +96,16 @@ void CMux::data_available(uint8_t *data, size_t len)
|
|||||||
if (data && type == 0xFF && len > 0 && dlci > 0) {
|
if (data && type == 0xFF && len > 0 && dlci > 0) {
|
||||||
int virtual_term = dlci - 1;
|
int virtual_term = dlci - 1;
|
||||||
if (virtual_term < max_terms && read_cb[virtual_term]) {
|
if (virtual_term < max_terms && read_cb[virtual_term]) {
|
||||||
// if (payload_start == nullptr) {
|
// Post partial data (or defragment to post on CMUX footer)
|
||||||
// payload_start = data;
|
#ifdef DEFRAGMENT_CMUX_PAYLOAD
|
||||||
// total_payload_size = 0;
|
if (payload_start == nullptr) {
|
||||||
// }
|
payload_start = data;
|
||||||
// total_payload_size += len;
|
total_payload_size = 0;
|
||||||
// Post partial data (if configured)
|
}
|
||||||
|
total_payload_size += len;
|
||||||
|
#else
|
||||||
read_cb[virtual_term](data, len);
|
read_cb[virtual_term](data, len);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else if (data == nullptr && type == 0x73 && len == 0) { // notify the initial SABM command
|
} else if (data == nullptr && type == 0x73 && len == 0) { // notify the initial SABM command
|
||||||
Scoped<Lock> l(lock);
|
Scoped<Lock> l(lock);
|
||||||
@ -105,7 +113,9 @@ void CMux::data_available(uint8_t *data, size_t len)
|
|||||||
} else if (data == nullptr) {
|
} else if (data == nullptr) {
|
||||||
int virtual_term = dlci - 1;
|
int virtual_term = dlci - 1;
|
||||||
if (virtual_term < max_terms && read_cb[virtual_term]) {
|
if (virtual_term < max_terms && read_cb[virtual_term]) {
|
||||||
// read_cb[virtual_term](payload_start, total_payload_size);
|
#ifdef DEFRAGMENT_CMUX_PAYLOAD
|
||||||
|
read_cb[virtual_term](payload_start, total_payload_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -114,7 +124,8 @@ void CMux::data_available(uint8_t *data, size_t len)
|
|||||||
bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
||||||
{
|
{
|
||||||
if (!data) {
|
if (!data) {
|
||||||
auto data_to_read = buffer_size - 155;
|
#ifdef DEFRAGMENT_CMUX_PAYLOAD
|
||||||
|
auto data_to_read = buffer_size - 128; // keep 128 (max CMUX payload) backup buffer)
|
||||||
if (payload_start) {
|
if (payload_start) {
|
||||||
data = payload_start + total_payload_size;
|
data = payload_start + total_payload_size;
|
||||||
data_to_read = payload_len + 2;
|
data_to_read = payload_len + 2;
|
||||||
@ -122,27 +133,12 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
data = buffer.get();
|
data = buffer.get();
|
||||||
}
|
}
|
||||||
actual_len = term->read(data, data_to_read);
|
actual_len = term->read(data, data_to_read);
|
||||||
// ESP_LOGE("Received", "data_to_read=%d, actual_len=%d, total_payload=%d", data_to_read, actual_len, total_payload_size);
|
#else
|
||||||
}
|
data = buffer.get();
|
||||||
#if 0
|
actual_len = term->read(data, buffer_size);
|
||||||
if (0){
|
|
||||||
static char buf[8*1024];
|
|
||||||
for (int i=0; i<actual_len; ++i)
|
|
||||||
sprintf(buf + 6*i, "0x%02x, ", data[i]);
|
|
||||||
buf[actual_len*6] = '\n';
|
|
||||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, buf, actual_len*6+1, ESP_APPTRACE_TMO_INFINITE);
|
|
||||||
if (res != ESP_OK) {
|
|
||||||
ESP_LOGE("cmux", "Failed to write data to host!");
|
|
||||||
}
|
|
||||||
esp_apptrace_flush(ESP_APPTRACE_DEST_TRAX, 1000);
|
|
||||||
// usleep(1000000);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
// printf("my_data[%d] = { ", actual_len);
|
}
|
||||||
// for (int i=0; i<actual_len; ++i)
|
ESP_LOG_BUFFER_HEXDUMP("CMUX Received", data, actual_len, ESP_LOG_DEBUG);
|
||||||
// printf("0x%02x, ", data[i]);
|
|
||||||
// printf("};\n");
|
|
||||||
// ESP_LOG_BUFFER_HEXDUMP("Received", data, actual_len, ESP_LOG_INFO);
|
|
||||||
uint8_t* frame = data;
|
uint8_t* frame = data;
|
||||||
uint8_t* recover_ptr;
|
uint8_t* recover_ptr;
|
||||||
auto available_len = actual_len;
|
auto available_len = actual_len;
|
||||||
@ -161,7 +157,7 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
available_len -= (recover_ptr - frame);
|
available_len -= (recover_ptr - frame);
|
||||||
frame = recover_ptr;
|
frame = recover_ptr;
|
||||||
state = cmux_state::INIT;
|
state = cmux_state::INIT;
|
||||||
ESP_LOGW("CMUX", "Protocol recovered");
|
ESP_LOGI("CMUX", "Protocol recovered");
|
||||||
if (available_len > 1 && frame[1] == SOF_MARKER) {
|
if (available_len > 1 && frame[1] == SOF_MARKER) {
|
||||||
// empty frame
|
// empty frame
|
||||||
available_len -= 1;
|
available_len -= 1;
|
||||||
@ -173,7 +169,7 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
return false;
|
return false;
|
||||||
case cmux_state::INIT:
|
case cmux_state::INIT:
|
||||||
if (frame[0] != SOF_MARKER) {
|
if (frame[0] != SOF_MARKER) {
|
||||||
ESP_LOGE("CMUX", "Protocol mismatch!");
|
ESP_LOGW("CMUX", "Protocol mismatch: Missed leading SOF, recovering...");
|
||||||
state = cmux_state::RECOVER;
|
state = cmux_state::RECOVER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -211,7 +207,7 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
state = cmux_state::PAYLOAD;
|
state = cmux_state::PAYLOAD;
|
||||||
break;
|
break;
|
||||||
case cmux_state::PAYLOAD:
|
case cmux_state::PAYLOAD:
|
||||||
ESP_LOGI("CMUX", "CMUX FR: A:%02x T:%02x L:%d available: %d", dlci, type, payload_len, available_len);
|
ESP_LOGD("CMUX", "Payload frame: dlci:%02x type:%02x payload:%d available:%d", dlci, type, payload_len, available_len);
|
||||||
if (available_len < payload_len) { // payload
|
if (available_len < payload_len) { // payload
|
||||||
state = cmux_state::PAYLOAD;
|
state = cmux_state::PAYLOAD;
|
||||||
data_available(frame, available_len); // partial read
|
data_available(frame, available_len); // partial read
|
||||||
@ -236,17 +232,18 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
|||||||
footer_offset = std::min(available_len, 6 - frame_header_offset);
|
footer_offset = std::min(available_len, 6 - frame_header_offset);
|
||||||
memcpy(frame_header + frame_header_offset, frame, footer_offset);
|
memcpy(frame_header + frame_header_offset, frame, footer_offset);
|
||||||
if (frame_header[5] != SOF_MARKER) {
|
if (frame_header[5] != SOF_MARKER) {
|
||||||
ESP_LOGE("CMUX-Footer", "Protocol mismatch! total pyaload: %d", total_payload_size);
|
ESP_LOGW("CMUX", "Protocol mismatch: Missed trailing SOF, recovering...");
|
||||||
ESP_LOG_BUFFER_HEXDUMP("Data-valid", payload_start, total_payload_size, ESP_LOG_INFO);
|
payload_start = nullptr;
|
||||||
ESP_LOG_BUFFER_HEXDUMP("Footer", frame-8, 16, ESP_LOG_ERROR);
|
total_payload_size = 0;
|
||||||
while(1) { usleep(10000); };
|
|
||||||
abort();
|
// ESP_LOGE("CMUX-Footer", "Protocol mismatch! total pyaload: %d", total_payload_size);
|
||||||
|
// ESP_LOG_BUFFER_HEXDUMP("Data-valid", payload_start, total_payload_size, ESP_LOG_INFO);
|
||||||
|
// ESP_LOG_BUFFER_HEXDUMP("Footer", frame-8, 16, ESP_LOG_ERROR);
|
||||||
|
// while(1) { usleep(10000); };
|
||||||
|
// abort();
|
||||||
state = cmux_state::RECOVER;
|
state = cmux_state::RECOVER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if (payload_len == 0) {
|
|
||||||
// data_available(frame_header, 0); // Null payload
|
|
||||||
// }
|
|
||||||
frame += footer_offset;
|
frame += footer_offset;
|
||||||
available_len -= footer_offset;
|
available_len -= footer_offset;
|
||||||
state = cmux_state::INIT;
|
state = cmux_state::INIT;
|
||||||
@ -275,7 +272,7 @@ bool CMux::init()
|
|||||||
{
|
{
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
send_sabm(i);
|
send_sabm(i);
|
||||||
while (1) {
|
while (true) {
|
||||||
usleep(10'000);
|
usleep(10'000);
|
||||||
Scoped<Lock> l(lock);
|
Scoped<Lock> l(lock);
|
||||||
if (sabm_ack == i) {
|
if (sabm_ack == i) {
|
||||||
|
@ -19,22 +19,25 @@
|
|||||||
#include "cxx_include/esp_modem_dce_module.hpp"
|
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||||
#include "cxx_include/esp_modem_command_library.hpp"
|
#include "cxx_include/esp_modem_command_library.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace esp_modem::dce_commands {
|
namespace esp_modem::dce_commands {
|
||||||
|
|
||||||
|
static const char *TAG = "command_lib";
|
||||||
|
|
||||||
command_result generic_command(CommandableIf* t, const std::string &command,
|
command_result generic_command(CommandableIf* t, const std::string &command,
|
||||||
const std::list<std::string_view>& pass_phrase,
|
const std::list<std::string_view>& pass_phrase,
|
||||||
const std::list<std::string_view>& fail_phrase,
|
const std::list<std::string_view>& fail_phrase,
|
||||||
uint32_t timeout_ms)
|
uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
printf("Command %s\n", command.c_str());
|
ESP_LOGI(TAG, "%s command %s\n", __func__, command.c_str());
|
||||||
return t->command(command, [&](uint8_t *data, size_t len) {
|
return t->command(command, [&](uint8_t *data, size_t len) {
|
||||||
std::string_view response((char*)data, len);
|
std::string_view response((char*)data, len);
|
||||||
printf("Response: %.*s\n", (int)response.length(), response.data());
|
if (data == nullptr || len == 0 || response.empty())
|
||||||
for (auto it : pass_phrase)
|
return command_result::TIMEOUT;
|
||||||
|
ESP_LOGI(TAG, "Response: %.*s\n", (int)response.length(), response.data());
|
||||||
|
for (auto &it : pass_phrase)
|
||||||
if (response.find(it) != std::string::npos)
|
if (response.find(it) != std::string::npos)
|
||||||
return command_result::OK;
|
return command_result::OK;
|
||||||
for (auto it : fail_phrase)
|
for (auto &it : fail_phrase)
|
||||||
if (response.find(it) != std::string::npos)
|
if (response.find(it) != std::string::npos)
|
||||||
return command_result::FAIL;
|
return command_result::FAIL;
|
||||||
return command_result::TIMEOUT;
|
return command_result::TIMEOUT;
|
||||||
@ -46,6 +49,7 @@ static inline command_result generic_command(CommandableIf* t, const std::string
|
|||||||
const std::string& pass_phrase,
|
const std::string& pass_phrase,
|
||||||
const std::string& fail_phrase, uint32_t timeout_ms)
|
const std::string& fail_phrase, uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
const auto pass = std::list<std::string_view>({pass_phrase});
|
const auto pass = std::list<std::string_view>({pass_phrase});
|
||||||
const auto fail = std::list<std::string_view>({fail_phrase});
|
const auto fail = std::list<std::string_view>({fail_phrase});
|
||||||
return generic_command(t, command, pass, fail, timeout_ms);
|
return generic_command(t, command, pass, fail, timeout_ms);
|
||||||
@ -53,6 +57,7 @@ static inline command_result generic_command(CommandableIf* t, const std::string
|
|||||||
|
|
||||||
static inline command_result generic_get_string(CommandableIf* t, const std::string& command, std::string_view& output, uint32_t timeout_ms = 500)
|
static inline command_result generic_get_string(CommandableIf* t, const std::string& 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) {
|
return t->command(command, [&](uint8_t *data, size_t len) {
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
std::string_view response((char*)data, len);
|
std::string_view response((char*)data, len);
|
||||||
@ -61,7 +66,7 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
|
|||||||
for (auto it = token.end() - 1; it > token.begin(); it--) // strip trailing CR or LF
|
for (auto it = token.end() - 1; it > token.begin(); it--) // strip trailing CR or LF
|
||||||
if (*it == '\r' || *it == '\n')
|
if (*it == '\r' || *it == '\n')
|
||||||
token.remove_suffix(1);
|
token.remove_suffix(1);
|
||||||
printf("{%.*s}\n", static_cast<int>(token.size()), token.data());
|
ESP_LOGV(TAG, "Token: {%.*s}\n", static_cast<int>(token.size()), token.data());
|
||||||
|
|
||||||
if (token.find("OK") != std::string::npos) {
|
if (token.find("OK") != std::string::npos) {
|
||||||
return command_result::OK;
|
return command_result::OK;
|
||||||
@ -78,6 +83,7 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
|
|||||||
|
|
||||||
static inline command_result generic_get_string(CommandableIf* t, const std::string& command, std::string& output, uint32_t timeout_ms = 500)
|
static inline command_result generic_get_string(CommandableIf* t, const std::string& command, std::string& output, uint32_t timeout_ms = 500)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, command, out, timeout_ms);
|
auto ret = generic_get_string(t, command, out, timeout_ms);
|
||||||
if (ret == command_result::OK)
|
if (ret == command_result::OK)
|
||||||
@ -88,51 +94,61 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
|
|||||||
|
|
||||||
static inline command_result generic_command_common(CommandableIf* t, const std::string &command, uint32_t timeout = 500)
|
static inline command_result generic_command_common(CommandableIf* t, const std::string &command, uint32_t timeout = 500)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, command, "OK", "ERROR", timeout);
|
return generic_command(t, command, "OK", "ERROR", timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result sync(CommandableIf* t)
|
command_result sync(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT\r");
|
return generic_command_common(t, "AT\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result store_profile(CommandableIf* t)
|
command_result store_profile(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT&W\r");
|
return generic_command_common(t, "AT&W\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result power_down(CommandableIf* t)
|
command_result power_down(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "AT+QPOWD=1\r", "POWERED DOWN", "ERROR", 1000);
|
return generic_command(t, "AT+QPOWD=1\r", "POWERED DOWN", "ERROR", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result power_down_sim7xxx(CommandableIf* t)
|
command_result power_down_sim7xxx(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT+CPOF\r", 1000);
|
return generic_command_common(t, "AT+CPOF\r", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result power_down_sim8xx(CommandableIf* t)
|
command_result power_down_sim8xx(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "AT+CPOWD=1\r", "POWER DOWN", "ERROR", 1000);
|
return generic_command(t, "AT+CPOWD=1\r", "POWER DOWN", "ERROR", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result reset(CommandableIf* t)
|
command_result reset(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "AT+CRESET\r", "PB DONE", "ERROR", 60000);
|
return generic_command(t, "AT+CRESET\r", "PB DONE", "ERROR", 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result set_baud(CommandableIf* t, int baud)
|
command_result set_baud(CommandableIf* t, int baud)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT+IPR=" + std::to_string(baud) + "\r");
|
return generic_command_common(t, "AT+IPR=" + std::to_string(baud) + "\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result hang_up(CommandableIf* t)
|
command_result hang_up(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "ATH\r", 90000);
|
return generic_command_common(t, "ATH\r", 90000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result get_battery_status(CommandableIf* t, int& voltage, int &bcs, int &bcl)
|
command_result get_battery_status(CommandableIf* t, int& voltage, int &bcs, int &bcl)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, "AT+CBC\r", out);
|
auto ret = generic_get_string(t, "AT+CBC\r", out);
|
||||||
if (ret != command_result::OK)
|
if (ret != command_result::OK)
|
||||||
@ -164,6 +180,7 @@ command_result get_battery_status(CommandableIf* t, int& voltage, int &bcs, int
|
|||||||
|
|
||||||
command_result get_battery_status_sim7xxx(CommandableIf* t, int& voltage, int &bcs, int &bcl)
|
command_result get_battery_status_sim7xxx(CommandableIf* t, int& voltage, int &bcs, int &bcl)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, "AT+CBC\r", out);
|
auto ret = generic_get_string(t, "AT+CBC\r", out);
|
||||||
if (ret != command_result::OK)
|
if (ret != command_result::OK)
|
||||||
@ -188,11 +205,13 @@ command_result get_battery_status_sim7xxx(CommandableIf* t, int& voltage, int &b
|
|||||||
|
|
||||||
command_result set_flow_control(CommandableIf* t, int dce_flow, int dte_flow)
|
command_result set_flow_control(CommandableIf* t, int dce_flow, int dte_flow)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT+IFC=" + std::to_string(dce_flow) + ", " + std::to_string(dte_flow) + "\r");
|
return generic_command_common(t, "AT+IFC=" + std::to_string(dce_flow) + ", " + std::to_string(dte_flow) + "\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result get_operator_name(CommandableIf* t, std::string& operator_name)
|
command_result get_operator_name(CommandableIf* t, std::string& operator_name)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000);
|
auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000);
|
||||||
if (ret != command_result::OK)
|
if (ret != command_result::OK)
|
||||||
@ -212,6 +231,7 @@ command_result get_operator_name(CommandableIf* t, std::string& operator_name)
|
|||||||
|
|
||||||
command_result set_echo(CommandableIf* t, bool on)
|
command_result set_echo(CommandableIf* t, bool on)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
if (on)
|
if (on)
|
||||||
return generic_command_common(t, "ATE1\r");
|
return generic_command_common(t, "ATE1\r");
|
||||||
return generic_command_common(t, "ATE0\r");
|
return generic_command_common(t, "ATE0\r");
|
||||||
@ -219,6 +239,7 @@ command_result set_echo(CommandableIf* t, bool on)
|
|||||||
|
|
||||||
command_result set_pdp_context(CommandableIf* t, PdpContext& pdp)
|
command_result set_pdp_context(CommandableIf* t, PdpContext& pdp)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string pdp_command = "AT+CGDCONT=" + std::to_string(pdp.context_id) +
|
std::string pdp_command = "AT+CGDCONT=" + std::to_string(pdp.context_id) +
|
||||||
",\"" + pdp.protocol_type + "\",\"" + pdp.apn + "\"\r";
|
",\"" + pdp.protocol_type + "\",\"" + pdp.apn + "\"\r";
|
||||||
return generic_command_common(t, pdp_command);
|
return generic_command_common(t, pdp_command);
|
||||||
@ -226,21 +247,25 @@ command_result set_pdp_context(CommandableIf* t, PdpContext& pdp)
|
|||||||
|
|
||||||
command_result set_data_mode(CommandableIf* t)
|
command_result set_data_mode(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000);
|
return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result set_data_mode_sim8xx(CommandableIf* t)
|
command_result set_data_mode_sim8xx(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000);
|
return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result resume_data_mode(CommandableIf* t)
|
command_result resume_data_mode(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command(t, "ATO\r", "CONNECT", "ERROR", 5000);
|
return generic_command(t, "ATO\r", "CONNECT", "ERROR", 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result set_command_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 pass = std::list<std::string_view>({"NO CARRIER", "OK"});
|
||||||
const auto fail = std::list<std::string_view>({"ERROR"});
|
const auto fail = std::list<std::string_view>({"ERROR"});
|
||||||
return generic_command(t, "+++", pass, fail, 5000);
|
return generic_command(t, "+++", pass, fail, 5000);
|
||||||
@ -248,21 +273,25 @@ command_result set_command_mode(CommandableIf* t)
|
|||||||
|
|
||||||
command_result get_imsi(CommandableIf* t, std::string& imsi_number)
|
command_result get_imsi(CommandableIf* t, std::string& imsi_number)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_get_string(t, "AT+CIMI\r", imsi_number, 5000);
|
return generic_get_string(t, "AT+CIMI\r", imsi_number, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result get_imei(CommandableIf* t, std::string& out)
|
command_result get_imei(CommandableIf* t, std::string& out)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_get_string(t, "AT+CGSN\r", out, 5000);
|
return generic_get_string(t, "AT+CGSN\r", out, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result get_module_name(CommandableIf* t, std::string& out)
|
command_result get_module_name(CommandableIf* t, std::string& out)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_get_string(t, "AT+CGMM\r", out, 5000);
|
return generic_get_string(t, "AT+CGMM\r", out, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result sms_txt_mode(CommandableIf* t, bool txt = true)
|
command_result sms_txt_mode(CommandableIf* t, bool txt = true)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
if (txt)
|
if (txt)
|
||||||
return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default)
|
return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default)
|
||||||
return generic_command_common(t, "AT+CMGF=0\r"); // PDU mode
|
return generic_command_common(t, "AT+CMGF=0\r"); // PDU mode
|
||||||
@ -271,14 +300,16 @@ command_result sms_txt_mode(CommandableIf* t, bool txt = true)
|
|||||||
command_result sms_character_set(CommandableIf* t)
|
command_result sms_character_set(CommandableIf* t)
|
||||||
{
|
{
|
||||||
// Sets the default GSM character set
|
// Sets the default GSM character set
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT+CSCS=\"GSM\"\r");
|
return generic_command_common(t, "AT+CSCS=\"GSM\"\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result send_sms(CommandableIf* t, const std::string& number, const std::string& message)
|
command_result send_sms(CommandableIf* t, const std::string& number, const std::string& message)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
auto ret = t->command("AT+CMGS=\"" + number + "\"\r", [&](uint8_t *data, size_t len) {
|
auto ret = t->command("AT+CMGS=\"" + number + "\"\r", [&](uint8_t *data, size_t len) {
|
||||||
std::string_view response((char*)data, len);
|
std::string_view response((char*)data, len);
|
||||||
printf("%.*s", static_cast<int>(response.size()), response.data());
|
ESP_LOGD(TAG,"Send SMS response %.*s", static_cast<int>(response.size()), response.data());
|
||||||
if (response.find('>') != std::string::npos) {
|
if (response.find('>') != std::string::npos) {
|
||||||
return command_result::OK;
|
return command_result::OK;
|
||||||
}
|
}
|
||||||
@ -292,11 +323,13 @@ command_result send_sms(CommandableIf* t, const std::string& number, const std::
|
|||||||
|
|
||||||
command_result set_cmux(CommandableIf* t)
|
command_result set_cmux(CommandableIf* t)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
return generic_command_common(t, "AT+CMUX=0\r");
|
return generic_command_common(t, "AT+CMUX=0\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result read_pin(CommandableIf* t, bool& pin_ok)
|
command_result read_pin(CommandableIf* t, bool& pin_ok)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, "AT+CPIN?\r", out);
|
auto ret = generic_get_string(t, "AT+CPIN?\r", out);
|
||||||
if (ret != command_result::OK)
|
if (ret != command_result::OK)
|
||||||
@ -316,13 +349,14 @@ command_result read_pin(CommandableIf* t, bool& pin_ok)
|
|||||||
|
|
||||||
command_result set_pin(CommandableIf* t, const std::string& pin)
|
command_result set_pin(CommandableIf* t, const std::string& pin)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string set_pin_command = "AT+CPIN=" + pin + "\r";
|
std::string set_pin_command = "AT+CPIN=" + pin + "\r";
|
||||||
return generic_command_common(t, set_pin_command);
|
return generic_command_common(t, set_pin_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
command_result get_signal_quality(CommandableIf* t, int &rssi, int &ber)
|
command_result get_signal_quality(CommandableIf* t, int &rssi, int &ber)
|
||||||
{
|
{
|
||||||
printf("%s", __func__ );
|
ESP_LOGV(TAG,"%s", __func__ );
|
||||||
std::string_view out;
|
std::string_view out;
|
||||||
auto ret = generic_get_string(t, "AT+CSQ\r", out);
|
auto ret = generic_get_string(t, "AT+CSQ\r", out);
|
||||||
if (ret != command_result::OK)
|
if (ret != command_result::OK)
|
||||||
|
@ -39,13 +39,11 @@ command_result DTE::command(const std::string &command, got_line_cb got_line, ui
|
|||||||
command_result res = command_result::TIMEOUT;
|
command_result res = command_result::TIMEOUT;
|
||||||
command_term->set_read_cb([&](uint8_t *data, size_t len) {
|
command_term->set_read_cb([&](uint8_t *data, size_t len) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = buffer.get(); // + consumed;
|
data = buffer.get();
|
||||||
len = command_term->read(data + consumed, buffer_size - consumed);
|
len = command_term->read(data + consumed, buffer_size - consumed);
|
||||||
} else {
|
} else {
|
||||||
consumed = 0;
|
consumed = 0; // if the underlying terminal contains data, we cannot fragment
|
||||||
}
|
}
|
||||||
// ESP_LOGD("CMD_read!", "-----");
|
|
||||||
// for (int i=0; i<len; i++) ESP_LOGV("CMD_read", "%02x",data[i] );
|
|
||||||
if (memchr(data + consumed, separator, len)) {
|
if (memchr(data + consumed, separator, len)) {
|
||||||
res = got_line(data, consumed + len);
|
res = got_line(data, consumed + len);
|
||||||
if (res == command_result::OK || res == command_result::FAIL) {
|
if (res == command_result::OK || res == command_result::FAIL) {
|
||||||
@ -92,7 +90,6 @@ bool DTE::setup_cmux()
|
|||||||
|
|
||||||
bool DTE::set_mode(modem_mode m)
|
bool DTE::set_mode(modem_mode m)
|
||||||
{
|
{
|
||||||
term->start();
|
|
||||||
mode = m;
|
mode = m;
|
||||||
if (m == modem_mode::DATA_MODE) {
|
if (m == modem_mode::DATA_MODE) {
|
||||||
term->set_read_cb(on_data);
|
term->set_read_cb(on_data);
|
||||||
|
@ -12,40 +12,31 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include "cxx_include/esp_modem_dte.hpp"
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "driver/uart.h"
|
|
||||||
#include "esp_modem_config.h"
|
#include "esp_modem_config.h"
|
||||||
#include "exception_stub.hpp"
|
#include "exception_stub.hpp"
|
||||||
|
#include "uart_resource.hpp" // In case of VFS using UART
|
||||||
|
|
||||||
static const char *TAG = "fs_terminal";
|
static const char *TAG = "fs_terminal";
|
||||||
|
|
||||||
namespace esp_modem::terminal {
|
namespace esp_modem {
|
||||||
|
|
||||||
struct uart_resource {
|
class Resource {
|
||||||
explicit uart_resource(const esp_modem_dte_config *config);
|
public:
|
||||||
~uart_resource();
|
Resource(const esp_modem_dte_config *config);
|
||||||
uart_port_t port;
|
|
||||||
int fd;
|
std::optional<uart_resource> uart;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FdTerminal : public Terminal {
|
||||||
|
|
||||||
class vfs_terminal : public Terminal {
|
|
||||||
public:
|
public:
|
||||||
explicit vfs_terminal(const esp_modem_dte_config *config) :
|
explicit FdTerminal(const esp_modem_dte_config *config);
|
||||||
uart(config), signal(),
|
|
||||||
task_handle(config->vfs_config.task_stack_size, config->vfs_config.task_prio, this, [](void* p){
|
|
||||||
auto t = static_cast<vfs_terminal *>(p);
|
|
||||||
t->task();
|
|
||||||
Task::Delete();
|
|
||||||
}) {}
|
|
||||||
|
|
||||||
~vfs_terminal() override {
|
~FdTerminal() override;
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() override {
|
void start() override {
|
||||||
signal.set(TASK_START);
|
signal.set(TASK_START);
|
||||||
@ -74,28 +65,45 @@ private:
|
|||||||
|
|
||||||
uart_resource uart;
|
uart_resource uart;
|
||||||
SignalGroup signal;
|
SignalGroup signal;
|
||||||
|
int fd;
|
||||||
Task task_handle;
|
Task task_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config) {
|
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config) {
|
||||||
TRY_CATCH_RET_NULL(
|
TRY_CATCH_RET_NULL(
|
||||||
auto term = std::make_unique<vfs_terminal>(config);
|
auto term = std::make_unique<FdTerminal>(config);
|
||||||
term->start();
|
term->start();
|
||||||
return term;
|
return term;
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfs_terminal::task() {
|
FdTerminal::FdTerminal(const esp_modem_dte_config *config) :
|
||||||
|
uart(config, nullptr), signal(), fd(-1),
|
||||||
|
task_handle(config->task_stack_size, config->task_priority, this, [](void* p){
|
||||||
|
auto t = static_cast<FdTerminal *>(p);
|
||||||
|
t->task();
|
||||||
|
Task::Delete();
|
||||||
|
if (t->fd >= 0) {
|
||||||
|
close(t->fd);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
fd = open(config->vfs_config.dev_name, O_RDWR);
|
||||||
|
throw_if_false(fd >= 0, "Cannot open the fd");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FdTerminal::task()
|
||||||
|
{
|
||||||
std::function<bool(uint8_t *data, size_t len)> on_data_priv = nullptr;
|
std::function<bool(uint8_t *data, size_t len)> on_data_priv = nullptr;
|
||||||
// size_t len;
|
|
||||||
signal.set(TASK_INIT);
|
signal.set(TASK_INIT);
|
||||||
signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY);
|
signal.wait_any(TASK_START | TASK_STOP, portMAX_DELAY);
|
||||||
if (signal.is_any(TASK_STOP)) {
|
if (signal.is_any(TASK_STOP)) {
|
||||||
return; // exits to the static method where the task gets deleted
|
return; // exits to the static method where the task gets deleted
|
||||||
}
|
}
|
||||||
// esp_vfs_dev_uart_use_driver(uart.port);
|
|
||||||
int flags = fcntl(uart.fd, F_GETFL, NULL) | O_NONBLOCK;
|
// Set the FD to non-blocking mode
|
||||||
fcntl(uart.fd, F_SETFL, flags);
|
int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK;
|
||||||
|
fcntl(fd, F_SETFL, flags);
|
||||||
|
|
||||||
while (signal.is_any(TASK_START)) {
|
while (signal.is_any(TASK_START)) {
|
||||||
int s;
|
int s;
|
||||||
@ -105,9 +113,9 @@ void vfs_terminal::task() {
|
|||||||
.tv_usec = 0,
|
.tv_usec = 0,
|
||||||
};
|
};
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(uart.fd, &rfds);
|
FD_SET(fd, &rfds);
|
||||||
|
|
||||||
s = select(uart.fd + 1, &rfds, NULL, NULL, &tv);
|
s = select(fd + 1, &rfds, nullptr, nullptr, &tv);
|
||||||
if (signal.is_any(TASK_PARAMS)) {
|
if (signal.is_any(TASK_PARAMS)) {
|
||||||
on_data_priv = on_data;
|
on_data_priv = on_data;
|
||||||
signal.clear(TASK_PARAMS);
|
signal.clear(TASK_PARAMS);
|
||||||
@ -116,11 +124,9 @@ void vfs_terminal::task() {
|
|||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
break;
|
break;
|
||||||
} else if (s == 0) {
|
} else if (s == 0) {
|
||||||
// ESP_LOGV(TAG, "Select exitted with timeout");
|
// ESP_LOGV(TAG, "Select exited with timeout");
|
||||||
} else {
|
} else {
|
||||||
if (FD_ISSET(uart.fd, &rfds)) {
|
if (FD_ISSET(fd, &rfds)) {
|
||||||
// ESP_LOGV(TAG, "FD is readable");
|
|
||||||
// uart_get_buffered_data_len(uart.port, &len);
|
|
||||||
if (on_data_priv) {
|
if (on_data_priv) {
|
||||||
if (on_data_priv(nullptr, 0)) {
|
if (on_data_priv(nullptr, 0)) {
|
||||||
on_data_priv = nullptr;
|
on_data_priv = nullptr;
|
||||||
@ -132,23 +138,32 @@ void vfs_terminal::task() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfs_terminal::read(uint8_t *data, size_t len)
|
int FdTerminal::read(uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
int size = ::read(uart.fd, data, len);
|
int size = ::read(fd, data, len);
|
||||||
// for (int i=0; i<size; i++) ESP_LOGD(TAG, "Read: %02x",data[i] );
|
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
|
if (errno != EAGAIN) {
|
||||||
ESP_LOGE(TAG, "Error occurred during read: %d", errno);
|
ESP_LOGE(TAG, "Error occurred during read: %d", errno);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfs_terminal::write(uint8_t *data, size_t len)
|
int FdTerminal::write(uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
|
int size = ::write(fd, data, len);
|
||||||
|
if (size < 0) {
|
||||||
|
ESP_LOGE(TAG, "Error occurred during read: %d", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
// for (int i=0; i<len; i++) ESP_LOGD(TAG, "%02x",data[i] );
|
FdTerminal::~FdTerminal()
|
||||||
return ::write(uart.fd, data, len);
|
{
|
||||||
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace esp_modem
|
} // namespace esp_modem
|
||||||
|
@ -11,67 +11,70 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#include "cxx_include/esp_modem_dte.hpp"
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "esp_modem_config.h"
|
#include "esp_modem_config.h"
|
||||||
#include "exception_stub.hpp"
|
|
||||||
#include "esp_vfs_dev.h"
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
|
|
||||||
|
namespace esp_modem {
|
||||||
|
|
||||||
static const char *TAG = "uart_terminal";
|
|
||||||
|
|
||||||
namespace esp_modem::terminal {
|
|
||||||
|
|
||||||
struct uart_resource {
|
struct uart_resource {
|
||||||
explicit uart_resource(const esp_modem_dte_config *config);
|
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue);
|
||||||
~uart_resource();
|
~uart_resource();
|
||||||
uart_port_t port;
|
uart_port_t port;
|
||||||
int fd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uart_resource::uart_resource(const esp_modem_dte_config *config) :
|
uart_resource::~uart_resource()
|
||||||
port(-1), fd(-1)
|
|
||||||
{
|
{
|
||||||
/* Config UART */
|
|
||||||
uart_config_t uart_config = {};
|
|
||||||
uart_config.baud_rate = config->vfs_config.baud_rate;
|
|
||||||
uart_config.data_bits = UART_DATA_8_BITS;
|
|
||||||
uart_config.parity = UART_PARITY_DISABLE;
|
|
||||||
uart_config.stop_bits = UART_STOP_BITS_1;
|
|
||||||
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
|
||||||
uart_config.source_clk = UART_SCLK_REF_TICK;
|
|
||||||
|
|
||||||
throw_if_esp_fail(uart_param_config(config->vfs_config.port_num, &uart_config), "config uart parameter failed");
|
|
||||||
|
|
||||||
throw_if_esp_fail(uart_set_pin(config->vfs_config.port_num, config->vfs_config.tx_io_num, config->vfs_config.rx_io_num,
|
|
||||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE), "config uart gpio failed");
|
|
||||||
|
|
||||||
throw_if_esp_fail(uart_driver_install(config->vfs_config.port_num, config->vfs_config.rx_buffer_size, config->vfs_config.tx_buffer_size,
|
|
||||||
0, nullptr, 0), "install uart driver failed");
|
|
||||||
|
|
||||||
// throw_if_esp_fail(uart_set_rx_timeout(config->vfs_config.port_num, 1), "set rx timeout failed");
|
|
||||||
//
|
|
||||||
// throw_if_esp_fail(uart_set_rx_full_threshold(config->uart_config.port_num, 64), "config rx full threshold failed");
|
|
||||||
|
|
||||||
/* mark UART as initialized */
|
|
||||||
port = config->vfs_config.port_num;
|
|
||||||
esp_vfs_dev_uart_use_driver(port);
|
|
||||||
|
|
||||||
fd = open(config->vfs_config.dev_name, O_RDWR);
|
|
||||||
|
|
||||||
throw_if_false(fd >= 0, "Cannot open the fd");
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_resource::~uart_resource() {
|
|
||||||
if (port >= UART_NUM_0 && port < UART_NUM_MAX) {
|
if (port >= UART_NUM_0 && port < UART_NUM_MAX) {
|
||||||
uart_driver_delete(port);
|
uart_driver_delete(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace esp_modem::terminal
|
uart_resource::uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue) :
|
||||||
|
port(-1)
|
||||||
|
{
|
||||||
|
esp_err_t res;
|
||||||
|
|
||||||
|
/* Config UART */
|
||||||
|
uart_config_t uart_config = {};
|
||||||
|
uart_config.baud_rate = config->uart_config.baud_rate;
|
||||||
|
uart_config.data_bits = config->uart_config.data_bits;
|
||||||
|
uart_config.parity = config->uart_config.parity;
|
||||||
|
uart_config.stop_bits = config->uart_config.stop_bits;
|
||||||
|
uart_config.flow_ctrl = (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS
|
||||||
|
: UART_HW_FLOWCTRL_DISABLE;
|
||||||
|
uart_config.source_clk = UART_SCLK_APB;
|
||||||
|
|
||||||
|
throw_if_esp_fail(uart_param_config(config->uart_config.port_num, &uart_config), "config uart parameter failed");
|
||||||
|
|
||||||
|
if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
||||||
|
res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num,
|
||||||
|
config->uart_config.rts_io_num, config->uart_config.cts_io_num);
|
||||||
|
} else {
|
||||||
|
res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num,
|
||||||
|
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||||
|
}
|
||||||
|
throw_if_esp_fail(res, "config uart gpio failed");
|
||||||
|
/* Set flow control threshold */
|
||||||
|
if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
||||||
|
res = uart_set_hw_flow_ctrl(config->uart_config.port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8);
|
||||||
|
} else if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_SW) {
|
||||||
|
res = uart_set_sw_flow_ctrl(config->uart_config.port_num, true, 8, UART_FIFO_LEN - 8);
|
||||||
|
}
|
||||||
|
throw_if_esp_fail(res, "config uart flow control failed");
|
||||||
|
|
||||||
|
/* Install UART driver and get event queue used inside driver */
|
||||||
|
res = uart_driver_install(config->uart_config.port_num,
|
||||||
|
config->uart_config.rx_buffer_size, config->uart_config.tx_buffer_size,
|
||||||
|
config->uart_config.event_queue_size, config->uart_config.event_queue_size ? event_queue : nullptr,
|
||||||
|
0);
|
||||||
|
throw_if_esp_fail(res, "install uart driver failed");
|
||||||
|
throw_if_esp_fail(uart_set_rx_timeout(config->uart_config.port_num, 1), "set rx timeout failed");
|
||||||
|
|
||||||
|
throw_if_esp_fail(uart_set_rx_full_threshold(config->uart_config.port_num, 64), "config rx full threshold failed");
|
||||||
|
|
||||||
|
/* mark UART as initialized */
|
||||||
|
port = config->uart_config.port_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace esp_modem
|
||||||
|
@ -25,22 +25,13 @@ static const char *TAG = "uart_terminal";
|
|||||||
|
|
||||||
namespace esp_modem {
|
namespace esp_modem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uart Resource is a platform specific struct which is implemented separately
|
||||||
|
*/
|
||||||
struct uart_resource {
|
struct uart_resource {
|
||||||
explicit uart_resource(const esp_modem_dte_config *config);
|
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue);
|
||||||
|
|
||||||
~uart_resource();
|
~uart_resource();
|
||||||
|
uart_port_t port;
|
||||||
bool get_event(uart_event_t &event, uint32_t time_ms) {
|
|
||||||
return xQueueReceive(event_queue, &event, pdMS_TO_TICKS(time_ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_events() {
|
|
||||||
uart_flush_input(port);
|
|
||||||
xQueueReset(event_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_port_t port; /*!< UART port */
|
|
||||||
QueueHandle_t event_queue; /*!< UART event queue handle */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uart_task {
|
struct uart_task {
|
||||||
@ -57,64 +48,13 @@ struct uart_task {
|
|||||||
TaskHandle_t task_handle; /*!< UART event task handle */
|
TaskHandle_t task_handle; /*!< UART event task handle */
|
||||||
};
|
};
|
||||||
|
|
||||||
uart_resource::~uart_resource()
|
|
||||||
{
|
|
||||||
if (port >= UART_NUM_0 && port < UART_NUM_MAX) {
|
|
||||||
uart_driver_delete(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uart_resource::uart_resource(const esp_modem_dte_config *config) :
|
|
||||||
port(-1)
|
|
||||||
{
|
|
||||||
esp_err_t res;
|
|
||||||
|
|
||||||
/* Config UART */
|
|
||||||
uart_config_t uart_config = {};
|
|
||||||
uart_config.baud_rate = config->uart_config.baud_rate;
|
|
||||||
uart_config.data_bits = config->uart_config.data_bits;
|
|
||||||
uart_config.parity = config->uart_config.parity;
|
|
||||||
uart_config.stop_bits = config->uart_config.stop_bits;
|
|
||||||
uart_config.flow_ctrl = (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS
|
|
||||||
: UART_HW_FLOWCTRL_DISABLE;
|
|
||||||
uart_config.source_clk = UART_SCLK_APB;
|
|
||||||
|
|
||||||
throw_if_esp_fail(uart_param_config(config->uart_config.port_num, &uart_config), "config uart parameter failed");
|
|
||||||
|
|
||||||
if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
|
||||||
res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num,
|
|
||||||
config->uart_config.rts_io_num, config->uart_config.cts_io_num);
|
|
||||||
} else {
|
|
||||||
res = uart_set_pin(config->uart_config.port_num, config->uart_config.tx_io_num, config->uart_config.rx_io_num,
|
|
||||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
|
||||||
}
|
|
||||||
throw_if_esp_fail(res, "config uart gpio failed");
|
|
||||||
/* Set flow control threshold */
|
|
||||||
if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
|
||||||
res = uart_set_hw_flow_ctrl(config->uart_config.port_num, UART_HW_FLOWCTRL_CTS_RTS, UART_FIFO_LEN - 8);
|
|
||||||
} else if (config->uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_SW) {
|
|
||||||
res = uart_set_sw_flow_ctrl(config->uart_config.port_num, true, 8, UART_FIFO_LEN - 8);
|
|
||||||
}
|
|
||||||
throw_if_esp_fail(res, "config uart flow control failed");
|
|
||||||
|
|
||||||
/* Install UART driver and get event queue used inside driver */
|
|
||||||
res = uart_driver_install(config->uart_config.port_num, config->uart_config.rx_buffer_size, config->uart_config.tx_buffer_size,
|
|
||||||
config->uart_config.event_queue_size, &(event_queue), 0);
|
|
||||||
throw_if_esp_fail(res, "install uart driver failed");
|
|
||||||
throw_if_esp_fail(uart_set_rx_timeout(config->uart_config.port_num, 1), "set rx timeout failed");
|
|
||||||
|
|
||||||
throw_if_esp_fail(uart_set_rx_full_threshold(config->uart_config.port_num, 64), "config rx full threshold failed");
|
|
||||||
|
|
||||||
/* mark UART as initialized */
|
|
||||||
port = config->uart_config.port_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
class uart_terminal : public Terminal {
|
class uart_terminal : public Terminal {
|
||||||
public:
|
public:
|
||||||
explicit uart_terminal(const esp_modem_dte_config *config) :
|
explicit uart_terminal(const esp_modem_dte_config *config) :
|
||||||
uart(config), signal(),
|
event_queue(), uart(config, &event_queue), signal(),
|
||||||
task_handle(config->uart_config.event_task_stack_size, config->uart_config.event_task_priority, this, s_task) {}
|
task_handle(config->task_stack_size, config->task_priority, this, s_task) {}
|
||||||
|
|
||||||
~uart_terminal() override = default;
|
~uart_terminal() override = default;
|
||||||
|
|
||||||
@ -139,16 +79,25 @@ private:
|
|||||||
static void s_task(void *task_param) {
|
static void s_task(void *task_param) {
|
||||||
auto t = static_cast<uart_terminal *>(task_param);
|
auto t = static_cast<uart_terminal *>(task_param);
|
||||||
t->task();
|
t->task();
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void task();
|
void task();
|
||||||
|
bool get_event(uart_event_t &event, uint32_t time_ms) {
|
||||||
|
return xQueueReceive(event_queue, &event, pdMS_TO_TICKS(time_ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_events() {
|
||||||
|
uart_flush_input(uart.port);
|
||||||
|
xQueueReset(event_queue);
|
||||||
|
}
|
||||||
|
|
||||||
static const size_t TASK_INIT = BIT0;
|
static const size_t TASK_INIT = BIT0;
|
||||||
static const size_t TASK_START = BIT1;
|
static const size_t TASK_START = BIT1;
|
||||||
static const size_t TASK_STOP = BIT2;
|
static const size_t TASK_STOP = BIT2;
|
||||||
static const size_t TASK_PARAMS = BIT3;
|
static const size_t TASK_PARAMS = BIT3;
|
||||||
|
|
||||||
|
QueueHandle_t event_queue;
|
||||||
uart_resource uart;
|
uart_resource uart;
|
||||||
SignalGroup signal;
|
SignalGroup signal;
|
||||||
uart_task task_handle;
|
uart_task task_handle;
|
||||||
@ -172,7 +121,7 @@ void uart_terminal::task() {
|
|||||||
return; // exits to the static method where the task gets deleted
|
return; // exits to the static method where the task gets deleted
|
||||||
}
|
}
|
||||||
while (signal.is_any(TASK_START)) {
|
while (signal.is_any(TASK_START)) {
|
||||||
if (uart.get_event(event, 100)) {
|
if (get_event(event, 100)) {
|
||||||
if (signal.is_any(TASK_PARAMS)) {
|
if (signal.is_any(TASK_PARAMS)) {
|
||||||
on_data_priv = on_data;
|
on_data_priv = on_data;
|
||||||
signal.clear(TASK_PARAMS);
|
signal.clear(TASK_PARAMS);
|
||||||
@ -190,13 +139,13 @@ void uart_terminal::task() {
|
|||||||
ESP_LOGW(TAG, "HW FIFO Overflow");
|
ESP_LOGW(TAG, "HW FIFO Overflow");
|
||||||
if (on_error)
|
if (on_error)
|
||||||
on_error(terminal_error::BUFFER_OVERFLOW);
|
on_error(terminal_error::BUFFER_OVERFLOW);
|
||||||
uart.reset_events();
|
reset_events();
|
||||||
break;
|
break;
|
||||||
case UART_BUFFER_FULL:
|
case UART_BUFFER_FULL:
|
||||||
ESP_LOGW(TAG, "Ring Buffer Full");
|
ESP_LOGW(TAG, "Ring Buffer Full");
|
||||||
if (on_error)
|
if (on_error)
|
||||||
on_error(terminal_error::BUFFER_OVERFLOW);
|
on_error(terminal_error::BUFFER_OVERFLOW);
|
||||||
uart.reset_events();
|
reset_events();
|
||||||
break;
|
break;
|
||||||
case UART_BREAK:
|
case UART_BREAK:
|
||||||
ESP_LOGW(TAG, "Rx Break");
|
ESP_LOGW(TAG, "Rx Break");
|
||||||
@ -224,11 +173,11 @@ void uart_terminal::task() {
|
|||||||
int uart_terminal::read(uint8_t *data, size_t len) {
|
int uart_terminal::read(uint8_t *data, size_t len) {
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
uart_get_buffered_data_len(uart.port, &length);
|
uart_get_buffered_data_len(uart.port, &length);
|
||||||
if (esp_random() < UINT32_MAX/4 && length > 32) {
|
// if (esp_random() < UINT32_MAX/4 && length > 32) {
|
||||||
printf("ahoj!\n");
|
// printf("ahoj!\n");
|
||||||
length -= length/4;
|
// length -= length/4;
|
||||||
}
|
// }
|
||||||
size_t new_size = length/2;
|
// size_t new_size = length/2;
|
||||||
length = std::min(len, length);
|
length = std::min(len, length);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
return uart_read_bytes(uart.port, data, length, portMAX_DELAY);
|
return uart_read_bytes(uart.port, data, length, portMAX_DELAY);
|
||||||
|
Reference in New Issue
Block a user