Applied astyle code formatting

This commit is contained in:
David Cermak
2021-06-01 10:21:51 +02:00
parent dc64f862c4
commit a61e9e2d40
43 changed files with 865 additions and 662 deletions

View File

@ -30,42 +30,49 @@ struct PdpContext;
static const char *TAG = "modem_api";
#endif
std::shared_ptr<DTE> create_uart_dte(const dte_config *config) {
std::shared_ptr<DTE> create_uart_dte(const dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = create_uart_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
auto term = create_uart_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
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(
auto term = create_vfs_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
auto term = create_vfs_terminal(config);
return std::make_shared<DTE>(config, std::move(term));
)
}
static inline std::unique_ptr<DCE>
create_modem_dce(dce_factory::ModemType m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
create_modem_dce(dce_factory::ModemType m, const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
dce_factory::Factory f(m);
TRY_CATCH_RET_NULL(
return f.build_unique(config, std::move(dte), netif);
return f.build_unique(config, std::move(dte), netif);
)
}
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
std::unique_ptr<DCE> create_SIM7600_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM7600, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
std::unique_ptr<DCE> create_SIM800_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::SIM800, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
std::unique_ptr<DCE> create_BG96_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::BG96, config, std::move(dte), netif);
}
std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif) {
std::unique_ptr<DCE> create_generic_dce(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
{
return create_modem_dce(dce_factory::ModemType::GenericModule, config, std::move(dte), netif);
}

View File

@ -27,22 +27,21 @@
// C API definitions
using namespace esp_modem;
struct esp_modem_dce_wrap // need to mimic the polymorphic dispatch as CPP uses templated dispatch
{
struct esp_modem_dce_wrap { // need to mimic the polymorphic dispatch as CPP uses templated dispatch
enum class modem_wrap_dte_type { UART, } dte_type;
dce_factory::ModemType modem_type;
DCE* dce;
DCE *dce;
};
static inline esp_err_t command_response_to_esp_err(command_result res)
{
switch (res) {
case command_result::OK:
return ESP_OK;
case command_result::FAIL:
return ESP_FAIL;
case command_result::TIMEOUT:
return ESP_ERR_TIMEOUT;
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;
}
@ -50,23 +49,24 @@ static inline esp_err_t command_response_to_esp_err(command_result res)
static inline dce_factory::ModemType convert_modem_enum(esp_modem_dce_device_t module)
{
switch (module) {
case ESP_MODEM_DCE_SIM7600:
return esp_modem::dce_factory::ModemType::SIM7600;
case ESP_MODEM_DCE_BG96:
return esp_modem::dce_factory::ModemType::BG96;
case ESP_MODEM_DCE_SIM800:
return esp_modem::dce_factory::ModemType::SIM800;
default:
case ESP_MODEM_DCE_GENETIC:
return esp_modem::dce_factory::ModemType::GenericModule;
case ESP_MODEM_DCE_SIM7600:
return esp_modem::dce_factory::ModemType::SIM7600;
case ESP_MODEM_DCE_BG96:
return esp_modem::dce_factory::ModemType::BG96;
case ESP_MODEM_DCE_SIM800:
return esp_modem::dce_factory::ModemType::SIM800;
default:
case ESP_MODEM_DCE_GENETIC:
return esp_modem::dce_factory::ModemType::GenericModule;
}
}
extern "C" esp_modem_dce_t *esp_modem_new_dev(esp_modem_dce_device_t module, const esp_modem_dte_config_t *dte_config, const esp_modem_dce_config_t *dce_config, esp_netif_t *netif)
{
auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap;
if (dce_wrap == nullptr)
if (dce_wrap == nullptr) {
return nullptr;
}
auto dte = create_uart_dte(dte_config);
if (dte == nullptr) {
delete dce_wrap;
@ -88,7 +88,7 @@ extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *dte_conf
return esp_modem_new_dev(ESP_MODEM_DCE_GENETIC, dte_config, dce_config, netif);
}
extern "C" void esp_modem_destroy(esp_modem_dce_t * dce_wrap)
extern "C" void esp_modem_destroy(esp_modem_dce_t *dce_wrap)
{
if (dce_wrap) {
delete dce_wrap->dce;
@ -96,10 +96,11 @@ extern "C" void esp_modem_destroy(esp_modem_dce_t * dce_wrap)
}
}
extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce_wrap, esp_modem_dce_mode_t mode)
extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t *dce_wrap, esp_modem_dce_mode_t mode)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
if (mode == ESP_MODEM_MODE_DATA) {
dce_wrap->dce->set_data();
} else if (mode == ESP_MODEM_MODE_COMMAND) {
@ -110,58 +111,65 @@ extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce_wrap, esp_modem_dc
return ESP_OK;
}
extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t * dce_wrap, bool *pin)
extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t *dce_wrap, bool *pin)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->read_pin(*pin));
}
extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t * dce_wrap, bool txt)
extern "C" esp_err_t esp_modem_sms_txt_mode(esp_modem_dce_t *dce_wrap, bool txt)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->sms_txt_mode(txt));
}
extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t * dce_wrap, const char * number, const char * message)
extern "C" esp_err_t esp_modem_send_sms(esp_modem_dce_t *dce_wrap, const char *number, const char *message)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
std::string number_str(number);
std::string message_str(message);
return command_response_to_esp_err(dce_wrap->dce->send_sms(number_str, message_str));
}
extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t * dce_wrap)
extern "C" esp_err_t esp_modem_sms_character_set(esp_modem_dce_t *dce_wrap)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->sms_character_set());
}
extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t * dce_wrap, const char *pin)
extern "C" esp_err_t esp_modem_set_pin(esp_modem_dce_t *dce_wrap, const char *pin)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
std::string pin_str(pin);
return command_response_to_esp_err(dce_wrap->dce->set_pin(pin_str));
}
extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t * dce_wrap, int *rssi, int *ber)
extern "C" esp_err_t esp_modem_get_signal_quality(esp_modem_dce_t *dce_wrap, int *rssi, int *ber)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
return command_response_to_esp_err(dce_wrap->dce->get_signal_quality(*rssi, *ber));
}
extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t * dce_wrap, char *p_imsi)
extern "C" esp_err_t esp_modem_get_imsi(esp_modem_dce_t *dce_wrap, char *p_imsi)
{
if (dce_wrap == nullptr || dce_wrap->dce == nullptr)
if (dce_wrap == nullptr || dce_wrap->dce == nullptr) {
return ESP_ERR_INVALID_ARG;
}
std::string imsi;
auto ret = command_response_to_esp_err(dce_wrap->dce->get_imsi(imsi));
if (ret == ESP_OK && !imsi.empty()) {

View File

@ -139,114 +139,114 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
#endif
}
ESP_LOG_BUFFER_HEXDUMP("CMUX Received", data, actual_len, ESP_LOG_DEBUG);
uint8_t* frame = data;
uint8_t* recover_ptr;
uint8_t *frame = data;
uint8_t *recover_ptr;
auto available_len = actual_len;
size_t payload_offset = 0;
size_t footer_offset = 0;
while (available_len > 0) {
switch (state) {
case cmux_state::RECOVER:
if (frame[0] == SOF_MARKER) {
// already init state
state = cmux_state::INIT;
break;
}
recover_ptr = static_cast<uint8_t*>(memchr(frame, SOF_MARKER, available_len));
if (recover_ptr && available_len > recover_ptr - frame) {
available_len -= (recover_ptr - frame);
frame = recover_ptr;
state = cmux_state::INIT;
ESP_LOGI("CMUX", "Protocol recovered");
if (available_len > 1 && frame[1] == SOF_MARKER) {
// empty frame
available_len -= 1;
frame += 1;
}
break;
}
// marker not found, continue with recovery
return false;
case cmux_state::INIT:
if (frame[0] != SOF_MARKER) {
ESP_LOGW("CMUX", "Protocol mismatch: Missed leading SOF, recovering...");
state = cmux_state::RECOVER;
break;
}
case cmux_state::RECOVER:
if (frame[0] == SOF_MARKER) {
// already init state
state = cmux_state::INIT;
break;
}
recover_ptr = static_cast<uint8_t *>(memchr(frame, SOF_MARKER, available_len));
if (recover_ptr && available_len > recover_ptr - frame) {
available_len -= (recover_ptr - frame);
frame = recover_ptr;
state = cmux_state::INIT;
ESP_LOGI("CMUX", "Protocol recovered");
if (available_len > 1 && frame[1] == SOF_MARKER) {
// empty frame
available_len -= 1;
frame += 1;
break;
}
state = cmux_state::HEADER;
break;
}
// marker not found, continue with recovery
return false;
case cmux_state::INIT:
if (frame[0] != SOF_MARKER) {
ESP_LOGW("CMUX", "Protocol mismatch: Missed leading SOF, recovering...");
state = cmux_state::RECOVER;
break;
}
if (available_len > 1 && frame[1] == SOF_MARKER) {
// empty frame
available_len -= 1;
frame += 1;
break;
}
state = cmux_state::HEADER;
available_len--;
frame_header_offset = 1;
frame++;
break;
case cmux_state::HEADER:
if (available_len > 0 && frame_header_offset == 1 && frame[0] == SOF_MARKER) {
// Previously trailing SOF interpreted as heading SOF, remove it and restart HEADER
available_len--;
frame_header_offset = 1;
frame++;
break;
case cmux_state::HEADER:
if (available_len > 0 && frame_header_offset == 1 && frame[0] == SOF_MARKER) {
// Previously trailing SOF interpreted as heading SOF, remove it and restart HEADER
available_len--;
frame++;
break;
}
if (available_len + frame_header_offset < 4) {
memcpy(frame_header + frame_header_offset, frame, available_len);
frame_header_offset += available_len;
return false; // need read more
}
payload_offset = std::min(available_len, 4 - frame_header_offset);
memcpy(frame_header + frame_header_offset, frame, payload_offset);
frame_header_offset += payload_offset;
dlci = frame_header[1] >> 2;
type = frame_header[2];
payload_len = (frame_header[3] >> 1);
frame += payload_offset;
available_len -= payload_offset;
}
if (available_len + frame_header_offset < 4) {
memcpy(frame_header + frame_header_offset, frame, available_len);
frame_header_offset += available_len;
return false; // need read more
}
payload_offset = std::min(available_len, 4 - frame_header_offset);
memcpy(frame_header + frame_header_offset, frame, payload_offset);
frame_header_offset += payload_offset;
dlci = frame_header[1] >> 2;
type = frame_header[2];
payload_len = (frame_header[3] >> 1);
frame += payload_offset;
available_len -= payload_offset;
state = cmux_state::PAYLOAD;
break;
case cmux_state::PAYLOAD:
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
state = cmux_state::PAYLOAD;
break;
case cmux_state::PAYLOAD:
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
state = cmux_state::PAYLOAD;
data_available(frame, available_len); // partial read
payload_len -= available_len;
return false;
} else { // complete
if (payload_len > 0) {
data_available(&frame[0], payload_len); // rest read
}
available_len -= payload_len;
frame += payload_len;
state = cmux_state::FOOTER;
payload_len = 0;
data_available(frame, available_len); // partial read
payload_len -= available_len;
return false;
} else { // complete
if (payload_len > 0) {
data_available(&frame[0], payload_len); // rest read
}
break;
case cmux_state::FOOTER:
if (available_len + frame_header_offset < 6) {
memcpy(frame_header + frame_header_offset, frame, available_len);
frame_header_offset += available_len;
return false; // need read more
} else {
footer_offset = std::min(available_len, 6 - frame_header_offset);
memcpy(frame_header + frame_header_offset, frame, footer_offset);
if (frame_header[5] != SOF_MARKER) {
ESP_LOGW("CMUX", "Protocol mismatch: Missed trailing SOF, recovering...");
payload_start = nullptr;
total_payload_size = 0;
state = cmux_state::RECOVER;
break;
}
frame += footer_offset;
available_len -= footer_offset;
state = cmux_state::INIT;
frame_header_offset = 0;
data_available(nullptr, 0);
available_len -= payload_len;
frame += payload_len;
state = cmux_state::FOOTER;
payload_len = 0;
}
break;
case cmux_state::FOOTER:
if (available_len + frame_header_offset < 6) {
memcpy(frame_header + frame_header_offset, frame, available_len);
frame_header_offset += available_len;
return false; // need read more
} else {
footer_offset = std::min(available_len, 6 - frame_header_offset);
memcpy(frame_header + frame_header_offset, frame, footer_offset);
if (frame_header[5] != SOF_MARKER) {
ESP_LOGW("CMUX", "Protocol mismatch: Missed trailing SOF, recovering...");
payload_start = nullptr;
total_payload_size = 0;
state = cmux_state::RECOVER;
break;
}
break;
frame += footer_offset;
available_len -= footer_offset;
state = cmux_state::INIT;
frame_header_offset = 0;
data_available(nullptr, 0);
payload_start = nullptr;
total_payload_size = 0;
}
break;
}
}
return true;
@ -262,8 +262,7 @@ bool CMux::init()
});
sabm_ack = -1;
for (size_t i = 0; i < 3; i++)
{
for (size_t i = 0; i < 3; i++) {
int timeout = 0;
send_sabm(i);
while (true) {
@ -273,8 +272,9 @@ bool CMux::init()
sabm_ack = -1;
break;
}
if (timeout++ > 100)
if (timeout++ > 100) {
return false;
}
}
}
return true;
@ -288,8 +288,9 @@ int CMux::write(int virtual_term, uint8_t *data, size_t len)
size_t need_write = len;
while (need_write > 0) {
size_t batch_len = need_write;
if (batch_len > cmux_max_len)
if (batch_len > cmux_max_len) {
batch_len = cmux_max_len;
}
uint8_t frame[6];
frame[0] = SOF_MARKER;
frame[1] = (i << 2) + 1;
@ -303,14 +304,16 @@ int CMux::write(int virtual_term, uint8_t *data, size_t len)
term->write(frame + 4, 2);
ESP_LOG_BUFFER_HEXDUMP("Send", frame, 4, ESP_LOG_VERBOSE);
ESP_LOG_BUFFER_HEXDUMP("Send", data, batch_len, ESP_LOG_VERBOSE);
ESP_LOG_BUFFER_HEXDUMP("Send", frame+4, 2, ESP_LOG_VERBOSE);
ESP_LOG_BUFFER_HEXDUMP("Send", frame + 4, 2, ESP_LOG_VERBOSE);
need_write -= batch_len;
data += batch_len;
}
return len;
}
void CMux::set_read_cb(int inst, std::function<bool(uint8_t *, size_t)> f) {
if (inst < max_terms)
void CMux::set_read_cb(int inst, std::function<bool(uint8_t *, size_t)> f)
{
if (inst < max_terms) {
read_cb[inst] = std::move(f);
}
}

View File

@ -23,49 +23,53 @@ namespace esp_modem::dce_commands {
static const char *TAG = "command_lib";
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, const std::string &command,
const std::list<std::string_view> &pass_phrase,
const std::list<std::string_view> &fail_phrase,
uint32_t timeout_ms)
{
ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str());
return t->command(command, [&](uint8_t *data, size_t len) {
std::string_view response((char*)data, len);
if (data == nullptr || len == 0 || response.empty())
std::string_view response((char *)data, len);
if (data == nullptr || len == 0 || response.empty()) {
return command_result::TIMEOUT;
}
ESP_LOGD(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;
}
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::TIMEOUT;
}, timeout_ms);
}
static inline command_result generic_command(CommandableIf* t, const std::string& command,
const std::string& pass_phrase,
const std::string& fail_phrase, uint32_t timeout_ms)
static inline command_result generic_command(CommandableIf *t, const std::string &command,
const std::string &pass_phrase,
const std::string &fail_phrase, uint32_t timeout_ms)
{
ESP_LOGV(TAG,"%s", __func__ );
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});
return generic_command(t, command, pass, fail, timeout_ms);
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
return t->command(command, [&](uint8_t *data, size_t len) {
size_t pos = 0;
std::string_view response((char*)data, len);
std::string_view response((char *)data, len);
while ((pos = response.find('\n')) != std::string::npos) {
std::string_view token = response.substr(0, pos);
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);
}
ESP_LOGV(TAG, "Token: {%.*s}\n", static_cast<int>(token.size()), token.data());
if (token.find("OK") != std::string::npos) {
@ -75,147 +79,157 @@ static inline command_result generic_get_string(CommandableIf* t, const std::str
} else if (token.size() > 2) {
output = token;
}
response = response.substr(pos+1);
response = response.substr(pos + 1);
}
return command_result::TIMEOUT;
}, timeout_ms);
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, command, out, timeout_ms);
if (ret == command_result::OK)
if (ret == command_result::OK) {
output = out;
}
return ret;
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
return generic_command(t, command, "OK", "ERROR", timeout);
}
command_result sync(CommandableIf* t)
command_result sync(CommandableIf *t)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
return generic_command_common(t, "AT\r");
}
command_result store_profile(CommandableIf* t)
command_result store_profile(CommandableIf *t)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, "AT+CBC\r", out);
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
}
constexpr std::string_view pattern = "+CBC: ";
if (out.find(pattern) == std::string_view::npos)
if (out.find(pattern) == std::string_view::npos) {
return command_result::FAIL;
}
// Parsing +CBC: <bcs>,<bcl>,<voltage>
out = out.substr(pattern.size());
int pos, value, property = 0;
while ((pos = out.find(',') != std::string::npos)) {
if (std::from_chars(out.data(), out.data() + pos, value).ec == std::errc::invalid_argument)
if (std::from_chars(out.data(), out.data() + pos, value).ec == std::errc::invalid_argument) {
return command_result::FAIL;
}
switch (property++) {
case 0: bcs = value;
break;
case 1: bcl = value;
break;
default:
return command_result::FAIL;
case 0: bcs = value;
break;
case 1: bcl = value;
break;
default:
return command_result::FAIL;
}
out = out.substr(pos + 1);
}
if (std::from_chars(out.data(), out.data() + out.size(), voltage).ec == std::errc::invalid_argument)
if (std::from_chars(out.data(), out.data() + out.size(), voltage).ec == std::errc::invalid_argument) {
return command_result::FAIL;
}
return command_result::OK;
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, "AT+CBC\r", out);
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
}
// Parsing +CBC: <voltage in Volts> V
constexpr std::string_view pattern = "+CBC: ";
constexpr int num_pos = pattern.size();
int dot_pos;
if (out.find(pattern) == std::string::npos ||
(dot_pos = out.find('.')) == std::string::npos)
(dot_pos = out.find('.')) == std::string::npos) {
return command_result::FAIL;
}
int volt, fraction;
if (std::from_chars(out.data() + num_pos, out.data() + dot_pos, volt).ec == std::errc::invalid_argument)
if (std::from_chars(out.data() + num_pos, out.data() + dot_pos, volt).ec == std::errc::invalid_argument) {
return command_result::FAIL;
if (std::from_chars(out.data() + dot_pos + 1, out.data() + out.size() - 1, fraction).ec == std::errc::invalid_argument)
}
if (std::from_chars(out.data() + dot_pos + 1, out.data() + out.size() - 1, fraction).ec == std::errc::invalid_argument) {
return command_result::FAIL;
}
bcl = bcs = -1; // not available for these models
voltage = 1000*volt + fraction;
voltage = 1000 * volt + fraction;
return command_result::OK;
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, "AT+COPS?\r", out, 75000);
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
}
auto pos = out.find("+COPS");
auto property = 0;
while (pos != std::string::npos) {
@ -229,113 +243,118 @@ command_result get_operator_name(CommandableIf* t, std::string& operator_name)
return command_result::FAIL;
}
command_result set_echo(CommandableIf* t, bool on)
command_result set_echo(CommandableIf *t, bool on)
{
ESP_LOGV(TAG,"%s", __func__ );
if (on)
ESP_LOGV(TAG, "%s", __func__ );
if (on) {
return generic_command_common(t, "ATE1\r");
}
return generic_command_common(t, "ATE0\r");
}
command_result set_pdp_context(CommandableIf* t, PdpContext& pdp)
command_result set_pdp_context(CommandableIf *t, PdpContext &pdp)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
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);
}
command_result set_data_mode(CommandableIf* t)
command_result set_data_mode(CommandableIf *t)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
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"});
return generic_command(t, "+++", pass, fail, 5000);
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
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)
return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default)
ESP_LOGV(TAG, "%s", __func__ );
if (txt) {
return generic_command_common(t, "AT+CMGF=1\r"); // Text mode (default)
}
return generic_command_common(t, "AT+CMGF=0\r"); // PDU mode
}
command_result sms_character_set(CommandableIf* t)
command_result sms_character_set(CommandableIf *t)
{
// Sets the default GSM character set
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
auto ret = t->command("AT+CMGS=\"" + number + "\"\r", [&](uint8_t *data, size_t len) {
std::string_view response((char*)data, len);
ESP_LOGD(TAG,"Send SMS response %.*s", static_cast<int>(response.size()), response.data());
std::string_view response((char *)data, len);
ESP_LOGD(TAG, "Send SMS response %.*s", static_cast<int>(response.size()), response.data());
if (response.find('>') != std::string::npos) {
return command_result::OK;
}
return command_result::TIMEOUT;
}, 5000, ' ');
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
return generic_command_common(t, message +"\x1A", 120000);
}
return generic_command_common(t, message + "\x1A", 120000);
}
command_result set_cmux(CommandableIf* t)
command_result set_cmux(CommandableIf *t)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, "AT+CPIN?\r", out);
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
if (out.find("+CPIN:") == std::string::npos)
}
if (out.find("+CPIN:") == std::string::npos) {
return command_result::FAIL;
}
if (out.find("SIM PIN") != std::string::npos || out.find("SIM PUK") != std::string::npos) {
pin_ok = false;
return command_result::OK;
@ -347,32 +366,36 @@ command_result read_pin(CommandableIf* t, bool& pin_ok)
return command_result::FAIL; // Neither pin-ok, nor waiting for pin/puk -> mark as error
}
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__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string set_pin_command = "AT+CPIN=" + pin + "\r";
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)
{
ESP_LOGV(TAG,"%s", __func__ );
ESP_LOGV(TAG, "%s", __func__ );
std::string_view out;
auto ret = generic_get_string(t, "AT+CSQ\r", out);
if (ret != command_result::OK)
if (ret != command_result::OK) {
return ret;
}
constexpr std::string_view pattern = "+CSQ: ";
constexpr int rssi_pos = pattern.size();
int ber_pos;
if (out.find(pattern) == std::string::npos ||
(ber_pos = out.find(',')) == std::string::npos)
(ber_pos = out.find(',')) == std::string::npos) {
return command_result::FAIL;
}
if (std::from_chars(out.data() + rssi_pos, out.data() + ber_pos, rssi).ec == std::errc::invalid_argument)
if (std::from_chars(out.data() + rssi_pos, out.data() + ber_pos, rssi).ec == std::errc::invalid_argument) {
return command_result::FAIL;
if (std::from_chars(out.data() + ber_pos + 1, out.data() + out.size(), ber).ec == std::errc::invalid_argument)
}
if (std::from_chars(out.data() + ber_pos + 1, out.data() + out.size(), ber).ec == std::errc::invalid_argument) {
return command_result::FAIL;
}
return command_result::OK;
}

