Update CMUX example to use VFS term and OTA

This commit is contained in:
David Cermak
2021-05-17 18:24:35 +02:00
parent 59c3837345
commit df3971105e
22 changed files with 532 additions and 372 deletions

View File

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

View File

@ -0,0 +1,17 @@
# 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.
The example uses the following configuration options to demonstrate basic esp-modem capabilities:
* `EXAMPLE_NEED_SIM_PIN`: To unlock the SIM card with a PIN code if needed
* `EXAMPLE_PERFORM_OTA`: To start simple OTA at the end of the example to exercise basic CMUX/modem networking. Please note that the option `CONFIG_UART_ISR_IN_IRAM` is not enabled automatically, so that buffer overflows are expected and CMUX/PPP and networking should recover.
* `EXAMPLE_USE_VFS_TERM`: To demonstrate using an abstract file descriptor to talk to the device (instead of the UART driver directly). This option could be used when implementing a custom VFS driver.
## About the esp_modem
Please check the component [README](../../README.md)

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "simple_client.cpp" "simple_mqtt_client.cpp"
INCLUDE_DIRS ".")

View File

@ -0,0 +1,64 @@
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
config EXAMPLE_USE_VFS_TERM
bool "Use VFS terminal"
default n
help
Demonstrate use of VFS as a communication terminal of the DTE.
VFS driver implements non-block reads, writes and selects to communicate with esp-modem,
but this implementation uses UART resource only.
config EXAMPLE_PERFORM_OTA
bool "Perform OTA in the example"
default n
help
Perform the OTA update after connecting to the network and mqtt broker.
This option is used only to exercise network stability in CMUX mode.
config EXAMPLE_PERFORM_OTA_URI
string "URI of the binary"
default "https://my.code/esp32.bin"
depends on EXAMPLE_PERFORM_OTA
help
HTTPS address of the update binary.
endmenu

View File

