mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-16 03:52:13 +02:00
Update CMUX example to use VFS term and OTA
This commit is contained in:
@ -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)
|
||||
|
||||
|
17
esp_modem/examples/simple_cmux_client/README.md
Normal file
17
esp_modem/examples/simple_cmux_client/README.md
Normal 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)
|
0
esp_modem/examples/simple_cmux_client/adc.log
Normal file
0
esp_modem/examples/simple_cmux_client/adc.log
Normal file
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "simple_client.cpp" "simple_mqtt_client.cpp"
|
||||
INCLUDE_DIRS ".")
|
64
esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild
Normal file
64
esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild
Normal 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
|
167
esp_modem/examples/simple_cmux_client/main/simple_client.cpp
Normal file
167
esp_modem/examples/simple_cmux_client/main/simple_client.cpp
Normal 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
|
||||
}
|
@ -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_
|
@ -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
|
@ -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
|
||||
|
@ -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.
|
@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "simple_client.cpp"
|
||||
INCLUDE_DIRS ".")
|
@ -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
|
@ -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");
|
||||
}
|
@ -37,7 +37,7 @@ typedef enum {
|
||||
} esp_modem_flow_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief DTE configuration structure
|
||||
* @brief UART configuration structure
|
||||
*
|
||||
*/
|
||||
struct esp_modem_uart_term_config {
|
||||
@ -66,11 +66,22 @@ typedef enum {
|
||||
} esp_modem_vfs_resource_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief VFS configuration structure
|
||||
*
|
||||
*/
|
||||
struct esp_modem_vfs_term_config {
|
||||
const char* dev_name; /*!< VFS device name, e.g. /dev/uart/n */
|
||||
esp_modem_vfs_resource_t resource; /*!< Underlying device which gets initialized during VFS init */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Complete DTE configuration structure
|
||||
*
|
||||
* Note that the generic part is common for DTE and its SW resources
|
||||
* The following portions for config is dedicated to the chosen HW resource
|
||||
* used as a communication terminal for this DTE
|
||||
*/
|
||||
struct esp_modem_dte_config {
|
||||
size_t dte_buffer_size; /*!< DTE buffer size */
|
||||
uint32_t task_stack_size; /*!< Terminal task stack size */
|
||||
@ -106,6 +117,7 @@ struct esp_modem_dte_config {
|
||||
}, \
|
||||
.vfs_config = { \
|
||||
.dev_name = "/null", \
|
||||
.resource = ESP_MODEM_VFS_IS_EXTERN \
|
||||
}\
|
||||
}
|
||||
|
||||
|
38
esp_modem/private_include/uart_resource.hpp
Normal file
38
esp_modem/private_include/uart_resource.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _UART_RESOURCE_HPP_
|
||||
#define _UART_RESOURCE_HPP_
|
||||
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "esp_modem_config.h"
|
||||
|
||||
struct esp_modem_dte_config;
|
||||
|
||||
namespace esp_modem {
|
||||
|
||||
/**
|
||||
* @brief Uart Resource is a platform specific struct which is implemented separately for ESP_PLATFORM and linux target
|
||||
*/
|
||||
struct uart_resource {
|
||||
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue, int fd);
|
||||
~uart_resource();
|
||||
uart_port_t port{};
|
||||
};
|
||||
|
||||
std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config);
|
||||
|
||||
} // namespace esp_modem
|
||||
|
||||
#endif // _UART_RESOURCE_HPP_
|
@ -235,12 +235,6 @@ bool CMux::on_cmux(uint8_t *data, size_t actual_len)
|
||||
ESP_LOGW("CMUX", "Protocol mismatch: Missed trailing SOF, recovering...");
|
||||
payload_start = nullptr;
|
||||
total_payload_size = 0;
|
||||
|
||||
// ESP_LOGE("CMUX-Footer", "Protocol mismatch! total pyaload: %d", total_payload_size);
|
||||
// ESP_LOG_BUFFER_HEXDUMP("Data-valid", payload_start, total_payload_size, ESP_LOG_INFO);
|
||||
// ESP_LOG_BUFFER_HEXDUMP("Footer", frame-8, 16, ESP_LOG_ERROR);
|
||||
// while(1) { usleep(10000); };
|
||||
// abort();
|
||||
state = cmux_state::RECOVER;
|
||||
break;
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ command_result generic_command(CommandableIf* t, const std::string &command,
|
||||
const std::list<std::string_view>& fail_phrase,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s command %s\n", __func__, command.c_str());
|
||||
ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str());
|
||||
return t->command(command, [&](uint8_t *data, size_t len) {
|
||||
std::string_view response((char*)data, len);
|
||||
if (data == nullptr || len == 0 || response.empty())
|
||||
return command_result::TIMEOUT;
|
||||
ESP_LOGI(TAG, "Response: %.*s\n", (int)response.length(), response.data());
|
||||
ESP_LOGD(TAG, "Response: %.*s\n", (int)response.length(), response.data());
|
||||
for (auto &it : pass_phrase)
|
||||
if (response.find(it) != std::string::npos)
|
||||
return command_result::OK;
|
||||
|
@ -27,11 +27,32 @@ namespace esp_modem {
|
||||
|
||||
class Resource {
|
||||
public:
|
||||
Resource(const esp_modem_dte_config *config);
|
||||
explicit Resource(const esp_modem_dte_config *config, int fd):
|
||||
uart(config->vfs_config.resource == ESP_MODEM_VFS_IS_EXTERN? std::nullopt : std::make_optional<uart_resource>(config, nullptr, fd))
|
||||
{}
|
||||
|
||||
std::optional<uart_resource> uart;
|
||||
};
|
||||
|
||||
struct File {
|
||||
explicit File(const char *name): fd(-1)
|
||||
{
|
||||
fd = open(name, O_RDWR);
|
||||
throw_if_false(fd >= 0, "Cannot open the fd");
|
||||
|
||||
// Set the FD to non-blocking mode
|
||||
int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK;
|
||||
fcntl(fd, F_SETFL, flags);
|
||||
}
|
||||
|
||||
~File() {
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
int fd;
|
||||
};
|
||||
|
||||
class FdTerminal : public Terminal {
|
||||
public:
|
||||
explicit FdTerminal(const esp_modem_dte_config *config);
|
||||
@ -63,9 +84,9 @@ private:
|
||||
static const size_t TASK_STOP = SignalGroup::bit2;
|
||||
static const size_t TASK_PARAMS = SignalGroup::bit3;
|
||||
|
||||
uart_resource uart;
|
||||
File f;
|
||||
Resource resource;
|
||||
SignalGroup signal;
|
||||
int fd;
|
||||
Task task_handle;
|
||||
};
|
||||
|
||||
@ -78,19 +99,13 @@ std::unique_ptr<Terminal> create_vfs_terminal(const esp_modem_dte_config *config
|
||||
}
|
||||
|
||||
FdTerminal::FdTerminal(const esp_modem_dte_config *config) :
|
||||
uart(config, nullptr), signal(), fd(-1),
|
||||
f(config->vfs_config.dev_name), resource(config, f.fd), signal(),
|
||||
task_handle(config->task_stack_size, config->task_priority, this, [](void* p){
|
||||
auto t = static_cast<FdTerminal *>(p);
|
||||
t->task();
|
||||
Task::Delete();
|
||||
if (t->fd >= 0) {
|
||||
close(t->fd);
|
||||
}
|
||||
})
|
||||
{
|
||||
fd = open(config->vfs_config.dev_name, O_RDWR);
|
||||
throw_if_false(fd >= 0, "Cannot open the fd");
|
||||
}
|
||||
{}
|
||||
|
||||
void FdTerminal::task()
|
||||
{
|
||||
@ -101,10 +116,6 @@ void FdTerminal::task()
|
||||
return; // exits to the static method where the task gets deleted
|
||||
}
|
||||
|
||||
// Set the FD to non-blocking mode
|
||||
int flags = fcntl(fd, F_GETFL, nullptr) | O_NONBLOCK;
|
||||
fcntl(fd, F_SETFL, flags);
|
||||
|
||||
while (signal.is_any(TASK_START)) {
|
||||
int s;
|
||||
fd_set rfds;
|
||||
@ -113,9 +124,9 @@ void FdTerminal::task()
|
||||
.tv_usec = 0,
|
||||
};
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
FD_SET(f.fd, &rfds);
|
||||
|
||||
s = select(fd + 1, &rfds, nullptr, nullptr, &tv);
|
||||
s = select(f.fd + 1, &rfds, nullptr, nullptr, &tv);
|
||||
if (signal.is_any(TASK_PARAMS)) {
|
||||
on_data_priv = on_data;
|
||||
signal.clear(TASK_PARAMS);
|
||||
@ -126,7 +137,7 @@ void FdTerminal::task()
|
||||
} else if (s == 0) {
|
||||
// ESP_LOGV(TAG, "Select exited with timeout");
|
||||
} else {
|
||||
if (FD_ISSET(fd, &rfds)) {
|
||||
if (FD_ISSET(f.fd, &rfds)) {
|
||||
if (on_data_priv) {
|
||||
if (on_data_priv(nullptr, 0)) {
|
||||
on_data_priv = nullptr;
|
||||
@ -140,7 +151,7 @@ void FdTerminal::task()
|
||||
|
||||
int FdTerminal::read(uint8_t *data, size_t len)
|
||||
{
|
||||
int size = ::read(fd, data, len);
|
||||
int size = ::read(f.fd, data, len);
|
||||
if (size < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
ESP_LOGE(TAG, "Error occurred during read: %d", errno);
|
||||
@ -153,7 +164,7 @@ int FdTerminal::read(uint8_t *data, size_t len)
|
||||
|
||||
int FdTerminal::write(uint8_t *data, size_t len)
|
||||
{
|
||||
int size = ::write(fd, data, len);
|
||||
int size = ::write(f.fd, data, len);
|
||||
if (size < 0) {
|
||||
ESP_LOGE(TAG, "Error occurred during read: %d", errno);
|
||||
return 0;
|
||||
|
@ -3,7 +3,6 @@
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@ -11,18 +10,14 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "uart_resource.hpp"
|
||||
|
||||
namespace esp_modem {
|
||||
|
||||
struct uart_resource {
|
||||
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue);
|
||||
~uart_resource();
|
||||
uart_port_t port;
|
||||
};
|
||||
|
||||
uart_resource::~uart_resource()
|
||||
{
|
||||
if (port >= UART_NUM_0 && port < UART_NUM_MAX) {
|
||||
@ -30,8 +25,8 @@ uart_resource::~uart_resource()
|
||||
}
|
||||
}
|
||||
|
||||
uart_resource::uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue) :
|
||||
port(-1)
|
||||
uart_resource::uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue, int fd)
|
||||
:port(-1)
|
||||
{
|
||||
esp_err_t res;
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
@ -20,19 +19,13 @@
|
||||
#include "driver/uart.h"
|
||||
#include "esp_modem_config.h"
|
||||
#include "exception_stub.hpp"
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "uart_resource.hpp"
|
||||
|
||||
static const char *TAG = "uart_terminal";
|
||||
|
||||
namespace esp_modem {
|
||||
|
||||
/**
|
||||
* @brief Uart Resource is a platform specific struct which is implemented separately
|
||||
*/
|
||||
struct uart_resource {
|
||||
explicit uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue);
|
||||
~uart_resource();
|
||||
uart_port_t port;
|
||||
};
|
||||
|
||||
struct uart_task {
|
||||
explicit uart_task(size_t stack_size, size_t priority, void *task_param, TaskFunction_t task_function) :
|
||||
@ -53,7 +46,7 @@ struct uart_task {
|
||||
class uart_terminal : public Terminal {
|
||||
public:
|
||||
explicit uart_terminal(const esp_modem_dte_config *config) :
|
||||
event_queue(), uart(config, &event_queue), signal(),
|
||||
event_queue(), uart(config, &event_queue, -1), signal(),
|
||||
task_handle(config->task_stack_size, config->task_priority, this, s_task) {}
|
||||
|
||||
~uart_terminal() override = default;
|
||||
|
@ -12,38 +12,21 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "esp_log.h"
|
||||
#include "driver/uart.h"
|
||||
#include "cxx_include/esp_modem_dte.hpp"
|
||||
#include "esp_modem_config.h"
|
||||
#include "exception_stub.hpp"
|
||||
#include "uart_resource.hpp"
|
||||
|
||||
namespace esp_modem::terminal {
|
||||
namespace esp_modem {
|
||||
|
||||
constexpr const char *TAG = "uart_term";
|
||||
constexpr const char *TAG = "uart_resource";
|
||||
|
||||
struct uart_resource {
|
||||
explicit uart_resource(const esp_modem_dte_config *config);
|
||||
|
||||
~uart_resource();
|
||||
|
||||
uart_port_t port{};
|
||||
int fd;
|
||||
};
|
||||
|
||||
uart_resource::uart_resource(const esp_modem_dte_config *config)
|
||||
uart_resource::uart_resource(const esp_modem_dte_config *config, struct QueueDefinition** event_queue, int fd): port(-1)
|
||||
{
|
||||
ESP_LOGD(TAG, "Creating uart resource" );
|
||||
struct termios tty = {};
|
||||
fd = open( config->vfs_config.dev_name, O_RDWR | O_NOCTTY | O_NONBLOCK );
|
||||
throw_if_false(fd >= 0 , "Failed to open serial port");
|
||||
throw_if_false(tcgetattr(fd, &tty) == 0, "Failed to tcgetattr()");
|
||||
|
||||
tty.c_cflag &= ~PARENB;
|
||||
@ -67,9 +50,6 @@ uart_resource::uart_resource(const esp_modem_dte_config *config)
|
||||
ioctl(fd, TCSETS, &tty);
|
||||
}
|
||||
|
||||
uart_resource::~uart_resource()
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
uart_resource::~uart_resource() = default;
|
||||
|
||||
}
|
||||
} // namespace esp_modem
|
Reference in New Issue
Block a user