esp-modem: C++ rework

This commit is contained in:
David Cermak
2021-02-26 18:32:15 +01:00
parent 3d00b41d2d
commit 86b8cfd6f5
15 changed files with 1103 additions and 12 deletions

View File

@ -0,0 +1,86 @@
#ifndef SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_HPP
#define SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_HPP
#include <memory>
#include <functional>
#include <exception>
#include <cstddef>
#include <cstdint>
#include <utility>
#include "esp_err.h"
#include "terminal_objects.hpp"
enum class terminal_error {
BUFFER_OVERFLOW,
CHECKSUM_ERROR,
UNEXPECTED_CONTROL_FLOW,
};
class terminal {
public:
virtual ~terminal() = default;
void set_data_cb(std::function<void(size_t len)> f) { on_data = std::move(f); }
void set_error_cb(std::function<void(terminal_error)> f) { on_error = std::move(f); }
virtual int write(uint8_t *data, size_t len) = 0;
virtual int read(uint8_t *data, size_t len) = 0;
virtual void start() = 0;
virtual void stop() = 0;
protected:
std::function<void(size_t len)> on_data;
std::function<void(terminal_error)> on_error;
};
class dte_adapter: public terminal {
public:
dte_adapter(std::unique_ptr<terminal> terminal):
original_dte(std::move(terminal)) {}
~dte_adapter() override = default;
int write(uint8_t *data, size_t len) override { return original_dte->write(data, len); }
int read(uint8_t *data, size_t len) override { return original_dte->read(data, len); }
private:
std::unique_ptr<terminal> original_dte;
};
enum class dte_mode {
UNDEF,
COMMAND_MODE,
DATA_MODE
};
const int DTE_BUFFER_SIZE = 1024;
struct dte_data {
uint8_t *data;
size_t len;
};
typedef std::function<bool(uint8_t *data, size_t len)> got_line_cb;
class dte {
public:
explicit dte(std::unique_ptr<terminal> terminal);
~dte() = default;
// void set_line_cb(got_line f) { on_line_cb = std::move(f); }
void set_mode(dte_mode m) { term->start(); mode = m; }
bool send_command(const std::string& command, got_line_cb got_line, uint32_t time_ms);
private:
const size_t GOT_LINE = BIT0;
size_t buffer_size;
size_t consumed;
std::unique_ptr<uint8_t[]> buffer;
std::unique_ptr<terminal> term;
got_line_cb on_line;
dte_mode mode;
signal_group signal;
};
#endif //SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_HPP

View File

@ -0,0 +1,84 @@
//
// Created by david on 2/26/21.
//
#ifndef SIMPLE_CXX_CLIENT_TERMINAL_OBJECTS_HPP
#define SIMPLE_CXX_CLIENT_TERMINAL_OBJECTS_HPP
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
class esp_err_exception: virtual public std::exception {
public:
explicit esp_err_exception(esp_err_t err): esp_err(err) {}
explicit esp_err_exception(std::string msg): esp_err(ESP_FAIL), message(std::move(msg)) {}
explicit esp_err_exception(std::string msg, esp_err_t err): esp_err(err), message(std::move(msg)) {}
virtual esp_err_t get_err_t() { return esp_err; }
~esp_err_exception() noexcept override = default;
virtual const char* what() const noexcept {
return message.c_str();
}
private:
esp_err_t esp_err;
std::string message;
};
static inline void throw_if_false(bool condition, std::string message)
{
if (!condition) {
throw(esp_err_exception(std::move(message)));
}
}
static inline void throw_if_esp_fail(esp_err_t err, std::string message)
{
if (err != ESP_OK) {
throw(esp_err_exception(std::move(message), err));
}
}
static inline void throw_if_esp_fail(esp_err_t err)
{
if (err != ESP_OK) {
throw(esp_err_exception(err));
}
}
struct signal_group {
explicit signal_group(): event_group(nullptr)
{
event_group = xEventGroupCreate();
throw_if_false(event_group != nullptr, "create signal event group failed");
}
void set(uint32_t bits)
{
xEventGroupSetBits(event_group, bits);
}
bool wait(uint32_t flags, uint32_t time_ms) // waiting for all and clearing if set
{
EventBits_t bits = xEventGroupWaitBits(event_group, flags, pdTRUE, pdTRUE, pdMS_TO_TICKS(time_ms));
return bits & flags;
}
bool is_any(uint32_t flags)
{
return xEventGroupGetBits(event_group) & flags;
}
bool wait_any(uint32_t flags, uint32_t time_ms) // waiting for any bit, not clearing them
{
EventBits_t bits = xEventGroupWaitBits(event_group, flags, pdFALSE, pdFALSE, pdMS_TO_TICKS(time_ms));
return bits & flags;
}
~signal_group()
{
if (event_group) vEventGroupDelete(event_group);
}
EventGroupHandle_t event_group;
};
#endif //SIMPLE_CXX_CLIENT_TERMINAL_OBJECTS_HPP