@ -0,0 +1,167 @@
/* 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 <iostream>
#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"
#include "esp_vfs_dev.h" // For optional VFS support
#include "esp_https_ota.h" // For potential OTA configuration
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
using namespace esp_modem;
using namespace idf::event;
static const char *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 and create the DTE */
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
#if CONFIG_EXAMPLE_USE_VFS_TERM == 1
/* The VFS terminal is just a demonstration of using an abstract file descriptor
* which implements non-block reads, writes and selects to communicate with esp-modem.
* This configuration uses the same UART driver as the terminal created by `create_uart_dte()`,
* so doesn't give any practical benefit besides the FD use demonstration and a placeholder
* to use FD terminal for other devices
*/
dte_config.vfs_config.dev_name = "/dev/uart/1";
dte_config.vfs_config.resource = ESP_MODEM_VFS_IS_UART;
dte_config.uart_config.event_queue_size = 0;
auto dte = create_vfs_dte(&dte_config);
esp_vfs_dev_uart_use_driver(dte_config.uart_config.port_num);
#else
auto dte = create_uart_dte(&dte_config);
#endif // CONFIG_EXAMPLE_USE_VFS_TERM
assert(dte);
/* 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 PPP and DCE objects */
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, 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) {
throw_if_false(dce->set_pin(CONFIG_EXAMPLE_SIM_PIN) == command_result::OK, "Cannot set PIN!");
vTaskDelay(pdMS_TO_TICKS(1000)); // Need to wait for some time after unlocking the SIM
}
#endif
if (dce->set_mode(esp_modem::modem_mode::CMUX_MODE) && dce->set_mode(esp_modem::modem_mode::DATA_MODE)) {
std::cout << "Modem has correctly entered multiplexed command/data mode" << std::endl;
} 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));
}
std::cout << "Operator name:" << str << std::endl;
/* 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, "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));
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;
});
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;
}
}
} 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) {
std::cout << "Modem IMSI number:" << str << std::endl;
}
#if CONFIG_EXAMPLE_PERFORM_OTA == 1
esp_http_client_config_t config = { };
config.skip_cert_common_name_check = true;
config.url = CONFIG_EXAMPLE_PERFORM_OTA_URI;
esp_err_t ret = esp_https_ota(&config);
if (ret == ESP_OK) {
esp_restart();
} else {
ESP_LOGE(TAG, "Firmware upgrade failed");
return;
}
#endif // CONFIG_EXAMPLE_PERFORM_OTA
}

View File

@ -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;

View File

@ -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_

View File

@ -3,6 +3,8 @@ 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
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_PARTITION_TABLE_TWO_OTA=y
CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y
CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y

View File

@ -1,9 +0,0 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := pppos_client
include $(IDF_PATH)/make/project.mk

View File

@ -1,10 +0,0 @@
# PPPoS simple client example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example shows how to act as a MQTT client after the PPPoS channel created by using [ESP-MQTT](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/mqtt.html) APIs.
## How to use this example
See the README.md file in the upper level `pppos` directory for more information about the PPPoS examples.

View File

@ -1,2 +0,0 @@
idf_component_register(SRCS "simple_client.cpp"
INCLUDE_DIRS ".")

View File

@ -1,35 +0,0 @@
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 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_SIM_PIN
string "Set SIM PIN"
default "1234"
help
Pin to unlock the SIM
endmenu

View File

@ -1,237 +0,0 @@
/* 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 <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_netif.h"
#include "esp_netif_ppp.h"
#include "mqtt_client.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 <iostream>
#include "esp_https_ota.h"
#include "esp_vfs_dev.h"
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
using namespace esp_modem;
static const char *TAG = "cmux_example";
static EventGroupHandle_t event_group = nullptr;
static const int CONNECT_BIT = BIT0;
static const int STOP_BIT = BIT1;
static const int GOT_DATA_BIT = BIT2;
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_subscribe(client, "/topic/esp-pppos", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
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);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
xEventGroupSetBits(event_group, GOT_DATA_BIT);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "MQTT other event id: %d", event->event_id);
break;
}
}
static void on_ppp_changed(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ESP_LOGI(TAG, "PPP state changed event %d", event_id);
if (event_id == NETIF_PPP_ERRORUSER) {
/* User interrupted event from esp-netif */
esp_netif_t *netif = (esp_netif_t *)event_data;
ESP_LOGI(TAG, "User interrupted event from netif:%p", netif);
}
}
static void on_ip_event(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "IP event! %d", event_id);
if (event_id == IP_EVENT_PPP_GOT_IP) {
esp_netif_dns_info_t dns_info;
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
esp_netif_t *netif = event->esp_netif;
ESP_LOGI(TAG, "Modem Connect to PPP Server");
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
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));
esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info);
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
esp_netif_get_dns_info(netif, ESP_NETIF_DNS_BACKUP, &dns_info);
ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
xEventGroupSetBits(event_group, CONNECT_BIT);
ESP_LOGI(TAG, "GOT ip event!!!");
} else if (event_id == IP_EVENT_PPP_LOST_IP) {
ESP_LOGI(TAG, "Modem Disconnect from PPP Server");
} else if (event_id == IP_EVENT_GOT_IP6) {
ESP_LOGI(TAG, "GOT IPv6 event!");
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
ESP_LOGI(TAG, "Got IPv6 address " IPV6STR, IPV62STR(event->ip6_info.ip));
}
}
extern "C" void app_main(void)
{
/* Init and register system/core components */
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &on_ip_event, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, NULL));
event_group = xEventGroupCreate();
/* Configure the DTE */
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
// dte_config.task_stack_size = 8192;
dte_config.vfs_config.dev_name = "/dev/uart/1";
dte_config.uart_config.event_queue_size = 0;
// esp_modem_dte_config_t dte_config2 = {
// .dte_buffer_size = 512,
// .vfs_config = {.port_num = UART_NUM_1,
// .dev_name = "/dev/uart/1",
// .rx_buffer_size = 1024,
// .tx_buffer_size = 512,
// .baud_rate = 115200,
// .tx_io_num = 25,
// .rx_io_num = 26,
// .task_stack_size = 4096,
// .task_prio = 5}
// };
/* 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();
// dte_config.dte_buffer_size = 512;
// dte_config.uart_config.port_num = UART_NUM_2;
// auto uart_dte = create_uart_dte(&dte_config);
auto uart_dte = create_vfs_dte(&dte_config);
esp_vfs_dev_uart_use_driver(dte_config.uart_config.port_num);
esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config);
assert(esp_netif);
#if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1
auto dce = create_BG96_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1
auto dce = create_SIM800_dce(&dce_config, uart_dte, esp_netif);
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1
auto dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif);
#else
#error "Unsupported device"
#endif
dce->set_command_mode();
std::string str;
dce->get_module_name(str);
std::cout << "Module name:" << str << std::endl;
bool pin_ok = true;
if (dce->read_pin(pin_ok) == command_result::OK && !pin_ok) {
throw_if_false(dce->set_pin(CONFIG_EXAMPLE_SIM_PIN) == command_result::OK, "Cannot set PIN!");
vTaskDelay(pdMS_TO_TICKS(1000));
}
// dce->get_imsi(str);
// std::cout << "Modem IMSI number:" << str << "|" << std::endl;
// std::cout << "|" << str << "|" << std::endl;
dce->set_mode(esp_modem::modem_mode::CMUX_MODE);
dce->get_imsi(str);
std::cout << "Modem IMSI number:" << str << "|" << std::endl;
dce->get_imei(str);
std::cout << "Modem IMEI number:" << str << "|" << std::endl;
dce->get_operator_name(str);
std::cout << "Operator name:" << str << "|" << std::endl;
// return;
// dce->set_mode(esp_modem::modem_mode::CMUX_MODE);
dce->set_data();
// MQTT connection
xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
esp_mqtt_client_config_t mqtt_config = { };
mqtt_config.uri = BROKER_URL;
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
esp_mqtt_client_register_event(mqtt_client, MQTT_EVENT_ANY, mqtt_event_handler, nullptr);
esp_mqtt_client_start(mqtt_client);
EventBits_t got_data = 0;
while (got_data == 0) { // reading IMSI number until we get published data from MQTT
// dce->get_imsi(str);
// std::cout << "Modem IMSI number:" << str << "|" << std::endl;
got_data = xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, pdMS_TO_TICKS(500));
}
esp_mqtt_client_destroy(mqtt_client);
// dce->get_imsi(str);
// std::cout << "Modem IMSI number:" << str << "|" << std::endl;
esp_http_client_config_t config = { };
config.skip_cert_common_name_check = true;
config.url = "https://github.com/david-cermak/esp32-ipv6-examples/raw/test/ota/hello-world.bin";
esp_err_t ret = esp_https_ota(&config);
if (ret == ESP_OK) {
esp_restart();
} else {
ESP_LOGE(TAG, "Firmware upgrade failed");
}
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
vTaskDelay(pdMS_TO_TICKS(1000));
ESP_LOGI(TAG, "Example finished");
}