pppos_client: udated example code to use esp-netif in PPP configuration

This commit is contained in:
David Cermak 2019-11-11 16:38:43 +01:00 committed by bot
parent 52ca3a917d
commit 25913af2cc
10 changed files with 838 additions and 204 deletions

View file

@ -0,0 +1,109 @@
// Copyright 2019 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 _ESP_NETIF_PPP_H_
#define _ESP_NETIF_PPP_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @brief PPP event base */
ESP_EVENT_DECLARE_BASE(NETIF_PPP_STATUS);
/** @brief Configuration structure for PPP network interface
*
*/
typedef struct esp_netif_ppp_config {
bool ppp_phase_event_enabled; /**< Enables events coming from PPP PHASE change */
bool ppp_error_event_enabled; /**< Enables events from main PPP state machine producing errors */
} esp_netif_ppp_config_t;
/** @brief event id offset for PHASE related events
*
* All PPP related events are produced from esp-netif under `NETIF_PPP_STATUS`, this offset defines
* helps distinguish between error and phase events
*/
#define NETIF_PP_PHASE_OFFSET (0x100)
/** @brief event ids for different PPP related events
*
*/
typedef enum {
NETIF_PPP_ERRORNONE = 0, /* No error. */
NETIF_PPP_ERRORPARAM = 1, /* Invalid parameter. */
NETIF_PPP_ERROROPEN = 2, /* Unable to open PPP session. */
NETIF_PPP_ERRORDEVICE = 3, /* Invalid I/O device for PPP. */
NETIF_PPP_ERRORALLOC = 4, /* Unable to allocate resources. */
NETIF_PPP_ERRORUSER = 5, /* User interrupt. */
NETIF_PPP_ERRORCONNECT = 6, /* Connection lost. */
NETIF_PPP_ERRORAUTHFAIL = 7, /* Failed authentication challenge. */
NETIF_PPP_ERRORPROTOCOL = 8, /* Failed to meet protocol. */
NETIF_PPP_ERRORPEERDEAD = 9, /* Connection timeout */
NETIF_PPP_ERRORIDLETIMEOUT = 10, /* Idle Timeout */
NETIF_PPP_ERRORCONNECTTIME = 11, /* Max connect time reached */
NETIF_PPP_ERRORLOOPBACK = 12, /* Loopback detected */
NETIF_PPP_PHASE_DEAD = NETIF_PP_PHASE_OFFSET + 0,
NETIF_PPP_PHASE_MASTER = NETIF_PP_PHASE_OFFSET + 1,
NETIF_PPP_PHASE_HOLDOFF = NETIF_PP_PHASE_OFFSET + 2,
NETIF_PPP_PHASE_INITIALIZE = NETIF_PP_PHASE_OFFSET + 3,
NETIF_PPP_PHASE_SERIALCONN = NETIF_PP_PHASE_OFFSET + 4,
NETIF_PPP_PHASE_DORMANT = NETIF_PP_PHASE_OFFSET + 5,
NETIF_PPP_PHASE_ESTABLISH = NETIF_PP_PHASE_OFFSET + 6,
NETIF_PPP_PHASE_AUTHENTICATE = NETIF_PP_PHASE_OFFSET + 7,
NETIF_PPP_PHASE_CALLBACK = NETIF_PP_PHASE_OFFSET + 8,
NETIF_PPP_PHASE_NETWORK = NETIF_PP_PHASE_OFFSET + 9,
NETIF_PPP_PHASE_RUNNING = NETIF_PP_PHASE_OFFSET + 10,
NETIF_PPP_PHASE_TERMINATE = NETIF_PP_PHASE_OFFSET + 11,
NETIF_PPP_PHASE_DISCONNECT = NETIF_PP_PHASE_OFFSET + 12,
} esp_netif_ppp_status_event_t;
/** @brief definitions of different authorisation types
*
*/
typedef enum {
NETIF_PPP_AUTHTYPE_PAP = 0x01,
NETIF_PPP_AUTHTYPE_CHAP = 0x02,
NETIF_PPP_AUTHTYPE_MSCHAP = 0x04,
NETIF_PPP_AUTHTYPE_MSCHAP_V2 = 0x08,
NETIF_PPP_AUTHTYPE_EAP = 0x10,
} esp_netif_auth_type_t;
/** @brief Sets the auth parameters for the supplied esp-netif.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] authtype Authorisation type
* @param[in] user User name
* @param[in] passwd Password
*
* @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP
*/
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd);
/** @brief Sets common parameters for the supplied esp-netif.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] config Pointer to PPP netif configuration structure
*
* @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP
*/
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config);
#ifdef __cplusplus
}
#endif
#endif //_ESP_NETIF_PPP_H_

