Files
esp-protocols/esp_modem/examples/simple_cxx_client/main/simple_client.cpp
2021-10-04 11:32:54 +02:00

376 lines
14 KiB
C++

/* 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_modem.h"
#include "esp_modem_netif.h"
#include "esp_log.h"
#include "cxx_include/esp_modem_dte.hpp"
#include "cxx_include/uart_terminal.hpp"
#define BROKER_URL "mqtt://mqtt.eclipse.org"
static const char *TAG = "pppos_example";
static EventGroupHandle_t event_group = NULL;
static const int CONNECT_BIT = BIT0;
static const int STOP_BIT = BIT1;
static const int GOT_DATA_BIT = BIT2;
#if CONFIG_EXAMPLE_SEND_MSG
/**
* @brief This example will also show how to send short message using the infrastructure provided by esp modem library.
* @note Not all modem support SMG.
*
*/
static esp_err_t example_default_handle(esp_modem_dce_t *dce, const char *line)
{
esp_err_t err = ESP_FAIL;
if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) {
err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS);
} else if (strstr(line, MODEM_RESULT_CODE_ERROR)) {
err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL);
}
return err;
}
static esp_err_t example_handle_cmgs(esp_modem_dce_t *dce, const char *line)
{
esp_err_t err = ESP_FAIL;
if (strstr(line, MODEM_RESULT_CODE_SUCCESS)) {
err = esp_modem_process_command_done(dce, MODEM_STATE_SUCCESS);
} else if (strstr(line, MODEM_RESULT_CODE_ERROR)) {
err = esp_modem_process_command_done(dce, MODEM_STATE_FAIL);
} else if (!strncmp(line, "+CMGS", strlen("+CMGS"))) {
err = ESP_OK;
}
return err;
}
#define MODEM_SMS_MAX_LENGTH (128)
#define MODEM_COMMAND_TIMEOUT_SMS_MS (120000)
#define MODEM_PROMPT_TIMEOUT_MS (10)
static esp_err_t example_send_message_text(modem_dce_t *user_dce, const char *phone_num, const char *text)
{
esp_modem_dce_t *dce = &user_dce->parent;
modem_dte_t *dte = dce->dte;
dce->handle_line = example_default_handle;
/* Set text mode */
if (dte->send_cmd(dte, "AT+CMGF=1\r", MODEM_COMMAND_TIMEOUT_DEFAULT) != ESP_OK) {
ESP_LOGE(TAG, "send command failed");
goto err;
}
if (dce->state != MODEM_STATE_SUCCESS) {
ESP_LOGE(TAG, "set message format failed");
goto err;
}
ESP_LOGD(TAG, "set message format ok");
/* Specify character set */
dce->handle_line = example_default_handle;
if (dte->send_cmd(dte, "AT+CSCS=\"GSM\"\r", MODEM_COMMAND_TIMEOUT_DEFAULT) != ESP_OK) {
ESP_LOGE(TAG, "send command failed");
goto err;
}
if (dce->state != MODEM_STATE_SUCCESS) {
ESP_LOGE(TAG, "set character set failed");
goto err;
}
ESP_LOGD(TAG, "set character set ok");
/* send message */
char command[MODEM_SMS_MAX_LENGTH] = {0};
int length = snprintf(command, MODEM_SMS_MAX_LENGTH, "AT+CMGS=\"%s\"\r", phone_num);
/* set phone number and wait for "> " */
dte->send_wait(dte, command, length, "\r\n> ", MODEM_PROMPT_TIMEOUT_MS);
/* end with CTRL+Z */
snprintf(command, MODEM_SMS_MAX_LENGTH, "%s\x1A", text);
dce->handle_line = example_handle_cmgs;
if (dte->send_cmd(dte, command, MODEM_COMMAND_TIMEOUT_SMS_MS) != ESP_OK) {
ESP_LOGE(TAG, "send command failed");
goto err;
}
if (dce->state != MODEM_STATE_SUCCESS) {
ESP_LOGE(TAG, "send message failed");
goto err;
}
ESP_LOGD(TAG, "send message ok");
return ESP_OK;
err:
return ESP_FAIL;
}
#endif
static void modem_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
switch (event_id) {
case ESP_MODEM_EVENT_PPP_START:
ESP_LOGI(TAG, "Modem PPP Started");
break;
case ESP_MODEM_EVENT_PPP_STOP:
ESP_LOGI(TAG, "Modem PPP Stopped");
xEventGroupSetBits(event_group, STOP_BIT);
break;
case ESP_MODEM_EVENT_UNKNOWN:
ESP_LOGW(TAG, "Unknown line received: %s", (char *)event_data);
break;
default:
break;
}
}
//static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
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));
}
}
static void modem_test_app(esp_modem_dte_config_t *dte_config, esp_modem_dce_config_t *dce_config, esp_netif_config_t *ppp_config);
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();
/* setup UART specific configuration based on kconfig options */
dte_config.tx_io_num = CONFIG_EXAMPLE_MODEM_UART_TX_PIN;
dte_config.rx_io_num = CONFIG_EXAMPLE_MODEM_UART_RX_PIN;
dte_config.rts_io_num = CONFIG_EXAMPLE_MODEM_UART_RTS_PIN;
dte_config.cts_io_num = CONFIG_EXAMPLE_MODEM_UART_CTS_PIN;
dte_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE;
dte_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE;
dte_config.pattern_queue_size = CONFIG_EXAMPLE_MODEM_UART_PATTERN_QUEUE_SIZE;
dte_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE;
dte_config.event_task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE;
dte_config.event_task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
dte_config.line_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
/* 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();
/* Run the modem demo app */
return modem_test_app(&dte_config, &dce_config,&netif_ppp_config);
}
#include <iostream>
static void modem_test_app(esp_modem_dte_config_t *dte_config, esp_modem_dce_config_t *dce_config, esp_netif_config_t *ppp_config)
{
/* create dte object */
esp_modem_dte_t *dte; // = esp_modem_dte_new(dte_config);
// assert(dte != NULL);
// dte_config->line_buffer_size = 1000000;
uint8_t data[32] = {};
int actual_len = 0;
auto ddd = create_dte(dte_config);
ddd->set_mode(dte_mode::UNDEF);
ddd->send_command("AT+CPIN?\r", [&](uint8_t *data, size_t len) {
std::string response((char*)data, len);
ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data);
std::cout << response << std::endl;
return true;
}, 1000);
// ddd->send_command("AT+CPIN=1234\r", [&](uint8_t *data, size_t len) {
// std::string response((char*)data, len);
// ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data);
// std::cout << response << std::endl;
// return true;
// }, 1000);
// return;
esp_netif_t *esp_netif = esp_netif_new(ppp_config);
assert(esp_netif);
auto my_dce = create_dce(ddd, esp_netif);
my_dce->command("AT+CPIN?\r", [&](uint8_t *data, size_t len) {
std::string response((char*)data, len);
ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data);
std::cout << response << std::endl;
return true;
}, 1000);
my_dce->set_data();
// ddd->send_command("AT+COPS=?\r", [&](uint8_t *data, size_t len) {
// std::string response((char*)data, len);
// ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data);
// std::cout << response << std::endl;
// return true;
// }, 60000);
// auto uart = create_uart_terminal(dte_config);
// uart->set_data_cb([&](size_t len){
// actual_len = uart->read(data, 32);
// ESP_LOGI("in the lambda", "len=%d data %s", len, (char*)data);
// });
// uart->write((uint8_t*)"AT\r",3);
vTaskDelay(pdMS_TO_TICKS(1000));
// int len = uart->read(data, 32);
// ESP_LOGI(TAG, "len=%d data %s", len, (char*)data);
// vTaskDelay(pdMS_TO_TICKS(1000));
// len = uart->read(data, 32);
ESP_LOGI(TAG, "len=%d data %s", actual_len, (char*)data);
return;
/* create dce object */
#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM800
dce_config->device = ESP_MODEM_DEVICE_SIM800;
#elif CONFIG_EXAMPLE_MODEM_DEVICE_BG96
dce_config->device = ESP_MODEM_DEVICE_BG96;
#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600
dce_config->device = ESP_MODEM_DEVICE_SIM7600;
#else
#error "Unsupported DCE"
#endif
esp_modem_dce_t *dce = esp_modem_dce_new(dce_config);
assert(dce != NULL);
/* create netif object */
// esp_netif_t *esp_netif = esp_netif_new(ppp_config);
assert(esp_netif);
#if !defined(CONFIG_EXAMPLE_MODEM_PPP_AUTH_NONE) && (defined(CONFIG_LWIP_PPP_PAP_SUPPORT) || defined(CONFIG_LWIP_PPP_CHAP_SUPPORT))
#if CONFIG_LWIP_PPP_PAP_SUPPORT
esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_PAP;
#elif CONFIG_LWIP_PPP_CHAP_SUPPORT
esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_CHAP;
#else
#error "Unsupported AUTH Negotiation"
#endif
esp_netif_ppp_set_auth(esp_netif, auth_type, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD);
#endif
/* Register event handler */
ESP_ERROR_CHECK(esp_modem_set_event_handler(dte, modem_event_handler, ESP_EVENT_ANY_ID, NULL));
/* attach the DCE, DTE, netif to initialize the modem */
ESP_ERROR_CHECK(esp_modem_default_attach(dte, dce, esp_netif));
while (1) {
ESP_ERROR_CHECK(esp_modem_default_start(dte));
/* Start PPP mode */
ESP_ERROR_CHECK(esp_modem_start_ppp(dte));
/* Wait for IP address */
xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
/* Config MQTT */
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, NULL);
esp_mqtt_client_start(mqtt_client);
xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
esp_mqtt_client_destroy(mqtt_client);
/* Exit PPP mode */
ESP_ERROR_CHECK(esp_modem_stop_ppp(dte));
xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
ESP_LOGI(TAG, "Restart after 60 seconds");
vTaskDelay(pdMS_TO_TICKS(60000));
}
/* Default destroy all modem sub-units attached to it (DTE, DCE, netif) */
ESP_ERROR_CHECK(esp_modem_default_destroy(dte));
}