|
|
@@ -0,0 +1,296 @@
|
|
|
+/* PPPoS Client Example with GSM (tested with Telit GL865-DUAL-V3)
|
|
|
+
|
|
|
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
+
|
|
|
+ Unless required by applicable law or agreed to in writing, this
|
|
|
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
|
+ CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ */
|
|
|
+#include <string.h>
|
|
|
+#include "freertos/FreeRTOS.h"
|
|
|
+#include "freertos/task.h"
|
|
|
+#include "freertos/event_groups.h"
|
|
|
+#include "esp_system.h"
|
|
|
+#include "esp_wifi.h"
|
|
|
+#include "esp_event_loop.h"
|
|
|
+#include "esp_log.h"
|
|
|
+#include "nvs_flash.h"
|
|
|
+
|
|
|
+#include "driver/uart.h"
|
|
|
+
|
|
|
+#include "netif/ppp/pppos.h"
|
|
|
+#include "lwip/err.h"
|
|
|
+#include "lwip/sockets.h"
|
|
|
+#include "lwip/sys.h"
|
|
|
+#include "lwip/netdb.h"
|
|
|
+#include "lwip/dns.h"
|
|
|
+#include "lwip/pppapi.h"
|
|
|
+
|
|
|
+/* The examples use simple GSM configuration that you can set via
|
|
|
+ 'make menuconfig'.
|
|
|
+ */
|
|
|
+#define BUF_SIZE (1024)
|
|
|
+const char *PPP_User = CONFIG_GSM_INTERNET_USER;
|
|
|
+const char *PPP_Pass = CONFIG_GSM_INTERNET_PASSWORD;
|
|
|
+const char *PPP_ApnATReq = "AT+CGDCONT=1,\"IP\",\"" \
|
|
|
+ CONFIG_GSM_APN \
|
|
|
+ "\"";
|
|
|
+
|
|
|
+/* Pins used for serial communication with GSM module */
|
|
|
+#define UART1_TX_PIN CONFIG_UART1_TX_PIN
|
|
|
+#define UART1_RX_PIN CONFIG_UART1_RX_PIN
|
|
|
+#define UART1_RTS_PIN CONFIG_UART1_RTS_PIN
|
|
|
+#define UART1_CTS_PIN CONFIG_UART1_CTS_PIN
|
|
|
+
|
|
|
+/* UART */
|
|
|
+int uart_num = UART_NUM_1;
|
|
|
+
|
|
|
+/* The PPP control block */
|
|
|
+ppp_pcb *ppp;
|
|
|
+
|
|
|
+/* The PPP IP interface */
|
|
|
+struct netif ppp_netif;
|
|
|
+
|
|
|
+static const char *TAG = "example";
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ char *cmd;
|
|
|
+ uint16_t cmdSize;
|
|
|
+ char *cmdResponseOnOk;
|
|
|
+ uint32_t timeoutMs;
|
|
|
+} GSM_Cmd;
|
|
|
+
|
|
|
+#define GSM_OK_Str "OK"
|
|
|
+
|
|
|
+GSM_Cmd GSM_MGR_InitCmds[] = {
|
|
|
+ {
|
|
|
+ .cmd = "AT\r",
|
|
|
+ .cmdSize = sizeof("AT\r") - 1,
|
|
|
+ .cmdResponseOnOk = GSM_OK_Str,
|
|
|
+ .timeoutMs = 3000,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .cmd = "ATE0\r",
|
|
|
+ .cmdSize = sizeof("ATE0\r") - 1,
|
|
|
+ .cmdResponseOnOk = GSM_OK_Str,
|
|
|
+ .timeoutMs = 3000,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .cmd = "AT+CPIN?\r",
|
|
|
+ .cmdSize = sizeof("AT+CPIN?\r") - 1,
|
|
|
+ .cmdResponseOnOk = "CPIN: READY",
|
|
|
+ .timeoutMs = 3000,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ //AT+CGDCONT=1,"IP","apn"
|
|
|
+ .cmd = "AT+CGDCONT=1,\"IP\",\"playmetric\"\r",
|
|
|
+ .cmdSize = sizeof("AT+CGDCONT=1,\"IP\",\"playmetric\"\r") - 1,
|
|
|
+ .cmdResponseOnOk = GSM_OK_Str,
|
|
|
+ .timeoutMs = 3000,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .cmd = "ATDT*99***1#\r",
|
|
|
+ .cmdSize = sizeof("ATDT*99***1#\r") - 1,
|
|
|
+ .cmdResponseOnOk = "CONNECT",
|
|
|
+ .timeoutMs = 30000,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+#define GSM_MGR_InitCmdsSize (sizeof(GSM_MGR_InitCmds)/sizeof(GSM_Cmd))
|
|
|
+
|
|
|
+/* PPP status callback example */
|
|
|
+static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
|
|
|
+{
|
|
|
+ struct netif *pppif = ppp_netif(pcb);
|
|
|
+ LWIP_UNUSED_ARG(ctx);
|
|
|
+
|
|
|
+ switch (err_code) {
|
|
|
+ case PPPERR_NONE: {
|
|
|
+ ESP_LOGI(TAG, "status_cb: Connected\n");
|
|
|
+#if PPP_IPV4_SUPPORT
|
|
|
+ ESP_LOGI(TAG, " our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
|
|
|
+ ESP_LOGI(TAG, " his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
|
|
|
+ ESP_LOGI(TAG, " netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
|
|
|
+#endif /* PPP_IPV4_SUPPORT */
|
|
|
+#if PPP_IPV6_SUPPORT
|
|
|
+ ESP_LOGI(TAG, " our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
|
|
|
+#endif /* PPP_IPV6_SUPPORT */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_PARAM: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Invalid parameter\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_OPEN: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Unable to open PPP session\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_DEVICE: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Invalid I/O device for PPP\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_ALLOC: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Unable to allocate resources\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_USER: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: User interrupt\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_CONNECT: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Connection lost\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_AUTHFAIL: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Failed authentication challenge\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_PROTOCOL: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Failed to meet protocol\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_PEERDEAD: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Connection timeout\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_IDLETIMEOUT: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Idle Timeout\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_CONNECTTIME: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Max connect time reached\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PPPERR_LOOPBACK: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Loopback detected\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ ESP_LOGE(TAG, "status_cb: Unknown error code %d\n", err_code);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This should be in the switch case, this is put outside of the switch
|
|
|
+ * case for example readability.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (err_code == PPPERR_NONE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ppp_close() was previously called, don't reconnect */
|
|
|
+ if (err_code == PPPERR_USER) {
|
|
|
+ /* ppp_free(); -- can be called here */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Try to reconnect in 30 seconds, if you need a modem chatscript you have
|
|
|
+ * to do a much better signaling here ;-)
|
|
|
+ */
|
|
|
+ //ppp_connect(pcb, 30);
|
|
|
+ /* OR ppp_listen(pcb); */
|
|
|
+}
|
|
|
+
|
|
|
+static u32_t ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
|
|
|
+{
|
|
|
+ ESP_LOGI(TAG, "PPP tx len %d", len);
|
|
|
+ return uart_write_bytes(uart_num, (const char *)data, len);
|
|
|
+}
|
|
|
+
|
|
|
+static void pppos_client_task()
|
|
|
+{
|
|
|
+ char *data = (char *) malloc(BUF_SIZE);
|
|
|
+ uart_config_t uart_config = {
|
|
|
+ .baud_rate = 115200,
|
|
|
+ .data_bits = UART_DATA_8_BITS,
|
|
|
+ .parity = UART_PARITY_DISABLE,
|
|
|
+ .stop_bits = UART_STOP_BITS_1,
|
|
|
+ .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS
|
|
|
+ };
|
|
|
+ //Configure UART1 parameters
|
|
|
+ uart_param_config(uart_num, &uart_config);
|
|
|
+
|
|
|
+ // Configure UART1 pins (as set in example's menuconfig)
|
|
|
+ ESP_LOGI(TAG, "Configuring UART1 GPIOs: TX:%d RX:%d RTS:%d CTS: %d",
|
|
|
+ UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN, UART1_CTS_PIN);
|
|
|
+ uart_set_pin(uart_num, UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN, UART1_CTS_PIN);
|
|
|
+ uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
|
|
|
+
|
|
|
+ while (1) {
|
|
|
+ //init gsm
|
|
|
+ int gsmCmdIter = 0;
|
|
|
+ while (1) {
|
|
|
+ ESP_LOGI(TAG, "%s", GSM_MGR_InitCmds[gsmCmdIter].cmd);
|
|
|
+ uart_write_bytes(uart_num, (const char *)GSM_MGR_InitCmds[gsmCmdIter].cmd,
|
|
|
+ GSM_MGR_InitCmds[gsmCmdIter].cmdSize);
|
|
|
+
|
|
|
+ int timeoutCnt = 0;
|
|
|
+ while (1) {
|
|
|
+ memset(data, 0, BUF_SIZE);
|
|
|
+ int len = uart_read_bytes(uart_num, (uint8_t *)data, BUF_SIZE, 500 / portTICK_RATE_MS);
|
|
|
+ if (len > 0) {
|
|
|
+ ESP_LOGI(TAG, "%s", data);
|
|
|
+ }
|
|
|
+
|
|
|
+ timeoutCnt += 500;
|
|
|
+ if (strstr(data, GSM_MGR_InitCmds[gsmCmdIter].cmdResponseOnOk) != NULL) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timeoutCnt > GSM_MGR_InitCmds[gsmCmdIter].timeoutMs) {
|
|
|
+ ESP_LOGE(TAG, "Gsm Init Error");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ gsmCmdIter++;
|
|
|
+
|
|
|
+ if (gsmCmdIter >= GSM_MGR_InitCmdsSize) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "Gsm init end");
|
|
|
+
|
|
|
+ ppp = pppapi_pppos_create(&ppp_netif,
|
|
|
+ ppp_output_callback, ppp_status_cb, NULL);
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "After pppapi_pppos_create");
|
|
|
+
|
|
|
+ if (ppp == NULL) {
|
|
|
+ ESP_LOGE(TAG, "Error init pppos");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pppapi_set_default(ppp);
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "After pppapi_set_default");
|
|
|
+
|
|
|
+ pppapi_set_auth(ppp, PPPAUTHTYPE_PAP, PPP_User, PPP_Pass);
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "After pppapi_set_auth");
|
|
|
+
|
|
|
+ pppapi_connect(ppp, 0);
|
|
|
+
|
|
|
+ ESP_LOGI(TAG, "After pppapi_connect");
|
|
|
+
|
|
|
+ while (1) {
|
|
|
+ memset(data, 0, BUF_SIZE);
|
|
|
+ int len = uart_read_bytes(uart_num, (uint8_t *)data, BUF_SIZE, 10 / portTICK_RATE_MS);
|
|
|
+ if (len > 0) {
|
|
|
+ ESP_LOGI(TAG, "PPP rx len %d", len);
|
|
|
+ pppos_input_tcpip(ppp, (u8_t *)data, len);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void app_main()
|
|
|
+{
|
|
|
+ tcpip_adapter_init();
|
|
|
+ xTaskCreate(&pppos_client_task, "pppos_client_task", 2048, NULL, 5, NULL);
|
|
|
+}
|