esp-idf/examples/protocols/pppos_client/components/modem/include/esp_modem.h
David Cermak 55d41c3377 esp_modem: Fixed race condition on exiting PPP mode
esp_modem_stop_ppp() stops both ppp netif and switches the modem back to
command mode. IF these two actions are not synchronised, we might
experience issues of
* active PPP session trying to send/receive uart-data
* command mode already active before modem switched to it
both resulting in crashes.
Fixed by introducing the transition mode and running these actions in sequence
* set esp-modem to transition mode
* enter command mode, wait for the reply or re-sync
* close the PPP netif
* wait until the netif closes
Other fixes include ignoring certain events if modem component not ready
or not in appropriate mode:
* ignoring all UART events comming from DTE with no DCE attached
* ignore pattern detection in PPP mode

Closes https://github.com/espressif/esp-idf/issues/6013
Closes https://github.com/espressif/esp-idf/issues/5737
Closes https://github.com/espressif/esp-idf/issues/6024
Closes https://github.com/espressif/esp-idf/issues/6058
Closes https://github.com/espressif/esp-idf/issues/5563
Closes https://github.com/espressif/esp-idf/issues/5695
Closes https://github.com/espressif/esp-idf/issues/5633
Closes https://github.com/espressif/esp-idf/issues/4482
Related https://github.com/espressif/esp-idf/pull/4849
Related https://github.com/espressif/esp-idf/pull/4653
2020-12-21 16:38:20 +01:00

175 lines
5.6 KiB
C

// 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
#include "esp_modem_dce.h"
#include "esp_modem_dte.h"
#include "esp_event.h"
#include "driver/uart.h"
#include "esp_modem_compat.h"
/**
* @brief Declare Event Base for ESP Modem
*
*/
ESP_EVENT_DECLARE_BASE(ESP_MODEM_EVENT);
/**
* @brief ESP Modem Event
*
*/
typedef enum {
ESP_MODEM_EVENT_PPP_START = 0, /*!< ESP Modem Start PPP Session */
ESP_MODEM_EVENT_PPP_STOP = 3, /*!< ESP Modem Stop PPP Session*/
ESP_MODEM_EVENT_UNKNOWN = 4 /*!< ESP Modem Unknown Response */
} esp_modem_event_t;
/**
* @brief ESP Modem DTE Configuration
*
*/
typedef struct {
uart_port_t port_num; /*!< UART port number */
uart_word_length_t data_bits; /*!< Data bits of UART */
uart_stop_bits_t stop_bits; /*!< Stop bits of UART */
uart_parity_t parity; /*!< Parity type */
modem_flow_ctrl_t flow_control; /*!< Flow control type */
uint32_t baud_rate; /*!< Communication baud rate */
int tx_io_num; /*!< TXD Pin Number */
int rx_io_num; /*!< RXD Pin Number */
int rts_io_num; /*!< RTS Pin Number */
int cts_io_num; /*!< CTS Pin Number */
int rx_buffer_size; /*!< UART RX Buffer Size */
int tx_buffer_size; /*!< UART TX Buffer Size */
int pattern_queue_size; /*!< UART Pattern Queue Size */
int event_queue_size; /*!< UART Event Queue Size */
uint32_t event_task_stack_size; /*!< UART Event Task Stack size */
int event_task_priority; /*!< UART Event Task Priority */
int line_buffer_size; /*!< Line buffer size for command mode */
} 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
*
*/
#define ESP_MODEM_DTE_DEFAULT_CONFIG() \
{ \
.port_num = UART_NUM_1, \
.data_bits = UART_DATA_8_BITS, \
.stop_bits = UART_STOP_BITS_1, \
.parity = UART_PARITY_DISABLE, \
.baud_rate = 115200, \
.flow_control = MODEM_FLOW_CONTROL_NONE,\
.tx_io_num = 25, \
.rx_io_num = 26, \
.rts_io_num = 27, \
.cts_io_num = 23, \
.rx_buffer_size = 1024, \
.tx_buffer_size = 512, \
.pattern_queue_size = 20, \
.event_queue_size = 30, \
.event_task_stack_size = 2048, \
.event_task_priority = 5, \
.line_buffer_size = 512 \
}
/**
* @brief Create and initialize Modem DTE object
*
* @param config configuration of ESP Modem DTE object
* @return modem_dte_t*
* - Modem DTE object
*/
modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config);
/**
* @brief Register event handler for ESP Modem event loop
*
* @param dte modem_dte_t type object
* @param handler event handler to register
* @param handler_args arguments for registered handler
* @return esp_err_t
* - ESP_OK on success
* - 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_set_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
*
* @param dte modem_dte_t type object
* @param handler event handler to unregister
* @return esp_err_t
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG on invalid combination of event base and event id
*/
esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t handler);
/**
* @brief Setup PPP Session
*
* @param dte Modem DTE object
* @return esp_err_t
* - ESP_OK on success
* - ESP_FAIL on error
*/
esp_err_t esp_modem_start_ppp(modem_dte_t *dte);
/**
* @brief Exit PPP Session
*
* @param dte Modem DTE Object
* @return esp_err_t
* - ESP_OK on success
* - ESP_FAIL on error
*/
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);
/**
* @brief Notify the modem, that ppp netif has closed
*
* @note This API should only be used internally by the modem-netif layer
*
* @param dte ESP Modem DTE object
*
* @return ESP_OK on success
*/
esp_err_t esp_modem_notify_ppp_netif_closed(modem_dte_t *dte);
#ifdef __cplusplus
}
#endif