mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-16 12:02:11 +02:00
Final cleanup of the docs and examples
This commit is contained in:
@ -1,18 +0,0 @@
|
|||||||
menu "ESP-MODEM"
|
|
||||||
|
|
||||||
config MODEM_LEGACY_API
|
|
||||||
bool "Enable Legacy API"
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Set to true if the original pppos_client API from the example's internal
|
|
||||||
component should be used.....
|
|
||||||
|
|
||||||
config MODEM_PPP_APN
|
|
||||||
string "Local netif hostname"
|
|
||||||
default 'internet'
|
|
||||||
depends on MODEM_LEGACY_API
|
|
||||||
help
|
|
||||||
APN (Access Point Name), a logical name of a network
|
|
||||||
the modem connects to in the PPP mode
|
|
||||||
|
|
||||||
endmenu
|
|
@ -10,6 +10,8 @@ Get started with one of the examples:
|
|||||||
* `examples/modem_console` -- C++ example implementing simple terminal console with DCE commands
|
* `examples/modem_console` -- C++ example implementing simple terminal console with DCE commands
|
||||||
* `examples/ap_to_pppos` -- this example focuses on the network connectivity of the esp-modem and provides a WiFi AP
|
* `examples/ap_to_pppos` -- this example focuses on the network connectivity of the esp-modem and provides a WiFi AP
|
||||||
that forwards packets (and uses NAT) to and from the PPPoS connection.
|
that forwards packets (and uses NAT) to and from the PPPoS connection.
|
||||||
|
* `examples/simple_cmux_client` -- this example sets up the CMUX mode to talk to the modem using AT commands
|
||||||
|
with simultaneously maintaining active network connection.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
COMPONENT_ADD_INCLUDEDIRS := include
|
|
||||||
COMPONENT_PRIV_INCLUDEDIRS := private_include
|
|
||||||
COMPONENT_SRCDIRS := src
|
|
@ -31,11 +31,14 @@ the specific module, using :cpp:func:`esp_modem::dce_factory::Factory::build`.
|
|||||||
|
|
||||||
Please refer to the implementation of the existing modules.
|
Please refer to the implementation of the existing modules.
|
||||||
|
|
||||||
|
Please note that the ``modem_console`` example defines a trivial custom modem DCE which overrides one command,
|
||||||
|
for demonstration purposes only.
|
||||||
|
|
||||||
|
|
||||||
Create new communication interface
|
Create new communication interface
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
In order to connect to a device using an unsuppoeted interface (e.g. SPI or I2C), it is necessary to implement
|
In order to connect to a device using an unsupported interface (e.g. SPI or I2C), it is necessary to implement
|
||||||
a custom DTE object and supply it into :ref:`the DCE factory<dce_factory>`. The DCE is typically created in two steps:
|
a custom DTE object and supply it into :ref:`the DCE factory<dce_factory>`. The DCE is typically created in two steps:
|
||||||
|
|
||||||
- Define and create the corresponding terminal, which can communicate on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it.
|
- Define and create the corresponding terminal, which can communicate on the custom interface. This terminal should support basic IO methods defined in :cpp:class:`esp_modem::Terminal` and derive from it.
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#
|
|
||||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
|
||||||
# project subdirectory.
|
|
||||||
#
|
|
||||||
|
|
||||||
PROJECT_NAME := ap-to-pppos
|
|
||||||
|
|
||||||
include $(IDF_PATH)/make/project.mk
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
|||||||
# PPPoS simple client example
|
# AP to PPPoS example
|
||||||
|
|
||||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This example focuses on the networking part, enables forwarding packets between network interfaces. It creates a WiFi soft AP, which uses NAT to forward packets to and from the PPP network
|
This example focuses on the networking part, enables forwarding packets between network interfaces. It creates a WiFi soft AP, which uses NAT to forward packets to and from the PPP network
|
||||||
interface.
|
interface.
|
||||||
|
|
||||||
## How to use this example
|
### Specific network DCE
|
||||||
|
|
||||||
See the README.md file in the upper level `pppos` directory for more information about the PPPoS examples.
|
Note, that this example could use of a minimal Network DCE, defined in the `network_dce.cpp` file.
|
||||||
|
Please set `EXAMPLE_USE_MINIMAL_DCE` to `y` in order to demonstrate this functionality.
|
||||||
|
|
||||||
|
By default, this example simply connects to the PPP server using a supported device with C-API modem interface.
|
||||||
|
|
||||||
|
This example however, doesn't rely on sending specific AT commands, just the bare minimum to setup the cellular network.
|
||||||
|
Thus, if the `EXAMPLE_USE_MINIMAL_DCE` option is enabled, we directly inherit from the `ModuleIf` and implement only the basic commands.
|
||||||
|
Also, to demonstrate the dce_factory functionality, a new `NetDCE_Factory` is implemented for creating the network module and the DCE.
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
idf_component_register(SRCS "ap2pppos_example_main.c"
|
if(CONFIG_EXAMPLE_USE_MINIMAL_DCE)
|
||||||
"NetworkDCE.cpp"
|
set(NETWORK_DCE "network_dce.cpp")
|
||||||
INCLUDE_DIRS ".")
|
else()
|
||||||
|
set(NETWORK_DCE "network_dce.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
#target_compile_features(${COMPONENT_LIB} PRIVATE cxx_std_17)
|
idf_component_register(SRCS "ap_to_pppos.c"
|
||||||
|
${NETWORK_DCE}
|
||||||
|
INCLUDE_DIRS ".")
|
||||||
|
@ -11,6 +11,7 @@ menu "Example Configuration"
|
|||||||
default "mypassword"
|
default "mypassword"
|
||||||
help
|
help
|
||||||
WiFi password (WPA or WPA2) for the example to use.
|
WiFi password (WPA or WPA2) for the example to use.
|
||||||
|
|
||||||
config ESP_WIFI_CHANNEL
|
config ESP_WIFI_CHANNEL
|
||||||
int "WiFi Channel"
|
int "WiFi Channel"
|
||||||
range 1 13
|
range 1 13
|
||||||
@ -23,4 +24,24 @@ menu "Example Configuration"
|
|||||||
default 4
|
default 4
|
||||||
help
|
help
|
||||||
Max number of the STA connects to AP.
|
Max number of the STA connects to AP.
|
||||||
|
|
||||||
|
config EXAMPLE_MODEM_PPP_APN
|
||||||
|
string "Set MODEM APN"
|
||||||
|
default "internet"
|
||||||
|
help
|
||||||
|
Set APN (Access Point Name), a logical name to choose data network
|
||||||
|
|
||||||
|
config EXAMPLE_SIM_PIN
|
||||||
|
string "Set SIM PIN"
|
||||||
|
default "1234"
|
||||||
|
help
|
||||||
|
Pin to unlock the SIM
|
||||||
|
|
||||||
|
config EXAMPLE_USE_MINIMAL_DCE
|
||||||
|
bool "Use minimal network DCE"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Define a specific network only DCE class and
|
||||||
|
create it using DCE factory
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -15,13 +15,16 @@
|
|||||||
#include "lwip/lwip_napt.h"
|
#include "lwip/lwip_napt.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
|
#include "network_dce.h"
|
||||||
|
|
||||||
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
|
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
|
||||||
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
|
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
|
||||||
#define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_ESP_WIFI_CHANNEL
|
#define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_ESP_WIFI_CHANNEL
|
||||||
#define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN
|
#define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN
|
||||||
|
|
||||||
static const char *TAG = "ap-2-pppos";
|
|
||||||
|
static const char *TAG = "ap_to_pppos";
|
||||||
|
|
||||||
static EventGroupHandle_t event_group = NULL;
|
static EventGroupHandle_t event_group = NULL;
|
||||||
static const int CONNECT_BIT = BIT0;
|
static const int CONNECT_BIT = BIT0;
|
||||||
static const int DISCONNECT_BIT = BIT1;
|
static const int DISCONNECT_BIT = BIT1;
|
||||||
@ -62,7 +65,6 @@ static void on_ip_event(void *arg, esp_event_base_t event_base,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t set_dhcps_dns(esp_netif_t *netif, uint32_t addr)
|
static esp_err_t set_dhcps_dns(esp_netif_t *netif, uint32_t addr)
|
||||||
{
|
{
|
||||||
esp_netif_dns_info_t dns;
|
esp_netif_dns_info_t dns;
|
||||||
@ -88,6 +90,7 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wifi_init_softap(void)
|
void wifi_init_softap(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -122,13 +125,9 @@ void wifi_init_softap(void)
|
|||||||
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
|
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t modem_init_network(esp_netif_t *netif);
|
|
||||||
void modem_start_network();
|
|
||||||
void modem_stop_network();
|
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
//Initialize NVS
|
// Initialize NVS
|
||||||
esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
@ -136,29 +135,33 @@ void app_main(void)
|
|||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(ret);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
// Initialize esp_netif and default event loop
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
event_group = xEventGroupCreate();
|
event_group = xEventGroupCreate();
|
||||||
|
|
||||||
// init the DTE
|
// Initialize lwip network interface in PPP mode
|
||||||
esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP();
|
esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP();
|
||||||
esp_netif_t *ppp_netif = esp_netif_new(&ppp_netif_config);
|
esp_netif_t *ppp_netif = esp_netif_new(&ppp_netif_config);
|
||||||
assert(ppp_netif);
|
assert(ppp_netif);
|
||||||
|
|
||||||
|
// Initialize the PPP network and register for IP event
|
||||||
ESP_ERROR_CHECK(modem_init_network(ppp_netif));
|
ESP_ERROR_CHECK(modem_init_network(ppp_netif));
|
||||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL));
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL));
|
||||||
|
|
||||||
/* Init and start the modem network */
|
// Start the PPP network and wait for connection
|
||||||
modem_start_network();
|
modem_start_network();
|
||||||
/* Wait for the first connection */
|
|
||||||
EventBits_t bits;
|
EventBits_t bits;
|
||||||
do {
|
do {
|
||||||
bits = xEventGroupWaitBits(event_group, (CONNECT_BIT | DISCONNECT_BIT), pdTRUE, pdFALSE, portMAX_DELAY);
|
bits = xEventGroupWaitBits(event_group, (CONNECT_BIT | DISCONNECT_BIT), pdTRUE, pdFALSE, portMAX_DELAY);
|
||||||
if (bits&DISCONNECT_BIT) {
|
if (bits & DISCONNECT_BIT) {
|
||||||
|
ESP_LOGW(TAG, "Modem got disconnected from the PPP server: retrying...");
|
||||||
|
modem_stop_network();
|
||||||
|
modem_start_network();
|
||||||
}
|
}
|
||||||
} while ((bits&CONNECT_BIT) == 0);
|
} while ((bits & CONNECT_BIT) == 0);
|
||||||
|
|
||||||
/* Init the AP with NAT enabled */
|
// Initialize the AP and setup the NAT
|
||||||
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
|
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
|
||||||
assert(ap_netif);
|
assert(ap_netif);
|
||||||
esp_netif_dns_info_t dns;
|
esp_netif_dns_info_t dns;
|
||||||
@ -168,11 +171,13 @@ void app_main(void)
|
|||||||
wifi_init_softap();
|
wifi_init_softap();
|
||||||
ip_napt_enable(_g_esp_netif_soft_ap_ip.ip.addr, 1);
|
ip_napt_enable(_g_esp_netif_soft_ap_ip.ip.addr, 1);
|
||||||
|
|
||||||
/* Provide recovery if disconnection of some kind registered */
|
// Provide a recovery if disconnection of some kind registered
|
||||||
while (DISCONNECT_BIT&xEventGroupWaitBits(event_group, DISCONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY)) {
|
while (true) {
|
||||||
// restart the modem PPP mode
|
bits = xEventGroupWaitBits(event_group, DISCONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||||
modem_stop_network();
|
if (bits & DISCONNECT_BIT) {
|
||||||
modem_start_network();
|
ESP_LOGW(TAG, "Modem got disconnected from the PPP server: restarting the network...");
|
||||||
|
modem_stop_network();
|
||||||
|
modem_start_network();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,8 +0,0 @@
|
|||||||
#
|
|
||||||
# Main component makefile.
|
|
||||||
#
|
|
||||||
# This Makefile can be left empty. By default, it will take the sources in the
|
|
||||||
# src/ directory, compile them and link them into lib(subdirectory_name).a
|
|
||||||
# in the build directory. This behaviour is entirely configurable,
|
|
||||||
# please read the ESP-IDF documents if you need to do this.
|
|
||||||
#
|
|
@ -1,7 +0,0 @@
|
|||||||
version: "0.0.2"
|
|
||||||
targets:
|
|
||||||
- esp32
|
|
||||||
description: pppos_client to AP
|
|
||||||
dependencies:
|
|
||||||
espressif/esp_modem:
|
|
||||||
version: "~0.0.2"
|
|
@ -1,162 +0,0 @@
|
|||||||
/* softAP to PPPoS Example (modem_board)
|
|
||||||
|
|
||||||
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 <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_modem_recov_helper.h"
|
|
||||||
#include "esp_modem_dce.h"
|
|
||||||
#include "esp_modem_dce_common_commands.h"
|
|
||||||
|
|
||||||
#define ESP_MODEM_EXAMPLE_CHECK(a, str, goto_tag, ...) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!(a)) \
|
|
||||||
{ \
|
|
||||||
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
||||||
goto goto_tag; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "sim7600_board";
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
esp_modem_dce_t parent;
|
|
||||||
esp_modem_recov_gpio_t *power_pin;
|
|
||||||
esp_modem_recov_gpio_t *reset_pin;
|
|
||||||
esp_err_t (*reset)(esp_modem_dce_t *dce);
|
|
||||||
esp_err_t (*power_down)(esp_modem_dce_t *dce);
|
|
||||||
esp_modem_recov_resend_t *re_sync;
|
|
||||||
esp_modem_recov_resend_t *re_store_profile;
|
|
||||||
} sim7600_board_t;
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_handle_powerup(esp_modem_dce_t *dce, const char *line)
|
|
||||||
{
|
|
||||||
if (strstr(line, "PB DONE")) {
|
|
||||||
ESP_LOGI(TAG, "Board ready after hard reset/power-cycle");
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_deinit(esp_modem_dce_t *dce)
|
|
||||||
{
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
board->power_pin->destroy(board->power_pin);
|
|
||||||
board->power_pin->destroy(board->reset_pin);
|
|
||||||
esp_err_t err = esp_modem_command_list_deinit(&board->parent);
|
|
||||||
if (err == ESP_OK) {
|
|
||||||
free(dce);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_reset(esp_modem_dce_t *dce)
|
|
||||||
{
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
ESP_LOGI(TAG, "sim7600_board_reset!");
|
|
||||||
dce->handle_line = sim7600_board_handle_powerup;
|
|
||||||
board->power_pin->pulse(board->reset_pin);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_power_up(esp_modem_dce_t *dce)
|
|
||||||
{
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
ESP_LOGI(TAG, "sim7600_board_power_up!");
|
|
||||||
dce->handle_line = sim7600_board_handle_powerup;
|
|
||||||
board->power_pin->pulse(board->power_pin);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_power_down(esp_modem_dce_t *dce)
|
|
||||||
{
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
ESP_LOGI(TAG, "sim7600_board_power_down!");
|
|
||||||
/* power down sequence (typical values for SIM7600 Toff=min2.5s, Toff-status=26s) */
|
|
||||||
dce->handle_line = sim7600_board_handle_powerup;
|
|
||||||
board->power_pin->pulse_special(board->power_pin, 3000, 26000);
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t my_recov(esp_modem_recov_resend_t *retry_cmd, esp_err_t err, int timeouts, int errors)
|
|
||||||
{
|
|
||||||
esp_modem_dce_t *dce = retry_cmd->dce;
|
|
||||||
ESP_LOGI(TAG, "Current timeouts: %d and errors: %d", timeouts, errors);
|
|
||||||
if (err == ESP_ERR_TIMEOUT) {
|
|
||||||
if (timeouts < 2) {
|
|
||||||
// first timeout, try to exit data mode and sync again
|
|
||||||
dce->set_command_mode(dce, NULL, NULL);
|
|
||||||
esp_modem_dce_sync(dce, NULL, NULL);
|
|
||||||
} else if (timeouts < 3) {
|
|
||||||
// try to reset with GPIO if resend didn't help
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
board->reset(dce);
|
|
||||||
} else {
|
|
||||||
// otherwise power-cycle the board
|
|
||||||
sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
board->power_down(dce);
|
|
||||||
esp_modem_dce_sync(dce, NULL, NULL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// check if a PIN needs to be supplied in case of a failure
|
|
||||||
bool ready = false;
|
|
||||||
esp_modem_dce_read_pin(dce, NULL, &ready);
|
|
||||||
if (!ready) {
|
|
||||||
esp_modem_dce_set_pin(dce, "1234", NULL);
|
|
||||||
}
|
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
|
||||||
esp_modem_dce_read_pin(dce, NULL, &ready);
|
|
||||||
if (!ready) {
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEFINE_RETRY_CMD(re_sync_fn, re_sync, sim7600_board_t)
|
|
||||||
|
|
||||||
static DEFINE_RETRY_CMD(re_store_profile_fn, re_store_profile, sim7600_board_t)
|
|
||||||
|
|
||||||
esp_err_t sim7600_board_start_up(esp_modem_dce_t *dce)
|
|
||||||
{
|
|
||||||
// sim7600_board_t *board = __containerof(dce, sim7600_board_t, parent);
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(re_sync_fn(dce, NULL, NULL) == ESP_OK, "sending sync failed", err);
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(dce->set_echo(dce, (void*)false, NULL) == ESP_OK, "set_echo failed", err);
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(dce->set_flow_ctrl(dce, (void*)ESP_MODEM_FLOW_CONTROL_NONE, NULL) == ESP_OK, "set_flow_ctrl failed", err);
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(dce->store_profile(dce, NULL, NULL) == ESP_OK, "store_profile failed", err);
|
|
||||||
return ESP_OK;
|
|
||||||
err:
|
|
||||||
return ESP_FAIL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_modem_dce_t *sim7600_board_create(esp_modem_dce_config_t *config)
|
|
||||||
{
|
|
||||||
sim7600_board_t *board = calloc(1, sizeof(sim7600_board_t));
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(board, "failed to allocate board-sim7600 object", err);
|
|
||||||
ESP_MODEM_EXAMPLE_CHECK(esp_modem_dce_init(&board->parent, config) == ESP_OK, "Failed to init sim7600", err);
|
|
||||||
/* power on sequence (typical values for SIM7600 Ton=500ms, Ton-status=16s) */
|
|
||||||
board->power_pin = esp_modem_recov_gpio_new( /*gpio_num*/ 12, /*inactive_level*/ 1, /*active_width*/
|
|
||||||
500, /*inactive_width*/ 16000);
|
|
||||||
/* reset sequence (typical values for SIM7600 Treset=200ms, wait 10s after reset */
|
|
||||||
board->reset_pin = esp_modem_recov_gpio_new( /*gpio_num*/ 13, /*inactive_level*/ 1, /*active_width*/
|
|
||||||
200, /*inactive_width*/ 10000);
|
|
||||||
board->parent.deinit = sim7600_board_deinit;
|
|
||||||
board->reset = sim7600_board_reset;
|
|
||||||
board->power_down = sim7600_board_power_down;
|
|
||||||
board->re_sync = esp_modem_recov_resend_new(&board->parent, board->parent.sync, my_recov, 5, 1);
|
|
||||||
board->parent.start_up = sim7600_board_start_up;
|
|
||||||
board->re_store_profile = esp_modem_recov_resend_new(&board->parent, board->parent.store_profile, my_recov, 2, 3);
|
|
||||||
board->parent.store_profile = re_store_profile_fn;
|
|
||||||
|
|
||||||
return &board->parent;
|
|
||||||
err:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
56
esp_modem/examples/ap_to_pppos/main/network_dce.c
Normal file
56
esp_modem/examples/ap_to_pppos/main/network_dce.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* softAP to PPPoS Example (network_dce)
|
||||||
|
|
||||||
|
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 "esp_netif.h"
|
||||||
|
#include "esp_modem_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
static esp_modem_dce_t *dce = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t modem_init_network(esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
// setup the DCE
|
||||||
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN);
|
||||||
|
dce = esp_modem_new(&dte_config, &dce_config, netif);
|
||||||
|
if (!dce) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure the PIN
|
||||||
|
bool pin_ok = false;
|
||||||
|
if (esp_modem_read_pin(dce, &pin_ok) == ESP_OK && pin_ok == false) {
|
||||||
|
if (esp_modem_set_pin(dce, CONFIG_EXAMPLE_SIM_PIN) == ESP_OK) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
} else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modem_deinit_network(void)
|
||||||
|
{
|
||||||
|
if (dce) {
|
||||||
|
esp_modem_destroy(dce);
|
||||||
|
dce = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void modem_start_network()
|
||||||
|
{
|
||||||
|
esp_modem_set_mode(dce, ESP_MODEM_MODE_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
void modem_stop_network()
|
||||||
|
{
|
||||||
|
esp_modem_set_mode(dce, ESP_MODEM_MODE_COMMAND);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* softAP to PPPoS Example (modem_board)
|
/* softAP to PPPoS Example (network_dce)
|
||||||
|
|
||||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include "cxx_include/esp_modem_dce_factory.hpp"
|
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "network_dce.h"
|
||||||
|
|
||||||
using namespace esp_modem;
|
using namespace esp_modem;
|
||||||
using namespace esp_modem::dce_factory;
|
using namespace esp_modem::dce_factory;
|
||||||
@ -26,6 +27,7 @@ typedef DCE_T<NetModule> NetDCE;
|
|||||||
class PPPNetwork {
|
class PPPNetwork {
|
||||||
public:
|
public:
|
||||||
esp_err_t init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number);
|
esp_err_t init(esp_netif_t *netif, const std::string& apn, const std::string &pin_number);
|
||||||
|
void deinit();
|
||||||
NetDCE * get_dce();
|
NetDCE * get_dce();
|
||||||
private:
|
private:
|
||||||
NetDCE *dce;
|
NetDCE *dce;
|
||||||
@ -120,7 +122,6 @@ esp_err_t PPPNetwork::init(esp_netif_t *netif, const std::string& apn, const std
|
|||||||
{
|
{
|
||||||
// configure
|
// configure
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
dte_config.uart_config.event_task_stack_size = 4096;
|
|
||||||
dte_config.uart_config.rx_buffer_size = 16384;
|
dte_config.uart_config.rx_buffer_size = 16384;
|
||||||
dte_config.uart_config.tx_buffer_size = 2048;
|
dte_config.uart_config.tx_buffer_size = 2048;
|
||||||
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(apn.c_str());
|
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(apn.c_str());
|
||||||
@ -140,14 +141,23 @@ esp_err_t PPPNetwork::init(esp_netif_t *netif, const std::string& apn, const std
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PPPNetwork::deinit()
|
||||||
|
{
|
||||||
|
free(dce);
|
||||||
|
dce = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
NetDCE *PPPNetwork::get_dce()
|
NetDCE *PPPNetwork::get_dce()
|
||||||
{
|
{
|
||||||
return dce;
|
return dce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implement the C-API for the AP-2-PPP functionality
|
||||||
|
*/
|
||||||
extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
|
extern "C" esp_err_t modem_init_network(esp_netif_t *netif)
|
||||||
{
|
{
|
||||||
return ppp_network.init(netif, "internet", "1234");
|
return ppp_network.init(netif, CONFIG_EXAMPLE_MODEM_PPP_APN, CONFIG_EXAMPLE_SIM_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void modem_start_network()
|
extern "C" void modem_start_network()
|
||||||
@ -159,3 +169,8 @@ extern "C" void modem_stop_network()
|
|||||||
{
|
{
|
||||||
ppp_network.get_dce()->set_mode(esp_modem::modem_mode::COMMAND_MODE);
|
ppp_network.get_dce()->set_mode(esp_modem::modem_mode::COMMAND_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void modem_deinit_network()
|
||||||
|
{
|
||||||
|
ppp_network.deinit();
|
||||||
|
}
|
47
esp_modem/examples/ap_to_pppos/main/network_dce.h
Normal file
47
esp_modem/examples/ap_to_pppos/main/network_dce.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* softAP to PPPoS Example (network_dce)
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NETWORK_DCE_H_
|
||||||
|
#define _NETWORK_DCE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a singleton covering the PPP network provided by the connected modem device
|
||||||
|
*
|
||||||
|
* @param netif Already created network interface in PPP mode
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
*/
|
||||||
|
esp_err_t modem_init_network(esp_netif_t *netif);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroys the single network DCE
|
||||||
|
*/
|
||||||
|
void modem_deinit_network();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the PPP network
|
||||||
|
*/
|
||||||
|
void modem_start_network();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the PPP network
|
||||||
|
*/
|
||||||
|
void modem_stop_network();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //_NETWORK_DCE_H_
|
@ -1,12 +1,8 @@
|
|||||||
# Override some defaults to enable PPP
|
|
||||||
CONFIG_LWIP_PPP_SUPPORT=y
|
CONFIG_LWIP_PPP_SUPPORT=y
|
||||||
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||||
# Do not enable IPV6 in dte<->dce link local
|
|
||||||
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||||
# Disable legacy API
|
CONFIG_UART_ISR_IN_IRAM=y
|
||||||
CONFIG_MODEM_LEGACY_API=n
|
|
||||||
# Enable NAPT
|
# Enable NAPT
|
||||||
CONFIG_LWIP_IP_FORWARD=y
|
CONFIG_LWIP_IP_FORWARD=y
|
||||||
CONFIG_LWIP_IPV4_NAPT=y
|
CONFIG_LWIP_IPV4_NAPT=y
|
||||||
|
|
||||||
|
@ -3,8 +3,15 @@
|
|||||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This example is mainly targets experimenting with a modem device, sending custom commands and switching to PPP mode using esp-console, command line API.
|
This example is mainly targets experimenting with a modem device, sending custom commands and switching to PPP mode using esp-console, command line API.
|
||||||
|
Please check the list of supported commands using `help` command.
|
||||||
|
|
||||||
## How to use this example
|
This example implements two very simple network commands to demonstrate and test basic network functionality.
|
||||||
|
* `httpget`: Connect and get http content
|
||||||
|
* `ping`: Send ICMP pings
|
||||||
|
|
||||||
See the README.md file in the upper level `pppos` directory for more information about the PPPoS examples.
|
To demonstrate creating custom modem devices, this example creates a DCE object using a locally defined create method,
|
||||||
|
that sets up the DCE based on a custom module implemented in the `my_module_dce.hpp` file. The module class only overrides
|
||||||
|
`get_module_name()` method supplying a user defined name, but keeps all other commands the same as defined in the `GenericModule`
|
||||||
|
class.
|
@ -20,15 +20,7 @@
|
|||||||
#include "cxx_include/esp_modem_api.hpp"
|
#include "cxx_include/esp_modem_api.hpp"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "console_helper.hpp"
|
#include "console_helper.hpp"
|
||||||
|
#include "my_module_dce.hpp"
|
||||||
extern "C" void modem_console_register_http(void);
|
|
||||||
extern "C" void modem_console_register_ping(void);
|
|
||||||
|
|
||||||
static const char *TAG = "modem_console";
|
|
||||||
|
|
||||||
static esp_console_repl_t *s_repl = nullptr;
|
|
||||||
|
|
||||||
using namespace esp_modem;
|
|
||||||
|
|
||||||
#define CHECK_ERR(cmd, success_action) do { \
|
#define CHECK_ERR(cmd, success_action) do { \
|
||||||
auto err = cmd; \
|
auto err = cmd; \
|
||||||
@ -40,63 +32,67 @@ using namespace esp_modem;
|
|||||||
return 1; \
|
return 1; \
|
||||||
} } while (0)
|
} } while (0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Please update the default APN name here (this could be updated runtime)
|
||||||
|
*/
|
||||||
|
#define DEFAULT_APN "my_apn"
|
||||||
|
|
||||||
|
extern "C" void modem_console_register_http(void);
|
||||||
|
extern "C" void modem_console_register_ping(void);
|
||||||
|
|
||||||
|
static const char *TAG = "modem_console";
|
||||||
|
static esp_console_repl_t *s_repl = nullptr;
|
||||||
|
|
||||||
|
using namespace esp_modem;
|
||||||
|
|
||||||
|
|
||||||
extern "C" void app_main(void)
|
extern "C" void app_main(void)
|
||||||
{
|
{
|
||||||
ESP_ERROR_CHECK(nvs_flash_init());
|
ESP_ERROR_CHECK(nvs_flash_init());
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
// init the DTE
|
// init the netif, DTE and DCE respectively
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
esp_modem_dte_config_t dte_config2 = {
|
|
||||||
.dte_buffer_size = 512,
|
|
||||||
.vfs_config = {.port_num = UART_NUM_1,
|
|
||||||
.dev_name = "/dev/uart/1",
|
|
||||||
.rx_buffer_size = 1024,
|
|
||||||
.tx_buffer_size = 1024,
|
|
||||||
.baud_rate = 115200,
|
|
||||||
.tx_io_num = 25,
|
|
||||||
.rx_io_num = 26,
|
|
||||||
.task_stack_size = 4096,
|
|
||||||
.task_prio = 5}
|
|
||||||
};
|
|
||||||
|
|
||||||
esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP();
|
esp_netif_config_t ppp_netif_config = ESP_NETIF_DEFAULT_PPP();
|
||||||
|
|
||||||
esp_netif_t *esp_netif = esp_netif_new(&ppp_netif_config);
|
esp_netif_t *esp_netif = esp_netif_new(&ppp_netif_config);
|
||||||
assert(esp_netif);
|
assert(esp_netif);
|
||||||
auto uart_dte = create_vfs_dte(&dte_config2);
|
auto uart_dte = create_uart_dte(&dte_config);
|
||||||
// auto uart_dte = create_uart_dte(&dte_config);
|
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(DEFAULT_APN);
|
||||||
|
auto dce = create_shiny_dce(&dce_config, uart_dte, esp_netif);
|
||||||
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("internet");
|
|
||||||
|
|
||||||
auto dce = create_SIM7600_dce(&dce_config, uart_dte, esp_netif);
|
|
||||||
assert(dce != nullptr);
|
assert(dce != nullptr);
|
||||||
|
|
||||||
|
// init console REPL environment
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
// init console REPL environment
|
|
||||||
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
|
|
||||||
modem_console_register_http();
|
modem_console_register_http();
|
||||||
modem_console_register_ping();
|
modem_console_register_ping();
|
||||||
const struct SetModeArgs {
|
const struct SetModeArgs {
|
||||||
SetModeArgs(): mode(STR1, nullptr, nullptr, "<mode>", "PPP or CMD") {}
|
SetModeArgs(): mode(STR1, nullptr, nullptr, "<mode>", "PPP, CMD or CMUX") {}
|
||||||
CommandArgs mode;
|
CommandArgs mode;
|
||||||
} set_mode_args;
|
} set_mode_args;
|
||||||
const ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand *c){
|
const ConsoleCommand SetModeParser("set_mode", "sets modem mode", &set_mode_args, sizeof(set_mode_args), [&](ConsoleCommand *c){
|
||||||
if (c->get_count_of(&SetModeArgs::mode)) {
|
if (c->get_count_of(&SetModeArgs::mode)) {
|
||||||
auto mode = c->get_string_of(&SetModeArgs::mode);
|
auto mode = c->get_string_of(&SetModeArgs::mode);
|
||||||
|
modem_mode dev_mode;
|
||||||
if (mode == "CMD") {
|
if (mode == "CMD") {
|
||||||
ESP_LOGI(TAG, "Switching to command mode...");
|
dev_mode = esp_modem::modem_mode::COMMAND_MODE;
|
||||||
dce->exit_data();
|
|
||||||
} else if (mode == "PPP") {
|
} else if (mode == "PPP") {
|
||||||
ESP_LOGI(TAG, "Switching to data mode...");
|
dev_mode = esp_modem::modem_mode::DATA_MODE;
|
||||||
dce->set_data();
|
} else if (mode == "CMUX") {
|
||||||
|
dev_mode = esp_modem::modem_mode::CMUX_MODE;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "Unsupported mode: %s", mode.c_str());
|
ESP_LOGE(TAG, "Unsupported mode: %s", mode.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ESP_LOGI(TAG, "Switching to %s name...", mode.c_str());
|
||||||
|
if (!dce->set_mode(dev_mode)) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set the desired mode");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "OK");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@ -151,7 +147,7 @@ extern "C" void app_main(void)
|
|||||||
cmd(STR1, nullptr, nullptr, "<command>", "AT command to send to the modem"),
|
cmd(STR1, nullptr, nullptr, "<command>", "AT command to send to the modem"),
|
||||||
timeout(INT0, "t", "timeout", "<timeout>", "command timeout"),
|
timeout(INT0, "t", "timeout", "<timeout>", "command timeout"),
|
||||||
pattern(STR0, "p", "pattern", "<pattern>", "command response to wait for"),
|
pattern(STR0, "p", "pattern", "<pattern>", "command response to wait for"),
|
||||||
no_cr(LIT0, "n", "no-cr", "not add trailing CR to the command") {}
|
no_cr(LIT0, "n", "no-cr", "do not add trailing CR to the command") {}
|
||||||
CommandArgs cmd;
|
CommandArgs cmd;
|
||||||
CommandArgs timeout;
|
CommandArgs timeout;
|
||||||
CommandArgs pattern;
|
CommandArgs pattern;
|
||||||
@ -193,6 +189,20 @@ extern "C" void app_main(void)
|
|||||||
ESP_LOGI(TAG, "Resetting the module...");
|
ESP_LOGI(TAG, "Resetting the module...");
|
||||||
CHECK_ERR(dce->reset(), ESP_LOGI(TAG, "OK"));
|
CHECK_ERR(dce->reset(), ESP_LOGI(TAG, "OK"));
|
||||||
});
|
});
|
||||||
|
const struct SetApn {
|
||||||
|
SetApn(): apn(STR1, nullptr, nullptr, "<apn>", "APN (Access Point Name)") {}
|
||||||
|
CommandArgs apn;
|
||||||
|
} set_apn;
|
||||||
|
const ConsoleCommand SetApnParser("set_apn", "sets APN", &set_apn, sizeof(set_apn), [&](ConsoleCommand *c){
|
||||||
|
if (c->get_count_of(&SetApn::apn)) {
|
||||||
|
auto apn = c->get_string_of(&SetApn::apn);
|
||||||
|
ESP_LOGI(TAG, "Setting the APN=%s...", apn.c_str());
|
||||||
|
auto new_pdp = std::unique_ptr<PdpContext>(new PdpContext(apn));
|
||||||
|
dce->get_module()->configure_pdp_context(std::move(new_pdp));
|
||||||
|
ESP_LOGI(TAG, "OK");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
SignalGroup exit_signal;
|
SignalGroup exit_signal;
|
||||||
const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand *c){
|
const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand *c){
|
||||||
|
43
esp_modem/examples/modem_console/main/my_module_dce.hpp
Normal file
43
esp_modem/examples/modem_console/main/my_module_dce.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* Modem console example: Custom DCE
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MY_MODULE_DCE_HPP__
|
||||||
|
#define __MY_MODULE_DCE_HPP__
|
||||||
|
|
||||||
|
|
||||||
|
#include "cxx_include/esp_modem_dce_factory.hpp"
|
||||||
|
#include "cxx_include/esp_modem_dce_module.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Definition of a custom modem which inherits from the GenericModule, uses all its methods
|
||||||
|
* and could override any of them. Here, for demonstration purposes only, we redefine just `get_module_name()`
|
||||||
|
*/
|
||||||
|
class MyShinyModem: public esp_modem::GenericModule {
|
||||||
|
using GenericModule::GenericModule;
|
||||||
|
public:
|
||||||
|
esp_modem::command_result get_module_name(std::string& name) override
|
||||||
|
{
|
||||||
|
name = "Custom Shiny Module";
|
||||||
|
return esp_modem::command_result::OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module
|
||||||
|
* @return unique pointer of the resultant DCE
|
||||||
|
*/
|
||||||
|
std::unique_ptr<esp_modem::DCE> create_shiny_dce(const esp_modem::dce_config *config,
|
||||||
|
std::shared_ptr<esp_modem::DTE> dte,
|
||||||
|
esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
return esp_modem::dce_factory::Factory::build_unique<MyShinyModem>(config, std::move(dte), netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //__MY_MODULE_DCE_HPP__
|
@ -1,9 +0,0 @@
|
|||||||
#
|
|
||||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
|
||||||
# project subdirectory.
|
|
||||||
#
|
|
||||||
|
|
||||||
PROJECT_NAME := pppos_client
|
|
||||||
|
|
||||||
include $(IDF_PATH)/make/project.mk
|
|
||||||
|
|
@ -26,14 +26,6 @@ menu "Example Configuration"
|
|||||||
help
|
help
|
||||||
Set APN (Access Point Name), a logical name to choose data network
|
Set APN (Access Point Name), a logical name to choose data network
|
||||||
|
|
||||||
config EXAMPLE_MODEM_LEGACY_API
|
|
||||||
bool "Use Modem legacy API"
|
|
||||||
default y
|
|
||||||
select MODEM_LEGACY_API
|
|
||||||
help
|
|
||||||
Set this to true to use backward compatible API to the original modem
|
|
||||||
component in example/protocol folder in IDFv4.2 and below
|
|
||||||
|
|
||||||
config EXAMPLE_MODEM_PPP_AUTH_USERNAME
|
config EXAMPLE_MODEM_PPP_AUTH_USERNAME
|
||||||
string "Set username for authentication"
|
string "Set username for authentication"
|
||||||
default "espressif"
|
default "espressif"
|
||||||
@ -68,6 +60,19 @@ menu "Example Configuration"
|
|||||||
Enter the peer phone number that you want to send message to.
|
Enter the peer phone number that you want to send message to.
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
config EXAMPLE_NEED_SIM_PIN
|
||||||
|
bool "SIM PIN needed"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable to set SIM PIN before starting the example
|
||||||
|
|
||||||
|
config EXAMPLE_SIM_PIN
|
||||||
|
string "Set SIM PIN"
|
||||||
|
default "1234"
|
||||||
|
depends on EXAMPLE_NEED_SIM_PIN
|
||||||
|
help
|
||||||
|
Pin to unlock the SIM
|
||||||
|
|
||||||
menu "UART Configuration"
|
menu "UART Configuration"
|
||||||
config EXAMPLE_MODEM_UART_TX_PIN
|
config EXAMPLE_MODEM_UART_TX_PIN
|
||||||
int "TXD Pin Number"
|
int "TXD Pin Number"
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#
|
|
||||||
# "main" pseudo-component makefile.
|
|
||||||
#
|
|
||||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
|
@ -20,10 +20,8 @@
|
|||||||
static const char *TAG = "pppos_example";
|
static const char *TAG = "pppos_example";
|
||||||
static EventGroupHandle_t event_group = NULL;
|
static EventGroupHandle_t event_group = NULL;
|
||||||
static const int CONNECT_BIT = BIT0;
|
static const int CONNECT_BIT = BIT0;
|
||||||
//static const int STOP_BIT = BIT1;
|
|
||||||
static const int GOT_DATA_BIT = BIT2;
|
static const int GOT_DATA_BIT = BIT2;
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||||
{
|
{
|
||||||
esp_mqtt_client_handle_t client = event->client;
|
esp_mqtt_client_handle_t client = event->client;
|
||||||
@ -131,8 +129,8 @@ void app_main(void)
|
|||||||
dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE;
|
dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE;
|
||||||
dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE;
|
dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE;
|
||||||
dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE;
|
dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE;
|
||||||
dte_config.uart_config.event_task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE;
|
dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE;
|
||||||
dte_config.uart_config.event_task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
|
dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY;
|
||||||
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
|
dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2;
|
||||||
|
|
||||||
/* Configure the DCE */
|
/* Configure the DCE */
|
||||||
@ -147,6 +145,7 @@ void app_main(void)
|
|||||||
assert(esp_netif);
|
assert(esp_netif);
|
||||||
esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif);
|
esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif);
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_NEED_SIM_PIN == 1
|
||||||
// check if PIN needed
|
// check if PIN needed
|
||||||
bool pin_ok = false;
|
bool pin_ok = false;
|
||||||
if (esp_modem_read_pin(dce, &pin_ok) == ESP_OK && pin_ok == false) {
|
if (esp_modem_read_pin(dce, &pin_ok) == ESP_OK && pin_ok == false) {
|
||||||
@ -156,6 +155,8 @@ void app_main(void)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int rssi, ber;
|
int rssi, ber;
|
||||||
esp_err_t err = esp_modem_get_signal_quality(dce, &rssi, &ber);
|
esp_err_t err = esp_modem_get_signal_quality(dce, &rssi, &ber);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
@ -164,7 +165,7 @@ void app_main(void)
|
|||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber);
|
ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber);
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_SEND_MSG
|
#if CONFIG_EXAMPLE_SEND_MSG
|
||||||
if (esp_modem_sms_txt_mode(dce, true) != ESP_OK || esp_modem_sms_character_set(dce) != ESP_OK) {
|
if (esp_modem_sms_txt_mode(dce, true) != ESP_OK || esp_modem_sms_character_set(dce) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Setting text mode or GSM character set failed");
|
ESP_LOGE(TAG, "Setting text mode or GSM character set failed");
|
||||||
return;
|
return;
|
||||||
@ -175,7 +176,6 @@ void app_main(void)
|
|||||||
ESP_LOGE(TAG, "esp_modem_send_sms() failed with %d", err);
|
ESP_LOGE(TAG, "esp_modem_send_sms() failed with %d", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = esp_modem_set_mode(dce, ESP_MODEM_MODE_DATA);
|
err = esp_modem_set_mode(dce, ESP_MODEM_MODE_DATA);
|
||||||
|
@ -3,5 +3,4 @@ CONFIG_LWIP_PPP_SUPPORT=y
|
|||||||
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
||||||
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||||
# Do not enable IPV6 in dte<->dce link local
|
|
||||||
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "0.1.4"
|
version: "0.1.5"
|
||||||
targets:
|
targets:
|
||||||
- esp32
|
- esp32
|
||||||
description: esp modem
|
description: esp modem
|
||||||
|
@ -49,7 +49,13 @@ using dte_config = ::esp_modem_dte_config;
|
|||||||
*/
|
*/
|
||||||
std::shared_ptr<DTE> create_uart_dte(const dte_config *config);
|
std::shared_ptr<DTE> create_uart_dte(const dte_config *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create VFS DTE
|
||||||
|
* @param config DTE configuration
|
||||||
|
* @return shared ptr to DTE on success
|
||||||
|
* nullptr on failure (either due to insufficient memory or wrong dte configuration)
|
||||||
|
* if exceptions are disabled the API abort()'s on error
|
||||||
|
*/
|
||||||
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config);
|
std::shared_ptr<DTE> create_vfs_dte(const dte_config *config);
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ template<class SpecificModule>
|
|||||||
class DCE_T {
|
class DCE_T {
|
||||||
static_assert(std::is_base_of<ModuleIf, SpecificModule>::value, "DCE must be instantiated with Module class only");
|
static_assert(std::is_base_of<ModuleIf, SpecificModule>::value, "DCE must be instantiated with Module class only");
|
||||||
public:
|
public:
|
||||||
explicit DCE_T(const std::shared_ptr<DTE>& dte, std::shared_ptr<SpecificModule> device, esp_netif_t * netif):
|
explicit DCE_T(const std::shared_ptr<DTE>& dte, std::shared_ptr<SpecificModule> dev, esp_netif_t * netif):
|
||||||
dte(dte), module(std::move(device)), netif(dte, netif)
|
dte(dte), device(std::move(dev)), netif(dte, netif)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~DCE_T() = default;
|
~DCE_T() = default;
|
||||||
@ -68,21 +68,18 @@ public:
|
|||||||
|
|
||||||
void set_cmux() { set_mode(modem_mode::CMUX_MODE); }
|
void set_cmux() { set_mode(modem_mode::CMUX_MODE); }
|
||||||
|
|
||||||
ModuleIf* get_module() { return module.get(); }
|
SpecificModule* get_module() { return device.get(); }
|
||||||
|
|
||||||
|
|
||||||
command_result command(const std::string& command, got_line_cb got_line, uint32_t time_ms)
|
command_result command(const std::string& command, got_line_cb got_line, uint32_t time_ms)
|
||||||
{
|
{
|
||||||
return dte->command(command, std::move(got_line), time_ms);
|
return dte->command(command, std::move(got_line), time_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_mode(modem_mode m) { return mode.set(dte.get(), module.get(), netif, m); }
|
bool set_mode(modem_mode m) { return mode.set(dte.get(), device.get(), netif, m); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<DTE> dte;
|
std::shared_ptr<DTE> dte;
|
||||||
std::shared_ptr<SpecificModule> module;
|
std::shared_ptr<SpecificModule> device;
|
||||||
Netif netif;
|
Netif netif;
|
||||||
DCE_Mode mode;
|
DCE_Mode mode;
|
||||||
};
|
};
|
||||||
@ -99,7 +96,7 @@ public:
|
|||||||
template <typename ...Agrs> \
|
template <typename ...Agrs> \
|
||||||
return_type name(Agrs&&... args) \
|
return_type name(Agrs&&... args) \
|
||||||
{ \
|
{ \
|
||||||
return module->name(std::forward<Agrs>(args)...); \
|
return device->name(std::forward<Agrs>(args)...); \
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_ALL_COMMAND_APIS(forwards name(...) { device->name(...); } )
|
DECLARE_ALL_COMMAND_APIS(forwards name(...) { device->name(...); } )
|
||||||
|
@ -64,19 +64,19 @@ template<typename Module>
|
|||||||
class Builder {
|
class Builder {
|
||||||
static_assert(std::is_base_of<ModuleIf, Module>::value, "Builder must be used only for Module classes");
|
static_assert(std::is_base_of<ModuleIf, Module>::value, "Builder must be used only for Module classes");
|
||||||
public:
|
public:
|
||||||
Builder(std::shared_ptr<DTE> x, esp_netif_t* esp_netif): dte(std::move(x)), module(nullptr), netif(esp_netif)
|
Builder(std::shared_ptr<DTE> x, esp_netif_t* esp_netif): dte(std::move(x)), device(nullptr), netif(esp_netif)
|
||||||
{
|
{
|
||||||
throw_if_false(netif != nullptr, "Null netif");
|
throw_if_false(netif != nullptr, "Null netif");
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder(std::shared_ptr<DTE> dte, esp_netif_t* esp_netif, std::shared_ptr<Module> dev): dte(std::move(dte)), module(std::move(dev)), netif(esp_netif)
|
Builder(std::shared_ptr<DTE> dte, esp_netif_t* esp_netif, std::shared_ptr<Module> dev): dte(std::move(dte)), device(std::move(dev)), netif(esp_netif)
|
||||||
{
|
{
|
||||||
throw_if_false(netif != nullptr, "Null netif");
|
throw_if_false(netif != nullptr, "Null netif");
|
||||||
}
|
}
|
||||||
|
|
||||||
~Builder()
|
~Builder()
|
||||||
{
|
{
|
||||||
throw_if_false(module == nullptr, "module was captured or created but never used");
|
throw_if_false(device == nullptr, "module was captured or created but never used");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ptr>
|
template<typename Ptr>
|
||||||
@ -90,17 +90,17 @@ public:
|
|||||||
{
|
{
|
||||||
if (dte == nullptr)
|
if (dte == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (module == nullptr) {
|
if (device == nullptr) {
|
||||||
module = create_module<decltype(module)>(config);
|
device = create_module<decltype(device)>(config);
|
||||||
if (module == nullptr)
|
if (device == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return FactoryHelper::make<DceT, Ptr>(std::move(dte), std::move(module), netif);
|
return FactoryHelper::make<DceT, Ptr>(std::move(dte), std::move(device), netif);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<DTE> dte;
|
std::shared_ptr<DTE> dte;
|
||||||
std::shared_ptr<Module> module;
|
std::shared_ptr<Module> device;
|
||||||
esp_netif_t *netif;
|
esp_netif_t *netif;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,10 +43,20 @@ struct PdpContext;
|
|||||||
*/
|
*/
|
||||||
class GenericModule: public ModuleIf {
|
class GenericModule: public ModuleIf {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief We can construct a generic device with an existent DTE and it's configuration
|
||||||
|
* The configuration could be either the dce-config struct or just a pdp context
|
||||||
|
*/
|
||||||
explicit GenericModule(std::shared_ptr<DTE> dte, std::unique_ptr<PdpContext> pdp):
|
explicit GenericModule(std::shared_ptr<DTE> dte, std::unique_ptr<PdpContext> pdp):
|
||||||
dte(std::move(dte)), pdp(std::move(pdp)) {}
|
dte(std::move(dte)), pdp(std::move(pdp)) {}
|
||||||
explicit GenericModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config* config);
|
explicit GenericModule(std::shared_ptr<DTE> dte, const esp_modem_dce_config* config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is a mandatory method for ModuleIf class, which sets up the device
|
||||||
|
* to be able to connect to the network. This typically consists of setting basic
|
||||||
|
* communication parameters and setting the PDP (defining logical access point
|
||||||
|
* to cellular network)
|
||||||
|
*/
|
||||||
bool setup_data_mode() override
|
bool setup_data_mode() override
|
||||||
{
|
{
|
||||||
if (set_echo(false) != command_result::OK)
|
if (set_echo(false) != command_result::OK)
|
||||||
@ -56,6 +66,10 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is a mandatory method of ModuleIf class, which defines
|
||||||
|
* basic commands for switching between DATA, COMMAND and CMUX modes
|
||||||
|
*/
|
||||||
bool set_mode(modem_mode mode) override
|
bool set_mode(modem_mode mode) override
|
||||||
{
|
{
|
||||||
if (mode == modem_mode::DATA_MODE) {
|
if (mode == modem_mode::DATA_MODE) {
|
||||||
@ -70,7 +84,17 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Additional method providing runtime configuration of PDP context
|
||||||
|
*/
|
||||||
|
void configure_pdp_context(std::unique_ptr<PdpContext> new_pdp)
|
||||||
|
{
|
||||||
|
pdp = std::move(new_pdp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Common DCE commands generated from the API AT list
|
||||||
|
*/
|
||||||
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
|
#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \
|
||||||
virtual return_type name(__VA_ARGS__);
|
virtual return_type name(__VA_ARGS__);
|
||||||
|
|
||||||
@ -80,8 +104,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<DTE> dte;
|
std::shared_ptr<DTE> dte; /*!< Generic device needs the DTE as a channel talk to the module using AT commands */
|
||||||
std::unique_ptr<PdpContext> pdp;
|
std::unique_ptr<PdpContext> pdp; /*!< It also needs a PDP data, const information used for setting up cellular network */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Definitions of other supported modules with some specific commands overwritten
|
// Definitions of other supported modules with some specific commands overwritten
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#ifndef _ESP_MODEM_API_H_
|
#ifndef _ESP_MODEM_API_H_
|
||||||
#define _ESP_MODEM_API_H_
|
#define _ESP_MODEM_API_H_
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
#include "generate/esp_modem_command_declare.inc"
|
#include "generate/esp_modem_command_declare.inc"
|
||||||
#include "esp_modem_c_api_types.h"
|
#include "esp_modem_c_api_types.h"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user