View File

@ -0,0 +1,17 @@
//
// Created by david on 2/25/21.
//
#ifndef SIMPLE_CXX_CLIENT_UART_TERMINAL_HPP
#define SIMPLE_CXX_CLIENT_UART_TERMINAL_HPP
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_dte_config.h"
std::unique_ptr<terminal> create_uart_terminal(const struct dte_config *config);
class dte;
std::unique_ptr<dte> create_dte(const struct dte_config *config);
#endif //SIMPLE_CXX_CLIENT_UART_TERMINAL_HPP

View File

@ -19,6 +19,7 @@ extern "C" {
#include "esp_event.h"
#include "driver/uart.h"
#include "esp_modem_dte_config.h"
/**
* @brief Forward declare DTE and DCE objects
@ -52,21 +53,15 @@ typedef enum {
* @{
*/
/**
* @brief Modem flow control type
*
*/
typedef enum {
ESP_MODEM_FLOW_CONTROL_NONE = 0,
ESP_MODEM_FLOW_CONTROL_SW,
ESP_MODEM_FLOW_CONTROL_HW
} esp_modem_flow_ctrl_t;
/**
* @brief ESP Modem DTE Configuration
*
*/
typedef struct {
typedef struct dte_config
#if 0
{
uart_port_t port_num; /*!< UART port number */
uart_word_length_t data_bits; /*!< Data bits of UART */
uart_stop_bits_t stop_bits; /*!< Stop bits of UART */
@ -84,7 +79,9 @@ typedef struct {
uint32_t event_task_stack_size; /*!< UART Event Task Stack size */
int event_task_priority; /*!< UART Event Task Priority */
int line_buffer_size; /*!< Line buffer size for command mode */
} esp_modem_dte_config_t;
}
#endif
esp_modem_dte_config_t;
/**
* @brief ESP Modem DTE Default Configuration

View File

@ -0,0 +1,39 @@
//
// Created by david on 2/24/21.
//
#ifndef SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_CONFIG_H
#define SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_CONFIG_H
/**
* @brief Modem flow control type
*
*/
typedef enum {
ESP_MODEM_FLOW_CONTROL_NONE = 0,
ESP_MODEM_FLOW_CONTROL_SW,
ESP_MODEM_FLOW_CONTROL_HW
} esp_modem_flow_ctrl_t;
struct dte_config {
uart_port_t port_num; /*!< UART port number */
uart_word_length_t data_bits; /*!< Data bits of UART */
uart_stop_bits_t stop_bits; /*!< Stop bits of UART */
uart_parity_t parity; /*!< Parity type */
esp_modem_flow_ctrl_t flow_control; /*!< Flow control type */
int baud_rate; /*!< Communication baud rate */
int tx_io_num; /*!< TXD Pin Number */
int rx_io_num; /*!< RXD Pin Number */
int rts_io_num; /*!< RTS Pin Number */
int cts_io_num; /*!< CTS Pin Number */
int rx_buffer_size; /*!< UART RX Buffer Size */
int tx_buffer_size; /*!< UART TX Buffer Size */
int pattern_queue_size; /*!< UART Pattern Queue Size */
int event_queue_size; /*!< UART Event Queue Size */
uint32_t event_task_stack_size; /*!< UART Event Task Stack size */
int event_task_priority; /*!< UART Event Task Priority */
int line_buffer_size; /*!< Line buffer size for command mode */
};
#endif //SIMPLE_CXX_CLIENT_ESP_MODEM_DTE_CONFIG_H