Reworded DCE/DTE modes and switching

This commit is contained in:
David Cermak
2021-03-03 20:35:08 +01:00
parent 00662fcaea
commit 25f5541199
20 changed files with 677 additions and 408 deletions

View File

@ -0,0 +1,14 @@
#pragma once
#include <memory>
#include "cxx_include/esp_modem_dce.hpp"
#include "cxx_include/esp_modem_device_factory.hpp"
class DTE;
struct dte_config;
typedef struct esp_netif_obj esp_netif_t;
std::shared_ptr<DTE> create_uart_dte(const dte_config *config);
std::unique_ptr<DCE> create_dce(const std::shared_ptr<DTE>& dte, const std::shared_ptr<DeviceIf>& dev, esp_netif_t *netif);

View File

@ -5,12 +5,81 @@
#ifndef SIMPLE_CXX_CLIENT_ESP_MODEM_COMMANDS_HPP
#define SIMPLE_CXX_CLIENT_ESP_MODEM_COMMANDS_HPP
#include "esp_err.h"
#include "esp_modem_dte.hpp"
//#include "esp_modem_dce_commands.hpp"
enum class command_result;
struct PdpContext {
PdpContext(std::string& apn): context_id(1), protocol_type("IP"), apn(apn) {}
size_t context_id;
std::string protocol_type;
std::string apn;
};
#include <iostream>
namespace esp_modem {
namespace dce_commands {
template <typename T> esp_err_t sync(T t);
template <typename T> static inline command_result generic_command(T t, const std::string& command,
const std::string& pass_phrase,
const std::string& fail_phrase, uint32_t timeout_ms)
{
std::cout << command << std::endl;
return t->command(command.c_str(), [&](uint8_t *data, size_t len) {
std::string response((char*)data, len);
std::cout << response << std::endl;
if (response.find(pass_phrase) != std::string::npos) {
return command_result::OK;
} else if (response.find(fail_phrase) != std::string::npos) {
return command_result::FAIL;
}
return command_result::TIMEOUT;
}, timeout_ms);
}
template <typename T> static inline command_result generic_command_common(T t, std::string command)
{
return generic_command(t, command, "OK", "ERROR", 500);
}
template <typename T> command_result sync(T t)
{
return generic_command_common(t, "AT\r");
}
template <typename T> command_result set_echo(T t, bool on)
{
if (on)
return generic_command_common(t, "ATE1\r");
return generic_command_common(t, "ATE0\r");
}
template <typename T> command_result set_pdp_context(T t, PdpContext& pdp)
{
std::string pdp_command = "AT+CGDCONT=" + std::to_string(pdp.context_id) +
",\"" + pdp.protocol_type + "\",\"" + pdp.apn + "\"\r";
return generic_command_common(t, pdp_command);
}
template <typename T> command_result set_data_mode(T t)
{
return generic_command(t, "ATD*99##\r", "CONNECT", "ERROR", 5000);
}
template <typename T> command_result resume_data_mode(T t)
{
return generic_command(t, "ATO\r", "CONNECT", "ERROR", 5000);
}
template <typename T> command_result set_command_mode(T t)
{
return generic_command(t, "+++", "OK", "ERROR", 50000);
}
} // dce_commands
} // esp_modem

View File

@ -0,0 +1,32 @@
#pragma once
#include "cxx_include/esp_modem_dce_commands_if.hpp"
class DCE {
public:
explicit DCE(const std::shared_ptr<DTE>& d, std::shared_ptr<DeviceIf> device, esp_netif_t * netif);
void set_data() {
// command("AT+CGDCONT=1,\"IP\",\"internet\"\r", [&](uint8_t *data, size_t len) {
// return command_result::OK;
// }, 1000);
// command("ATD*99***1#\r", [&](uint8_t *data, size_t len) {
// return command_result::OK;
// }, 1000);
device->setup_data_mode();
device->set_mode(dte_mode::DATA_MODE);
dce_dte->set_mode(dte_mode::DATA_MODE);
ppp_netif.start();
}
void exit_data() {
ppp_netif.stop();
device->set_mode(dte_mode::COMMAND_MODE);
ppp_netif.wait_until_ppp_exits();
dce_dte->set_mode(dte_mode::COMMAND_MODE);
}
command_result command(const std::string& command, got_line_cb got_line, uint32_t time_ms) {
return dce_dte->command(command, got_line, time_ms);
}
private:
std::shared_ptr<DTE> dce_dte;
std::shared_ptr<DeviceIf> device;
ppp ppp_netif;
};

View File

