Skip to content

Commit a299192

Browse files
committed
feat(esp_modem): Add mqtt example in AT-only mode
Similar to pppos-client, but without PPP mode. This uses standard mqtt client and a loopback service that forwards the TCP traffic from localhost to the modem and vice-versa. (next step is to create a dedicated tcp-transport layer for modem)
1 parent a9b5e66 commit a299192

17 files changed

+1066
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# The following lines of boilerplate have to be in your project's CMakeLists
2+
# in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.5)
4+
5+
set(EXTRA_COMPONENT_DIRS "../..")
6+
7+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
8+
project(modem_tcp_client)
9+
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Modem TCP client
2+
3+
(See the README.md file in the upper level 'examples' directory for more information about examples.)
4+
5+
## Overview
6+
This example demonstrates how to act as a MQTT client using modem's TCP commands (provided, the device supports "socket" related commands)
7+
8+
### Supported IDF versions
9+
10+
This example is only supported from `v4.1`, as this is the default dependency of `esp-modem` component.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
idf_component_register(SRCS "modem_client.cpp"
2+
"sock_dce.cpp"
3+
"sock_commands.cpp"
4+
INCLUDE_DIRS ".")
5+
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
menu "Example Configuration"
2+
3+
choice EXAMPLE_MODEM_DEVICE
4+
prompt "Choose supported modem device (DCE)"
5+
default EXAMPLE_MODEM_DEVICE_BG96
6+
help
7+
Select modem device connected to the ESP DTE.
8+
config EXAMPLE_MODEM_DEVICE_SIM800
9+
bool "SIM800"
10+
help
11+
SIMCom SIM800L is a GSM/GPRS module.
12+
It supports Quad-band 850/900/1800/1900MHz.
13+
config EXAMPLE_MODEM_DEVICE_BG96
14+
bool "BG96"
15+
help
16+
Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module.
17+
config EXAMPLE_MODEM_DEVICE_SIM7600
18+
bool "SIM7600"
19+
help
20+
SIM7600 is Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module
21+
endchoice
22+
23+
config EXAMPLE_MODEM_APN
24+
string "Set MODEM APN"
25+
default "internet"
26+
help
27+
Set APN (Access Point Name), a logical name to choose data network
28+
29+
config EXAMPLE_MODEM_PPP_AUTH_USERNAME
30+
string "Set username for authentication"
31+
default "espressif"
32+
depends on !EXAMPLE_MODEM_PPP_AUTH_NONE
33+
help
34+
Set username for PPP Authentication.
35+
36+
config EXAMPLE_MODEM_PPP_AUTH_PASSWORD
37+
string "Set password for authentication"
38+
default "esp32"
39+
depends on !EXAMPLE_MODEM_PPP_AUTH_NONE
40+
help
41+
Set password for PPP Authentication.
42+
43+
config EXAMPLE_MODEM_PPP_AUTH_NONE
44+
bool "Skip PPP authentication"
45+
default n
46+
help
47+
Set to true for the PPP client to skip authentication
48+
49+
config EXAMPLE_SEND_MSG
50+
bool "Short message (SMS)"
51+
default n
52+
help
53+
Select this, the modem will send a short message before power off.
54+
55+
if EXAMPLE_SEND_MSG
56+
config EXAMPLE_SEND_MSG_PEER_PHONE_NUMBER
57+
string "Peer Phone Number (with area code)"
58+
default "+8610086"
59+
help
60+
Enter the peer phone number that you want to send message to.
61+
endif
62+
63+
config EXAMPLE_NEED_SIM_PIN
64+
bool "SIM PIN needed"
65+
default n
66+
help
67+
Enable to set SIM PIN before starting the example
68+
69+
config EXAMPLE_SIM_PIN
70+
string "Set SIM PIN"
71+
default "1234"
72+
depends on EXAMPLE_NEED_SIM_PIN
73+
help
74+
Pin to unlock the SIM
75+
76+
menu "UART Configuration"
77+
config EXAMPLE_MODEM_UART_TX_PIN
78+
int "TXD Pin Number"
79+
default 25
80+
range 0 31
81+
help
82+
Pin number of UART TX.
83+
84+
config EXAMPLE_MODEM_UART_RX_PIN
85+
int "RXD Pin Number"
86+
default 26
87+
range 0 31
88+
help
89+
Pin number of UART RX.
90+
91+
config EXAMPLE_MODEM_UART_RTS_PIN
92+
int "RTS Pin Number"
93+
default 27
94+
range 0 31
95+
help
96+
Pin number of UART RTS.
97+
98+
config EXAMPLE_MODEM_UART_CTS_PIN
99+
int "CTS Pin Number"
100+
default 23
101+
range 0 31
102+
help
103+
Pin number of UART CTS.
104+
105+
config EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE
106+
int "UART Event Task Stack Size"
107+
range 2000 6000
108+
default 2048
109+
help
110+
Stack size of UART event task.
111+
112+
config EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY
113+
int "UART Event Task Priority"
114+
range 3 22
115+
default 5
116+
help
117+
Priority of UART event task.
118+
119+
config EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE
120+
int "UART Event Queue Size"
121+
range 10 40
122+
default 30
123+
help
124+
Length of UART event queue.
125+
126+
config EXAMPLE_MODEM_UART_PATTERN_QUEUE_SIZE
127+
int "UART Pattern Queue Size"
128+
range 10 40
129+
default 20
130+
help
131+
Length of UART pattern queue.
132+
133+
config EXAMPLE_MODEM_UART_TX_BUFFER_SIZE
134+
int "UART TX Buffer Size"
135+
range 256 2048
136+
default 512
137+
help
138+
Buffer size of UART TX buffer.
139+
140+
config EXAMPLE_MODEM_UART_RX_BUFFER_SIZE
141+
int "UART RX Buffer Size"
142+
range 256 2048
143+
default 1024
144+
help
145+
Buffer size of UART RX buffer.
146+
endmenu
147+
148+
endmenu
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/* PPPoS Client Example
2+
3+
This example code is in the Public Domain (or CC0 licensed, at your option.)
4+
5+
Unless required by applicable law or agreed to in writing, this
6+
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7+
CONDITIONS OF ANY KIND, either express or implied.
8+
*/
9+
#include <string>
10+
#include "freertos/FreeRTOS.h"
11+
#include "freertos/event_groups.h"
12+
#include "esp_netif.h"
13+
#include "esp_netif_ppp.h"
14+
#include "mqtt_client.h"
15+
#include "esp_modem_config.h"
16+
#include "cxx_include/esp_modem_api.hpp"
17+
#include "sock_dce.hpp"
18+
#include "esp_log.h"
19+
20+
#define BROKER_URL "mqtt://mqtt.eclipseprojects.io"
21+
22+
static const char *TAG = "modem_client";
23+
static EventGroupHandle_t event_group = NULL;
24+
static const int CONNECT_BIT = BIT0;
25+
static const int GOT_DATA_BIT = BIT2;
26+
27+
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
28+
{
29+
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
30+
esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data;
31+
esp_mqtt_client_handle_t client = event->client;
32+
int msg_id;
33+
switch ((esp_mqtt_event_id_t)event_id) {
34+
case MQTT_EVENT_CONNECTED:
35+
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
36+
msg_id = esp_mqtt_client_subscribe(client, "/topic/esp-pppos", 0);
37+
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
38+
break;
39+
case MQTT_EVENT_DISCONNECTED:
40+
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
41+
break;
42+
case MQTT_EVENT_SUBSCRIBED:
43+
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
44+
msg_id = esp_mqtt_client_publish(client, "/topic/esp-pppos", "esp32-pppos", 0, 0, 0);
45+
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
46+
break;
47+
case MQTT_EVENT_UNSUBSCRIBED:
48+
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
49+
break;
50+
case MQTT_EVENT_PUBLISHED:
51+
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
52+
break;
53+
case MQTT_EVENT_DATA:
54+
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
55+
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
56+
printf("DATA=%.*s\r\n", event->data_len, event->data);
57+
xEventGroupSetBits(event_group, GOT_DATA_BIT);
58+
break;
59+
case MQTT_EVENT_ERROR:
60+
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
61+
break;
62+
default:
63+
ESP_LOGI(TAG, "MQTT other event id: %d", event->event_id);
64+
break;
65+
}
66+
}
67+
68+
69+
70+
71+
72+
73+
74+
75+
extern "C" void app_main(void)
76+
{
77+
78+
/* Init and register system/core components */
79+
ESP_ERROR_CHECK(esp_netif_init());
80+
ESP_ERROR_CHECK(esp_event_loop_create_default());
81+
82+
event_group = xEventGroupCreate();
83+
84+
/* Configure and create the UART DTE */
85+
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
86+
/* setup UART specific configuration based on kconfig options */
87+
dte_config.uart_config.tx_io_num = CONFIG_EXAMPLE_MODEM_UART_TX_PIN;
88+
dte_config.uart_config.rx_io_num = CONFIG_EXAMPLE_MODEM_UART_RX_PIN;
89+
dte_config.uart_config.rts_io_num = CONFIG_EXAMPLE_MODEM_UART_RTS_PIN;
90+
dte_config.uart_config.cts_io_num = CONFIG_EXAMPLE_MODEM_UART_CTS_PIN;
91+
dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE;
92+
dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE;
93+
dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE;
94+
dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE*2;
95+
dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
96+
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
97+
98+
auto dte = esp_modem::create_uart_dte(&dte_config);
99+
assert(dte);
100+
101+
/* Configure the DCE */
102+
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_APN);
103+
104+
/* create the DCE and initialize network manually (using AT commands) */
105+
auto dce = sock_dce::create(&dce_config, std::move(dte));
106+
if (!dce->init_network()) {
107+
ESP_LOGE(TAG, "Failed to setup network");
108+
return;
109+
}
110+
111+
dce->init(1883);
112+
esp_mqtt_client_config_t mqtt_config = {};
113+
mqtt_config.broker.address.uri = "mqtt://127.0.0.1";
114+
mqtt_config.session.message_retransmit_timeout = 10000;
115+
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
116+
esp_mqtt_client_register_event(mqtt_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID), mqtt_event_handler, NULL);
117+
esp_mqtt_client_start(mqtt_client);
118+
if (!dce->start("test.mosquitto.org", 1883)) {
119+
ESP_LOGE(TAG, "Failed to start DCE");
120+
return;
121+
}
122+
while (1) {
123+
while (dce->perform()) {
124+
ESP_LOGD(TAG, "...performing");
125+
}
126+
ESP_LOGE(TAG, "Loop exit.. retrying");
127+
// handle disconnections errors
128+
if (!dce->init_network()) {
129+
ESP_LOGE(TAG, "Failed to reinit network");
130+
return;
131+
}
132+
if (!dce->start("test.mosquitto.org", 1883)) {
133+
ESP_LOGI(TAG, "Network reinitialized, retrying");
134+
}
135+
}
136+
137+
}

0 commit comments

Comments
 (0)