View file

@ -0,0 +1,327 @@
// Copyright 2019 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.
#include "lwip/dns.h"
#include "esp_netif.h"
#include "netif/ppp/pppapi.h"
#include "netif/ppp/pppos.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
#include "esp_event.h"
#include "esp_netif_ppp.h"
#include "esp_netif_lwip_internal.h"
ESP_EVENT_DEFINE_BASE(NETIF_PPP_STATUS);
static const char *TAG = "esp-netif_lwip-ppp";
#if PPPOS_SUPPORT
/**
* @brief internal lwip_ppp context struct, used to hold PPP netif related parameters
*/
struct lwip_ppp_ctx {
bool ppp_phase_event_enabled;
bool ppp_error_event_enabled;
ppp_pcb *ppp;
};
/**
* @brief lwip callback from PPP client used here to produce PPP error related events,
* as well as some IP events
*/
static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
{
struct netif *pppif = ppp_netif(pcb);
const ip_addr_t *dest_ip = NULL;
ip_event_ap_staipassigned_t evt = { 0 };
esp_err_t err;
esp_netif_t *netif = ctx;
struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx;
esp_netif_ip_info_t ipinfo = { {0}, {0}, {0} };
esp_ip4_addr_t ns1;
esp_ip4_addr_t ns2;
switch (err_code) {
case PPPERR_NONE: /* Connected */
ESP_LOGI(TAG, "Connected");
ipinfo.ip.addr = pppif->ip_addr.u_addr.ip4.addr;
ipinfo.gw.addr = pppif->gw.u_addr.ip4.addr;
ipinfo.netmask.addr = pppif->netmask.u_addr.ip4.addr;
dest_ip = dns_getserver(0);
if(dest_ip != NULL){
ns1.addr = (*dest_ip).u_addr.ip4.addr;
}
dest_ip = dns_getserver(1);
if(dest_ip != NULL){
ns2.addr = (*dest_ip).u_addr.ip4.addr;
}
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ns1));
ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ns2));
evt.ip.addr = ipinfo.ip.addr;
err = esp_event_post(IP_EVENT, netif->get_ip_event, &evt, sizeof(evt), 0);
if (ESP_OK != err) {
ESP_LOGE(TAG, "esp_event_send_internal failed with code %d", err);
}
return;
case PPPERR_PARAM:
ESP_LOGE(TAG, "Invalid parameter");
break;
case PPPERR_OPEN:
ESP_LOGE(TAG, "Unable to open PPP session");
break;
case PPPERR_DEVICE:
ESP_LOGE(TAG, "Invalid I/O device for PPP");
break;
case PPPERR_ALLOC:
ESP_LOGE(TAG, "Unable to allocate resources");
break;
case PPPERR_USER: /* User interrupt */
ESP_LOGI(TAG, "User interrupt");
break;
case PPPERR_CONNECT: /* Connection lost */
ESP_LOGI(TAG, "Connection lost");
err = esp_event_post(IP_EVENT, netif->lost_ip_event, &evt, sizeof(evt), 0);
if (ESP_OK != err) {
ESP_LOGE(TAG, "esp_event_send_internal failed with code %d", err);
}
return;
case PPPERR_AUTHFAIL:
ESP_LOGE(TAG, "Failed authentication challenge");
break;
case PPPERR_PROTOCOL:
ESP_LOGE(TAG, "Failed to meet protocol");
break;
case PPPERR_PEERDEAD:
ESP_LOGE(TAG, "Connection timeout");
break;
case PPPERR_IDLETIMEOUT:
ESP_LOGE(TAG, "Idle Timeout");
break;
case PPPERR_CONNECTTIME:
ESP_LOGE(TAG, "Max connect time reached");
break;
case PPPERR_LOOPBACK:
ESP_LOGE(TAG, "Loopback detected");
break;
default:
ESP_LOGE(TAG, "Unknown error code %d", err_code);
break;
}
if (obj->ppp_error_event_enabled) {
err = esp_event_post(NETIF_PPP_STATUS, err_code, netif, sizeof(netif), 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_event_post failed with code %d", err);
}
}
}
#if PPP_NOTIFY_PHASE
/**
* @brief Notify phase callback which is called on each PPP internal state change
*
* @param pcb PPP control block
* @param phase Phase ID
* @param ctx Context of callback
*/
static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx)
{
switch (phase) {
case PPP_PHASE_DEAD:
ESP_LOGD(TAG, "Phase Dead");
break;
case PPP_PHASE_INITIALIZE:
ESP_LOGD(TAG, "Phase Start");
break;
case PPP_PHASE_ESTABLISH:
ESP_LOGD(TAG, "Phase Establish");
break;
case PPP_PHASE_AUTHENTICATE:
ESP_LOGD(TAG, "Phase Authenticate");
break;
case PPP_PHASE_NETWORK:
ESP_LOGD(TAG, "Phase Network");
break;
case PPP_PHASE_RUNNING:
ESP_LOGD(TAG, "Phase Running");
break;
case PPP_PHASE_TERMINATE:
ESP_LOGD(TAG, "Phase Terminate");
break;
case PPP_PHASE_DISCONNECT:
ESP_LOGD(TAG, "Phase Disconnect");
break;
default:
ESP_LOGW(TAG, "Phase Unknown: %d", phase);
break;
}
esp_netif_t *netif = ctx;
struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx;
if (obj && obj->ppp_phase_event_enabled) {
esp_err_t err = esp_event_post(NETIF_PPP_STATUS, NETIF_PP_PHASE_OFFSET + phase, netif, sizeof(netif), 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_event_post failed with code %d", err);
}
}
}
#endif // PPP_NOTIFY_PHASE
/**
* @brief PPP low level output callback used to transmit data using standard esp-netif interafce
*
* @param pcb PPP control block
* @param data Buffer to write to serial port
* @param len Length of the data buffer
* @param ctx Context of callback
*
* @return uint32_t Length of data successfully sent
*/
static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *netif)
{
esp_err_t ret = esp_netif_transmit(netif, data, len);
if (ret == ESP_OK) {
return len;
}
return 0;
}
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd)
{
if (netif == NULL || !netif->is_ppp_netif) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx;
#if PAP_SUPPORT
pppapi_set_auth(obj->ppp, authtype, user, passwd);
#elif CHAP_SUPPORT
pppapi_set_auth(obj->ppp, authtype, user, passwd);
#else
#error "Unsupported AUTH Negotiation"
#endif
return ESP_OK;
}
void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx)
{
pppapi_set_default(ppp_ctx->ppp);
}
lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config)
{
struct netif * netif_impl = esp_netif->lwip_netif;
struct lwip_ppp_ctx * ppp_obj = calloc(1, sizeof(struct lwip_ppp_ctx));
if (ppp_obj == NULL) {
ESP_LOGE(TAG, "%s: cannot allocate lwip_ppp_ctx", __func__);
return NULL;
}
ppp_obj->ppp = pppapi_pppos_create(netif_impl, pppos_low_level_output, on_ppp_status_changed, esp_netif);
ESP_LOGD(TAG, "%s: PPP connection created: %p", __func__, ppp_obj->ppp);
if (!ppp_obj->ppp) {
ESP_LOGE(TAG, "%s: lwIP PPP connection cannot be created", __func__);
}
#if PPP_NOTIFY_PHASE
ppp_set_notify_phase_callback(ppp_obj->ppp, on_ppp_notify_phase);
#endif
ppp_set_usepeerdns(ppp_obj->ppp, 1);
return ppp_obj;
}
esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx)
{
ESP_LOGD(TAG, "%s: Starting PPP connection: %p", __func__, ppp_ctx->ppp);
esp_err_t err = pppapi_connect(ppp_ctx->ppp, 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "%s: PPP connection cannot be started", __func__);
return ESP_FAIL;
}
return ESP_OK;
}
void esp_netif_lwip_ppp_input(void *ppp_ctx, void *buffer, size_t len, void *eb)
{
struct lwip_ppp_ctx * obj = ppp_ctx;
err_t ret = pppos_input_tcpip(obj->ppp, buffer, len);
if (ret != ERR_OK) {
ESP_LOGE(TAG, "pppos_input_tcpip failed with %d", ret);
}
}
esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp_ctx)
{
ESP_LOGD(TAG, "%s: Stopped PPP connection: %p", __func__, ppp_ctx->ppp);
err_t ret = pppapi_close(ppp_ctx->ppp, 0);
if (ret != ERR_OK) {
ESP_LOGE(TAG, "pppapi_close failed with %d", ret);
return ESP_FAIL;
}
return ESP_OK;
}
void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp_ctx)
{
pppapi_free(ppp_ctx->ppp);
free(ppp_ctx);
}
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config)
{
struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx;
obj->ppp_phase_event_enabled = config->ppp_phase_event_enabled;
obj->ppp_error_event_enabled = config->ppp_error_event_enabled;
return ESP_OK;
}
#else /* PPPOS_SUPPORT */
/**
* @brief If PPP not enabled in menuconfig, log the error and return appropriate code indicating failure
*/
#define LOG_PPP_DISABLED_AND_DO(action) \
{ \
ESP_LOGE(TAG, "%s not supported, please enable PPP in lwIP component configuration", __func__); \
action; \
}
esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd)
LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED)
void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx)
LOG_PPP_DISABLED_AND_DO()
lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config)
LOG_PPP_DISABLED_AND_DO(return NULL)
esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx)
LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED)
void esp_netif_lwip_ppp_input(void *ppp_ctx, void *buffer, size_t len, void *eb)
LOG_PPP_DISABLED_AND_DO()
esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp_ctx)
LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED)
void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp_ctx)
LOG_PPP_DISABLED_AND_DO()
esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config)
LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED)
#endif /* PPPOS_SUPPORT */

