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 ".")
|
INCLUDE_DIRS ".")
|
||||||
|
|||||||
@@ -2,7 +2,5 @@ dependencies:
|
|||||||
espressif/esp_modem:
|
espressif/esp_modem:
|
||||||
version: "^1.0.1"
|
version: "^1.0.1"
|
||||||
override_path: "../../../"
|
override_path: "../../../"
|
||||||
espressif/mqtt:
|
console_cmd_ping:
|
||||||
rules:
|
version: '*'
|
||||||
- if: idf_version >=6.0
|
|
||||||
version: ^1.0.0
|
|
||||||
|
|||||||
@@ -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
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@@ -21,11 +21,13 @@
|
|||||||
#include "cxx_include/esp_modem_dte.hpp"
|
#include "cxx_include/esp_modem_dte.hpp"
|
||||||
#include "esp_modem_config.h"
|
#include "esp_modem_config.h"
|
||||||
#include "cxx_include/esp_modem_api.hpp"
|
#include "cxx_include/esp_modem_api.hpp"
|
||||||
#include "simple_mqtt_client.hpp"
|
|
||||||
#include "esp_vfs_dev.h" // For optional VFS support
|
#include "esp_vfs_dev.h" // For optional VFS support
|
||||||
#include "esp_https_ota.h" // For potential OTA configuration
|
#include "esp_https_ota.h" // For potential OTA configuration
|
||||||
#include "vfs_resource/vfs_create.hpp"
|
#include "vfs_resource/vfs_create.hpp"
|
||||||
#include "SIM7070_gnss.hpp"
|
#include "SIM7070_gnss.hpp"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "console_ping.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
|
#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE)
|
||||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
|
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE
|
||||||
@@ -35,9 +37,6 @@
|
|||||||
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW
|
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BROKER_URL CONFIG_BROKER_URI
|
|
||||||
|
|
||||||
|
|
||||||
using namespace esp_modem;
|
using namespace esp_modem;
|
||||||
|
|
||||||
static const char *TAG = "cmux_example";
|
static const char *TAG = "cmux_example";
|
||||||
@@ -45,8 +44,6 @@ static const char *TAG = "cmux_example";
|
|||||||
class StatusHandler {
|
class StatusHandler {
|
||||||
public:
|
public:
|
||||||
static constexpr auto IP_Event = SignalGroup::bit0;
|
static constexpr auto IP_Event = SignalGroup::bit0;
|
||||||
static constexpr auto MQTT_Connect = SignalGroup::bit1;
|
|
||||||
static constexpr auto MQTT_Data = SignalGroup::bit2;
|
|
||||||
|
|
||||||
StatusHandler()
|
StatusHandler()
|
||||||
{
|
{
|
||||||
@@ -58,12 +55,6 @@ public:
|
|||||||
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_event);
|
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)
|
esp_err_t wait_for(decltype(IP_Event) event, int milliseconds)
|
||||||
{
|
{
|
||||||
return signal.wait_any(event, milliseconds);
|
return signal.wait_any(event, milliseconds);
|
||||||
@@ -80,8 +71,6 @@ private:
|
|||||||
auto *handler = static_cast<StatusHandler *>(arg);
|
auto *handler = static_cast<StatusHandler *>(arg);
|
||||||
if (base == IP_EVENT) {
|
if (base == IP_EVENT) {
|
||||||
handler->ip_event(event, data);
|
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, "IP : " IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask));
|
ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask));
|
||||||
ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.gw));
|
ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.gw));
|
||||||
|
ip_event_type = static_cast<ip_event_t>(id);
|
||||||
signal.set(IP_Event);
|
signal.set(IP_Event);
|
||||||
} else if (id == IP_EVENT_PPP_LOST_IP) {
|
} else if (id == IP_EVENT_PPP_LOST_IP) {
|
||||||
signal.set(IP_Event);
|
|
||||||
}
|
|
||||||
ip_event_type = static_cast<ip_event_t>(id);
|
ip_event_type = static_cast<ip_event_t>(id);
|
||||||
}
|
signal.set(IP_Event);
|
||||||
|
|
||||||
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{};
|
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_event_loop_create_default());
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
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 */
|
/* Configure and create the DTE */
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
/* setup UART specific configuration based on kconfig options */
|
/* setup UART specific configuration based on kconfig options */
|
||||||
@@ -175,7 +158,7 @@ extern "C" void app_main(void)
|
|||||||
#endif
|
#endif
|
||||||
assert(dce);
|
assert(dce);
|
||||||
|
|
||||||
/* Try to connect to the network and publish an mqtt topic */
|
/* Try to connect to the network */
|
||||||
StatusHandler handler;
|
StatusHandler handler;
|
||||||
|
|
||||||
if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
|
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) {
|
} else if (handler.get_ip_event_type() == IP_EVENT_PPP_GOT_IP) {
|
||||||
std::cout << "Got IP address" << std::endl;
|
std::cout << "Got IP address" << std::endl;
|
||||||
|
|
||||||
/* When connected to network, subscribe and publish some MQTT data */
|
/* When connected to network, we can ping the internet */
|
||||||
MqttClient mqtt(BROKER_URL);
|
int ping_ret_val;
|
||||||
handler.handle_mqtt(&mqtt);
|
ESP_ERROR_CHECK(esp_console_run("ping www.espressif.com", &ping_ret_val));
|
||||||
mqtt.connect();
|
ESP_LOGI(TAG, "Ping command finished with return value: %d", ping_ret_val);
|
||||||
if (!handler.wait_for(StatusHandler::MQTT_Connect, 60000)) {
|
if (ping_ret_val != 0) {
|
||||||
ESP_LOGE(TAG, "Cannot connect to %s within specified timeout... exiting", BROKER_URL);
|
ESP_LOGE(TAG, "Ping command failed with return value: %d", ping_ret_val);
|
||||||
return;
|
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) {
|
} else if (handler.get_ip_event_type() == IP_EVENT_PPP_LOST_IP) {
|
||||||
ESP_LOGE(TAG, "PPP client has lost connection... exiting");
|
ESP_LOGE(TAG, "PPP client has lost connection... exiting");
|
||||||
return;
|
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
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
@@ -6,21 +6,10 @@ from __future__ import print_function, unicode_literals
|
|||||||
def test_cmux_connection(dut):
|
def test_cmux_connection(dut):
|
||||||
"""
|
"""
|
||||||
steps:
|
steps:
|
||||||
1. initializes connection with SIM800
|
1. checks we're in CMUX mode and get an IP
|
||||||
2. checks we get an IP
|
2. checks for ping command
|
||||||
3. checks for the MQTT events
|
|
||||||
"""
|
"""
|
||||||
# Get topic and data from Kconfig
|
# Check we're in CMUX mode and get an IP
|
||||||
topic = ''
|
dut.expect('Modem has correctly entered multiplexed command/data mode', timeout=60)
|
||||||
data = ''
|
# Check for ping command
|
||||||
try:
|
dut.expect('Ping command finished with return value: 0', timeout=30)
|
||||||
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}')
|
|
||||||
|
|||||||
Reference in New Issue
Block a user