View File

@ -22,44 +22,53 @@ namespace esp_modem {
bool DCE_Mode::set(DTE *dte, ModuleIf *device, Netif &netif, modem_mode m)
{
switch (m) {
case modem_mode::UNDEF:
break;
case modem_mode::COMMAND_MODE:
if (mode == modem_mode::COMMAND_MODE)
return false;
netif.stop();
if (!device->set_mode(modem_mode::COMMAND_MODE))
return false;
dte->set_read_cb([&](uint8_t *data, size_t len) -> bool {
ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_INFO);
return false;
});
netif.wait_until_ppp_exits();
dte->set_read_cb(nullptr);
if (!dte->set_mode(modem_mode::COMMAND_MODE))
return false;
mode = m;
return true;
case modem_mode::DATA_MODE:
if (mode == modem_mode::DATA_MODE)
return false;
if (!device->setup_data_mode())
return false;
if (!device->set_mode(modem_mode::DATA_MODE))
return false;
if (!dte->set_mode(modem_mode::DATA_MODE))
return false;
netif.start();
mode = m;
return true;
case modem_mode::CMUX_MODE:
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE)
return false;
device->set_mode(modem_mode::CMUX_MODE);
if (!dte->set_mode(modem_mode::CMUX_MODE))
return false;
mode = modem_mode::COMMAND_MODE;
return true;
case modem_mode::UNDEF:
break;
case modem_mode::COMMAND_MODE:
if (mode == modem_mode::COMMAND_MODE) {
return false;
}
netif.stop();
if (!device->set_mode(modem_mode::COMMAND_MODE)) {
return false;
}
dte->set_read_cb([&](uint8_t *data, size_t len) -> bool {
ESP_LOG_BUFFER_HEXDUMP("esp-modem: debug_data", data, len, ESP_LOG_INFO);
return false;
});
netif.wait_until_ppp_exits();
dte->set_read_cb(nullptr);
if (!dte->set_mode(modem_mode::COMMAND_MODE)) {
return false;
}
mode = m;
return true;
case modem_mode::DATA_MODE:
if (mode == modem_mode::DATA_MODE) {
return false;
}
if (!device->setup_data_mode()) {
return false;
}
if (!device->set_mode(modem_mode::DATA_MODE)) {
return false;
}
if (!dte->set_mode(modem_mode::DATA_MODE)) {
return false;
}
netif.start();
mode = m;
return true;
case modem_mode::CMUX_MODE:
if (mode == modem_mode::DATA_MODE || mode == modem_mode::CMUX_MODE) {
return false;
}
device->set_mode(modem_mode::CMUX_MODE);
if (!dte->set_mode(modem_mode::CMUX_MODE)) {
return false;
}
mode = modem_mode::COMMAND_MODE;
return true;
}
return false;
}