View file

@ -0,0 +1,76 @@
// Copyright 2019 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 _ESP_NETIF_LWIP_PPP_H_
#define _ESP_NETIF_LWIP_PPP_H_
/**
* @brief Creates new PPP related structure
*
* @param[in] esp_netif pointer esp-netif instance
* @param[in] stack_config TCP/IP stack configuration structure
*
* @return
* - pointer to ppp-netif object on success
* - NULL otherwise
*/
lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config);
/**
* @brief Creates new PPP related structure
*
* @param[in] ppp pointer to internal ppp context instance
*
* @return
* - ESP_OK on success
*/
esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp);
/**
* @brief Data path API to input incoming packets to PPP
*
* @param[in] ppp pointer to internal ppp context instance
* @param[in] buffer pointer to the incoming data
* @param[in] len length of the data
* @param[in] eb external buffer ptr not used here (to be inline with input function prototypes)
*
* @return
* - ESP_OK on success
*/
void esp_netif_lwip_ppp_input(void *ppp, void *buffer, size_t len, void *eb);
/**
* @brief Destroys the ppp netif object
*
* @param[in] ppp pointer to internal ppp context instance
*/
void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp);
/**
* @brief Stops the PPP interface
*
* @param[in] ppp pointer to internal ppp context instance
*
* @return
* - ESP_OK on success
*/
esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp);
/**
* @brief Sets default netif for routing priority config
*
*/
void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx);
#endif // _ESP_NETIF_LWIP_PPP_H_

