瀏覽代碼

Merge branch 'feature/ppp_over_serial' into 'master'

Enable experimental/unsupported PPP over Serial driver

From PR #272 https://github.com/espressif/esp-idf/pull/272

See merge request !690

Jiang Jiang Jian 8 年之前
父節點
當前提交
3f4e917ad6

+ 0 - 1
components/esp32/Kconfig

@@ -208,7 +208,6 @@ config SYSTEM_EVENT_TASK_STACK_SIZE
     help
         Config system event task stack size in different application.
 
-
 config MAIN_TASK_STACK_SIZE
     int "Main task stack size"
     default 4096

+ 1 - 1
components/esp32/include/esp_task.h

@@ -46,7 +46,7 @@
 #define ESP_TASKD_EVENT_PRIO          (ESP_TASK_PRIO_MAX - 5)
 #define ESP_TASKD_EVENT_STACK         CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE
 #define ESP_TASK_TCPIP_PRIO           (ESP_TASK_PRIO_MAX - 7)
-#define ESP_TASK_TCPIP_STACK          2048
+#define ESP_TASK_TCPIP_STACK          CONFIG_TCPIP_TASK_STACK_SIZE
 #define ESP_TASK_MAIN_PRIO            (ESP_TASK_PRIO_MIN + 1)
 #define ESP_TASK_MAIN_STACK           CONFIG_MAIN_TASK_STACK_SIZE
 

+ 49 - 1
components/lwip/Kconfig

@@ -89,6 +89,54 @@ config LWIP_DHCP_DOES_ARP_CHECK
         Enabling this option allows check if the offered IP address is not already
         in use by another host on the network.
 
-endmenu
+config TCPIP_TASK_STACK_SIZE
+    int "TCP/IP Task Stack Size"
+    default 2048
+    help
+       Configure TCP/IP task stack size, used by LWIP to process multi-threaded TCP/IP operations.
+       The default is 2048 bytes, setting this stack too small will result in stack overflow crashes.
+
+menuconfig PPP_SUPPORT
+    bool "Enable PPP support (new/experimental)"
+    default n
+    help
+        Enable PPP stack. Now only PPP over serial is possible.
+
+        PPP over serial support is experimental and unsupported.
 
+config PPP_PAP_SUPPORT
+   bool "Enable PAP support"
+   depends on PPP_SUPPORT
+   default n
+   help
+       Enable Password Authentication Protocol (PAP) support
 
+config PPP_CHAP_SUPPORT
+   bool "Enable CHAP support"
+   depends on PPP_SUPPORT
+   default n
+   help
+       Enable Challenge Handshake Authentication Protocol (CHAP) support
+
+config PPP_MSCHAP_SUPPORT
+   bool "Enable MSCHAP support"
+   depends on PPP_SUPPORT
+   default n
+   help
+       Enable Microsoft version of the Challenge-Handshake Authentication Protocol (MSCHAP) support
+
+config PPP_MPPE_SUPPORT
+   bool "Enable MPPE support"
+   depends on PPP_SUPPORT
+   default n
+   help
+       Enable Microsoft Point-to-Point Encryption (MPPE) support
+
+config PPP_DEBUG_ON
+   bool "Enable PPP debug log output"
+   depends on PPP_SUPPORT
+   default n
+   help
+       Enable PPP debug log output
+
+endmenu

+ 12 - 12
components/lwip/api/pppapi.c

@@ -73,10 +73,10 @@ pppapi_set_default(ppp_pcb *pcb)
 static err_t
 pppapi_do_ppp_set_auth(struct tcpip_api_call *m)
 {
-  struct pppapi_msg_msg *msg = (struct pppapi_msg_msg *)m;
+  struct pppapi_msg *msg = (struct pppapi_msg *)m;
 
-  ppp_set_auth(msg->ppp, msg->msg.setauth.authtype,
-               msg->msg.setauth.user, msg->msg.setauth.passwd);
+  ppp_set_auth(msg->msg.ppp, msg->msg.msg.setauth.authtype,
+               msg->msg.msg.setauth.user, msg->msg.msg.setauth.passwd);
   return ERR_OK;
 }
 
