1. add support for ESP32 DTE 2. add support for SIM800/BG96 DCE 3. add PPPoS setup procedure 4. add support for SMS 5. add mqtt example after PPP connection established
240 lines
8.6 KiB
C
240 lines
8.6 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 "tcpip_adapter.h"
|
|
#include "mqtt_client.h"
|
|
#include "esp_modem.h"
|
|
#include "esp_log.h"
|
|
#include "sim800.h"
|
|
#include "bg96.h"
|
|
|
|
#define BROKER_URL "mqtt://iot.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_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(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(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 *dce, const char *phone_num, const char *text)
|
|
{
|
|
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 MODEM_EVENT_PPP_START:
|
|
ESP_LOGI(TAG, "Modem PPP Started");
|
|
break;
|
|
case MODEM_EVENT_PPP_CONNECT:
|
|
ESP_LOGI(TAG, "Modem Connect to PPP Server");
|
|
ppp_client_ip_info_t *ipinfo = (ppp_client_ip_info_t *)(event_data);
|
|
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
|
|
ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&ipinfo->ip));
|
|
ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&ipinfo->netmask));
|
|
ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&ipinfo->gw));
|
|
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ipinfo->ns1));
|
|
ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ipinfo->ns2));
|
|
ESP_LOGI(TAG, "~~~~~~~~~~~~~~");
|
|
xEventGroupSetBits(event_group, CONNECT_BIT);
|
|
break;
|
|
case MODEM_EVENT_PPP_DISCONNECT:
|
|
ESP_LOGI(TAG, "Modem Disconnect from PPP Server");
|
|
break;
|
|
case MODEM_EVENT_PPP_STOP:
|
|
ESP_LOGI(TAG, "Modem PPP Stopped");
|
|
xEventGroupSetBits(event_group, STOP_BIT);
|
|
break;
|
|
case MODEM_EVENT_UNKNOWN:
|
|
ESP_LOGW(TAG, "Unknow line received: %s", (char *)event_data);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
|
{
|
|
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;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
void app_main()
|
|
{
|
|
tcpip_adapter_init();
|
|
event_group = xEventGroupCreate();
|
|
/* create dte object */
|
|
esp_modem_dte_config_t config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
|
modem_dte_t *dte = esp_modem_dte_init(&config);
|
|
/* Register event handler */
|
|
ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, NULL));
|
|
/* create dce object */
|
|
#if CONFIG_ESP_MODEM_DEVICE_SIM800
|
|
modem_dce_t *dce = sim800_init(dte);
|
|
#elif CONFIG_ESP_MODEM_DEVICE_BG96
|
|
modem_dce_t *dce = bg96_init(dte);
|
|
#else
|
|
#error "Unsupported DCE"
|
|
#endif
|
|
ESP_ERROR_CHECK(dce->set_flow_ctrl(dce, MODEM_FLOW_CONTROL_NONE));
|
|
ESP_ERROR_CHECK(dce->store_profile(dce));
|
|
/* Print Module ID, Operator, IMEI, IMSI */
|
|
ESP_LOGI(TAG, "Module: %s", dce->name);
|
|
ESP_LOGI(TAG, "Operator: %s", dce->oper);
|
|
ESP_LOGI(TAG, "IMEI: %s", dce->imei);
|
|
ESP_LOGI(TAG, "IMSI: %s", dce->imsi);
|
|
/* Get signal quality */
|
|
uint32_t rssi = 0, ber = 0;
|
|
ESP_ERROR_CHECK(dce->get_signal_quality(dce, &rssi, &ber));
|
|
ESP_LOGI(TAG, "rssi: %d, ber: %d", rssi, ber);
|
|
/* Get battery voltage */
|
|
uint32_t voltage = 0, bcs = 0, bcl = 0;
|
|
ESP_ERROR_CHECK(dce->get_battery_status(dce, &bcs, &bcl, &voltage));
|
|
ESP_LOGI(TAG, "Battery voltage: %d mV", voltage);
|
|
/* Setup PPP environment */
|
|
esp_modem_setup_ppp(dte);
|
|
/* Wait for IP address */
|
|
xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
|
|
/* Config MQTT */
|
|
esp_mqtt_client_config_t mqtt_config = {
|
|
.uri = BROKER_URL,
|
|
.event_handle = mqtt_event_handler,
|
|
};
|
|
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
|
|
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_exit_ppp(dte));
|
|
xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
|
|
#if CONFIG_SEND_MSG
|
|
const char *message = "Welcome to ESP32!";
|
|
ESP_ERROR_CHECK(example_send_message_text(dce, CONFIG_SEND_MSG_PEER_PHONE_NUMBER, message));
|
|
ESP_LOGI(TAG, "Send send message [%s] ok", message);
|
|
#endif
|
|
/* Power down module */
|
|
ESP_ERROR_CHECK(dce->power_down(dce));
|
|
ESP_LOGI(TAG, "Power down");
|
|
ESP_ERROR_CHECK(dce->deinit(dce));
|
|
ESP_ERROR_CHECK(dte->deinit(dte));
|
|
}
|