View file

@ -24,7 +24,7 @@ extern "C" {
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(void *h, void *buffer, size_t len, void *eb);
void ethernetif_input(void *netif, void *buffer, size_t len, void *eb);
void netif_reg_addr_change_cb(void* cb);

View file

@ -1,5 +1,6 @@
set(srcs "src/esp_modem.c"
"src/esp_modem_dce_service"
"src/esp_modem_netif.c"
"src/sim800.c"
"src/bg96.c")

View file

@ -21,7 +21,6 @@ extern "C" {
#include "esp_modem_dte.h"
#include "esp_event.h"
#include "driver/uart.h"
#include "lwip/ip_addr.h"
/**
* @brief Declare Event Base for ESP Modem
@ -35,8 +34,6 @@ ESP_EVENT_DECLARE_BASE(ESP_MODEM_EVENT);
*/
typedef enum {
MODEM_EVENT_PPP_START, /*!< ESP Modem Start PPP Session */
MODEM_EVENT_PPP_CONNECT, /*!< ESP Modem Connect to PPP Server */
MODEM_EVENT_PPP_DISCONNECT, /*!< ESP Modem Disconnect from PPP Server */
MODEM_EVENT_PPP_STOP, /*!< ESP Modem Stop PPP Session*/
MODEM_EVENT_UNKNOWN /*!< ESP Modem Unknown Response */
} esp_modem_event_t;
@ -54,6 +51,12 @@ typedef struct {
uint32_t baud_rate; /*!< Communication baud rate */
} esp_modem_dte_config_t;
/**
* @brief Type used for reception callback
*
*/
typedef esp_err_t (*esp_modem_on_receive)(void *buffer, size_t len, void *context);
/**
* @brief ESP Modem DTE Default Configuration
*
@ -88,7 +91,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config);
* - ESP_ERR_NO_MEM on allocating memory for the handler failed
* - ESP_ERR_INVALID_ARG on invalid combination of event base and event id
*/
esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args);
esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args);
/**
* @brief Unregister event handler for ESP Modem event loop
@ -101,18 +104,6 @@ esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t hand
*/
esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t handler);
/**
* @brief PPPoS Client IP Information
*
*/
typedef struct {
ip4_addr_t ip; /*!< IP Address */
ip4_addr_t netmask; /*!< Net Mask */
ip4_addr_t gw; /*!< Gateway */
ip4_addr_t ns1; /*!< Name Server1 */
ip4_addr_t ns2; /*!< Name Server2 */
} ppp_client_ip_info_t;
/**
* @brief Setup PPP Session
*
@ -121,7 +112,7 @@ typedef struct {
* - ESP_OK on success
* - ESP_FAIL on error
*/
esp_err_t esp_modem_setup_ppp(modem_dte_t *dte);
esp_err_t esp_modem_start_ppp(modem_dte_t *dte);
/**
* @brief Exit PPP Session
@ -131,7 +122,18 @@ esp_err_t esp_modem_setup_ppp(modem_dte_t *dte);
* - ESP_OK on success
* - ESP_FAIL on error
*/
esp_err_t esp_modem_exit_ppp(modem_dte_t *dte);
esp_err_t esp_modem_stop_ppp(modem_dte_t *dte);
/**
* @brief Setup on reception callback
*
* @param dte ESP Modem DTE object
* @param receive_cb Function pointer to the reception callback
* @param receive_cb_ctx Contextual pointer to be passed to the reception callback
*
* @return ESP_OK on success
*/
esp_err_t esp_modem_set_rx_cb(modem_dte_t *dte, esp_modem_on_receive receive_cb, void *receive_cb_ctx);
#ifdef __cplusplus
}

