// // Created by david on 3/3/21. // #include "cxx_include/esp_modem_dte.hpp" #include "uart_terminal.hpp" #include "esp_log.h" #include "cxx_include/esp_modem_api.hpp" #include "esp_modem_api.h" #include "esp_modem_config.h" #include "exception_stub.hpp" struct PdpContext; static const char *TAG = "modem_api"; std::shared_ptr create_uart_dte(const esp_modem_dte_config *config) { TRY_CATCH_RET_NULL( auto term = create_uart_terminal(config); return std::make_shared(std::move(term)); ) } template std::unique_ptr> create_dce(const std::shared_ptr& dte, const std::shared_ptr& dev, esp_netif_t *netif) { TRY_CATCH_RET_NULL( return std::make_unique>(dte, dev, netif); ) } std::unique_ptr> create_generic_dce_from_module(const std::shared_ptr& dte, const std::shared_ptr& dev, esp_netif_t *netif) { return create_dce(dte, dev, netif); } std::unique_ptr> create_SIM7600_dce_from_module(const std::shared_ptr& dte, const std::shared_ptr& dev, esp_netif_t *netif) { return create_dce(dte, dev, netif); } std::unique_ptr> create_SIM7600_dce(const std::shared_ptr& dte, esp_netif_t *netif, std::string &apn) { auto pdp = std::make_unique(apn); auto dev = std::make_shared(dte, std::move(pdp)); return create_dce(dte, std::move(dev), netif); } // // C API definitions struct esp_modem_dce_wrap // need to mimic the polymorphic dispatch as CPP uses templated dispatch { enum esp_modem_t { MODEM_SIM7600, MODEM_SIM800, MODEM_BG96 } modem_type; void * dce_ptr; }; 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; } return ESP_ERR_INVALID_ARG; } extern "C" esp_modem_dce_t *esp_modem_new(const esp_modem_dte_config_t *config, esp_netif_t *netif, const char* apn) { auto dce_wrap = new (std::nothrow) esp_modem_dce_wrap; if (dce_wrap == nullptr) return nullptr; std::string apn_str(apn); auto dte = create_uart_dte(config); auto dce = create_SIM7600_dce(dte, netif, apn_str); dce_wrap->modem_type = esp_modem_dce_wrap::MODEM_SIM7600; dce_wrap->dce_ptr = dce.release(); return dce_wrap; } extern "C" void esp_modem_destroy(esp_modem_dce_t * dce) { assert(dce->modem_type == esp_modem_dce_wrap::MODEM_SIM7600); auto dce_sim7600 = static_cast*>(dce->dce_ptr); delete dce_sim7600; delete dce; } extern "C" esp_err_t esp_modem_set_mode(esp_modem_dce_t * dce, esp_modem_dce_mode_t mode) { assert(dce->modem_type == esp_modem_dce_wrap::MODEM_SIM7600); auto dce_sim7600 = static_cast*>(dce->dce_ptr); if (mode == ESP_MODEM_MODE_DATA) { dce_sim7600->set_data(); } else if (mode == ESP_MODEM_MODE_COMMAND) { dce_sim7600->set_data(); } else { return ESP_ERR_NOT_SUPPORTED; } return ESP_OK; } extern "C" esp_err_t esp_modem_read_pin(esp_modem_dce_t * dce, bool &x) { assert(dce->modem_type == esp_modem_dce_wrap::MODEM_SIM7600); auto dce_sim7600 = static_cast*>(dce->dce_ptr); return command_response_to_esp_err(dce_sim7600->read_pin(x)); } // define all commands manually, as we have to convert char* strings to CPP strings and references to