Merge pull request #214 from david-cermak/bugfix/modem_cxx_broken_components

fix(esp_modem): Fix cmux client compilation issue
This commit is contained in:
david-cermak
2023-01-31 14:42:46 +01:00
committed by GitHub
10 changed files with 142 additions and 69 deletions

View File

@ -184,4 +184,22 @@ menu "Example Configuration"
endmenu
config EXAMPLE_MQTT_BROKER_URI
string "MQTT Broker URL"
default "mqtt://mqtt.eclipseprojects.io"
help
URL of the mqtt broker which this example connects to.
config EXAMPLE_MQTT_TEST_TOPIC
string "MQTT topic to publish/subscribe"
default "/topic/esp-pppos"
help
MQTT topic, which we subscribe on and publish to.
config EXAMPLE_MQTT_TEST_DATA
string "MQTT data to publish/receive"
default "esp32-pppos"
help
MQTT data message, which we publish and expect to receive.
endmenu

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -30,7 +30,6 @@
#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW
#endif
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
static const char *TAG = "pppos_example";
static EventGroupHandle_t event_group = NULL;
@ -68,7 +67,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_subscribe(client, "/topic/esp-pppos", 0);
msg_id = esp_mqtt_client_subscribe(client, CONFIG_EXAMPLE_MQTT_TEST_TOPIC, 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
@ -76,7 +75,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
msg_id = esp_mqtt_client_publish(client, "/topic/esp-pppos", "esp32-pppos", 0, 0, 0);
msg_id = esp_mqtt_client_publish(client, CONFIG_EXAMPLE_MQTT_TEST_TOPIC, CONFIG_EXAMPLE_MQTT_TEST_DATA, 0, 0, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
@ -271,11 +270,11 @@ void app_main(void)
/* Config MQTT */
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
esp_mqtt_client_config_t mqtt_config = {
.broker.address.uri = BROKER_URL,
.broker.address.uri = CONFIG_EXAMPLE_MQTT_BROKER_URI,
};
#else
esp_mqtt_client_config_t mqtt_config = {
.uri = BROKER_URL,
.uri = CONFIG_EXAMPLE_MQTT_BROKER_URI,
};
#endif
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
from __future__ import print_function, unicode_literals
@ -16,7 +16,7 @@ def test_pppos_connect(dut):
# Check for MQTT connection and the data event
dut.expect('MQTT_EVENT_CONNECTED')
dut.expect('MQTT_EVENT_DATA')
dut.expect('TOPIC=/topic/esp-pppos')
dut.expect('TOPIC=/ci/esp-modem/pppos-client')
dut.expect('DATA=esp32-pppos')
# Check that we have disconnected
dut.expect('User interrupted event')

View File

@ -9,5 +9,6 @@ CONFIG_EXAMPLE_MODEM_UART_RX_PIN=5
CONFIG_EXAMPLE_MODEM_DEVICE_SIM800=y
CONFIG_EXAMPLE_MODEM_DEVICE_BG96=n
CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client"
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y

View File

@ -2,7 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS "../.." $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component)
set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(simple_cmux_client)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -17,10 +17,10 @@
#include "freertos/event_groups.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_event.h"
#include "cxx_include/esp_modem_dte.hpp"
#include "esp_modem_config.h"
#include "cxx_include/esp_modem_api.hpp"
#include "esp_event_cxx.hpp"
#include "simple_mqtt_client.hpp"
#include "esp_vfs_dev.h" // For optional VFS support
#include "esp_https_ota.h" // For potential OTA configuration
@ -39,16 +39,87 @@
using namespace esp_modem;
using namespace idf::event;
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;
StatusHandler()
{
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_event, this));
}
~StatusHandler()
{
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);
}
ip_event_t get_ip_event_type()
{
return ip_event_type;
}
private:
static void on_event(void *arg, esp_event_base_t base, int32_t event, void *data)
{
auto *handler = static_cast<StatusHandler *>(arg);
if (base == IP_EVENT) {
handler->ip_event(event, data);
} else {
handler->mqtt_event(event, data);
}
}
void ip_event(int32_t id, void *data)
{
if (id == IP_EVENT_PPP_GOT_IP) {
auto *event = (ip_event_got_ip_t *)data;
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));
signal.set(IP_Event);
} else if (id == IP_EVENT_PPP_LOST_IP) {
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;
};
extern "C" void app_main(void)
{
/* Init and register system/core components */
auto loop = std::make_shared<ESPEventLoop>();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_netif_init());
/* Configure and create the DTE */
@ -145,45 +216,32 @@ extern "C" void app_main(void)
#endif
/* Try to connect to the network and publish an mqtt topic */
ESPEventHandlerSync event_handler(loop);
event_handler.listen_to(ESPEvent(IP_EVENT, ESPEventID(ESP_EVENT_ANY_ID)));
auto result = event_handler.wait_event_for(std::chrono::milliseconds(60000));
if (result.timeout) {
StatusHandler handler;
if (!handler.wait_for(StatusHandler::IP_Event, 60000)) {
ESP_LOGE(TAG, "Cannot get IP within specified timeout... exiting");
return;
} else if (result.event.id == ESPEventID(IP_EVENT_PPP_GOT_IP)) {
auto *event = (ip_event_got_ip_t *)result.ev_data;
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));
} 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);
event_handler.listen_to(MqttClient::get_event(MqttClient::Event::CONNECT));
event_handler.listen_to(MqttClient::get_event(MqttClient::Event::DATA));
auto reg = loop->register_event(MqttClient::get_event(MqttClient::Event::DATA),
[&mqtt](const ESPEvent & event, void *data) {
std::cout << " TOPIC:" << mqtt.get_topic(data) << std::endl;
std::cout << " DATA:" << mqtt.get_data(data) << std::endl;
});
handler.handle_mqtt(&mqtt);
mqtt.connect();
while (true) {
result = event_handler.wait_event_for(std::chrono::milliseconds(60000));
if (result.event == MqttClient::get_event(MqttClient::Event::CONNECT)) {
mqtt.subscribe("/topic/esp-modem");
mqtt.publish("/topic/esp-modem", "Hello modem");
continue;
} else if (result.event == MqttClient::get_event(MqttClient::Event::DATA)) {
std::cout << "Data received" << std::endl;
break; /* Continue with CMUX example after getting data from MQTT */
} else {
break;
}
if (!handler.wait_for(StatusHandler::MQTT_Connect, 60000)) {
ESP_LOGE(TAG, "Cannot connect to %s within specified timeout... exiting", BROKER_URL);
return;
}
std::cout << "Connected" << std::endl;
} else if (result.event.id == ESPEventID(IP_EVENT_PPP_LOST_IP)) {
mqtt.subscribe("/topic/esp-modem");
mqtt.publish("/topic/esp-modem", "Hello modem");
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;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -10,11 +10,8 @@
#include <memory>
#include "mqtt_client.h"
#include "esp_event_cxx.hpp"
#include "simple_mqtt_client.hpp"
using namespace idf::event;
/**
* Reference to the MQTT event base
*/
@ -33,7 +30,6 @@ struct MqttClientHandle {
config.uri = uri.c_str();
#endif
client = esp_mqtt_client_init(&config);
esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, this);
}
~MqttClientHandle()
@ -41,12 +37,6 @@ struct MqttClientHandle {
esp_mqtt_client_destroy(client);
}
static void mqtt_event_handler(void *args, esp_event_base_t base, int32_t id, void *data)
{
// forwards the internal event to the global ESPEvent
esp_event_post(base, id, data, sizeof(esp_mqtt_event_t), portMAX_DELAY);
}
esp_mqtt_client_handle_t client;
};
@ -62,16 +52,16 @@ void MqttClient::connect()
esp_mqtt_client_start(h->client);
}
idf::event::ESPEvent MqttClient::get_event(MqttClient::Event ev)
int32_t MqttClient::get_event(MqttClient::Event ev)
{
switch (ev) {
case Event::CONNECT: {
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_CONNECTED) };
return MQTT_EVENT_CONNECTED;
}
case Event::DATA:
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_DATA) };
return MQTT_EVENT_DATA;
}
return { };
return -1;
}
int MqttClient::publish(const std::string &topic, const std::string &data, int qos)
@ -102,4 +92,9 @@ std::string MqttClient::get_data(void *event_data)
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;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -11,7 +11,6 @@
#include <string>
#include <memory>
#include "esp_event_cxx.hpp"
struct MqttClientHandle;
@ -62,12 +61,20 @@ public:
*/
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 ESPEvent
* @return corresponding esp_event id
*/
static idf::event::ESPEvent get_event(Event ev);
static int32_t get_event(Event ev);
private:
std::unique_ptr<MqttClientHandle> h;

View File

@ -1,4 +1,4 @@
version: "0.1.25"
version: "0.1.26"
description: esp modem
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem
dependencies:

View File

@ -55,7 +55,6 @@
#define INC_TASK_H
#define pdMS_TO_TICKS(a) a
#define portTICK_PERIOD_MS 10
#define xSemaphoreTake(s,d) true
#define xTaskDelete(a)
#define vTaskDelete(a) free(a)
@ -87,10 +86,6 @@ typedef int BaseType_t;
typedef uint32_t TickType_t;
extern const char *WIFI_EVENT;
extern const char *IP_EVENT;
extern const char *ETH_EVENT;
struct udp_pcb {
uint8_t dummy;
};