View file

@ -0,0 +1,53 @@
// Copyright 2015-2018 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Creates handle to esp_modem used as an esp-netif driver
*
* @param dte ESP Modem DTE object
*
* @return opaque pointer to esp-modem IO driver used to attach to esp-netif
*/
void *esp_modem_netif_setup(modem_dte_t *dte);
/**
* @brief Destroys the esp-netif driver handle
*
* @param h pointer to the esp-netif adapter for esp-modem
*/
void esp_modem_netif_teardown(void *h);
/**
* @brief Clears default handlers for esp-modem lifecycle
*
* @param h pointer to the esp-netif adapter for esp-modem
*/
esp_err_t esp_modem_netif_clear_default_handlers(void *h);
/**
* @brief Setups default handlers for esp-modem lifecycle
*
* @param h pointer to the esp-netif adapter for esp-modem
* @param esp_netif pointer corresponding esp-netif instance
*/
esp_err_t esp_modem_netif_set_default_handlers(void *h, esp_netif_t * esp_netif);
#ifdef __cplusplus
}
#endif

View file

@ -17,10 +17,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "netif/ppp/pppapi.h"
#include "netif/ppp/pppos.h"
#include "lwip/dns.h"
#include "esp_netif.h"
#include "esp_modem.h"
#include "esp_log.h"
#include "sdkconfig.h"
@ -60,11 +56,21 @@ typedef struct {
esp_event_loop_handle_t event_loop_hdl; /*!< Event loop handle */
TaskHandle_t uart_event_task_hdl; /*!< UART event task handle */
SemaphoreHandle_t process_sem; /*!< Semaphore used for indicating processing status */
struct netif pppif; /*!< PPP network interface */
ppp_pcb *ppp; /*!< PPP control block */
modem_dte_t parent; /*!< DTE interface that should extend */
esp_modem_on_receive receive_cb; /*!< ptr to data reception */
void *receive_cb_ctx; /*!< ptr to rx fn context data */
} esp_modem_dte_t;
esp_err_t esp_modem_set_rx_cb(modem_dte_t *dte, esp_modem_on_receive receive_cb, void *receive_cb_ctx)
{
esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent);
esp_dte->receive_cb_ctx = receive_cb_ctx;
esp_dte->receive_cb = receive_cb;
return ESP_OK;
}
/**
* @brief Handle one line in DTE
*
@ -135,9 +141,9 @@ static void esp_handle_uart_data(esp_modem_dte_t *esp_dte)
uart_get_buffered_data_len(esp_dte->uart_port, &length);
length = MIN(ESP_MODEM_LINE_BUFFER_SIZE, length);
length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY);
/* pass input data to the lwIP core thread */
/* pass the input data to configured callback */
if (length) {
pppos_input_tcpip(esp_dte->ppp, esp_dte->buffer, length);
esp_dte->receive_cb(esp_dte->buffer, length, esp_dte->receive_cb_ctx);
}
}
@ -236,6 +242,8 @@ err:
return -1;
}
/**
* @brief Send data and wait for prompt from DCE
*
@ -344,6 +352,8 @@ static esp_err_t esp_modem_dte_deinit(modem_dte_t *dte)
return ESP_OK;
}
modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config)
{
esp_err_t res;
@ -363,6 +373,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config)
esp_dte->parent.change_mode = esp_modem_dte_change_mode;
esp_dte->parent.process_cmd_done = esp_modem_dte_process_cmd_done;
esp_dte->parent.deinit = esp_modem_dte_deinit;
/* Config UART */
uart_config_t uart_config = {
.baud_rate = config->baud_rate,
@ -434,10 +445,10 @@ err_dte_mem:
return NULL;
}
esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args)
esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args)
{
esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent);
return esp_event_handler_register_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_EVENT_ANY_ID, handler, handler_args);
return esp_event_handler_register_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, event_id, handler, handler_args);
}
esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t handler)
@ -446,137 +457,7 @@ esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t h
return esp_event_handler_unregister_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_EVENT_ANY_ID, handler);
}
/**
* @brief PPP status callback which is called on PPP status change (up, down, ) by lwIP core thread
*
* @param pcb PPP control block
* @param err_code Error code
* @param ctx Context of callback
*/
static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx)
{
struct netif *pppif = ppp_netif(pcb);
const ip_addr_t *dest_ip = NULL;
modem_dte_t *dte = (modem_dte_t *)(ctx);
esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent);
ppp_client_ip_info_t ipinfo = {0};
switch (err_code) {
case PPPERR_NONE: /* Connected */
ipinfo.ip = pppif->ip_addr.u_addr.ip4;
ipinfo.gw = pppif->gw.u_addr.ip4;
ipinfo.netmask = pppif->netmask.u_addr.ip4;
dest_ip = dns_getserver(0);
if(dest_ip != NULL){
ipinfo.ns1 = (*dest_ip).u_addr.ip4;
}
dest_ip = dns_getserver(1);
if(dest_ip != NULL){
ipinfo.ns2 = (*dest_ip).u_addr.ip4;
}
esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_CONNECT, &ipinfo, sizeof(ipinfo), 0);
break;
case PPPERR_PARAM:
ESP_LOGE(MODEM_TAG, "Invalid parameter");
break;
case PPPERR_OPEN:
ESP_LOGE(MODEM_TAG, "Unable to open PPP session");
break;
case PPPERR_DEVICE:
ESP_LOGE(MODEM_TAG, "Invalid I/O device for PPP");
break;
case PPPERR_ALLOC:
ESP_LOGE(MODEM_TAG, "Unable to allocate resources");
break;
case PPPERR_USER: /* User interrupt */
esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_STOP, NULL, 0, 0);
/* Free the PPP control block */
pppapi_free(esp_dte->ppp);
break;
case PPPERR_CONNECT: /* Connection lost */
esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_DISCONNECT, NULL, 0, 0);
break;
case PPPERR_AUTHFAIL:
ESP_LOGE(MODEM_TAG, "Failed authentication challenge");
break;
case PPPERR_PROTOCOL:
ESP_LOGE(MODEM_TAG, "Failed to meet protocol");
break;
case PPPERR_PEERDEAD:
ESP_LOGE(MODEM_TAG, "Connection timeout");
break;
case PPPERR_IDLETIMEOUT:
ESP_LOGE(MODEM_TAG, "Idle Timeout");
break;
case PPPERR_CONNECTTIME:
ESP_LOGE(MODEM_TAG, "Max connect time reached");
break;
case PPPERR_LOOPBACK:
ESP_LOGE(MODEM_TAG, "Loopback detected");
break;
default:
ESP_LOGE(MODEM_TAG, "Unknown error code %d", err_code);
break;
}
}
#if PPP_NOTIFY_PHASE
/**
* @brief Notify phase callback which is called on each PPP internal state change
*
* @param pcb PPP control block
* @param phase Phase ID
* @param ctx Context of callback
*/
static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx)
{
switch (phase) {
case PPP_PHASE_DEAD:
ESP_LOGD(MODEM_TAG, "Phase Dead");
break;
case PPP_PHASE_INITIALIZE:
ESP_LOGD(MODEM_TAG, "Phase Start");
break;
case PPP_PHASE_ESTABLISH:
ESP_LOGD(MODEM_TAG, "Phase Establish");
break;
case PPP_PHASE_AUTHENTICATE:
ESP_LOGD(MODEM_TAG, "Phase Authenticate");
break;
case PPP_PHASE_NETWORK:
ESP_LOGD(MODEM_TAG, "Phase Network");
break;
case PPP_PHASE_RUNNING:
ESP_LOGD(MODEM_TAG, "Phase Running");
break;
case PPP_PHASE_TERMINATE:
ESP_LOGD(MODEM_TAG, "Phase Terminate");
break;
case PPP_PHASE_DISCONNECT:
ESP_LOGD(MODEM_TAG, "Phase Disconnect");
break;
default:
ESP_LOGW(MODEM_TAG, "Phase Unknown: %d", phase);
break;
}
}
#endif
/**
* @brief PPPoS serial output callback
*
* @param pcb PPP control block
* @param data Buffer to write to serial port
* @param len Length of the data buffer
* @param ctx Context of callback
* @return uint32_t Length of data successfully sent
*/
static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx)
{
modem_dte_t *dte = (modem_dte_t *)ctx;
return dte->send_data(dte, (const char *)data, len);
}
esp_err_t esp_modem_setup_ppp(modem_dte_t *dte)
esp_err_t esp_modem_start_ppp(modem_dte_t *dte)
{
modem_dce_t *dce = dte->dce;
MODEM_CHECK(dce, "DTE has not yet bind with DCE", err);
@ -585,40 +466,18 @@ esp_err_t esp_modem_setup_ppp(modem_dte_t *dte)
MODEM_CHECK(dce->define_pdp_context(dce, 1, "IP", CONFIG_EXAMPLE_MODEM_APN) == ESP_OK, "set MODEM APN failed", err);
/* Enter PPP mode */
MODEM_CHECK(dte->change_mode(dte, MODEM_PPP_MODE) == ESP_OK, "enter ppp mode failed", err);
/* Create PPPoS interface */
esp_dte->ppp = pppapi_pppos_create(&(esp_dte->pppif), pppos_low_level_output, on_ppp_status_changed, dte);
MODEM_CHECK(esp_dte->ppp, "create pppos interface failed", err);
#if PPP_NOTIFY_PHASE
ppp_set_notify_phase_callback(esp_dte->ppp, on_ppp_notify_phase);
#endif
/* Initiate PPP client connection */
/* Set default route */
MODEM_CHECK(pppapi_set_default(esp_dte->ppp) == ERR_OK, "set default route failed", err);
/* Ask the peer for up to 2 DNS server addresses */
ppp_set_usepeerdns(esp_dte->ppp, 1);
/* Auth configuration */
#if PAP_SUPPORT
pppapi_set_auth(esp_dte->ppp, PPPAUTHTYPE_PAP, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD);
#elif CHAP_SUPPORT
pppapi_set_auth(esp_dte->ppp, PPPAUTHTYPE_CHAP, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD);
#else
#error "Unsupported AUTH Negotiation"
#endif
/* Initiate PPP negotiation, without waiting */
MODEM_CHECK(pppapi_connect(esp_dte->ppp, 0) == ERR_OK, "initiate ppp negotiation failed", err);
/* post PPP mode started event */
esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_START, NULL, 0, 0);
return ESP_OK;
err:
return ESP_FAIL;
}
esp_err_t esp_modem_exit_ppp(modem_dte_t *dte)
esp_err_t esp_modem_stop_ppp(modem_dte_t *dte)
{
modem_dce_t *dce = dte->dce;
MODEM_CHECK(dce, "DTE has not yet bind with DCE", err);
esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent);
/* Shutdown of PPP protocols */
MODEM_CHECK(pppapi_close(esp_dte->ppp, 0) == ERR_OK, "close ppp connection failed", err);
/* Enter command mode */
MODEM_CHECK(dte->change_mode(dte, MODEM_COMMAND_MODE) == ESP_OK, "enter command mode failed", err);
/* Hang up */