@@ -131,10 +131,10 @@ pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_pha
 static err_t
 pppapi_do_pppos_create(struct tcpip_api_call *m)
 {
-  struct pppapi_msg_msg *msg = (struct pppapi_msg_msg *)m;
+  struct pppapi_msg *msg = (struct pppapi_msg *)(m);
 
-  msg->ppp = pppos_create(msg->msg.serialcreate.pppif, msg->msg.serialcreate.output_cb,
-    msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.ctx_cb);
+  msg->msg.ppp = pppos_create(msg->msg.msg.serialcreate.pppif, msg->msg.msg.serialcreate.output_cb,
+    msg->msg.msg.serialcreate.link_status_cb, msg->msg.msg.serialcreate.ctx_cb);
   return ERR_OK;
 }
 
@@ -247,9 +247,9 @@ pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipad
 static err_t
 pppapi_do_ppp_connect(struct tcpip_api_call *m)
 {
-  struct pppapi_msg_msg *msg = (struct pppapi_msg_msg *)m;
+  struct pppapi_msg *msg = (struct pppapi_msg *)m;
 
-  return ppp_connect(msg->ppp, msg->msg.connect.holdoff);
+  return ppp_connect(msg->msg.ppp, msg->msg.msg.connect.holdoff);
 }
 
 /**
@@ -300,9 +300,9 @@ pppapi_listen(ppp_pcb *pcb, struct ppp_addrs *addrs)
 static err_t
 pppapi_do_ppp_close(struct tcpip_api_call *m)
 {
-  struct pppapi_msg_msg *msg = (struct pppapi_msg_msg *)m;
+  struct pppapi_msg *msg = (struct pppapi_msg *)m;
 
-  return ppp_close(msg->ppp, msg->msg.close.nocarrier);
+  return ppp_close(msg->msg.ppp, msg->msg.msg.close.nocarrier);
 }
 
 /**
@@ -349,9 +349,9 @@ pppapi_free(ppp_pcb *pcb)
 static err_t
 pppapi_do_ppp_ioctl(struct tcpip_api_call *m)
 {
-  struct pppapi_msg_msg *msg = (struct pppapi_msg_msg *)m;
+  struct pppapi_msg *msg = (struct pppapi_msg *)m;
 
-  return ppp_ioctl(msg->ppp, msg->msg.ioctl.cmd, msg->msg.ioctl.arg);
+  return ppp_ioctl(msg->msg.ppp, msg->msg.msg.ioctl.cmd, msg->msg.msg.ioctl.arg);
 }
 
 /**

+ 3 - 1
components/lwip/component.mk

@@ -4,9 +4,11 @@
 
 COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port include/lwip/posix apps/ping
 
-COMPONENT_SRCDIRS := api apps/sntp apps/ping apps core/ipv4 core/ipv6 core netif port/freertos port/netif port/debug port
+COMPONENT_SRCDIRS := api apps/sntp apps/ping apps core/ipv4 core/ipv6 core netif netif/ppp netif/ppp/polarssl port/freertos port/netif port/debug port
 
 CFLAGS += -Wno-address  # lots of LWIP source files evaluate macros that check address of stack variables
 
 api/tcpip.o apps/dhcpserver.o: CFLAGS += -Wno-unused-variable
 apps/dhcpserver.o core/pbuf.o core/tcp_in.o: CFLAGS += -Wno-unused-but-set-variable
+netif/ppp/pppos.o: CFLAGS += -Wno-type-limits
+

+ 50 - 0
components/lwip/include/lwip/port/lwipopts.h

@@ -503,6 +503,56 @@
    ---------------------------------
 */
 
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT                     CONFIG_PPP_SUPPORT
+
+#if PPP_SUPPORT
+
+/**
+ * PAP_SUPPORT==1: Support PAP.
+ */
+#define PAP_SUPPORT                     CONFIG_PPP_PAP_SUPPORT
+
+/**
+ * CHAP_SUPPORT==1: Support CHAP.
+ */
+#define CHAP_SUPPORT                    CONFIG_PPP_CHAP_SUPPORT
+
+/**
+ * MSCHAP_SUPPORT==1: Support MSCHAP.
+ */
+#define MSCHAP_SUPPORT                  CONFIG_PPP_MSCHAP_SUPPORT
+
+/**
+ * CCP_SUPPORT==1: Support CCP.
+ */
+#define MPPE_SUPPORT                    CONFIG_PPP_MPPE_SUPPORT
+
+/**
+ * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char.
+ * TODO: If PPP_MAXIDLEFLAG > 0 and next package is send during PPP_MAXIDLEFLAG time,
+ *       then 0x7E is not added at the begining of PPP package but 0x7E termination
+ *       is always at the end. This behaviour brokes PPP dial with GSM (PPPoS).
+ *       The PPP package should always start and end with 0x7E.
+ */
+
+#define PPP_MAXIDLEFLAG                 0
+
+/**
+ * PPP_DEBUG: Enable debugging for PPP.
+ */
+#define PPP_DEBUG_ON					CONFIG_PPP_DEBUG_ON
+
+#if PPP_DEBUG_ON
+#define PPP_DEBUG                       LWIP_DBG_ON
+#else
+#define PPP_DEBUG                       LWIP_DBG_OFF
+#endif
+
+#endif
+
 /*
    --------------------------------------
    ---------- Checksum options ----------

+ 7 - 0
components/lwip/port/freertos/sys_arch.c

@@ -435,6 +435,13 @@ sys_init(void)
     }
 }
 
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_jiffies(void)
+{
+  return xTaskGetTickCount();
+}
+
 /*-----------------------------------------------------------------------------------*/
 u32_t
 sys_now(void)

