mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-12-04 16:19:20 +01:00
fix(modem): Replace MQTT client with simple ping command
This commit is contained in:
@@ -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 ".")
|
||||
|
||||
@@ -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: '*'
|
||||
|
||||
@@ -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<StatusHandler *>(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<ip_event_t>(id);
|
||||
signal.set(IP_Event);
|
||||
} else if (id == IP_EVENT_PPP_LOST_IP) {
|
||||
ip_event_type = static_cast<ip_event_t>(id);
|
||||
signal.set(IP_Event);
|
||||
}
|
||||
ip_event_type = static_cast<ip_event_t>(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;
|
||||
|
||||
@@ -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 <memory>
|
||||
#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<MqttClientHandle>(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;
|
||||
@@ -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 <string>
|
||||
#include <memory>
|
||||
|
||||
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<MqttClientHandle> h;
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user