From 0ccaf2c0bbc784ec3d5896f81b05e830348e7dbf Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 24 Nov 2025 09:07:19 +0100 Subject: [PATCH] fix(modem): Replace MQTT client with simple ping command --- .../simple_cmux_client/main/CMakeLists.txt | 2 +- .../simple_cmux_client/main/idf_component.yml | 6 +- .../main/simple_cmux_client_main.cpp | 67 ++++-------- .../main/simple_mqtt_client.cpp | 100 ------------------ .../main/simple_mqtt_client.hpp | 81 -------------- .../simple_cmux_client/pytest_cmux.py | 25 ++--- 6 files changed, 30 insertions(+), 251 deletions(-) delete mode 100644 components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.cpp delete mode 100644 components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.hpp diff --git a/components/esp_modem/examples/simple_cmux_client/main/CMakeLists.txt b/components/esp_modem/examples/simple_cmux_client/main/CMakeLists.txt index 15b3f752d..ba28f9672 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/CMakeLists.txt +++ b/components/esp_modem/examples/simple_cmux_client/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "simple_cmux_client_main.cpp" "simple_mqtt_client.cpp" +idf_component_register(SRCS "simple_cmux_client_main.cpp" INCLUDE_DIRS ".") diff --git a/components/esp_modem/examples/simple_cmux_client/main/idf_component.yml b/components/esp_modem/examples/simple_cmux_client/main/idf_component.yml index 228838410..ea41f4cad 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/idf_component.yml +++ b/components/esp_modem/examples/simple_cmux_client/main/idf_component.yml @@ -2,7 +2,5 @@ dependencies: espressif/esp_modem: version: "^1.0.1" override_path: "../../../" - espressif/mqtt: - rules: - - if: idf_version >=6.0 - version: ^1.0.0 + console_cmd_ping: + version: '*' diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp index 50df83219..272d6314a 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp +++ b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -21,11 +21,13 @@ #include "cxx_include/esp_modem_dte.hpp" #include "esp_modem_config.h" #include "cxx_include/esp_modem_api.hpp" -#include "simple_mqtt_client.hpp" #include "esp_vfs_dev.h" // For optional VFS support #include "esp_https_ota.h" // For potential OTA configuration #include "vfs_resource/vfs_create.hpp" #include "SIM7070_gnss.hpp" +#include "esp_console.h" +#include "console_ping.h" +#include "esp_event.h" #if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE) #define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE @@ -35,18 +37,13 @@ #define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW #endif -#define BROKER_URL CONFIG_BROKER_URI - - using namespace esp_modem; static const char *TAG = "cmux_example"; class StatusHandler { public: - static constexpr auto IP_Event = SignalGroup::bit0; - static constexpr auto MQTT_Connect = SignalGroup::bit1; - static constexpr auto MQTT_Data = SignalGroup::bit2; + static constexpr auto IP_Event = SignalGroup::bit0; StatusHandler() { @@ -58,12 +55,6 @@ public: esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_event); } - void handle_mqtt(MqttClient *client) - { - mqtt_client = client; - client->register_handler(ESP_EVENT_ANY_ID, on_event, this); - } - esp_err_t wait_for(decltype(IP_Event) event, int milliseconds) { return signal.wait_any(event, milliseconds); @@ -80,8 +71,6 @@ private: auto *handler = static_cast(arg); if (base == IP_EVENT) { handler->ip_event(event, data); - } else { - handler->mqtt_event(event, data); } } @@ -92,27 +81,16 @@ private: ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&event->ip_info.ip)); ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask)); ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.gw)); + ip_event_type = static_cast(id); signal.set(IP_Event); } else if (id == IP_EVENT_PPP_LOST_IP) { + ip_event_type = static_cast(id); signal.set(IP_Event); } - ip_event_type = static_cast(id); - } - - void mqtt_event(int32_t event, void *data) - { - if (mqtt_client && event == mqtt_client->get_event(MqttClient::Event::CONNECT)) { - signal.set(MQTT_Connect); - } else if (mqtt_client && event == mqtt_client->get_event(MqttClient::Event::DATA)) { - ESP_LOGI(TAG, " TOPIC: %s", mqtt_client->get_topic(data).c_str()); - ESP_LOGI(TAG, " DATA: %s", mqtt_client->get_data(data).c_str()); - signal.set(MQTT_Data); - } } esp_modem::SignalGroup signal{}; - MqttClient *mqtt_client{nullptr}; - ip_event_t ip_event_type; + ip_event_t ip_event_type{}; }; @@ -122,6 +100,11 @@ extern "C" void app_main(void) ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_netif_init()); + // Initialize console REPL, register ping and start it + ESP_ERROR_CHECK(console_cmd_init()); + ESP_ERROR_CHECK(console_cmd_ping_register()); + ESP_ERROR_CHECK(console_cmd_start()); + /* Configure and create the DTE */ esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); /* setup UART specific configuration based on kconfig options */ @@ -175,7 +158,7 @@ extern "C" void app_main(void) #endif assert(dce); - /* Try to connect to the network and publish an mqtt topic */ + /* Try to connect to the network */ StatusHandler handler; if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { @@ -224,24 +207,14 @@ extern "C" void app_main(void) } else if (handler.get_ip_event_type() == IP_EVENT_PPP_GOT_IP) { std::cout << "Got IP address" << std::endl; - /* When connected to network, subscribe and publish some MQTT data */ - MqttClient mqtt(BROKER_URL); - handler.handle_mqtt(&mqtt); - mqtt.connect(); - if (!handler.wait_for(StatusHandler::MQTT_Connect, 60000)) { - ESP_LOGE(TAG, "Cannot connect to %s within specified timeout... exiting", BROKER_URL); + /* When connected to network, we can ping the internet */ + int ping_ret_val; + ESP_ERROR_CHECK(esp_console_run("ping www.espressif.com", &ping_ret_val)); + ESP_LOGI(TAG, "Ping command finished with return value: %d", ping_ret_val); + if (ping_ret_val != 0) { + ESP_LOGE(TAG, "Ping command failed with return value: %d", ping_ret_val); return; } - std::cout << "Connected" << std::endl; - - mqtt.subscribe(CONFIG_EXAMPLE_MQTT_TEST_TOPIC); - mqtt.publish(CONFIG_EXAMPLE_MQTT_TEST_TOPIC, CONFIG_EXAMPLE_MQTT_TEST_DATA); - if (!handler.wait_for(StatusHandler::MQTT_Data, 60000)) { - ESP_LOGE(TAG, "Didn't receive published data within specified timeout... exiting"); - return; - } - std::cout << "Received MQTT data" << std::endl; - } else if (handler.get_ip_event_type() == IP_EVENT_PPP_LOST_IP) { ESP_LOGE(TAG, "PPP client has lost connection... exiting"); return; diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.cpp deleted file mode 100644 index 1f86e5a0a..000000000 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -/* - * PPPoS Client Example -*/ - -#include -#include "mqtt_client.h" -#include "simple_mqtt_client.hpp" - -/** - * Reference to the MQTT event base - */ -ESP_EVENT_DECLARE_BASE(MQTT_EVENTS); - -/** - * Thin wrapper around C mqtt_client - */ -struct MqttClientHandle { - explicit MqttClientHandle(const std::string &uri) - { - esp_mqtt_client_config_t config = { }; -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - config.broker.address.uri = uri.c_str(); -#else - config.uri = uri.c_str(); -#endif - client = esp_mqtt_client_init(&config); - } - - ~MqttClientHandle() - { - esp_mqtt_client_destroy(client); - } - - esp_mqtt_client_handle_t client; -}; - -/** - * @brief Definitions of MqttClient methods - */ -MqttClient::MqttClient(const std::string &uri): - h(std::unique_ptr(new MqttClientHandle(uri))) -{} - -void MqttClient::connect() -{ - esp_mqtt_client_start(h->client); -} - -int32_t MqttClient::get_event(MqttClient::Event ev) -{ - switch (ev) { - case Event::CONNECT: { - return MQTT_EVENT_CONNECTED; - } - case Event::DATA: - return MQTT_EVENT_DATA; - } - return -1; -} - -int MqttClient::publish(const std::string &topic, const std::string &data, int qos) -{ - return esp_mqtt_client_publish(h->client, topic.c_str(), data.c_str(), 0, qos, 0); -} - -int MqttClient::subscribe(const std::string &topic, int qos) -{ - return esp_mqtt_client_subscribe(h->client, topic.c_str(), qos); -} - -std::string MqttClient::get_topic(void *event_data) -{ - auto event = (esp_mqtt_event_handle_t)event_data; - if (event == nullptr || event->client != h->client) - return {}; - - return std::string(event->topic, event->topic_len); -} - -std::string MqttClient::get_data(void *event_data) -{ - auto event = (esp_mqtt_event_handle_t)event_data; - if (event == nullptr || event->client != h->client) - return {}; - - return std::string(event->data, event->data_len); -} - -void MqttClient::register_handler(int32_t event_id, esp_event_handler_t event_handler, void *arg) -{ - ESP_ERROR_CHECK(esp_mqtt_client_register_event(h->client, MQTT_EVENT_ANY, event_handler, arg)); -} - -MqttClient::~MqttClient() = default; diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.hpp b/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.hpp deleted file mode 100644 index f726e4639..000000000 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_mqtt_client.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -/* - * PPPoS Client Example -*/ -#pragma once - -#include -#include - -struct MqttClientHandle; - -/** - * @brief Simple MQTT client wrapper - */ -class MqttClient { -public: - enum class Event { - CONNECT, - DATA, - }; - - explicit MqttClient(const std::string &uri); - ~MqttClient(); - - /** - * @brief Start the mqtt-client - */ - void connect(); - - /** - * @brief Publish to topic - * @param topic Topic to publish - * @param data Data to publish - * @param qos QoS (0 by default) - * @return message id - */ - int publish(const std::string &topic, const std::string &data, int qos = 0); - - /** - * @brief Subscribe to a topic - * @param topic Topic to subscribe - * @param qos QoS (0 by default) - * @return message id - */ - int subscribe(const std::string &topic, int qos = 0); - - /** - * @brief Get topic from event data - * @return String topic - */ - std::string get_topic(void *); - - /** - * @brief Get published data from event - * @return String representation of the data - */ - std::string get_data(void *); - - /** - * @brief Register MQTT event - * @param id Event id - * @param event_handler Event handler - * @param event_handler_arg Event handler parameters - */ - void register_handler(int32_t id, esp_event_handler_t event_handler, void *event_handler_arg); - - /** - * @brief Convert internal MQTT event to standard ESPEvent - * @param ev internal mqtt event - * @return corresponding esp_event id - */ - static int32_t get_event(Event ev); - -private: - std::unique_ptr h; -}; diff --git a/components/esp_modem/examples/simple_cmux_client/pytest_cmux.py b/components/esp_modem/examples/simple_cmux_client/pytest_cmux.py index af82e7798..a44c72b4f 100644 --- a/components/esp_modem/examples/simple_cmux_client/pytest_cmux.py +++ b/components/esp_modem/examples/simple_cmux_client/pytest_cmux.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 from __future__ import print_function, unicode_literals @@ -6,21 +6,10 @@ from __future__ import print_function, unicode_literals def test_cmux_connection(dut): """ steps: - 1. initializes connection with SIM800 - 2. checks we get an IP - 3. checks for the MQTT events + 1. checks we're in CMUX mode and get an IP + 2. checks for ping command """ - # Get topic and data from Kconfig - topic = '' - data = '' - try: - topic = dut.app.sdkconfig.get('EXAMPLE_MQTT_TEST_TOPIC') - data = dut.app.sdkconfig.get('EXAMPLE_MQTT_TEST_DATA') - except Exception: - print('ENV_TEST_FAILURE: Cannot find broker url in sdkconfig') - raise - # Check the sequence of connecting, publishing, disconnecting - dut.expect('Modem has correctly entered multiplexed') - # Check for MQTT connection and the data event - dut.expect(f'TOPIC: {topic}') - dut.expect(f'DATA: {data}') + # Check we're in CMUX mode and get an IP + dut.expect('Modem has correctly entered multiplexed command/data mode', timeout=60) + # Check for ping command + dut.expect('Ping command finished with return value: 0', timeout=30)