+ 9 - 0
examples/protocols/pppos_client/Makefile

@@ -0,0 +1,9 @@
+#
+# 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
+

+ 9 - 0
examples/protocols/pppos_client/README.md

@@ -0,0 +1,9 @@
+#PPP over Serial (PPPoS) client example
+
+It shows example of ppp client using lwip PPPoS api and GSM.
+Before you run this example, make sure your GSM is in command mode
+and is registered to network.
+
+PPP over serial support is experimental and unsupported. This example was tested with GSM Telit GL865-DUAL V3.
+
+See the README.md file in the upper level 'examples' directory for more information about examples.

+ 49 - 0
examples/protocols/pppos_client/main/Kconfig.projbuild

@@ -0,0 +1,49 @@
+menu "Example Configuration"
+
+config GSM_INTERNET_USER
+    string "GSM Internet User"
+	default ""
+	help
+		Network provider internet user.
+
+config GSM_INTERNET_PASSWORD
+    string "GSM Internet password"
+	default ""
+	help
+		Network provider internet password
+
+config GSM_APN
+    string "GSM Internet APN"
+    default "playmetric"
+    help
+       APN from network provider for internet access
+
+config UART1_TX_PIN
+    int "PPP serial TX GPIO"
+    default 17
+    range 0 31
+    help
+       Pin to configure for UART1 TX
+
+config UART1_RX_PIN
+    int "PPP serial RX GPIO"
+    default 16
+    range 0 31
+    help
+       Pin to configure for UART1 RX
+
+config UART1_RTS_PIN
+    int "PPP serial RTS GPIO"
+    default 18
+    range 0 31
+    help
+       Pin to configure for UART1 RTS
+
+config UART1_CTS_PIN
+    int "PPP serial CTS GPIO"
+    default 23
+    range 0 31
+    help
+       Pin to configure for UART1 CTS
+
+endmenu

+ 4 - 0
examples/protocols/pppos_client/main/component.mk

@@ -0,0 +1,4 @@
+#
+# "main" pseudo-component makefile.
+#
+# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

+ 296 - 0
examples/protocols/pppos_client/main/pppos_client_main.c

@@ -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);
+}

+ 5 - 0
examples/protocols/pppos_client/sdkconfig.defaults

@@ -0,0 +1,5 @@
+# Override some defaults to enable PPP
+CONFIG_PPP_SUPPORT=y
+CONFIG_PPP_PAP_SUPPORT=y
+CONFIG_PPP_DEBUG_ON=y
+CONFIG_TCPIP_TASK_STACK_SIZE=4096