mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-19 05:22:21 +02:00
fix(esp_modem): Cleanup custom lib-commands and factory
This commit is contained in:
@ -96,20 +96,6 @@ menu "Example Configuration"
|
||||
help
|
||||
Pin to unlock the SIM
|
||||
|
||||
choice EXAMPLE_FLOW_CONTROL
|
||||
bool "Set preferred modem control flow"
|
||||
default EXAMPLE_FLOW_CONTROL_NONE
|
||||
help
|
||||
Set the modem's preferred control flow
|
||||
|
||||
config EXAMPLE_FLOW_CONTROL_NONE
|
||||
bool "No control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_SW
|
||||
bool "SW control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_HW
|
||||
bool "HW control flow"
|
||||
endchoice
|
||||
|
||||
menu "UART Configuration"
|
||||
depends on EXAMPLE_SERIAL_CONFIG_UART
|
||||
config EXAMPLE_MODEM_UART_TX_PIN
|
||||
@ -181,6 +167,21 @@ menu "Example Configuration"
|
||||
default 1024
|
||||
help
|
||||
Buffer size of UART RX buffer.
|
||||
|
||||
choice EXAMPLE_FLOW_CONTROL
|
||||
bool "Set preferred modem control flow"
|
||||
default EXAMPLE_FLOW_CONTROL_NONE
|
||||
help
|
||||
Set the modem's preferred control flow
|
||||
|
||||
config EXAMPLE_FLOW_CONTROL_NONE
|
||||
bool "No control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_SW
|
||||
bool "SW control flow"
|
||||
config EXAMPLE_FLOW_CONTROL_HW
|
||||
bool "HW control flow"
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
@ -197,6 +197,15 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "Initializing esp_modem for a generic module...");
|
||||
esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif);
|
||||
#endif
|
||||
assert(dce);
|
||||
if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
||||
esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control.
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "HW set_flow_control OK");
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB)
|
||||
while (1) {
|
||||
@ -205,26 +214,17 @@ void app_main(void)
|
||||
const esp_modem_dte_config_t dte_usb_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config);
|
||||
ESP_LOGI(TAG, "Waiting for USB device connection...");
|
||||
esp_modem_dce_t *dce = esp_modem_new_dev_usb(ESP_MODEM_DCE_BG96, &dte_usb_config, &dce_config, esp_netif);
|
||||
assert(dce);
|
||||
esp_modem_set_error_cb(dce, usb_terminal_error_handler);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000)); // Although the DTE should be ready after USB enumeration, sometimes it fails to respond without this delay
|
||||
|
||||
#else
|
||||
#error Invalid serial connection to modem.
|
||||
#endif
|
||||
assert(dce);
|
||||
|
||||
xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT);
|
||||
|
||||
/* Run the modem demo app */
|
||||
|
||||
if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
||||
esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control.
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "set_flow_control OK");
|
||||
}
|
||||
|
||||
#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
|
||||
// check if PIN needed
|
||||
bool pin_ok = false;
|
||||
|
@ -7,36 +7,37 @@
|
||||
// Created on: 23.08.2022
|
||||
// Author: franz
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <charconv>
|
||||
#include <list>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_event.h"
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "cxx_include/esp_modem_dce.hpp"
|
||||
#include "esp_modem_config.h"
|
||||
#include "cxx_include/esp_modem_api.hpp"
|
||||
#include "cxx_include/command_library.hpp"
|
||||
#include "cxx_include/esp_modem_command_library_utils.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "SIM7070_gnss.hpp"
|
||||
|
||||
|
||||
const static char *const TAG = "SIM7070_gnss";
|
||||
constexpr auto const TAG = "SIM7070_gnss";
|
||||
|
||||
|
||||
class LocalFactory: public esp_modem::dce_factory::Factory {
|
||||
namespace gnss_factory {
|
||||
using namespace esp_modem;
|
||||
using namespace dce_factory;
|
||||
|
||||
class LocalFactory: public Factory {
|
||||
using DCE_gnss_ret = std::unique_ptr<DCE_gnss>; // this custom Factory manufactures only unique_ptr<DCE>'s
|
||||
public:
|
||||
static std::unique_ptr<DCE_gnss> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte, esp_netif_t *netif)
|
||||
static DCE_gnss_ret create(const dce_config *config, std::shared_ptr<DTE> dte, esp_netif_t *netif)
|
||||
{
|
||||
return esp_modem::dce_factory::Factory::build_generic_DCE<SIM7070_gnss, DCE_gnss, std::unique_ptr<DCE_gnss>>(config, dte, netif);
|
||||
return Factory::build_generic_DCE<SIM7070_gnss, DCE_gnss, DCE_gnss_ret>
|
||||
(config, std::move(dte), netif);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace gnss_factory
|
||||
|
||||
/**
|
||||
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
|
||||
* @return unique pointer of the resultant DCE
|
||||
@ -45,19 +46,19 @@ std::unique_ptr<DCE_gnss> create_SIM7070_GNSS_dce(const esp_modem::dce_config *c
|
||||
std::shared_ptr<esp_modem::DTE> dte,
|
||||
esp_netif_t *netif)
|
||||
{
|
||||
return LocalFactory::create(config, std::move(dte), netif);
|
||||
return gnss_factory::LocalFactory::create(config, std::move(dte), netif);
|
||||
}
|
||||
|
||||
esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, gps_t &gps)
|
||||
esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, esp_modem_gps_t &gps)
|
||||
{
|
||||
|
||||
ESP_LOGV(TAG, "%s", __func__ );
|
||||
std::string_view out;
|
||||
auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", out);
|
||||
std::string str_out;
|
||||
auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", str_out);
|
||||
if (ret != esp_modem::command_result::OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string_view out(str_out);
|
||||
|
||||
|
||||
constexpr std::string_view pattern = "+CGNSINF: ";
|
||||
@ -329,12 +330,12 @@ esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::Commandabl
|
||||
return esp_modem::command_result::OK;
|
||||
}
|
||||
|
||||
esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(gps_t &gps)
|
||||
esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(esp_modem_gps_t &gps)
|
||||
{
|
||||
return get_gnss_information_sim70xx_lib(dte.get(), gps);
|
||||
}
|
||||
|
||||
esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(gps_t &gps)
|
||||
esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(esp_modem_gps_t &gps)
|
||||
{
|
||||
return device->get_gnss_information_sim70xx(gps);
|
||||
}
|
||||
|
@ -16,15 +16,19 @@
|
||||
#include "nmea_parser.h"
|
||||
|
||||
/**
|
||||
* @brief Definition of a custom modem which inherits from the GenericModule, uses all its methods
|
||||
* and could override any of them. Here, for demonstration purposes only, we redefine just `get_module_name()`
|
||||
* @brief Definition of a custom SIM7070 class with GNSS capabilities.
|
||||
* This inherits from the official esp-modem's SIM7070 device which contains all common library methods.
|
||||
* On top of that, the SIM7070_gnss adds reading GNSS information, which is implemented in a private component.
|
||||
*/
|
||||
class SIM7070_gnss: public esp_modem::SIM7070 {
|
||||
using SIM7070::SIM7070;
|
||||
public:
|
||||
esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps);
|
||||
esp_modem::command_result get_gnss_information_sim70xx(esp_modem_gps_t &gps);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DCE for the SIM7070_gnss. Here we've got to forward the general commands, aa well as the GNSS one.
|
||||
*/
|
||||
class DCE_gnss : public esp_modem::DCE_T<SIM7070_gnss> {
|
||||
public:
|
||||
|
||||
@ -43,14 +47,14 @@ public:
|
||||
|
||||
#undef ESP_MODEM_DECLARE_DCE_COMMAND
|
||||
|
||||
esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps);
|
||||
esp_modem::command_result get_gnss_information_sim70xx(esp_modem_gps_t &gps);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
|
||||
* @return unique pointer of the resultant DCE
|
||||
* @brief Helper create method which employs the customized DCE factory for building DCE_gnss objects
|
||||
* @return unique pointer of the specific DCE
|
||||
*/
|
||||
std::unique_ptr<DCE_gnss> create_SIM7070_GNSS_dce(const esp_modem::dce_config *config,
|
||||
std::shared_ptr<esp_modem::DTE> dte,
|
||||
|
@ -97,7 +97,7 @@ typedef enum {
|
||||
* @brief GPS object
|
||||
*
|
||||
*/
|
||||
struct gps_s {
|
||||
struct esp_modem_gps {
|
||||
float latitude; /*!< Latitude (degrees) */
|
||||
float longitude; /*!< Longitude (degrees) */
|
||||
float altitude; /*!< Altitude (meters) */
|
||||
@ -117,11 +117,7 @@ struct gps_s {
|
||||
float vpa; /*!< Vertical Position Accuracy */
|
||||
};
|
||||
|
||||
typedef struct gps_s gps_t;
|
||||
typedef struct gps_s esp_modem_gps_s_t;
|
||||
|
||||
|
||||
|
||||
typedef struct esp_modem_gps esp_modem_gps_t;
|
||||
|
||||
/**
|
||||
* @brief NMEA Parser Event ID
|
||||
|
@ -195,7 +195,7 @@ extern "C" void app_main(void)
|
||||
|
||||
|
||||
#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1
|
||||
gps_t gps;
|
||||
esp_modem_gps_t gps;
|
||||
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
if (dce->get_gnss_information_sim70xx(gps) == esp_modem::command_result::OK) {
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
namespace esp_modem::dce_commands {
|
||||
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::string &pass_phrase,
|
||||
const std::string &fail_phrase, uint32_t timeout_ms);
|
||||
|
||||
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500);
|
||||
|
||||
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500);
|
||||
|
||||
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500);
|
||||
|
||||
|
||||
|
||||
} // esp_modem::dce_commands
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace esp_modem::dce_commands {
|
||||
|
||||
/**
|
||||
* @brief Generic command that passes on supplied pass_phrase, and fails on fail_phrase
|
||||
* @param t Any "Command-able" class that implements "command()" method
|
||||
* @param command Command to issue
|
||||
* @param pass_phrase Pattern to find in replies to complete the command successfully
|
||||
* @param fail_phrase If this pattern found the command fails immediately
|
||||
* @param timeout_ms Command timeout in ms
|
||||
* @return Generic command return type (OK, FAIL, TIMEOUT)
|
||||
*/
|
||||
command_result generic_command(CommandableIf *t, const std::string &command,
|
||||
const std::string &pass_phrase,
|
||||
const std::string &fail_phrase, uint32_t timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Utility command to send command and return reply (after DCE says OK)
|
||||
* @param t Anything that is "command-able"
|
||||
* @param command Command to issue
|
||||
* @param output String to return
|
||||
* @param timeout_ms
|
||||
* @param timeout_ms Command timeout in ms
|
||||
* @return Generic command return type (OK, FAIL, TIMEOUT)
|
||||
*/
|
||||
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500);
|
||||
|
||||
/**
|
||||
* @brief Generic command that passes on "OK" and fails on "ERROR"
|
||||
* @param t Anything that is "command-able"
|
||||
* @param command Command to issue
|
||||
* @param timeout
|
||||
* @param timeout_ms Command timeout in ms
|
||||
* @return Generic command return type (OK, FAIL, TIMEOUT)
|
||||
*/
|
||||
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms = 500);
|
||||
|
||||
} // esp_modem::dce_commands
|
@ -10,17 +10,16 @@
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||
#include "cxx_include/esp_modem_command_library.hpp"
|
||||
#include "cxx_include/command_library.hpp"
|
||||
|
||||
#include "cxx_include/esp_modem_command_library_utils.hpp"
|
||||
|
||||
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)
|
||||
static 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) {
|
||||
@ -52,7 +51,7 @@ command_result generic_command(CommandableIf *t, const std::string &command,
|
||||
return generic_command(t, command, pass, fail, timeout_ms);
|
||||
}
|
||||
|
||||
command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms)
|
||||
static 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__ );
|
||||
return t->command(command, [&](uint8_t *data, size_t len) {
|
||||
@ -91,10 +90,10 @@ command_result generic_get_string(CommandableIf *t, const std::string &command,
|
||||
}
|
||||
|
||||
|
||||
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout)
|
||||
command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms)
|
||||
{
|
||||
ESP_LOGV(TAG, "%s", __func__ );
|
||||
return generic_command(t, command, "OK", "ERROR", timeout);
|
||||
return generic_command(t, command, "OK", "ERROR", timeout_ms);
|
||||
}
|
||||
|
||||
command_result sync(CommandableIf *t)
|
||||
|
Reference in New Issue
Block a user