View File

@ -22,10 +22,10 @@ using namespace esp_modem;
static const size_t dte_default_buffer_size = 1000;
DTE::DTE(const esp_modem_dte_config *config, std::unique_ptr<Terminal> terminal):
buffer_size(config->dte_buffer_size), consumed(0),
buffer(std::make_unique<uint8_t[]>(buffer_size)),
term(std::move(terminal)), command_term(term.get()), other_term(nullptr),
mode(modem_mode::UNDEF) {}
buffer_size(config->dte_buffer_size), consumed(0),
buffer(std::make_unique<uint8_t[]>(buffer_size)),
term(std::move(terminal)), command_term(term.get()), other_term(nullptr),
mode(modem_mode::UNDEF) {}
DTE::DTE(std::unique_ptr<Terminal> terminal):
buffer_size(dte_default_buffer_size), consumed(0),
@ -72,17 +72,21 @@ command_result DTE::command(const std::string &cmd, got_line_cb got_line, uint32
bool DTE::setup_cmux()
{
auto original_term = std::move(term);
if (original_term == nullptr)
if (original_term == nullptr) {
return false;
}
auto cmux_term = std::make_shared<CMux>(std::move(original_term), std::move(buffer), buffer_size);
if (cmux_term == nullptr)
if (cmux_term == nullptr) {
return false;
}
buffer_size = 0;
if (!cmux_term->init())
if (!cmux_term->init()) {
return false;
}
term = std::make_unique<CMuxInstance>(cmux_term, 0);
if (term == nullptr)
if (term == nullptr) {
return false;
}
command_term = term.get(); // use command terminal as previously
other_term = std::make_unique<CMuxInstance>(cmux_term, 1);
return true;
@ -110,8 +114,9 @@ void DTE::set_read_cb(std::function<bool(uint8_t *, size_t)> f)
data = buffer.get();
len = term->read(buffer.get(), buffer_size);
}
if (on_data)
if (on_data) {
return on_data(data, len);
}
return false;
});
}