@ -0,0 +1,28 @@
#pragma once
#include "cxx_include/esp_modem_dce_commands_if.hpp"
#include "cxx_include/esp_modem_commands.hpp"
#include <memory>
#include <utility>
enum class command_result;
class DTE;
class Device: public DeviceIf {
public:
explicit Device(std::shared_ptr<DTE> dte, std::unique_ptr<PdpContext> pdp):
dte(std::move(dte)), pdp(std::move(pdp)) {}
bool setup_data_mode() override;
bool set_mode(dte_mode mode) override;
command_result set_echo(bool on) { return esp_modem::dce_commands::set_echo(dte, on); }
command_result set_data_mode() { return esp_modem::dce_commands::set_data_mode(dte); }
command_result resume_data_mode() { return esp_modem::dce_commands::resume_data_mode(dte); }
command_result set_pdp_context(PdpContext& pdp_context) { return esp_modem::dce_commands::set_pdp_context(dte.get(), pdp_context); }
command_result set_command_mode() { return esp_modem::dce_commands::set_command_mode(dte); }
private:
std::shared_ptr<DTE> dte;
std::unique_ptr<PdpContext> pdp;
};

View File

@ -0,0 +1,9 @@
#pragma once
enum class dte_mode;
class DeviceIf {
public:
virtual bool setup_data_mode() = 0;
virtual bool set_mode(dte_mode mode) = 0;
};

View File

@ -0,0 +1,3 @@
#pragma once
std::shared_ptr<DeviceIf> create_device(const std::shared_ptr<DTE>& dte, std::string &apn);

View File

@ -51,19 +51,21 @@ enum class dte_mode {
DATA_MODE
};
const int DTE_BUFFER_SIZE = 1024;
struct dte_data {
uint8_t *data;
size_t len;
enum class command_result {
OK,
FAIL,
TIMEOUT
};
typedef std::function<bool(uint8_t *data, size_t len)> got_line_cb;
const int DTE_BUFFER_SIZE = 1024;
class dte {
typedef std::function<command_result(uint8_t *data, size_t len)> got_line_cb;
class DTE {
public:
explicit dte(std::unique_ptr<terminal> t);
~dte() = default;
explicit DTE(std::unique_ptr<terminal> t);
~DTE() = default;
// void set_line_cb(got_line f) { on_line_cb = std::move(f); }
int write(uint8_t *data, size_t len) { return term->write(data, len); }
int read(uint8_t **d, size_t len) {
@ -83,7 +85,7 @@ public:
term->set_data_cb(on_data);
}
}
bool send_command(const std::string& command, got_line_cb got_line, uint32_t time_ms);
command_result command(const std::string& command, got_line_cb got_line, uint32_t time_ms);
private:
const size_t GOT_LINE = BIT0;
@ -98,27 +100,7 @@ private:
};
class dce {
public:
explicit dce(std::shared_ptr<dte> d, esp_netif_t * netif);
void set_data() {
command("AT+CGDCONT=1,\"IP\",\"internet\"\r", [&](uint8_t *data, size_t len) {
return true;
}, 1000);
command("ATD*99***1#\r", [&](uint8_t *data, size_t len) {
return true;
}, 1000);
dce_dte->set_mode(dte_mode::DATA_MODE);
ppp_netif.start();
}
bool command(const std::string& command, got_line_cb got_line, uint32_t time_ms) {
return dce_dte->send_command(command, got_line, time_ms);
}
private:
std::shared_ptr<dte> dce_dte;
ppp ppp_netif;
};

View File

@ -0,0 +1,10 @@
//
// Created by david on 3/3/21.
//
#ifndef SIMPLE_CXX_CLIENT_ESP_MODEM_UART_TERMINAL_HPP
#define SIMPLE_CXX_CLIENT_ESP_MODEM_UART_TERMINAL_HPP
#endif //SIMPLE_CXX_CLIENT_ESP_MODEM_UART_TERMINAL_HPP

View File

@ -6,26 +6,33 @@
#define SIMPLE_CXX_CLIENT_PPP_NETIF_HPP
#include "esp_netif.h"
#include "cxx_include/terminal_objects.hpp"
class dte;
class DTE;
//struct ppp_netif_driver;
struct ppp_netif_driver {
esp_netif_driver_base_t base;
dte *e;
DTE *e;
};
class ppp {
public:
explicit ppp(std::shared_ptr<dte> e, esp_netif_t *netif);
explicit ppp(std::shared_ptr<DTE> e, esp_netif_t *netif);
void start();
void notify_ppp_exit() { signal.set(PPP_EXIT); }
void wait_until_ppp_exits() { signal.wait(PPP_EXIT, 50000); }
void stop();
private:
void receive(uint8_t *data, size_t len) const;
std::shared_ptr<dte> ppp_dte;
std::shared_ptr<DTE> ppp_dte;
esp_netif_t *netif;
struct ppp_netif_driver driver;
signal_group signal;
const size_t PPP_EXIT = BIT0;
};

View File

@ -6,15 +6,12 @@
#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;
struct dte_config;
std::shared_ptr<dte> create_dte(const struct dte_config *config);
std::unique_ptr<terminal> create_uart_terminal(const dte_config *config);
std::unique_ptr<dce> create_dce(const std::shared_ptr<dte>& e, esp_netif_t *netif);
#endif //SIMPLE_CXX_CLIENT_UART_TERMINAL_HPP