code clean and reset default values

This commit is contained in:
oarcher 2024-07-29 23:46:18 +02:00
parent c4c96e4bc9
commit 8175da82ee
3 changed files with 63 additions and 97 deletions

View file

@ -133,23 +133,13 @@ async def to_code(config):
add_idf_sdkconfig_option("CONFIG_PPP", True) add_idf_sdkconfig_option("CONFIG_PPP", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_SUPPORT", True) add_idf_sdkconfig_option("CONFIG_LWIP_PPP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_PAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_PAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP", 0) add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DELAY_AFTER_DLCI_SETUP", 0)
add_idf_sdkconfig_option("CONFIG_PPP_SUPPORT", True) add_idf_sdkconfig_option("CONFIG_PPP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_NOTIFY_PHASE_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_PPP_CHAP_SUPPORT", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION", True)
add_idf_sdkconfig_option("CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT", True)
# commented because cause crash if another UART is defined in the yaml
# If enabled, it should increase the reliability and the speed of the connection (TODO: test)
# add_idf_sdkconfig_option("CONFIG_UART_ISR_IN_IRAM", True)
# If Uart queue full message ( A7672 ), those config option might be changed # If Uart queue full message ( A7672 ), those config option might be changed
# https://github.com/espressif/esp-protocols/issues/272#issuecomment-1558682967 # https://github.com/espressif/esp-protocols/issues/272#issuecomment-1558682967
add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD", True) add_idf_sdkconfig_option("CONFIG_ESP_MODEM_CMUX_DEFRAGMENT_PAYLOAD", True)
add_idf_sdkconfig_option("ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED", False) add_idf_sdkconfig_option("ESP_MODEM_USE_INFLATABLE_BUFFER_IF_NEEDED", True)
add_idf_sdkconfig_option("ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY", False) add_idf_sdkconfig_option("ESP_MODEM_CMUX_USE_SHORT_PAYLOADS_ONLY", False)
cg.add_define("USE_MODEM") cg.add_define("USE_MODEM")

View file

@ -21,7 +21,8 @@
#include <iostream> #include <iostream>
#ifndef USE_MODEM_MODEL #ifndef USE_MODEM_MODEL
#define USE_MODEM_MODEL "UNKNOWN" #define USE_MODEM_MODEL "GENERIC"
#define USE_MODEM_MODEL_GENERIC
#endif #endif
#define ESPHL_ERROR_CHECK(err, message) \ #define ESPHL_ERROR_CHECK(err, message) \
@ -36,12 +37,6 @@
ESP_LOGE(TAG, message ": %s", command_result_to_string(err).c_str()); \ ESP_LOGE(TAG, message ": %s", command_result_to_string(err).c_str()); \
} }
static const size_t CONFIG_MODEM_UART_RX_BUFFER_SIZE = 32768;
static const size_t CONFIG_MODEM_UART_TX_BUFFER_SIZE = 32768;
static const uint8_t CONFIG_MODEM_UART_EVENT_QUEUE_SIZE = 30;
static const size_t CONFIG_MODEM_UART_EVENT_TASK_STACK_SIZE = 32768;
static const uint8_t CONFIG_MODEM_UART_EVENT_TASK_PRIORITY = 5;
namespace esphome { namespace esphome {
namespace modem { namespace modem {
@ -63,13 +58,8 @@ bool ModemComponent::can_proceed() { return this->is_connected(); }
network::IPAddresses ModemComponent::get_ip_addresses() { network::IPAddresses ModemComponent::get_ip_addresses() {
network::IPAddresses addresses; network::IPAddresses addresses;
esp_netif_ip_info_t ip; esp_netif_ip_info_t ip;
ESP_LOGV(TAG, "get_ip_addresses"); esp_netif_get_ip_info(this->ppp_netif_, &ip);
esp_err_t err = esp_netif_get_ip_info(this->ppp_netif_, &ip); addresses[0] = network::IPAddress(&ip.ip);
if (err != ESP_OK) {
ESP_LOGV(TAG, "esp_netif_get_ip_info failed: %s", esp_err_to_name(err));
} else {
addresses[0] = network::IPAddress(&ip.ip);
}
return addresses; return addresses;
} }
@ -125,19 +115,15 @@ void ModemComponent::setup() {
this->ppp_netif_ = esp_netif_new(&netif_ppp_config); this->ppp_netif_ = esp_netif_new(&netif_ppp_config);
assert(this->ppp_netif_); assert(this->ppp_netif_);
ESP_LOGV(TAG, "Set APN: %s", this->apn_.c_str());
this->dce_config_ = ESP_MODEM_DCE_DEFAULT_CONFIG(this->apn_.c_str());
if (!this->username_.empty()) { if (!this->username_.empty()) {
ESP_LOGV(TAG, "Set auth: username: %s password: %s", this->username_.c_str(), this->password_.c_str()); ESP_LOGV(TAG, "Set auth: username: %s password: %s", this->username_.c_str(), this->password_.c_str());
ESPHL_ERROR_CHECK(esp_netif_ppp_set_auth(this->ppp_netif_, NETIF_PPP_AUTHTYPE_PAP, this->username_.c_str(), ESPHL_ERROR_CHECK(esp_netif_ppp_set_auth(this->ppp_netif_, NETIF_PPP_AUTHTYPE_PAP, this->username_.c_str(),
this->password_.c_str()), this->password_.c_str()),
"ppp set auth"); "PPP set auth");
} }
// err = esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &ModemComponent::ip_event_handler, nullptr, err = esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &ModemComponent::ip_event_handler, nullptr,
// nullptr); nullptr);
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ModemComponent::ip_event_handler, nullptr);
ESPHL_ERROR_CHECK(err, "IP event handler register error"); ESPHL_ERROR_CHECK(err, "IP event handler register error");
this->create_dte_dce_(); this->create_dte_dce_();
@ -159,47 +145,46 @@ void ModemComponent::create_dte_dce_() {
this->dce.reset(); this->dce.reset();
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
this->dte_config_ = dte_config;
this->dte_config_.uart_config.tx_io_num = this->tx_pin_->get_pin(); dte_config.uart_config.tx_io_num = this->tx_pin_->get_pin();
this->dte_config_.uart_config.rx_io_num = this->rx_pin_->get_pin(); dte_config.uart_config.rx_io_num = this->rx_pin_->get_pin();
// this->dte_config_.uart_config.rts_io_num = static_cast<gpio_num_t>( CONFIG_EXAMPLE_MODEM_UART_RTS_PIN); dte_config.uart_config.rx_buffer_size = this->uart_rx_buffer_size_;
// this->dte_config_.uart_config.cts_io_num = static_cast<gpio_num_t>( CONFIG_EXAMPLE_MODEM_UART_CTS_PIN); dte_config.uart_config.tx_buffer_size = this->uart_tx_buffer_size_;
this->dte_config_.uart_config.rx_buffer_size = CONFIG_MODEM_UART_RX_BUFFER_SIZE; dte_config.uart_config.event_queue_size = this->uart_event_queue_size_;
this->dte_config_.uart_config.tx_buffer_size = CONFIG_MODEM_UART_TX_BUFFER_SIZE; dte_config.task_stack_size = this->uart_event_task_stack_size_;
this->dte_config_.uart_config.event_queue_size = CONFIG_MODEM_UART_EVENT_QUEUE_SIZE; dte_config.task_priority = this->uart_event_task_priority_;
this->dte_config_.task_stack_size = CONFIG_MODEM_UART_EVENT_TASK_STACK_SIZE * 2; dte_config.dte_buffer_size = this->uart_rx_buffer_size_ / 2;
this->dte_config_.task_priority = CONFIG_MODEM_UART_EVENT_TASK_PRIORITY;
this->dte_config_.dte_buffer_size = CONFIG_MODEM_UART_RX_BUFFER_SIZE / 2;
this->dte_ = create_uart_dte(&this->dte_config_); this->dte_ = create_uart_dte(&dte_config);
// this->dte_->set_mode(modem_mode::COMMAND_MODE); esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(this->apn_.c_str());
#if defined(USE_MODEM_MODEL_GENERIC) #if defined(USE_MODEM_MODEL_GENERIC)
this->dce = create_generic_dce(&this->dce_config_, this->dte_, this->ppp_netif_); this->dce = create_generic_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_BG96) #elif defined(USE_MODEM_MODEL_BG96)
this->dce = create_BG96_dce(&this->dce_config_, this->dte_, this->ppp_netif_); this->dce = create_BG96_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_SIM800) #elif defined(USE_MODEM_MODEL_SIM800)
this->dce = create_SIM800_dce(&this->dce_config_, this->dte_, this->ppp_netif_); this->dce = create_SIM800_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_SIM7000) #elif defined(USE_MODEM_MODEL_SIM7000)
this->dce = create_SIM7000_dce(&this->dce_config_, this->dte_, this->ppp_netif_); this->dce = create_SIM7000_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_SIM7600) #elif defined(USE_MODEM_MODEL_SIM7600)
this->dce = create_SIM7600_dce(&this->dce_config_, this->dte_, this->ppp_netif_); this->dce = create_SIM7600_dce(&dce_config, this->dte_, this->ppp_netif_);
#else #else
#error Modem model not known #error Modem model not known
#endif #endif
// flow control not fully implemented, but kept here for future work // flow control not fully implemented, but kept here for future work
if (this->dte_config_.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { // if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
if (command_result::OK != this->dce->set_flow_control(2, 2)) { // if (command_result::OK != this->dce->set_flow_control(2, 2)) {
ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); // ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
return; // return;
} // }
ESP_LOGD(TAG, "set_flow_control OK"); // ESP_LOGD(TAG, "set_flow_control OK");
} // }
// Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any // Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any
// No error check done. It can take some times if the commands fail
// but this allow to recover from a previous session.
Watchdog wdt(60); Watchdog wdt(60);
if (this->cmux_) { if (this->cmux_) {
this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE); this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE);
@ -211,6 +196,8 @@ void ModemComponent::create_dte_dce_() {
if (this->modem_ready()) { if (this->modem_ready()) {
ESP_LOGD(TAG, "modem ready after exiting cmux/data mode"); ESP_LOGD(TAG, "modem ready after exiting cmux/data mode");
} else { } else {
// the modem may be off. As the status pin is optionnal (and seems to be unreliable)
// we can be sure of the cause.
ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode"); ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode");
} }
} }
@ -226,7 +213,7 @@ bool ModemComponent::prepare_sim_() {
if (!pin_ok) { if (!pin_ok) {
if (!this->pin_code_.empty()) { if (!this->pin_code_.empty()) {
ESP_LOGV(TAG, "Set pin code: %s", this->pin_code_.c_str()); ESP_LOGV(TAG, "Set pin code: %s", this->pin_code_.c_str());
ESPMODEM_ERROR_CHECK(this->dce->set_pin(this->pin_code_), ""); ESPMODEM_ERROR_CHECK(this->dce->set_pin(this->pin_code_), "Set pin code failed");
delay(this->command_delay_); delay(this->command_delay_);
} }
} }
@ -281,7 +268,7 @@ void ModemComponent::start_connect_() {
if (this->dce->set_mode(modem_mode::DATA_MODE)) { if (this->dce->set_mode(modem_mode::DATA_MODE)) {
ESP_LOGD(TAG, "Modem has correctly entered data mode"); ESP_LOGD(TAG, "Modem has correctly entered data mode");
} else { } else {
ESP_LOGD(TAG, "Unable to enter DATA mode"); ESP_LOGE(TAG, "Unable to enter DATA mode");
this->status_set_error("Unable to enter DATA mode"); this->status_set_error("Unable to enter DATA mode");
} }
assert(!this->modem_ready()); assert(!this->modem_ready());
@ -408,9 +395,7 @@ void ModemComponent::loop() {
} }
delay(200); // NOLINT delay(200); // NOLINT
ESP_LOGD(TAG, "Hanging up connection after %.1fmin", float(this->connect_begin_) / (1000 * 60)); ESP_LOGD(TAG, "Hanging up connection after %.1fmin", float(this->connect_begin_) / (1000 * 60));
if (this->dce->hang_up() != command_result::OK) { ESPMODEM_ERROR_CHECK(this->dce->hang_up(), "Unable to hang up modem. Trying to continue anyway.");
ESP_LOGW(TAG, "Unable to hang up modem. Trying to continue anyway.");
}
this->dump_connect_params_(); this->dump_connect_params_();
} }
this->start_ = false; this->start_ = false;
@ -475,9 +460,10 @@ bool ModemComponent::get_power_status() {
// This code is not fully checked. The status pin seems to be flickering on Lilygo T-SIM7600 // This code is not fully checked. The status pin seems to be flickering on Lilygo T-SIM7600
return this->status_pin_->digital_read(); return this->status_pin_->digital_read();
#else #else
// No status pin, assuming the modem is ON if (!this->cmux_ && this->connected_) {
// return true; // Data mode, connected: assume power is OK
// Watchdog wdt(60); return true;
}
return this->modem_ready(); return this->modem_ready();
#endif #endif
} }
@ -489,23 +475,19 @@ void ModemComponent::poweron_() {
ESP_LOGV(TAG, "Powering up modem with power_pin..."); ESP_LOGV(TAG, "Powering up modem with power_pin...");
this->power_transition_ = true; this->power_transition_ = true;
this->power_pin_->digital_write(false); this->power_pin_->digital_write(false);
// min 100 for SIM7600, but min 1200 for SIM800. min BG96: 650
delay(USE_MODEM_POWER_TON); delay(USE_MODEM_POWER_TON);
this->power_pin_->digital_write(true); this->power_pin_->digital_write(true);
// use a timout for long wait delay // use a timout for long wait delay
ESP_LOGD(TAG, "Will check that the modem is on in %.1fs...", float(USE_MODEM_POWER_TONUART) / 1000); ESP_LOGD(TAG, "Will check that the modem is on in %.1fs...", float(USE_MODEM_POWER_TONUART) / 1000);
this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() { this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() {
Watchdog wdt(60); Watchdog wdt(60);
// while (!this->get_power_status()) {
// delay(this->command_delay_);
// ESP_LOGV(TAG, "Waiting for modem to poweron...");
// }
this->create_dte_dce_(); this->create_dte_dce_();
while (!this->modem_ready()) { delay(500); // NOLINT
delay(500); // NOLINT if (!this->modem_ready()) {
ESP_LOGV(TAG, "Waiting for modem to be ready after poweron..."); ESP_LOGE(TAG, "Unable to power on the modem");
} else {
ESP_LOGD(TAG, "Modem ready after power ON");
} }
ESP_LOGV(TAG, "Modem ready after power ON");
this->power_transition_ = false; this->power_transition_ = false;
}); });
} }
@ -514,7 +496,6 @@ void ModemComponent::poweron_() {
void ModemComponent::poweroff_() { void ModemComponent::poweroff_() {
#ifdef USE_MODEM_POWER #ifdef USE_MODEM_POWER
// if (this->get_power_status()) {
if (this->power_pin_) { if (this->power_pin_) {
ESP_LOGV(TAG, "Powering off modem with power pin..."); ESP_LOGV(TAG, "Powering off modem with power pin...");
this->power_transition_ = true; this->power_transition_ = true;
@ -529,15 +510,15 @@ void ModemComponent::poweroff_() {
this->set_timeout("wait_poweroff", USE_MODEM_POWER_TOFFUART, [this]() { this->set_timeout("wait_poweroff", USE_MODEM_POWER_TOFFUART, [this]() {
Watchdog wdt(60); Watchdog wdt(60);
// while (this->get_power_status()) { if (this->modem_ready()) {
// delay(this->command_delay_); ESP_LOGE(TAG, "Unable to power off the modem");
// } } else {
assert(!this->modem_ready()); ESP_LOGD(TAG, "Modem OFF");
ESP_LOGV(TAG, "Modem OFF"); }
this->power_transition_ = false; this->power_transition_ = false;
}); });
} }
// }
#endif // USE_MODEM_POWER #endif // USE_MODEM_POWER
} }
@ -549,17 +530,17 @@ void ModemComponent::dump_connect_params_() {
esp_netif_ip_info_t ip; esp_netif_ip_info_t ip;
esp_netif_get_ip_info(this->ppp_netif_, &ip); esp_netif_get_ip_info(this->ppp_netif_, &ip);
ESP_LOGCONFIG(TAG, "Modem connection:"); ESP_LOGCONFIG(TAG, "Modem connection:");
ESP_LOGCONFIG(TAG, " IP Address: %s", network::IPAddress(&ip.ip).str().c_str()); ESP_LOGCONFIG(TAG, " IP Address : %s", network::IPAddress(&ip.ip).str().c_str());
ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str()); ESP_LOGCONFIG(TAG, " Hostname : '%s'", App.get_name().c_str());
ESP_LOGCONFIG(TAG, " Subnet: %s", network::IPAddress(&ip.netmask).str().c_str()); ESP_LOGCONFIG(TAG, " Subnet : %s", network::IPAddress(&ip.netmask).str().c_str());
ESP_LOGCONFIG(TAG, " Gateway: %s", network::IPAddress(&ip.gw).str().c_str()); ESP_LOGCONFIG(TAG, " Gateway : %s", network::IPAddress(&ip.gw).str().c_str());
const ip_addr_t *dns_main_ip = dns_getserver(ESP_NETIF_DNS_MAIN); const ip_addr_t *dns_main_ip = dns_getserver(ESP_NETIF_DNS_MAIN);
const ip_addr_t *dns_backup_ip = dns_getserver(ESP_NETIF_DNS_BACKUP); const ip_addr_t *dns_backup_ip = dns_getserver(ESP_NETIF_DNS_BACKUP);
const ip_addr_t *dns_fallback_ip = dns_getserver(ESP_NETIF_DNS_FALLBACK); const ip_addr_t *dns_fallback_ip = dns_getserver(ESP_NETIF_DNS_FALLBACK);
ESP_LOGCONFIG(TAG, " DNS main: %s", network::IPAddress(dns_main_ip).str().c_str()); ESP_LOGCONFIG(TAG, " DNS main : %s", network::IPAddress(dns_main_ip).str().c_str());
ESP_LOGCONFIG(TAG, " DNS backup: %s", network::IPAddress(dns_backup_ip).str().c_str()); ESP_LOGCONFIG(TAG, " DNS backup : %s", network::IPAddress(dns_backup_ip).str().c_str());
ESP_LOGCONFIG(TAG, " DNS fallback: %s", network::IPAddress(dns_fallback_ip).str().c_str()); ESP_LOGCONFIG(TAG, " DNS fallback: %s", network::IPAddress(dns_fallback_ip).str().c_str());
} }
@ -603,12 +584,6 @@ bool ModemComponent::get_imei(std::string &result) {
bool ModemComponent::modem_ready() { bool ModemComponent::modem_ready() {
// check if the modem is ready to answer AT commands // check if the modem is ready to answer AT commands
std::string imei; std::string imei;
// bool status;
// {
// // Temp increase watchdog timout. // FIXME infinite loop if while(!this->modem_ready())
// Watchdog wdt(60);
// status = this->get_imei(imei);
// }
return this->get_imei(imei); return this->get_imei(imei);
} }

View file

@ -70,7 +70,6 @@ class ModemComponent : public Component {
void disable(); void disable();
void add_on_state_callback(std::function<void(ModemComponentState)> &&callback); void add_on_state_callback(std::function<void(ModemComponentState)> &&callback);
std::unique_ptr<DCE> dce{nullptr}; std::unique_ptr<DCE> dce{nullptr};
uint8_t get_cmux_vt_states();
protected: protected:
void create_dte_dce_(); // (re)create dte and dce void create_dte_dce_(); // (re)create dte and dce
@ -81,7 +80,6 @@ class ModemComponent : public Component {
void poweroff_(); void poweroff_();
static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
void dump_connect_params_(); void dump_connect_params_();
void exit_cmux_();
InternalGPIOPin *tx_pin_; InternalGPIOPin *tx_pin_;
InternalGPIOPin *rx_pin_; InternalGPIOPin *rx_pin_;
GPIOPin *status_pin_{nullptr}; GPIOPin *status_pin_{nullptr};
@ -91,10 +89,13 @@ class ModemComponent : public Component {
std::string password_; std::string password_;
std::string apn_; std::string apn_;
std::vector<std::string> init_at_commands_; std::vector<std::string> init_at_commands_;
size_t uart_rx_buffer_size_ = 2048; // 256-2048
size_t uart_tx_buffer_size_ = 1024; // 256-2048
uint8_t uart_event_queue_size_ = 30; // 10-40
size_t uart_event_task_stack_size_ = 2048; // 2000-6000
uint8_t uart_event_task_priority_ = 5; // 3-22
std::shared_ptr<DTE> dte_{nullptr}; std::shared_ptr<DTE> dte_{nullptr};
esp_netif_t *ppp_netif_{nullptr}; esp_netif_t *ppp_netif_{nullptr};
esp_modem_dte_config_t dte_config_;
esp_modem_dce_config_t dce_config_;
ModemComponentState state_{ModemComponentState::DISABLED}; ModemComponentState state_{ModemComponentState::DISABLED};
bool cmux_{false}; bool cmux_{false};
bool start_{false}; bool start_{false};