View file

@ -0,0 +1,155 @@
// Copyright 2015-2018 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.
#include "esp_netif.h"
#include "esp_modem.h"
#include "esp_log.h"
static const char *TAG = "esp-modem-netif";
/**
* @brief ESP32 Modem handle to be used as netif IO object
*/
typedef struct esp_modem_netif_driver_s {
esp_netif_driver_base_t base; /*!< base structure reserved as esp-netif driver */
modem_dte_t *dte; /*!< ptr to the esp_modem objects (DTE) */
} esp_modem_netif_driver_t;
/**
* @brief Transmit function called from esp_netif to output network stack data
*
* Note: This API has to conform to esp-netif transmit prototype
*
* @param h Opaque pointer representing esp-netif driver, esp_dte in this case of esp_modem
* @param data data buffer
* @param length length of data to send
*
* @return ESP_OK on success
*/
static esp_err_t esp_modem_dte_transmit(void *h, void *buffer, size_t len)
{
modem_dte_t *dte = h;
if (dte->send_data(dte, (const char *)buffer, len) > 0) {
return ESP_OK;
}
return ESP_FAIL;
}
/**
* @brief Post attach adapter for esp-modem
*
* Used to exchange internal callbacks, context between esp-netif nad modem-netif
*
* @param esp_netif handle to esp-netif object
* @param args pointer to modem-netif driver
*
* @return ESP_OK on success
*/
static esp_err_t esp_modem_post_attach_start(esp_netif_t * esp_netif, void * args)
{
esp_modem_netif_driver_t *driver = args;
modem_dte_t *dte = driver->dte;
const esp_netif_driver_ifconfig_t driver_ifconfig = {
.driver_free_rx_buffer = NULL,
.transmit = esp_modem_dte_transmit,
.handle = dte
};
driver->base.netif = esp_netif;
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
esp_modem_start_ppp(dte);
return ESP_OK;
}
/**
* @brief Data path callback from esp-modem to pass data to esp-netif
*
* @param buffer data pointer
* @param len data length
* @param context context data used for esp-modem-netif handle
*
* @return ESP_OK on success
*/
static esp_err_t modem_netif_receive_cb(void *buffer, size_t len, void *context)
{
esp_modem_netif_driver_t *driver = context;
esp_netif_receive(driver->base.netif, buffer, len, NULL);
return ESP_OK;
}
void *esp_modem_netif_setup(modem_dte_t *dte)
{
esp_modem_netif_driver_t *driver = calloc(1, sizeof(esp_modem_netif_driver_t));
if (driver == NULL) {
ESP_LOGE(TAG, "Cannot allocate esp_modem_netif_driver_t");
goto drv_create_failed;
}
esp_err_t err = esp_modem_set_rx_cb(dte, modem_netif_receive_cb, driver);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_modem_set_rx_cb failed with: %d", err);
goto drv_create_failed;
}
driver->base.post_attach = esp_modem_post_attach_start;
driver->dte = dte;
return driver;
drv_create_failed:
return NULL;
}
void esp_modem_netif_teardown(void *h)
{
esp_modem_netif_driver_t *driver = h;
esp_netif_destroy(driver->base.netif);
free(driver);
}
esp_err_t esp_modem_netif_clear_default_handlers(void *h)
{
esp_modem_netif_driver_t *driver = h;
esp_err_t ret;
ret = esp_modem_remove_event_handler(driver->dte, esp_netif_action_start);
if (ret != ESP_OK) {
goto clear_event_failed;
}
ret = esp_modem_remove_event_handler(driver->dte, esp_netif_action_stop);
if (ret != ESP_OK) {
goto clear_event_failed;
}
return ESP_OK;
clear_event_failed:
ESP_LOGE(TAG, "Failed to unregister event handlers");
return ESP_FAIL;
}
esp_err_t esp_modem_netif_set_default_handlers(void *h, esp_netif_t * esp_netif)
{
esp_modem_netif_driver_t *driver = h;
esp_err_t ret;
ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_start, MODEM_EVENT_PPP_START, esp_netif);
if (ret != ESP_OK) {
goto set_event_failed;
}
ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_stop, MODEM_EVENT_PPP_STOP, esp_netif);
if (ret != ESP_OK) {
goto set_event_failed;
}
return ESP_OK;
set_event_failed:
ESP_LOGE(TAG, "Failed to register event handlers");
esp_modem_netif_clear_default_handlers(driver);
return ESP_FAIL;
}

