mirror of
https://github.com/esphome/esphome.git
synced 2024-12-26 07:24:54 +01:00
common exit_cmux_
This commit is contained in:
parent
971fbd6d26
commit
adad7469e5
2 changed files with 35 additions and 43 deletions
|
@ -120,6 +120,10 @@ void ModemComponent::setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->reset_();
|
this->reset_();
|
||||||
|
// At boot time, if the modem power is up, but the modem is not ready, it is probably still in cmux mode
|
||||||
|
if (this->enabled_ && this->get_power_status() && !this->modem_ready()) {
|
||||||
|
this->exit_cmux_();
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOGV(TAG, "Setup finished");
|
ESP_LOGV(TAG, "Setup finished");
|
||||||
}
|
}
|
||||||
|
@ -127,6 +131,7 @@ void ModemComponent::setup() {
|
||||||
void ModemComponent::reset_() {
|
void ModemComponent::reset_() {
|
||||||
// destroy previous dte/dce, and recreate them.
|
// destroy previous dte/dce, and recreate them.
|
||||||
// destroying them seems to be the only way to have a clear state after hang up, and be able to reconnect.
|
// destroying them seems to be the only way to have a clear state after hang up, and be able to reconnect.
|
||||||
|
// if the modem was previously in cmux mode, this->exit_cmux_(), will be needed after.
|
||||||
|
|
||||||
this->dte_.reset();
|
this->dte_.reset();
|
||||||
this->dce.reset();
|
this->dce.reset();
|
||||||
|
@ -186,21 +191,6 @@ void ModemComponent::reset_() {
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "not set_flow_control, because 2-wire mode active.");
|
ESP_LOGI(TAG, "not set_flow_control, because 2-wire mode active.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->enabled_ && this->get_power_status() && !this->modem_ready()) {
|
|
||||||
// if the esp has rebooted, but the modem not, it is still in cmux mode
|
|
||||||
// So we close cmux.
|
|
||||||
// The drawback is that if the modem is poweroff, those commands will take some time to execute.
|
|
||||||
Watchdog wdt(60);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_MODE);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_COMMAND);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT);
|
|
||||||
if (!this->modem_ready()) {
|
|
||||||
ESP_LOGE(TAG, "Modem still not ready after reset");
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "Modem exited previous CMUX session");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModemComponent::prepare_sim_() {
|
bool ModemComponent::prepare_sim_() {
|
||||||
|
@ -379,23 +369,12 @@ void ModemComponent::loop() {
|
||||||
ESP_LOGE(TAG, "modem not ready after hang up");
|
ESP_LOGE(TAG, "modem not ready after hang up");
|
||||||
}
|
}
|
||||||
this->set_timeout("wait_lost_ip", 60000, [this]() {
|
this->set_timeout("wait_lost_ip", 60000, [this]() {
|
||||||
this->dump_connect_params_();
|
this->status_set_error("No lost ip event received. Forcing disconnect state");
|
||||||
this->status_set_error("No lost ip event received");
|
|
||||||
|
|
||||||
this->state_ = ModemComponentState::DISCONNECTED;
|
this->state_ = ModemComponentState::DISCONNECTED;
|
||||||
|
|
||||||
// This seems to be the only way to exit CMUX
|
|
||||||
this->reset_(); // reset dce/dte
|
this->reset_(); // reset dce/dte
|
||||||
if (!(this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_MODE) &&
|
this->exit_cmux_();
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT))) {
|
|
||||||
this->status_set_error("Unable to exit CMUX.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->modem_ready()) {
|
|
||||||
ESP_LOGE(TAG, "modem not ready after reset");
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this->start_ = false;
|
this->start_ = false;
|
||||||
|
@ -406,14 +385,7 @@ void ModemComponent::loop() {
|
||||||
|
|
||||||
// This seems to be the only way to exit CMUX
|
// This seems to be the only way to exit CMUX
|
||||||
this->reset_(); // reset dce/dte
|
this->reset_(); // reset dce/dte
|
||||||
if (!(this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_MODE) &&
|
this->exit_cmux_();
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT))) {
|
|
||||||
this->status_set_error("Unable to exit CMUX.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->modem_ready()) {
|
|
||||||
ESP_LOGE(TAG, "modem not ready after reset");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -455,6 +427,25 @@ void ModemComponent::disable() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModemComponent::exit_cmux_() {
|
||||||
|
// This must be called to gain command mode if:
|
||||||
|
// - if the esp has rebooted, but the modem not, it is still in cmux mode
|
||||||
|
// - after a dte/dce reset.
|
||||||
|
// If the modem was previously ready, this will *HANG* de dte, and the modem will be unreachable, with no chances to
|
||||||
|
// recover it.
|
||||||
|
// We need this because we are not able to do a simple esp_modem::modem_mode::COMMAND_MODE (this is probably a bug in
|
||||||
|
// esp_modem)
|
||||||
|
Watchdog wdt(60);
|
||||||
|
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_MODE);
|
||||||
|
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_COMMAND);
|
||||||
|
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT);
|
||||||
|
if (!this->modem_ready()) {
|
||||||
|
ESP_LOGE(TAG, "Modem still not ready after reset");
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Modem exited previous CMUX session");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ModemComponent::get_power_status() {
|
bool ModemComponent::get_power_status() {
|
||||||
if (!this->status_pin_) {
|
if (!this->status_pin_) {
|
||||||
ESP_LOGV(TAG, "No status pin, assuming the modem is ON");
|
ESP_LOGV(TAG, "No status pin, assuming the modem is ON");
|
||||||
|
|
|
@ -78,6 +78,14 @@ class ModemComponent : public Component {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reset_(); // (re)create dte and dce
|
void reset_(); // (re)create dte and dce
|
||||||
|
bool prepare_sim_();
|
||||||
|
void send_init_at_();
|
||||||
|
void start_connect_();
|
||||||
|
void poweron_();
|
||||||
|
void poweroff_();
|
||||||
|
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 exit_cmux_();
|
||||||
InternalGPIOPin *tx_pin_;
|
InternalGPIOPin *tx_pin_;
|
||||||
InternalGPIOPin *rx_pin_;
|
InternalGPIOPin *rx_pin_;
|
||||||
InternalGPIOPin *status_pin_{nullptr};
|
InternalGPIOPin *status_pin_{nullptr};
|
||||||
|
@ -98,19 +106,12 @@ class ModemComponent : public Component {
|
||||||
esp_modem_dte_config_t dte_config_;
|
esp_modem_dte_config_t dte_config_;
|
||||||
esp_modem_dce_config_t dce_config_;
|
esp_modem_dce_config_t dce_config_;
|
||||||
ModemComponentState state_{ModemComponentState::DISABLED};
|
ModemComponentState state_{ModemComponentState::DISABLED};
|
||||||
bool prepare_sim_();
|
|
||||||
void send_init_at_();
|
|
||||||
void start_connect_();
|
|
||||||
void poweron_();
|
|
||||||
void poweroff_();
|
|
||||||
bool start_{false};
|
bool start_{false};
|
||||||
bool enabled_{false};
|
bool enabled_{false};
|
||||||
bool connected_{false};
|
bool connected_{false};
|
||||||
bool got_ipv4_address_{false};
|
bool got_ipv4_address_{false};
|
||||||
// date start (millis())
|
// date start (millis())
|
||||||
uint32_t connect_begin_;
|
uint32_t connect_begin_;
|
||||||
static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
|
||||||
void dump_connect_params_();
|
|
||||||
std::string use_address_;
|
std::string use_address_;
|
||||||
// timeout for AT commands
|
// timeout for AT commands
|
||||||
uint32_t command_delay_ = 500;
|
uint32_t command_delay_ = 500;
|
||||||
|
|
Loading…
Reference in a new issue