mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 13:44:32 +02:00
Merge branch 'feature/esp_netif_ppp_params' into 'master'
Examples: Add esp_modem example to experimental cxx components Closes IDF-1923, IDFGH-217, IDFGH-2608, IDFGH-4838, IDFGH-1229, IDFGH-3848, and IDFGH-3809 See merge request espressif/esp-idf!13161
This commit is contained in:
@@ -38,6 +38,11 @@ typedef struct esp_netif_ppp_config {
|
|||||||
*/
|
*/
|
||||||
#define NETIF_PP_PHASE_OFFSET (0x100)
|
#define NETIF_PP_PHASE_OFFSET (0x100)
|
||||||
|
|
||||||
|
/** @brief event id offset for internal errors
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define NETIF_PPP_INTERNAL_ERR_OFFSET (0x200)
|
||||||
|
|
||||||
/** @brief event ids for different PPP related events
|
/** @brief event ids for different PPP related events
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +73,7 @@ typedef enum {
|
|||||||
NETIF_PPP_PHASE_RUNNING = NETIF_PP_PHASE_OFFSET + 10,
|
NETIF_PPP_PHASE_RUNNING = NETIF_PP_PHASE_OFFSET + 10,
|
||||||
NETIF_PPP_PHASE_TERMINATE = NETIF_PP_PHASE_OFFSET + 11,
|
NETIF_PPP_PHASE_TERMINATE = NETIF_PP_PHASE_OFFSET + 11,
|
||||||
NETIF_PPP_PHASE_DISCONNECT = NETIF_PP_PHASE_OFFSET + 12,
|
NETIF_PPP_PHASE_DISCONNECT = NETIF_PP_PHASE_OFFSET + 12,
|
||||||
|
NETIF_PPP_CONNECT_FAILED = NETIF_PPP_INTERNAL_ERR_OFFSET + 0,
|
||||||
} esp_netif_ppp_status_event_t;
|
} esp_netif_ppp_status_event_t;
|
||||||
|
|
||||||
/** @brief definitions of different authorisation types
|
/** @brief definitions of different authorisation types
|
||||||
@@ -89,7 +95,8 @@ typedef enum {
|
|||||||
* @param[in] user User name
|
* @param[in] user User name
|
||||||
* @param[in] passwd Password
|
* @param[in] passwd Password
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP
|
* @return ESP_OK on success,
|
||||||
|
* ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd);
|
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd);
|
||||||
|
|
||||||
@@ -98,10 +105,20 @@ esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t autht
|
|||||||
* @param[in] esp_netif Handle to esp-netif instance
|
* @param[in] esp_netif Handle to esp-netif instance
|
||||||
* @param[in] config Pointer to PPP netif configuration structure
|
* @param[in] config Pointer to PPP netif configuration structure
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP
|
* @return ESP_OK on success,
|
||||||
|
* ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config);
|
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config);
|
||||||
|
|
||||||
|
/** @brief Gets parameters configured in the supplied esp-netif.
|
||||||
|
*
|
||||||
|
* @param[in] esp_netif Handle to esp-netif instance
|
||||||
|
* @param[out] config Pointer to PPP netif configuration structure
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success,
|
||||||
|
* ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null
|
||||||
|
*/
|
||||||
|
esp_err_t esp_netif_ppp_get_params(esp_netif_t *netif, esp_netif_ppp_config_t *config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -786,7 +786,7 @@ esp_err_t esp_netif_start(esp_netif_t *esp_netif)
|
|||||||
if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
|
if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
|
||||||
#if CONFIG_PPP_SUPPORT
|
#if CONFIG_PPP_SUPPORT
|
||||||
// No need to start PPP interface in lwip thread
|
// No need to start PPP interface in lwip thread
|
||||||
esp_err_t ret = esp_netif_start_ppp(esp_netif->related_data);
|
esp_err_t ret = esp_netif_start_ppp(esp_netif);
|
||||||
if (ret == ESP_OK) {
|
if (ret == ESP_OK) {
|
||||||
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
|
esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
|
||||||
}
|
}
|
||||||
|
@@ -296,8 +296,9 @@ netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif
|
|||||||
return (netif_related_data_t *)ppp_obj;
|
return (netif_related_data_t *)ppp_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_netif_start_ppp(netif_related_data_t *netif_related)
|
esp_err_t esp_netif_start_ppp(esp_netif_t *esp_netif)
|
||||||
{
|
{
|
||||||
|
netif_related_data_t *netif_related = esp_netif->related_data;
|
||||||
lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related;
|
lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related;
|
||||||
assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF);
|
assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF);
|
||||||
|
|
||||||
@@ -305,6 +306,9 @@ esp_err_t esp_netif_start_ppp(netif_related_data_t *netif_related)
|
|||||||
esp_err_t err = pppapi_connect(ppp_ctx->ppp, 0);
|
esp_err_t err = pppapi_connect(ppp_ctx->ppp, 0);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "%s: PPP connection cannot be started", __func__);
|
ESP_LOGE(TAG, "%s: PPP connection cannot be started", __func__);
|
||||||
|
if (ppp_ctx->ppp_error_event_enabled) {
|
||||||
|
esp_event_post(NETIF_PPP_STATUS, NETIF_PPP_CONNECT_FAILED, esp_netif, sizeof(esp_netif), 0);
|
||||||
|
}
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -343,10 +347,26 @@ void esp_netif_destroy_ppp(netif_related_data_t *netif_related)
|
|||||||
|
|
||||||
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config)
|
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config)
|
||||||
{
|
{
|
||||||
|
if (netif == NULL || netif->related_data == NULL || config == NULL ||
|
||||||
|
((struct lwip_peer2peer_ctx *)netif->related_data)->base.netif_type != PPP_LWIP_NETIF) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
struct lwip_peer2peer_ctx *obj = (struct lwip_peer2peer_ctx *)netif->related_data;
|
struct lwip_peer2peer_ctx *obj = (struct lwip_peer2peer_ctx *)netif->related_data;
|
||||||
obj->ppp_phase_event_enabled = config->ppp_phase_event_enabled;
|
obj->ppp_phase_event_enabled = config->ppp_phase_event_enabled;
|
||||||
obj->ppp_error_event_enabled = config->ppp_error_event_enabled;
|
obj->ppp_error_event_enabled = config->ppp_error_event_enabled;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_netif_ppp_get_params(esp_netif_t *netif, esp_netif_ppp_config_t *config)
|
||||||
|
{
|
||||||
|
if (netif == NULL || netif->related_data == NULL || config == NULL ||
|
||||||
|
((struct lwip_peer2peer_ctx *)netif->related_data)->base.netif_type != PPP_LWIP_NETIF) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
struct lwip_peer2peer_ctx *obj = (struct lwip_peer2peer_ctx *)netif->related_data;
|
||||||
|
config->ppp_phase_event_enabled = obj->ppp_phase_event_enabled;
|
||||||
|
config->ppp_error_event_enabled = obj->ppp_error_event_enabled;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */
|
#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */
|
||||||
|
@@ -32,12 +32,12 @@ netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif
|
|||||||
/**
|
/**
|
||||||
* @brief Creates new PPP related structure
|
* @brief Creates new PPP related structure
|
||||||
*
|
*
|
||||||
* @param[in] netif_related pointer to internal ppp context instance
|
* @param[in] esp_netif pointer esp-netif instance
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK on success
|
* - ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_netif_start_ppp(netif_related_data_t *netif_related);
|
esp_err_t esp_netif_start_ppp(esp_netif_t *esp_netif);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Data path API to input incoming packets to PPP
|
* @brief Data path API to input incoming packets to PPP
|
||||||
|
8
examples/cxx/experimental/esp_modem_cxx/CMakeLists.txt
Normal file
8
examples/cxx/experimental/esp_modem_cxx/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(simple_cxx_ppp_client)
|
18
examples/cxx/experimental/esp_modem_cxx/README.md
Normal file
18
examples/cxx/experimental/esp_modem_cxx/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
| Supported Targets | ESP32 | ESP32-S2 |
|
||||||
|
| ----------------- | ----- | -------- |
|
||||||
|
|
||||||
|
# Simple example of esp_modem component
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This example demonstrates the use of the [esp-modem component](https://components.espressif.com/component/espressif/esp_modem) to connect to a network and send some AT commands.
|
||||||
|
It uses modem CMUX mode so that commands and network could be used at the same time.
|
||||||
|
|
||||||
|
## About the esp_modem
|
||||||
|
|
||||||
|
Please check the component [README](managed_components/espressif__esp_modem/README.md)
|
||||||
|
|
||||||
|
Or refer to the component's [documentation](managed_components/espressif__esp_modem/docs/html/index.html)
|
@@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "simple_client.cpp" "simple_mqtt_client.cpp"
|
||||||
|
INCLUDE_DIRS ".")
|
@@ -0,0 +1,42 @@
|
|||||||
|
menu "Example Configuration"
|
||||||
|
|
||||||
|
choice EXAMPLE_MODEM_DEVICE
|
||||||
|
prompt "Choose supported modem device (DCE)"
|
||||||
|
default EXAMPLE_MODEM_DEVICE_BG96
|
||||||
|
help
|
||||||
|
Select modem device connected to the ESP DTE.
|
||||||
|
config EXAMPLE_MODEM_DEVICE_SIM800
|
||||||
|
bool "SIM800"
|
||||||
|
help
|
||||||
|
SIMCom SIM800L is a GSM/GPRS module.
|
||||||
|
It supports Quad-band 850/900/1800/1900MHz.
|
||||||
|
config EXAMPLE_MODEM_DEVICE_BG96
|
||||||
|
bool "BG96"
|
||||||
|
help
|
||||||
|
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
|
||||||
|
config EXAMPLE_MODEM_DEVICE_SIM7600
|
||||||
|
bool "SIM7600"
|
||||||
|
help
|
||||||
|
SIM7600 is a Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module.
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MODEM_PPP_APN
|
||||||
|
string "Set MODEM APN"
|
||||||
|
default "internet"
|
||||||
|
help
|
||||||
|
Set APN (Access Point Name), a logical name to choose data network
|
||||||
|
|
||||||
|
config EXAMPLE_NEED_SIM_PIN
|
||||||
|
bool "SIM PIN needed"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable to set SIM PIN before starting the example
|
||||||
|
|
||||||
|
config EXAMPLE_SIM_PIN
|
||||||
|
string "Set SIM PIN"
|
||||||
|
default "1234"
|
||||||
|
depends on EXAMPLE_NEED_SIM_PIN
|
||||||
|
help
|
||||||
|
Pin to unlock the SIM
|
||||||
|
|
||||||
|
endmenu
|
@@ -0,0 +1,7 @@
|
|||||||
|
targets:
|
||||||
|
- esp32
|
||||||
|
- esp32s2
|
||||||
|
description: cmux example of esp_modem
|
||||||
|
dependencies:
|
||||||
|
espressif/esp_modem:
|
||||||
|
version: "0.1.9"
|
137
examples/cxx/experimental/esp_modem_cxx/main/simple_client.cpp
Normal file
137
examples/cxx/experimental/esp_modem_cxx/main/simple_client.cpp
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/* PPPoS Client Example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
#include <cstring>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "esp_log.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"
|
||||||
|
|
||||||
|
|
||||||
|
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
|
||||||
|
|
||||||
|
using namespace esp_modem;
|
||||||
|
using namespace idf::event;
|
||||||
|
|
||||||
|
constexpr auto TAG = "cmux_example";
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void app_main(void)
|
||||||
|
{
|
||||||
|
/* Init and register system/core components */
|
||||||
|
auto loop = std::make_shared<ESPEventLoop>();
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
/* Configure the DTE */
|
||||||
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
|
|
||||||
|
/* Configure the DCE */
|
||||||
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
|
||||||
|
|
||||||
|
/* Configure the PPP netif */
|
||||||
|
esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
|
||||||
|
|
||||||
|
/* Create the DTE, PPP and DCE objects */
|
||||||
|
auto uart_dte = create_uart_dte(&dte_config);
|
||||||
|
assert(uart_dte);
|
||||||
|
|
||||||
|
esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config);
|
||||||
|
assert(esp_netif);
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
|
||||||
|
std::unique_ptr<DCE> dce = create_BG96_dce(&dce_config, uart_dte, esp_netif);
|
||||||
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
|
||||||
|
std::unique_ptr<DCE> dce = create_SIM800_dce(&dce_config, uart_dte, esp_netif);
|
||||||
|
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
|
||||||
|
std::unique_ptr<DCE> dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif);
|
||||||
|
#else
|
||||||
|
#error "Unsupported device"
|
||||||
|
#endif
|
||||||
|
assert(dce);
|
||||||
|
|
||||||
|
/* Setup basic operation mode for the DCE (pin if used, CMUX mode) */
|
||||||
|
#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
|
||||||
|
bool pin_ok = true;
|
||||||
|
if (dce->read_pin(pin_ok) == command_result::OK && !pin_ok) {
|
||||||
|
if (dce->set_pin(CONFIG_EXAMPLE_SIM_PIN) == command_result::OK) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000)); // Need to wait for some time after unlocking the SIM
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Failed to set PIN... exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dce->set_mode(esp_modem::modem_mode::CMUX_MODE) && dce->set_mode(esp_modem::modem_mode::DATA_MODE)) {
|
||||||
|
ESP_LOGI(TAG, "Modem has correctly entered multiplexed command/data mode");
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Failed to configure desired mode... exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read some data from the modem */
|
||||||
|
std::string str;
|
||||||
|
while (dce->get_operator_name(str) != esp_modem::command_result::OK) {
|
||||||
|
// Getting operator name could fail... retry after 500 ms
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Operator name: %s", str.c_str());
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
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, "Got IP address");
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* 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) {
|
||||||
|
ESP_LOGI(TAG, " TOPIC: %s", mqtt.get_topic(data).c_str());
|
||||||
|
ESP_LOGI(TAG, " DATA: %s", mqtt.get_data(data).c_str());
|
||||||
|
});
|
||||||
|
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)) {
|
||||||
|
ESP_LOGI(TAG, "Data received");
|
||||||
|
break; /* Continue with CMUX example after getting data from MQTT */
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (result.event.id == ESPEventID(IP_EVENT_PPP_LOST_IP)) {
|
||||||
|
ESP_LOGE(TAG, "PPP client has lost connection... exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Again reading some data from the modem */
|
||||||
|
if (dce->get_imsi(str) == esp_modem::command_result::OK) {
|
||||||
|
ESP_LOGI(TAG, "Modem IMSI number: %s", str.c_str());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,101 @@
|
|||||||
|
/* PPPoS Client Example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
||||||
|
*/
|
||||||
|
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 = { };
|
||||||
|
config.uri = uri.c_str();
|
||||||
|
client = esp_mqtt_client_init(&config);
|
||||||
|
esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
|
idf::event::ESPEvent MqttClient::get_event(MqttClient::Event ev)
|
||||||
|
{
|
||||||
|
switch (ev) {
|
||||||
|
case Event::CONNECT: {
|
||||||
|
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_CONNECTED) };
|
||||||
|
}
|
||||||
|
case Event::DATA:
|
||||||
|
return { MQTT_EVENTS, ESPEventID(MQTT_EVENT_DATA) };
|
||||||
|
}
|
||||||
|
return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
MqttClient::~MqttClient() = default;
|
@@ -0,0 +1,77 @@
|
|||||||
|
/* PPPoS Client Example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
#ifndef _SIMPLE_MQTT_CLIENT_H_
|
||||||
|
#define _SIMPLE_MQTT_CLIENT_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "esp_event_cxx.hpp"
|
||||||
|
|
||||||
|
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 Convert internal MQTT event to standard ESPEvent
|
||||||
|
* @param ev internal mqtt event
|
||||||
|
* @return corresponding ESPEvent
|
||||||
|
*/
|
||||||
|
static idf::event::ESPEvent get_event(Event ev);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<MqttClientHandle> h;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_SIMPLE_MQTT_CLIENT_H_
|
@@ -0,0 +1,8 @@
|
|||||||
|
# Override some defaults to enable PPP
|
||||||
|
CONFIG_LWIP_PPP_SUPPORT=y
|
||||||
|
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
||||||
|
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||||
|
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||||
|
# Do not enable IPV6 in dte<->dce link local
|
||||||
|
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||||
|
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
@@ -1,6 +1,7 @@
|
|||||||
components/
|
components/
|
||||||
common_components/
|
common_components/
|
||||||
cxx/experimental/experimental_cpp_component/
|
cxx/experimental/experimental_cpp_component/
|
||||||
|
cxx/experimental/esp_modem_cxx
|
||||||
main/
|
main/
|
||||||
build_system/cmake/
|
build_system/cmake/
|
||||||
mb_example_common/
|
mb_example_common/
|
||||||
|
@@ -2,3 +2,4 @@ build_system/cmake
|
|||||||
temp_
|
temp_
|
||||||
examples/bluetooth/bluedroid/ble_50/
|
examples/bluetooth/bluedroid/ble_50/
|
||||||
examples/cxx/experimental/blink_cxx
|
examples/cxx/experimental/blink_cxx
|
||||||
|
examples/cxx/experimental/esp_modem_cxx/
|
||||||
|
Reference in New Issue
Block a user