View file

@ -10,8 +10,10 @@
#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 "sim800.h"
#include "bg96.h"
@ -112,21 +114,6 @@ static void modem_event_handler(void *event_handler_arg, esp_event_base_t event_
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);
@ -179,15 +166,72 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
return ESP_OK;
}
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 = 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_LOGI(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.ip));
esp_netif_get_dns_info(netif, 0, &dns_info);
ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
esp_netif_get_dns_info(netif, 1, &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");
}
}
void app_main(void)
{
#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_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();
// Init netif object
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP();
esp_netif_t *esp_netif = esp_netif_new(&cfg);
assert(esp_netif);
/* 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));
ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, ESP_EVENT_ANY_ID, NULL));
/* create dce object */
#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM800
modem_dce_t *dce = sim800_init(dte);
@ -211,10 +255,15 @@ void app_main(void)
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);
/* setup PPPoS network parameters */
esp_netif_ppp_set_auth(esp_netif, auth_type, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD);
void *modem_netif_adapter = esp_modem_netif_setup(dte);
esp_modem_netif_set_default_handlers(modem_netif_adapter, esp_netif);
/* attach the modem to the network interface */
esp_netif_attach(esp_netif, modem_netif_adapter);
/* Wait for IP address */
xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
ESP_ERROR_CHECK(dce->power_down(dce));
/* Config MQTT */
esp_mqtt_client_config_t mqtt_config = {
.uri = BROKER_URL,
@ -225,7 +274,10 @@ void app_main(void)
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));
ESP_ERROR_CHECK(esp_modem_stop_ppp(dte));
/* Destroy the netif adapter withe events, which internally frees also the esp-netif instance */
esp_modem_netif_clear_default_handlers(modem_netif_adapter);
esp_modem_netif_teardown(modem_netif_adapter);
xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
#if CONFIG_EXAMPLE_SEND_MSG
const char *message = "Welcome to ESP32!";