View File

@ -20,18 +20,18 @@
namespace esp_modem {
template<typename T>
std::shared_ptr<T> create_device(const std::shared_ptr<DTE>& dte, std::string &apn)
std::shared_ptr<T> create_device(const std::shared_ptr<DTE> &dte, std::string &apn)
{
auto pdp = std::make_unique<PdpContext>(apn);
return std::make_shared<T>(dte, std::move(pdp));
}
std::shared_ptr<GenericModule> create_generic_module(const std::shared_ptr<DTE>& dte, std::string &apn)
std::shared_ptr<GenericModule> create_generic_module(const std::shared_ptr<DTE> &dte, std::string &apn)
{
return create_device<GenericModule>(dte, apn);
}
std::shared_ptr<SIM7600> create_SIM7600_module(const std::shared_ptr<DTE>& dte, std::string &apn)
std::shared_ptr<SIM7600> create_SIM7600_module(const std::shared_ptr<DTE> &dte, std::string &apn)
{
return create_device<SIM7600>(dte, apn);
}
@ -42,7 +42,8 @@ std::shared_ptr<SIM7600> create_SIM7600_module(const std::shared_ptr<DTE>& dte,
#include "cxx_include/esp_modem_dce_factory.hpp"
namespace esp_modem::dce_factory {
std::unique_ptr<PdpContext> FactoryHelper::create_pdp_context(std::string &apn) {
std::unique_ptr<PdpContext> FactoryHelper::create_pdp_context(std::string &apn)
{
return std::unique_ptr<PdpContext>();
}

View File

@ -19,7 +19,7 @@
namespace esp_modem {
GenericModule::GenericModule(std::shared_ptr<DTE> dte, const dce_config *config) :
dte(std::move(dte)), pdp(std::make_unique<PdpContext>(config->apn)) {}
dte(std::move(dte)), pdp(std::make_unique<PdpContext>(config->apn)) {}
//
// Define preprocessor's forwarding to dce_commands definitions
@ -50,33 +50,40 @@ DECLARE_ALL_COMMAND_APIS(return_type name(...) )
//
// Handle specific commands for specific supported modems
//
command_result SIM7600::get_module_name(std::string &name) {
command_result SIM7600::get_module_name(std::string &name)
{
name = "7600";
return command_result::OK;
}
command_result SIM7600::get_battery_status(int& voltage, int &bcs, int &bcl) {
command_result SIM7600::get_battery_status(int &voltage, int &bcs, int &bcl)
{
return dce_commands::get_battery_status_sim7xxx(dte.get(), voltage, bcs, bcl);
}
command_result SIM7600::power_down() {
command_result SIM7600::power_down()
{
return dce_commands::power_down_sim7xxx(dte.get());
}
command_result SIM800::get_module_name(std::string &name) {
command_result SIM800::get_module_name(std::string &name)
{
name = "800L";
return command_result::OK;
}
command_result SIM800::power_down() {
command_result SIM800::power_down()
{
return dce_commands::power_down_sim8xx(dte.get());
}
command_result SIM800::set_data_mode() {
command_result SIM800::set_data_mode()
{
return dce_commands::set_data_mode_sim8xx(dte.get());
}
command_result BG96::get_module_name(std::string &name) {
command_result BG96::get_module_name(std::string &name)
{
name = "BG96";
return command_result::OK;
}

View File

@ -24,7 +24,8 @@
namespace esp_modem {
void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
int32_t event_id, void *event_data)
{
auto *ppp = static_cast<Netif *>(arg);
if (event_id < NETIF_PP_PHASE_OFFSET) {
ESP_LOGI("esp_modem_netif", "PPP state changed event %d", event_id);
@ -33,7 +34,8 @@ void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
}
}
esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len) {
esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
{
auto *ppp = static_cast<Netif *>(h);
if (ppp->signal.is_any(PPP_STARTED)) {
if (ppp->ppp_dte && ppp->ppp_dte->write((uint8_t *) buffer, len) > 0) {
@ -43,7 +45,8 @@ esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len) {
return ESP_FAIL;
}
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
auto d = (ppp_netif_driver *) args;
esp_netif_driver_ifconfig_t driver_ifconfig = {};
driver_ifconfig.transmit = Netif::esp_modem_dte_transmit;
@ -53,7 +56,8 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
// check if PPP error events are enabled, if not, do enable the error occurred/state changed
// to notify the modem layer when switching modes
esp_netif_ppp_config_t ppp_config = { .ppp_phase_event_enabled = true, // assuming phase enabled, as earlier IDFs
.ppp_error_event_enabled = false }; // don't provide cfg getters so we enable both events
.ppp_error_event_enabled = false
}; // don't provide cfg getters so we enable both events
#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 4
esp_netif_ppp_get_params(esp_netif, &ppp_config);
#endif // ESP-IDF >= v4.4
@ -65,25 +69,28 @@ esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
return ESP_OK;
}
void Netif::receive(uint8_t *data, size_t len) {
void Netif::receive(uint8_t *data, size_t len)
{
if (signal.is_any(PPP_STARTED)) {
esp_netif_receive(driver.base.netif, data, len, nullptr);
}
}
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
ppp_dte(std::move(e)), netif(ppp_netif) {
ppp_dte(std::move(e)), netif(ppp_netif)
{
driver.base.netif = ppp_netif;
driver.ppp = this;
driver.base.post_attach = esp_modem_post_attach;
throw_if_esp_fail(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, (void *) this));
throw_if_esp_fail(esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, ppp_netif));
throw_if_esp_fail(
esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected, ppp_netif));
esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected, ppp_netif));
throw_if_esp_fail(esp_netif_attach(ppp_netif, &driver));
}
void Netif::start() {
void Netif::start()
{
ppp_dte->set_read_cb([this](uint8_t *data, size_t len) -> bool {
receive(data, len);
return false;
@ -92,12 +99,14 @@ void Netif::start() {
signal.set(PPP_STARTED);
}
void Netif::stop() {
void Netif::stop()
{
esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr);
signal.clear(PPP_STARTED);
}
Netif::~Netif() {
Netif::~Netif()
{
if (signal.is_any(PPP_STARTED)) {
esp_netif_action_stop(driver.base.netif, nullptr, 0, nullptr);
signal.clear(PPP_STARTED);
@ -108,7 +117,8 @@ Netif::~Netif() {
esp_event_handler_unregister(IP_EVENT, IP_EVENT_PPP_LOST_IP, esp_netif_action_disconnected);
}
void Netif::wait_until_ppp_exits() {
void Netif::wait_until_ppp_exits()
{
signal.wait(PPP_EXIT, 30000);
}

View File

@ -19,7 +19,8 @@
namespace esp_modem {
void Netif::on_ppp_changed(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
int32_t event_id, void *event_data)
{
}
esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
@ -29,7 +30,8 @@ esp_err_t Netif::esp_modem_dte_transmit(void *h, void *buffer, size_t len)
return len;
}
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args) {
esp_err_t Netif::esp_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
return ESP_OK;
}
@ -39,7 +41,7 @@ void Netif::receive(uint8_t *data, size_t len)
}
Netif::Netif(std::shared_ptr<DTE> e, esp_netif_t *ppp_netif) :
ppp_dte(std::move(e)), netif(ppp_netif) {}
ppp_dte(std::move(e)), netif(ppp_netif) {}
void Netif::start()
{
@ -48,7 +50,7 @@ void Netif::start()
return false;
});
netif->transmit = esp_modem_dte_transmit;
netif->ctx = (void*)this;
netif->ctx = (void *)this;
signal.set(PPP_STARTED);
}
@ -56,7 +58,8 @@ void Netif::stop() {}
Netif::~Netif() = default;
void Netif::wait_until_ppp_exits() {
void Netif::wait_until_ppp_exits()
{
}

View File

@ -20,7 +20,8 @@
namespace esp_modem {
void Lock::unlock() {
void Lock::unlock()
{
xSemaphoreGiveRecursive(m);
}
@ -30,11 +31,13 @@ Lock::Lock(): m(nullptr)
throw_if_false(m != nullptr, "create signal event group failed");
}
Lock::~Lock() {
Lock::~Lock()
{
vSemaphoreDelete(m);
}
void Lock::lock() {
void Lock::lock()
{
xSemaphoreTakeRecursive(m, portMAX_DELAY);
}
@ -74,12 +77,13 @@ bool SignalGroup::wait_any(uint32_t flags, uint32_t time_ms)
SignalGroup::~SignalGroup()
{
if (event_group)
if (event_group) {
vEventGroupDelete(event_group);
}
}
Task::Task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function)
:task_handle(nullptr)
: task_handle(nullptr)
{
BaseType_t ret = xTaskCreate(task_function, "vfs_task", stack_size, task_param, priority, &task_handle);
throw_if_false(ret == pdTRUE, "create vfs task failed");
@ -87,8 +91,9 @@ Task::Task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t
Task::~Task()
{
if (task_handle)
if (task_handle) {
vTaskDelete(task_handle);
}
}
void Task::Delete()

View File

@ -46,8 +46,9 @@ void SignalGroup::clear(uint32_t bits)
bool SignalGroup::wait(uint32_t flags, uint32_t time_ms)
{
std::unique_lock<std::mutex> lock(event_group->m);
return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&]{
if ((flags&event_group->flags) == flags) {
return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] {
if ((flags & event_group->flags) == flags)
{
event_group->flags &= ~flags;
return true;
}
@ -60,13 +61,13 @@ bool SignalGroup::wait(uint32_t flags, uint32_t time_ms)
bool SignalGroup::is_any(uint32_t flags)
{
std::unique_lock<std::mutex> lock(event_group->m);
return flags&event_group->flags;
return flags & event_group->flags;
}
bool SignalGroup::wait_any(uint32_t flags, uint32_t time_ms)
{
std::unique_lock<std::mutex> lock(event_group->m);
return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&]{ return flags&event_group->flags; });
return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] { return flags & event_group->flags; });
}
SignalGroup::~SignalGroup() = default;

View File

@ -29,7 +29,8 @@ struct File {
fd(config->vfs_config.fd), deleter(config->vfs_config.deleter), resource(config->vfs_config.resource)
{}
~File() {
~File()
{
if (deleter) {
deleter(fd, resource);
}
@ -45,11 +46,13 @@ public:
~FdTerminal() override;
void start() override {
void start() override
{
signal.set(TASK_START);
}
void stop() override {
void stop() override
{
signal.clear(TASK_START);
}
@ -57,7 +60,8 @@ public:
int read(uint8_t *data, size_t len) override;
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override
{
on_read = std::move(f);
signal.set(TASK_PARAMS);
}
@ -75,22 +79,24 @@ private:
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(
auto term = std::make_unique<FdTerminal>(config);
term->start();
return term;
auto term = std::make_unique<FdTerminal>(config);
term->start();
return term;
)
}
FdTerminal::FdTerminal(const esp_modem_dte_config *config) :
f(config), signal(),
task_handle(config->task_stack_size, config->task_priority, this, [](void* p){
auto t = static_cast<FdTerminal *>(p);
t->task();
Task::Delete();
})
{}
f(config), signal(),
task_handle(config->task_stack_size, config->task_priority, this, [](void *p)
{
auto t = static_cast<FdTerminal *>(p);
t->task();
Task::Delete();
})
{}
void FdTerminal::task()
{
@ -105,8 +111,8 @@ void FdTerminal::task()
int s;
fd_set rfds;
struct timeval tv = {
.tv_sec = 1,
.tv_usec = 0,
.tv_sec = 1,
.tv_usec = 0,
};
FD_ZERO(&rfds);
FD_SET(f.fd, &rfds);

View File

@ -25,8 +25,8 @@ uart_resource::~uart_resource()
}
}
uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t* event_queue, int fd)
:port(-1)
uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t *event_queue, int fd)
: port(-1)
{
esp_err_t res;
@ -37,7 +37,7 @@ uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHand
uart_config.parity = config->parity;
uart_config.stop_bits = config->stop_bits;
uart_config.flow_ctrl = (config->flow_control == ESP_MODEM_FLOW_CONTROL_HW) ? UART_HW_FLOWCTRL_CTS_RTS
: UART_HW_FLOWCTRL_DISABLE;
: UART_HW_FLOWCTRL_DISABLE;
uart_config.source_clk = UART_SCLK_APB;
throw_if_esp_fail(uart_param_config(config->port_num, &uart_config), "config uart parameter failed");

View File

@ -30,13 +30,17 @@ namespace esp_modem {
struct uart_task {
explicit uart_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) :
task_handle(nullptr) {
task_handle(nullptr)
{
BaseType_t ret = xTaskCreate(task_function, "uart_task", stack_size, task_param, priority, &task_handle);
throw_if_false(ret == pdTRUE, "create uart event task failed");
}
~uart_task() {
if (task_handle) vTaskDelete(task_handle);
~uart_task()
{
if (task_handle) {
vTaskDelete(task_handle);
}
}
TaskHandle_t task_handle; /*!< UART event task handle */
@ -47,16 +51,18 @@ struct uart_task {
class UartTerminal : public Terminal {
public:
explicit UartTerminal(const esp_modem_dte_config *config) :
event_queue(), uart(&config->uart_config, &event_queue, -1), signal(),
task_handle(config->task_stack_size, config->task_priority, this, s_task) {}
event_queue(), uart(&config->uart_config, &event_queue, -1), signal(),
task_handle(config->task_stack_size, config->task_priority, this, s_task) {}
~UartTerminal() override = default;
void start() override {
void start() override
{
signal.set(TASK_START);
}
void stop() override {
void stop() override
{
signal.set(TASK_STOP);
}
@ -64,24 +70,28 @@ public:
int read(uint8_t *data, size_t len) override;
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override {
void set_read_cb(std::function<bool(uint8_t *data, size_t len)> f) override
{
on_read = std::move(f);
signal.set(TASK_PARAMS);
}
private:
static void s_task(void *task_param) {
static void s_task(void *task_param)
{
auto t = static_cast<UartTerminal *>(task_param);
t->task();
vTaskDelete(nullptr);
}
void task();
bool get_event(uart_event_t &event, uint32_t time_ms) {
bool get_event(uart_event_t &event, uint32_t time_ms)
{
return xQueueReceive(event_queue, &event, pdMS_TO_TICKS(time_ms));
}
void reset_events() {
void reset_events()
{
uart_flush_input(uart.port);
xQueueReset(event_queue);
}
@ -97,15 +107,17 @@ private:
uart_task task_handle;
};
std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *config) {
std::unique_ptr<Terminal> create_uart_terminal(const esp_modem_dte_config *config)
{
TRY_CATCH_RET_NULL(
auto term = std::make_unique<UartTerminal>(config);
term->start();
return term;
auto term = std::make_unique<UartTerminal>(config);
term->start();
return term;
)
}
void UartTerminal::task() {
void UartTerminal::task()
{
std::function<bool(uint8_t *data, size_t len)> on_read_priv = nullptr;
uart_event_t event;
size_t len;
@ -121,44 +133,49 @@ void UartTerminal::task() {
signal.clear(TASK_PARAMS);
}
switch (event.type) {
case UART_DATA:
uart_get_buffered_data_len(uart.port, &len);
if (len && on_read_priv) {
if (on_read_priv(nullptr, len)) {
on_read_priv = nullptr;
}
case UART_DATA:
uart_get_buffered_data_len(uart.port, &len);
if (len && on_read_priv) {
if (on_read_priv(nullptr, len)) {
on_read_priv = nullptr;
}
break;
case UART_FIFO_OVF:
ESP_LOGW(TAG, "HW FIFO Overflow");
if (on_error)
on_error(terminal_error::BUFFER_OVERFLOW);
reset_events();
break;
case UART_BUFFER_FULL:
ESP_LOGW(TAG, "Ring Buffer Full");
if (on_error)
on_error(terminal_error::BUFFER_OVERFLOW);
reset_events();
break;
case UART_BREAK:
ESP_LOGW(TAG, "Rx Break");
if (on_error)
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
break;
case UART_PARITY_ERR:
ESP_LOGE(TAG, "Parity Error");
if (on_error)
on_error(terminal_error::CHECKSUM_ERROR);
break;
case UART_FRAME_ERR:
ESP_LOGE(TAG, "Frame Error");
if (on_error)
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
break;
default:
ESP_LOGW(TAG, "unknown uart event type: %d", event.type);
break;
}
break;
case UART_FIFO_OVF:
ESP_LOGW(TAG, "HW FIFO Overflow");
if (on_error) {
on_error(terminal_error::BUFFER_OVERFLOW);
}
reset_events();
break;
case UART_BUFFER_FULL:
ESP_LOGW(TAG, "Ring Buffer Full");
if (on_error) {
on_error(terminal_error::BUFFER_OVERFLOW);
}
reset_events();
break;
case UART_BREAK:
ESP_LOGW(TAG, "Rx Break");
if (on_error) {
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break;
case UART_PARITY_ERR:
ESP_LOGE(TAG, "Parity Error");
if (on_error) {
on_error(terminal_error::CHECKSUM_ERROR);
}
break;
case UART_FRAME_ERR:
ESP_LOGE(TAG, "Frame Error");
if (on_error) {
on_error(terminal_error::UNEXPECTED_CONTROL_FLOW);
}
break;
default:
ESP_LOGW(TAG, "unknown uart event type: %d", event.type);
break;
}
}
}

View File

@ -23,7 +23,7 @@ namespace esp_modem {
constexpr const char *TAG = "uart_resource";
uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t* event_queue, int fd): port(-1)
uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHandle_t *event_queue, int fd): port(-1)
{
ESP_LOGD(TAG, "Creating uart resource" );
struct termios tty = {};
@ -39,7 +39,7 @@ uart_resource::uart_resource(const esp_modem_uart_term_config *config, QueueHand
tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
tty.c_cc[VTIME] = 0;

View File

@ -34,7 +34,7 @@ constexpr const char *TAG = "vfs_socket_creator";
* @note: Remote command:
* socat TCP-L:2222 GOPEN:/dev/ttyS0,ispeed=115200,ospeed=1152000,b115200,raw,echo=0
*/
static esp_err_t hostname_to_fd(const char *host, int port, int* fd)
static esp_err_t hostname_to_fd(const char *host, int port, int *fd)
{
struct sockaddr_storage address = {};
struct addrinfo *address_info;
@ -46,7 +46,7 @@ static esp_err_t hostname_to_fd(const char *host, int port, int* fd)
int res = getaddrinfo(host, nullptr, &hints, &address_info);
if (res != 0 || address_info == nullptr) {
ESP_LOGE(TAG, "couldn't get hostname for :%s: "
"getaddrinfo() returns %d, addrinfo=%p", host, res, address_info);
"getaddrinfo() returns %d, addrinfo=%p", host, res, address_info);
return ESP_FAIL;
}
*fd = socket(address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol);
@ -77,7 +77,7 @@ static esp_err_t hostname_to_fd(const char *host, int port, int* fd)
}
static void vfs_destroy_socket(int fd, struct esp_modem_vfs_resource * resource)
static void vfs_destroy_socket(int fd, struct esp_modem_vfs_resource *resource)
{
if (fd >= 0) {
close(fd);

View File

@ -27,13 +27,13 @@ constexpr const char *TAG = "vfs_uart_creator";
struct esp_modem_vfs_resource {
explicit esp_modem_vfs_resource(const esp_modem_uart_term_config *config, int fd)
: internal(config, nullptr, fd) {}
: internal(config, nullptr, fd) {}
esp_modem::uart_resource internal;
};
static void vfs_destroy_uart(int fd, struct esp_modem_vfs_resource * resource)
static void vfs_destroy_uart(int fd, struct esp_modem_vfs_resource *resource)
{
if (fd >= 0) {
close(fd);
@ -58,7 +58,7 @@ bool vfs_create_uart(struct esp_modem_vfs_uart_creator *config, struct esp_modem
int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
, return false)
, return false)
return true;
}