Переглянути джерело

Merge wifi branch commit '588d384393536a040f899b382890316c56061b6a' into feature/wifi-stage-one

Angus Gratton 9 роки тому
батько
коміт
2f54d0e425

+ 1 - 8
components/esp32/cpu_start.c

@@ -206,15 +206,7 @@ void user_start_cpu0(void) {
 	ets_setup_syscalls();
 	do_global_ctors();
 
-	// TODO: consider ethernet interface
-
 #if CONFIG_WIFI_ENABLED
-#if 1 //workaround
-    for (uint8_t i = 5; i < 8; i++) {
-        ets_printf("erase sector %d\n", i);
-        spi_flash_erase_sector(i);
-    }
-#endif
     ets_printf("nvs_flash_init\n");
     esp_err_t ret = nvs_flash_init(5, 3);
     if (ret != ESP_OK) {
@@ -225,6 +217,7 @@ void user_start_cpu0(void) {
 
     esp_event_init(NULL);
 
+    // TODO: consider ethernet interface
     tcpip_adapter_init();
 
 #endif

+ 70 - 46
components/esp32/event.c

@@ -28,26 +28,10 @@
 #define ESP32_WORKAROUND 1
 
 #if CONFIG_WIFI_ENABLED
-
-#ifdef ESP32_WORKAROUND
-
-extern SemaphoreHandle_t stdio_mutex_tx;
-#define os_printf(fmt, ...) do {\
-    if (!stdio_mutex_tx) {\
-        stdio_mutex_tx = xSemaphoreCreateMutex();\
-    }\
-\
-    xSemaphoreTake(stdio_mutex_tx, portMAX_DELAY);\
-    ets_printf(fmt, ##__VA_ARGS__);\
-    xSemaphoreGive(stdio_mutex_tx);\
-} while (0)
-
-#endif
-
 static xQueueHandle g_event_handler = NULL;
 static system_event_cb_t g_event_handler_cb;
 
-#define WIFI_DEBUG  os_printf
+#define WIFI_DEBUG  printf
 #define WIFI_API_CALL_CHECK(info, api_call, ret) \
 do{\
     esp_err_t __err = (api_call);\
@@ -79,6 +63,7 @@ static system_event_handle_t g_system_event_handle_table[] = {
     {SYSTEM_EVENT_STA_CONNECTED,       system_event_sta_connected_handle_default},
     {SYSTEM_EVENT_STA_DISCONNECTED,    system_event_sta_disconnected_handle_default},
     {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, NULL},
+    {SYSTEM_EVENT_STA_GOTIP,           NULL},
     {SYSTEM_EVENT_AP_START,            system_event_ap_start_handle_default},
     {SYSTEM_EVENT_AP_STOP,             system_event_ap_stop_handle_default},
     {SYSTEM_EVENT_AP_STACONNECTED,     NULL},
@@ -131,10 +116,17 @@ esp_err_t system_event_sta_stop_handle_default(system_event_t *event)
 
 esp_err_t system_event_sta_connected_handle_default(system_event_t *event)
 {
+    tcpip_adapter_dhcp_status_t status;
+	
     WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK);
 
     tcpip_adapter_up(TCPIP_ADAPTER_IF_STA);
-    tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
+
+    tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status);
+
+    if (status == TCPIP_ADAPTER_DHCP_INIT) {
+        tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
+    }
 
     return ESP_OK;
 }
@@ -157,78 +149,110 @@ static esp_err_t esp_wifi_post_event_to_user(system_event_t *event)
 
 static esp_err_t esp_system_event_debug(system_event_t *event)
 {
-    system_event_sta_scan_done_t *scan_done;
-    system_event_sta_connected_t *connected; 
-    system_event_sta_disconnected_t *disconnected;
-    system_event_sta_authmode_change_t *auth_change;
-    system_event_ap_staconnected_t *staconnected;
-    system_event_ap_stadisconnected_t *stadisconnected;
-    system_event_ap_probe_req_rx_t *ap_probereqrecved;
-
     if (event == NULL) {
-        os_printf("Error: event is null!\n");
+        printf("Error: event is null!\n");
         return ESP_FAIL;
     }
 
-    os_printf("received event: ");
+    printf("received event: ");
     switch (event->event_id) {
         case SYSTEM_EVENT_WIFI_READY:
-            os_printf("SYSTEM_EVENT_WIFI_READY\n");
+        {
+            printf("SYSTEM_EVENT_WIFI_READY\n");
             break;
+        }
         case SYSTEM_EVENT_SCAN_DONE:
+        {
+            system_event_sta_scan_done_t *scan_done;
             scan_done = &event->event_info.scan_done;
-            os_printf("SYSTEM_EVENT_SCAN_DONE\nstatus:%d, number:%d\n", \
+            printf("SYSTEM_EVENT_SCAN_DONE\nstatus:%d, number:%d\n", \
                 scan_done->status, scan_done->number);
             break;
+        }
         case SYSTEM_EVENT_STA_START:
-            os_printf("SYSTEM_EVENT_STA_START\n");
+        {
+            printf("SYSTEM_EVENT_STA_START\n");
             break;
+        }
         case SYSTEM_EVENT_STA_STOP:
-            os_printf("SYSTEM_EVENT_STA_STOP\n");
+        {
+            printf("SYSTEM_EVENT_STA_STOP\n");
             break;
+        }
         case SYSTEM_EVENT_STA_CONNECTED:
+        {
+            system_event_sta_connected_t *connected; 
             connected = &event->event_info.connected;
-            os_printf("SYSTEM_EVENT_STA_CONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d\n", \
+            printf("SYSTEM_EVENT_STA_CONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d\n", \
                 connected->ssid, connected->ssid_len, connected->bssid[0], connected->bssid[0], connected->bssid[1], \
                 connected->bssid[3], connected->bssid[4], connected->bssid[5], connected->channel);
             break;
+        }
         case SYSTEM_EVENT_STA_DISCONNECTED:
+        {
+            system_event_sta_disconnected_t *disconnected;
             disconnected = &event->event_info.disconnected;
-            os_printf("SYSTEM_EVENT_STA_DISCONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d\n", \
+            printf("SYSTEM_EVENT_STA_DISCONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d\n", \
                 disconnected->ssid, disconnected->ssid_len, disconnected->bssid[0], disconnected->bssid[0], disconnected->bssid[1], \
                 disconnected->bssid[3], disconnected->bssid[4], disconnected->bssid[5], disconnected->reason);
             break;
+        }
         case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
+        {
+            system_event_sta_authmode_change_t *auth_change;
             auth_change = &event->event_info.auth_change;
-            os_printf("SYSTEM_EVENT_STA_AUTHMODE_CHNAGE\nold_mode:%d, new_mode:%d\n", auth_change->old_mode, auth_change->new_mode);
+            printf("SYSTEM_EVENT_STA_AUTHMODE_CHNAGE\nold_mode:%d, new_mode:%d\n", auth_change->old_mode, auth_change->new_mode);
             break;
+        }
+        case SYSTEM_EVENT_STA_GOTIP:
+        {
+            system_event_sta_gotip_t *got_ip;
+            got_ip = &event->event_info.got_ip;
+            printf("SYSTEM_EVENT_STA_GOTIP\n");
+            break;
+        }
         case SYSTEM_EVENT_AP_START:
-            os_printf("SYSTEM_EVENT_AP_START\n");
+        {
+            printf("SYSTEM_EVENT_AP_START\n");
             break;
+        }
         case SYSTEM_EVENT_AP_STOP:
-            os_printf("SYSTEM_EVENT_AP_STOP\n");
+        {
+            printf("SYSTEM_EVENT_AP_STOP\n");
             break;
+        }
         case SYSTEM_EVENT_AP_STACONNECTED:
+        {
+            system_event_ap_staconnected_t *staconnected;
             staconnected = &event->event_info.sta_connected;
-            os_printf("SYSTEM_EVENT_AP_STACONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
+            printf("SYSTEM_EVENT_AP_STACONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
                 staconnected->mac[0], staconnected->mac[0], staconnected->mac[1], \
                 staconnected->mac[3], staconnected->mac[4], staconnected->mac[5], staconnected->aid);
             break;
+        }
         case SYSTEM_EVENT_AP_STADISCONNECTED:
+        {
+            system_event_ap_stadisconnected_t *stadisconnected;
             stadisconnected = &event->event_info.sta_disconnected;
-            os_printf("SYSTEM_EVENT_AP_STADISCONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
+            printf("SYSTEM_EVENT_AP_STADISCONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
                 stadisconnected->mac[0], stadisconnected->mac[0], stadisconnected->mac[1], \
                 stadisconnected->mac[3], stadisconnected->mac[4], stadisconnected->mac[5], stadisconnected->aid);
             break;
+        }
         case SYSTEM_EVENT_AP_PROBEREQRECVED:
+        {
+            system_event_ap_probe_req_rx_t *ap_probereqrecved;
             ap_probereqrecved = &event->event_info.ap_probereqrecved;
-            os_printf("SYSTEM_EVENT_AP_PROBEREQRECVED\nrssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", \
+            printf("SYSTEM_EVENT_AP_PROBEREQRECVED\nrssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", \
                 ap_probereqrecved->rssi, ap_probereqrecved->mac[0], ap_probereqrecved->mac[0], ap_probereqrecved->mac[1], \
                 ap_probereqrecved->mac[3], ap_probereqrecved->mac[4], ap_probereqrecved->mac[5]);
             break;
+        }
         default:
-            os_printf("Error: no such kind of event!\n");
+        {
+            printf("Error: no such kind of event!\n");
             break;
+        }
     }
 
     return ESP_OK;
@@ -237,19 +261,19 @@ static esp_err_t esp_system_event_debug(system_event_t *event)
 static esp_err_t esp_system_event_handler(system_event_t *event)
 {
     if (event == NULL) {
-        os_printf("Error: event is null!\n");
+        printf("Error: event is null!\n");
         return ESP_FAIL;
     }
 
     esp_system_event_debug(event);
     if ((event->event_id < SYSTEM_EVENT_MAX) && (event->event_id == g_system_event_handle_table[event->event_id].event_id)){
         if (g_system_event_handle_table[event->event_id].event_handle){
-            os_printf("enter default callback\n");
+            printf("enter default callback\n");
             g_system_event_handle_table[event->event_id].event_handle(event);
-            os_printf("exit default callback\n");
+            printf("exit default callback\n");
         }
     } else {
-        os_printf("mismatch or invalid event, id=%d\n", event->event_id);
+        printf("mismatch or invalid event, id=%d\n", event->event_id);
     }
 
     return esp_wifi_post_event_to_user(event);
@@ -264,7 +288,7 @@ static void esp_system_event_task(void *pvParameters)
         if (xQueueReceive(g_event_handler, &evt, portMAX_DELAY) == pdPASS) {
             ret = esp_system_event_handler(&evt);
             if (ret == ESP_FAIL)
-                os_printf("esp wifi post event to user fail!\n");
+                printf("esp wifi post event to user fail!\n");
         }
     }
 }

+ 12 - 0
components/esp32/include/esp_event.h

@@ -32,6 +32,7 @@ typedef enum {
     SYSTEM_EVENT_STA_CONNECTED,            /**< ESP32 station connected to AP */
     SYSTEM_EVENT_STA_DISCONNECTED,         /**< ESP32 station disconnected to AP */
     SYSTEM_EVENT_STA_AUTHMODE_CHANGE,      /**< the auth mode of AP connected by ESP32 station changed */
+    SYSTEM_EVENT_STA_GOTIP,
     SYSTEM_EVENT_AP_START,                 /**< ESP32 softap start */
     SYSTEM_EVENT_AP_STOP,                  /**< ESP32 softap start */
     SYSTEM_EVENT_AP_STACONNECTED,          /**< a station connected to ESP32 soft-AP */
@@ -40,6 +41,10 @@ typedef enum {
     SYSTEM_EVENT_MAX
 } system_event_id_t;
 
+typedef struct {
+    uint32_t addr;
+} esp_ip_addr_t;
+
 typedef struct {
     uint32_t status;          /**< status of scanning APs*/
     uint8_t  number;
@@ -64,6 +69,12 @@ typedef struct {
     uint8_t new_mode;         /**< the new auth mode of AP */
 } system_event_sta_authmode_change_t;
 
+typedef struct {
+    esp_ip_addr_t ip;
+    esp_ip_addr_t netmask;
+    esp_ip_addr_t gw;
+} system_event_sta_gotip_t;
+
 typedef struct {
     uint8_t mac[6];           /**< MAC address of the station connected to ESP32 soft-AP */
     uint8_t aid;              /**< the aid that ESP32 soft-AP gives to the station connected to  */
@@ -84,6 +95,7 @@ typedef union {
     system_event_sta_disconnected_t            disconnected;       /**< ESP32 station disconnected to AP */
     system_event_sta_scan_done_t               scan_done;          /**< ESP32 station scan (APs) done */
     system_event_sta_authmode_change_t         auth_change;        /**< the auth mode of AP ESP32 station connected to changed */
+    system_event_sta_gotip_t                   got_ip;
     system_event_ap_staconnected_t             sta_connected;      /**< a station connected to ESP32 soft-AP */
     system_event_ap_stadisconnected_t          sta_disconnected;   /**< a station disconnected to ESP32 soft-AP */
     system_event_ap_probe_req_rx_t             ap_probereqrecved;  /**< ESP32 softAP receive probe request packet */

+ 209 - 0
components/esp32/include/esp_intr.h

@@ -0,0 +1,209 @@
+// Copyright 2010-2016 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_INTR_H__
+#define __ESP_INTR_H__
+
+#include "rom/ets_sys.h"
+#include "freertos/xtensa_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ESP_CCOMPARE_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_CCOMPARE_INUM, (func), (void *)(arg))
+
+#define ESP_EPWM_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_EPWM_INUM, (func), (void *)(arg))
+
+#define ESP_MPWM_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_MPWM_INUM, (func), (void *)(arg))
+
+#define ESP_SPI1_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_SPI1_INUM, (func), (void *)(arg))
+
+#define ESP_SPI2_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_SPI2_INUM, (func), (void *)(arg))
+
+#define ESP_SPI3_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_SPI3_INUM, (func), (void *)(arg))
+
+#define ESP_I2S0_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_I2S0_INUM, (func), (void *)(arg))
+
+#define ESP_PCNT_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_PCNT_INUM, (func), (void *)(arg))
+
+#define ESP_LEDC_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_LEDC_INUM, (func), (void *)(arg))
+
+#define ESP_WMAC_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_WMAC_INUM, (func), (void *)(arg))
+
+#define ESP_FRC_TIMER1_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_FRC_TIMER1_INUM, (func), (void *)(arg))
+
+#define ESP_FRC_TIMER2_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_FRC_TIMER2_INUM, (func), (void *)(arg))
+
+#define ESP_GPIO_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_GPIO_INUM, (func), (void *)(arg))
+
+#define ESP_UART_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_UART_INUM, (func), (void *)(arg))
+
+#define ESP_WDT_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_WDT_INUM, (func), (void *)(arg))
+
+#define ESP_RTC_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_RTC_INUM, (func), (void *)(arg))
+
+#define ESP_SLC_INTR_ATTACH(func, arg) \
+    xt_set_interrupt_handler(ETS_SLC_INUM, (func), (void *)(arg))
+
+#define ESP_RMT_CTRL_INTRL(func,arg)\
+    xt_set_interrupt_handler(ETS_RMT_CTRL_INUM, (func), (void *)(arg))
+
+#define ESP_INTR_ENABLE(inum) \
+    xt_ints_on((1<<inum))
+
+#define ESP_INTR_DISABLE(inum) \
+    xt_ints_off((1<<inum))
+
+#define ESP_CCOMPARE_INTR_ENBALE() \
+    ESP_INTR_ENABLE(ETS_CCOMPARE_INUM)
+
+#define ESP_CCOMPARE_INTR_DISBALE() \
+    ESP_INTR_DISABLE(ETS_CCOMPARE_INUM)
+
+#define ESP_SPI1_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_SPI1_INUM)
+
+#define ESP_SPI1_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_SPI1_INUM)
+
+#define ESP_SPI2_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_SPI2_INUM)
+
+#define ESP_PWM_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_PWM_INUM)
+
+#define ESP_PWM_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_PWM_INUM)
+
+#define ESP_SPI2_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_SPI2_INUM)
+
+#define ESP_SPI3_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_SPI3_INUM)
+
+#define ESP_SPI3_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_SPI3_INUM)
+
+#define ESP_I2S0_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_I2S0_INUM)
+
+#define ESP_I2S0_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_I2S0_INUM)
+
+#define ESP_I2S1_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_I2S1_INUM)
+
+#define ESP_I2S1_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_I2S1_INUM)
+
+#define ESP_MPWM_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_MPWM_INUM)
+
+#define ESP_EPWM_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_EPWM_INUM)
+
+#define ESP_MPWM_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_MPWM_INUM)
+
+#define ESP_EPWM_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_EPWM_INUM)
+
+#define ESP_BB_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_BB_INUM)
+
+#define ESP_BB_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_BB_INUM)
+
+#define ESP_UART_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_UART_INUM)
+
+#define ESP_UART_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_UART_INUM)
+
+#define ESP_LEDC_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_LEDC_INUM)
+
+#define ESP_LEDC_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_LEDC_INUM)
+
+#define ESP_GPIO_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_GPIO_INUM)
+
+#define ESP_GPIO_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_GPIO_INUM)
+
+#define ESP_WDT_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_WDT_INUM)
+
+#define ESP_WDT_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_WDT_INUM)
+
+#define ESP_FRC1_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_FRC_TIMER1_INUM)
+
+#define ESP_FRC1_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_FRC_TIMER1_INUM)
+
+#define ESP_FRC2_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_FRC_TIMER2_INUM)
+
+#define ESP_FRC2_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_FRC_TIMER2_INUM)
+
+#define ESP_RTC_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_RTC_INUM)
+
+#define ESP_RTC_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_RTC_INUM)
+
+#define ESP_SLC_INTR_ENABLE() \
+    ESP_INTR_ENABLE(ETS_SLC_INUM)
+
+#define ESP_SLC_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_SLC_INUM)
+
+#define ESP_PCNT_INTR_ENABLE()  \
+    ESP_INTR_ENABLE(ETS_PCNT_INUM)
+
+#define ESP_PCNT_INTR_DISABLE() \
+    ESP_INTR_DISABLE(ETS_PCNT_INUM)
+
+#define ESP_RMT_CTRL_ENABLE() \
+    ESP_INTR_ENABLE(ETS_RMT_CTRL_INUM)
+
+#define ESP_RMT_CTRL_DIABLE() \
+    ESP_INTR_DISABLE(ETS_RMT_CTRL_INUM)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ESP_INTR_H__ */

+ 5 - 168
components/esp32/include/esp_system.h

@@ -17,6 +17,8 @@
 
 #include <stdint.h>
 
+#include "esp_err.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -84,15 +86,6 @@ void system_deep_sleep(uint64_t time_in_us);
   */
 uint32_t system_get_time(void);
 
-/**
-  * @brief  Print the system memory distribution, including data/rodata/bss/heap.
-  *
-  * @param  null
-  *
-  * @return null
-  */
-void system_print_meminfo(void);
-
 /**
   * @brief  Get the size of available heap.
   *
@@ -102,22 +95,6 @@ void system_print_meminfo(void);
   */
 uint32_t system_get_free_heap_size(void);
 
-/**
-  * @brief  Get the chip ID.
-  *
-  * Example:          
-  * <pre> 
-  *         uint8 chip_id[6];
-  *         system_get_chip_id(chip_id);
-  * </pre>
-  *
-  * @param  uint8 *chip_id : the chip ID
-  *
-  * @return    true  : succeed
-  * @return    false : fail
-  */
-bool system_get_chip_id(uint8_t *chip_id);
-
 /**
   * @brief     Get RTC time, unit: RTC clock cycle.
   *
@@ -171,98 +148,6 @@ bool system_rtc_mem_read(uint16_t src, void *dst, uint16_t n);
   */
 bool system_rtc_mem_write(uint16_t dst, const void *src, uint16_t n);
 
-typedef enum {
-    ADC1_PAD_GPIO36 = 0,
-    ADC1_PAD_GPIO37,
-    ADC1_PAD_GPIO38,
-    ADC1_PAD_GPIO39,
-    ADC1_PAD_GPIO32,
-    ADC1_PAD_GPIO33,
-    ADC1_PAD_GPIO34,
-    ADC1_PAD_GPIO35
-} adc1_read_pad_t;
-
-typedef enum {
-    ADC1_ATTEN_0DB = 0,
-    ADC1_ATTEN_3DB,
-    ADC1_ATTEN_6DB,
-    ADC1_ATTEN_12DB
-} adc1_read_atten_t;
-
-/**
-  * @brief    Read ADC1.
-  *
-  * @param     adc1_read_pad pad : the corresponding GPIO
-  * @param     adc1_read_atten atten :  value of attenuation 
-  *
-  * @return    range of the return value is [0, 4096].
-  *    - If atten == 0, the range of voltage can be measured is  [0, 1] V.
-  *    - If atten == 1, the range of voltage can be measured is  [0, 1.4] V.
-  *    - If atten == 2, the range of voltage can be measured is  [0, 2] V.
-  *    - If atten == 3, the range of voltage can be measured is  [0, 4] V.
-  */
-uint16_t system_adc1_read(adc1_read_pad_t pad, adc1_read_atten_t atten);
-
-/**
-  * @brief     Measure the power voltage of VDD3P3 pin 3 and 4, unit : 1/1024 V.
-  *
-  * @attention system_get_vdd33 depends on RF, please do not use it if RF is disabled.
-  *
-  * @param     null
-  *
-  * @return    Power voltage of VDD33, unit : 1/1024 V
-  */
-uint16_t system_get_vdd33(void);
-
-/**
-  * @brief  Write data into flash with protection.
-  *
-  *         Flash read/write has to be 4-bytes aligned.
-  *
-  *         Protection of flash read/write :
-  *             use 3 sectors (4KBytes per sector) to save  4KB data with protect,
-  *             sector 0 and sector 1 are data sectors, back up each other,
-  *             save data alternately, sector 2 is flag sector, point out which sector
-  *             is keeping the latest data, sector 0 or sector 1.
-  *
-  * @param  uint16 start_sec : start sector (sector 0) of the 3 sectors which are
-  *                            used for flash read/write protection.
-  *    - For example, in IOT_Demo we can use the 3 sectors (3 * 4KB) starting from flash
-  *      0x3D000 for flash read/write protection, so the parameter start_sec should be 0x3D
-  * @param  void *param : pointer of the data to be written
-  * @param  uint16 len : data length, should be less than a sector, which is 4 * 1024
-  *
-  * @return true  : succeed
-  * @return false : fail
-  */
-bool system_param_save_with_protect(uint16_t start_sec, void *param, uint16_t len);
-
-/**
-  * @brief  Read the data saved into flash with the read/write protection.
-  *
-  *         Flash read/write has to be 4-bytes aligned.
-  *
-  *         Read/write protection of flash:
-  *             use 3 sectors (4KB per sector) to save  4KB data with protect, sector
-  *             0 and sector 1 are data sectors, back up each other, save data alternately,
-  *             sector 2 is flag sector, point out which sector is keeping the latest data,
-  *             sector 0 or sector 1.
-  *
-  * @param  uint16 start_sec : start sector (sector 0) of the 3 sectors used for
-  *                            flash read/write protection. It cannot be sector 1 or sector 2.
-  *    - For example, in IOT_Demo, the 3 sectors (3 * 4KB) starting from flash 0x3D000
-  *      can be used for flash read/write protection.
-  *      The parameter start_sec is 0x3D, and it cannot be 0x3E or 0x3F.
-  * @param  uint16 offset : offset of data saved in sector
-  * @param  void *param : data pointer
-  * @param  uint16 len : data length, offset + len =< 4 * 1024
-  *
-  * @return true  : succeed
-  * @return false : fail
-  */
-bool system_param_load(uint16_t start_sec, uint16_t offset, void *param, uint16_t len);
-
-
 /** \defgroup System_boot_APIs Boot APIs
   * @brief boot APIs
   */
@@ -288,63 +173,15 @@ bool system_param_load(uint16_t start_sec, uint16_t offset, void *param, uint16_
   * @{
   */
 
-typedef enum {
-    DEFAULT_MAC = 0,    /**< Default hardware MAC provided by Espressif Systems */
-    USER_MAC,           /**< User-define hardware MAC  */
-} mac_group_t;
-
-typedef enum {
-    WIFI_MAC = 0,       /**< Hardware MAC address of ESP32 WiFi  */
-    BT_MAC,             /**< Hardware MAC address of ESP32 bluetooth  */
-} mac_type_t;
-
-/**
-  * @brief  Set user-define hardware MAC address.
-  *
-  * @attention  Hardware MAC address can only be set ONCE for each ESP32 chip.
-  *
-  * @param  mac_type type : type of hardware MAC address.
-  * @param  uint8 *mac : user-define hardware MAC address, length: 6 bytes.
-  *
-  * @return  0 : succeed to set.
-  * @return  1 : the hardware MAC has been set once, users can not set it any more.
-  * @return  2 : fail to set.
-  * @return  3 : invalid parameter.
-  */
-int system_efuse_program_user_mac(mac_type_t type, uint8_t *mac);
-
 /**
   * @brief  Read hardware MAC address.
   *
-  * @param  mac_group group : default MAC or user-defined MAC.
-  * @param  mac_type type : type of hardware MAC address.
-  * @param  uint8 *mac : the hardware MAC address, length: 6 bytes.
-  *
-  * @return  true  : succeed
-  * @return  false : fail
-  */
-bool system_efuse_read_mac(mac_group_t group, mac_type_t type, uint8_t *mac);
-
-/**
-  * @brief  Set hardware MAC group, default MAC or user-defined MAC.
-  *
-  * @attention  This API needs system_restart to take effect.
+  * @param  uint8 mac[6] : the hardware MAC address, length: 6 bytes.
   *
-  * @param  mac_group group : default MAC or user-defined MAC.
-  *
-  * @return  true  : succeed
-  * @return  false : fail
+  * @return esp_err_t
   */
-bool system_efuse_set_mac_group(mac_group_t group);
+esp_err_t system_efuse_read_mac(uint8_t mac[6]);
 
-/**
-  * @brief  Get hardware MAC group, default MAC or user-defined MAC.
-  *
-  * @param  null
-  *
-  * @return  mac_group, the hardware MAC group.
-  */
-mac_group_t system_efuse_get_mac_group(void);
 
 void system_init(void);
 

+ 10 - 0
components/esp32/include/esp_wifi.h

@@ -19,6 +19,7 @@
 #include <stdbool.h>
 
 #include "esp_err.h"
+#include "rom/queue.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -220,6 +221,15 @@ esp_err_t esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf);
 
 esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf);
 
+struct station_info {
+    STAILQ_ENTRY(station_info) next;
+    uint8_t bssid[6];
+};
+
+esp_err_t esp_wifi_get_station_list(struct station_info **station);
+
+esp_err_t esp_wifi_free_station_list(void);
+
 typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void* eb);
 
 esp_err_t esp_wifi_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);

+ 2 - 2
components/esp32/include/rom/ets_sys.h

@@ -232,10 +232,10 @@ void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
 
 
 #define ETS_INTR_ENABLE(inum) \
-	ets_isr_unmask((1<<inum))
+        xt_ints_on((1<<inum))
 
 #define ETS_INTR_DISABLE(inum) \
-	ets_isr_mask((1<<inum))
+        xt_ints_off((1<<inum))
 
 #define ETS_CCOMPARE_INTR_ENBALE() \
     ETS_INTR_ENABLE(ETS_CCOMPARE_INUM)

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

@@ -89,7 +89,7 @@
 #define  APB_CLK_FREQ_ROM                            13*1000000
 #define  CPU_CLK_FREQ_ROM                            APB_CLK_FREQ_ROM
 #define  CPU_CLK_FREQ                                APB_CLK_FREQ
-#define  APB_CLK_FREQ                                40*1000000       //unit: Hz
+#define  APB_CLK_FREQ                                80*1000000       //unit: Hz
 #define  UART_CLK_FREQ                               APB_CLK_FREQ
 //#define  WDT_CLK_FREQ                                APB_CLK_FREQ
 #define  TIMER_CLK_FREQ                              (80000000>>4) //80MHz divided by 16

+ 1 - 1
components/esp32/lib

@@ -1 +1 @@
-Subproject commit 40dc7af7f3d8da6745476e66cbd65be9b8988f6c
+Subproject commit 7c8bd4ec5a3e099768b15372fcb98959d6617e92

+ 14 - 23
components/esp32/wifi.c

@@ -13,6 +13,7 @@
 // limitations under the License.
 #include <stddef.h>
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "esp_err.h"
 #include "esp_wifi.h"
@@ -23,30 +24,11 @@
 #include "freertos/queue.h"
 #include "freertos/semphr.h"
 
-//#include "tcpip_adapter.h"
-
-#define ESP32_WORKAROUND 1
-
 #if CONFIG_WIFI_ENABLED
 
-#ifdef ESP32_WORKAROUND
-
-SemaphoreHandle_t stdio_mutex_tx = NULL;
-#define os_printf(fmt, ...) do {\
-    if (!stdio_mutex_tx) {\
-        stdio_mutex_tx = xSemaphoreCreateMutex();\
-    }\
-\
-    xSemaphoreTake(stdio_mutex_tx, portMAX_DELAY);\
-    ets_printf(fmt, ##__VA_ARGS__);\
-    xSemaphoreGive(stdio_mutex_tx);\
-} while (0)
-
-#endif
-
 static wifi_startup_cb_t startup_cb;
 
-#define WIFI_DEBUG  os_printf
+#define WIFI_DEBUG  printf
 #define WIFI_API_CALL_CHECK(info, api_call, ret) \
 do{\
     esp_err_t __err = (api_call);\
@@ -56,6 +38,8 @@ do{\
     }\
 } while(0)
 
+
+
 static void esp_wifi_task(void *pvParameters)
 {
     esp_err_t err;
@@ -65,29 +49,35 @@ static void esp_wifi_task(void *pvParameters)
     do {
         err = esp_wifi_init(&cfg);
         if (err != ESP_OK) {
+            WIFI_DEBUG("esp_wifi_init fail, ret=%d\n", err);
             break;
         }
 
         if (startup_cb) {
             err = (*startup_cb)();
             if (err != ESP_OK) {
+                WIFI_DEBUG("startup_cb fail, ret=%d\n", err);
                 break;
             }
         }
 
         err = esp_wifi_start();
-        if (err != ESP_OK) {    // TODO: if already started, it's also OK
+        if (err != ESP_OK) {
+            WIFI_DEBUG("esp_wifi_start fail, ret=%d\n", err);
             break;
         }
 
 #if CONFIG_WIFI_AUTO_CONNECT
         wifi_mode_t mode;
-
-        esp_wifi_get_mode(&mode);
+        err = esp_wifi_get_mode(&mode);
+        if (err != ESP_OK){
+            WIFI_DEBUG("esp_wifi_get_mode fail, ret=%d\n", err);
+        }
 
         if (mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA) {
             err = esp_wifi_connect();
             if (err != ESP_OK) {
+                WIFI_DEBUG("esp_wifi_connect fail, ret=%d\n", err);
                 break;
             }
         }
@@ -95,6 +85,7 @@ static void esp_wifi_task(void *pvParameters)
     } while (0);
 
     if (err != ESP_OK) {
+        WIFI_DEBUG("wifi startup fail, deinit\n");
         esp_wifi_deinit();
     }
 

+ 4 - 0
components/freertos/include/freertos/FreeRTOS.h

@@ -783,6 +783,10 @@ V8 if desired. */
 	#define xList List_t
 #endif /* configENABLE_BACKWARD_COMPATIBILITY */
 
+#ifndef configESP32_PER_TASK_DATA
+	#define configESP32_PER_TASK_DATA 1
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
components/freertos/panic.c

@@ -35,7 +35,7 @@ overflow handler also is in here.
 */
 
 #if !CONFIG_FREERTOS_PANIC_SILENT_REBOOT
-//os_printf may be broken, so we fix our own printing fns...
+//printf may be broken, so we fix our own printing fns...
 inline static void panicPutchar(char c) {
 	while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ;
 	WRITE_PERI_REG(UART_FIFO_REG(0), c);

+ 1 - 3
components/freertos/tasks.c

@@ -84,6 +84,7 @@ task.h is included from an application file. */
 #include "timers.h"
 #include "StackMacros.h"
 #include "portmacro.h"
+#include "semphr.h"
 
 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
@@ -4579,9 +4580,6 @@ TickType_t uxReturn;
 
 #endif /* configUSE_TASK_NOTIFICATIONS */
 
-/*-----------------------------------------------------------*/
-
-
 #ifdef FREERTOS_MODULE_TEST
 	#include "tasks_test_access_functions.h"
 #endif

+ 1 - 1
components/lwip/api/sockets.c

@@ -405,7 +405,7 @@ do{\
 
 /** The global array of available sockets */
 static struct lwip_sock sockets[NUM_SOCKETS];
-#ifdef LWIP_THREAD_SAFE
+#if LWIP_THREAD_SAFE
 static bool sockets_init_flag = false;
 #endif
 /** The global list of tasks waiting for select */

+ 26 - 6
components/lwip/apps/dhcpserver.c

@@ -69,7 +69,7 @@ enum dyc_dhcps_flags{
 #define DHCPS_DEBUG          0
 #define DHCPS_LOG printf
 
-#define DYC_DHCP_CRASH //os_printf
+#define DYC_DHCP_CRASH //printf
 
 
 #define MAX_STATION_NUM      8
@@ -376,7 +376,7 @@ u32_t magic_cookie_temp = magic_cookie;
 
 //extern bool system_get_string_from_flash(void *flash_str, void* ram_str,uint8 ram_str_len);
 //system_get_string_from_flash((void *)(&magic_cookie), (void *)(&magic_cookie_temp),4);
-//os_printf("ck_tmp3:%08X\n",magic_cookie_temp);
+//printf("ck_tmp3:%08X\n",magic_cookie_temp);
 
         //memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie));
         memcpy((char *) m->options, &magic_cookie_temp, sizeof(magic_cookie_temp));
@@ -698,7 +698,7 @@ static s16_t parse_msg(struct dhcps_msg *m, u16_t len)
 //u32 magic_cookie_temp = magic_cookie;
 //extern bool system_get_string_from_flash(void *flash_str, void* ram_str,uint8 ram_str_len);
 //system_get_string_from_flash((void *)(&magic_cookie), (void *)(&magic_cookie_temp),4);
-//os_printf("ck_tmp4:%08X\n",magic_cookie_temp);
+//printf("ck_tmp4:%08X\n",magic_cookie_temp);
 
 		if(memcmp((char *)m->options,
                     &magic_cookie,
@@ -726,7 +726,7 @@ static s16_t parse_msg(struct dhcps_msg *m, u16_t len)
 			for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
 				pdhcps_pool = pback_node->pnode;
 				if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){
-//									os_printf("the same device request ip\n");
+//									printf("the same device request ip\n");
 					if (memcmp(&pdhcps_pool->ip.addr, m->ciaddr, sizeof(pdhcps_pool->ip.addr)) == 0) {
 					    renew = true;
 					}
@@ -736,7 +736,7 @@ static s16_t parse_msg(struct dhcps_msg *m, u16_t len)
 					goto POOL_CHECK;
 				} else if (pdhcps_pool->ip.addr == client_address_plus.addr){
 //									client_address.addr = client_address_plus.addr;
-//									os_printf("the ip addr has been request\n");
+//									printf("the ip addr has been request\n");
 					addr_tmp.addr = htonl(client_address_plus.addr);
 					addr_tmp.addr++;
 					client_address_plus.addr = htonl(addr_tmp.addr);
@@ -967,7 +967,7 @@ static void wifi_softap_init_dhcps_lease(u32_t ip)
 		dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr);
 		dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr);
 	}
-//	os_printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip);
+//	printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip);
 }
 
 
@@ -1211,6 +1211,25 @@ u32_t wifi_softap_get_dhcps_lease_time(void) // minute
 {
     return dhcps_lease_time;
 }
+
+/* Search ip address based on mac address */
+bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip)
+{
+    struct dhcps_pool *pdhcps_pool = NULL;
+    list_node *pback_node = NULL;
+    bool ret = false;
+    
+    for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
+        pdhcps_pool = pback_node->pnode;
+        if (memcmp(pdhcps_pool->mac, mac, sizeof(pdhcps_pool->mac)) == 0){
+            memcpy(&ip->addr, &pdhcps_pool->ip.addr, sizeof(pdhcps_pool->ip.addr));
+            ret = true;
+            break;
+        }
+    }
+   
+    return ret;
+}
 #else
 #include <stdio.h>
 #include <sys/types.h>
@@ -2477,6 +2496,7 @@ bool wifi_softap_set_dhcps_lease_time(u32_t minute)
     return false;
 }
 
+
 #endif   /*ifdef  LWIP_ESP8266*/
 
 

+ 3 - 3
components/lwip/core/ipv4/dhcp.c

@@ -459,7 +459,7 @@ dhcp_fine_tmr(void)
 #if 0
       if (DHCP_MAXRTX != 0) {
     	  if (netif->dhcp->tries >= DHCP_MAXRTX){
-			  //os_printf("DHCP timeout\n");
+			  //printf("DHCP timeout\n");
 			  if (netif->dhcp_event != NULL)
 				  netif->dhcp_event();
 			  break;
@@ -1539,7 +1539,7 @@ again:
         break;
       case(DHCP_OPTION_DNS_SERVER):
         /* special case: there might be more than one server */
-        LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;);
+        //LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;);
         /* limit number of DNS servers */
         decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
         LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
@@ -1595,7 +1595,7 @@ decode_next:
         pbuf_copy_partial(q, &value, copy_len, val_offset);
         if (decode_len > 4) {
           /* decode more than one u32_t */
-          LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
+          //LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
           dhcp_got_option(dhcp, decode_idx);
           dhcp_set_option_value(dhcp, decode_idx, htonl(value));
           decode_len -= 4;

+ 3 - 2
components/lwip/include/lwip/apps/dhcpserver.h

@@ -77,6 +77,7 @@ extern u32_t dhcps_lease_time;
 void dhcps_start(struct netif *netif);
 void dhcps_stop(struct netif *netif);
 
+bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip);
 #else
 #include "lwip/opt.h"
 
@@ -87,8 +88,8 @@ void dhcps_stop(struct netif *netif);
 #define DHCPS_DEBUG 1
 #if DHCPS_DEBUG    	
 #define log_info(message, ...)   do { \
-		os_printf((message), ##__VA_ARGS__);   \
-		os_printf("\n");		  \
+		printf((message), ##__VA_ARGS__);   \
+		printf("\n");		  \
 	  } while(0);
 	
 #else

+ 1 - 0
components/lwip/include/lwip/lwip/debug.h

@@ -97,6 +97,7 @@
 /** print debug message only if debug message type is enabled...
  *  AND is of correct type AND is at least LWIP_DBG_LEVEL
  */
+//#define LWIP_DEBUGF(debug, message) do { 
 #define LWIP_DEBUGF(debug, message) do { \
                                if ( \
                                    ((debug) & LWIP_DBG_ON) && \

+ 3 - 3
components/lwip/include/lwip/lwip/priv/api_msg.h

@@ -188,9 +188,9 @@ struct dns_api_msg {
 
 #if LWIP_NETCONN_SEM_PER_THREAD
 #ifdef LWIP_ESP8266
-#define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem()
-#define LWIP_NETCONN_THREAD_SEM_ALLOC()
-#define LWIP_NETCONN_THREAD_SEM_FREE() 
+#define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem_get()
+#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_thread_sem_init()
+#define LWIP_NETCONN_THREAD_SEM_FREE() sys_thread_sem_deinit()
 #endif
 #endif
 

+ 1 - 1
components/lwip/include/lwip/lwip/sockets.h

@@ -505,7 +505,7 @@ int lwip_fcntl(int s, int cmd, int val);
 #if LWIP_COMPAT_SOCKETS
 #if LWIP_COMPAT_SOCKETS != 2
 
-#ifdef LWIP_THREAD_SAFE
+#if LWIP_THREAD_SAFE
 
 int lwip_accept_r(int s, struct sockaddr *addr, socklen_t *addrlen);
 int lwip_bind_r(int s, const struct sockaddr *name, socklen_t namelen);

+ 3 - 2
components/lwip/include/lwip/port/arch/sys_arch.h

@@ -64,9 +64,10 @@ typedef struct sys_mbox_s {
 
 void sys_arch_assert(const char *file, int line);
 uint32_t system_get_time(void);
-sys_sem_t* sys_thread_sem(void);
 void sys_delay_ms(uint32_t ms);
-
+sys_sem_t* sys_thread_sem_init(void);
+void sys_thread_sem_deinit(void);
+sys_sem_t* sys_thread_sem_get(void);
 
 
 #endif /* __SYS_ARCH_H__ */

+ 4 - 5
components/lwip/include/lwip/port/lwipopts.h

@@ -222,7 +222,6 @@ extern unsigned long os_random(void);
  * (2 * TCP_MSS) for things to work well
  */
 #ifdef PERF
-
 extern unsigned char misc_prof_get_tcpw(void);
 extern unsigned char misc_prof_get_tcp_snd_buf(void);
 #define TCP_WND                         (misc_prof_get_tcpw()*TCP_MSS)
@@ -470,7 +469,7 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
 /**
  * SOCKETS_DEBUG: Enable debugging in sockets.c.
  */
-#define SOCKETS_DEBUG                   LWIP_DBG_OFF
+#define SOCKETS_DEBUG                   LWIP_DBG_ON
 
 /**
  * ICMP_DEBUG: Enable debugging in icmp.c.
@@ -506,9 +505,9 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
  * DHCP_DEBUG: Enable debugging in dhcp.c.
  */
 #define DHCP_DEBUG                      LWIP_DBG_OFF
-//#define LWIP_DEBUG                      1
-//#define TCP_DEBUG                     LWIP_DBG_ON
-#define THREAD_SAFE_DEBUG               LWIP_DBG_OFF
+#define LWIP_DEBUG                      1
+#define TCP_DEBUG                       LWIP_DBG_ON
+#define THREAD_SAFE_DEBUG               LWIP_DBG_ON
 #define LWIP_THREAD_SAFE                1
 
 #define CHECKSUM_CHECK_UDP              0

+ 81 - 16
components/lwip/port/freertos/sys_arch.c

@@ -213,7 +213,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
 
   (*mbox)->alive = true;
 
-  LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("new *mbox ok\n"));
+  LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p mbox_lock=%p\n", *mbox, (*mbox)->os_mbox, (*mbox)->lock));
   return ERR_OK;
 }
 
@@ -234,6 +234,7 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
   if (xQueueSend((*mbox)->os_mbox, &msg, (portTickType)0) == pdPASS) {
     xReturn = ERR_OK;
   } else {
+    LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox));
     xReturn = ERR_MEM;
   }
 
@@ -291,9 +292,12 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
       ulReturn = SYS_ARCH_TIMEOUT;
     }
   } else { // block forever for a message.
+    
     while (1){
-
+      LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch: fetch mbox=%p os_mbox=%p lock=%p\n", mbox, (*mbox)->os_mbox, (*mbox)->lock));
       if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), portMAX_DELAY)){
+      //if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), 3000/portTICK_RATE_MS)){ //ESP32_WORKAROUND
+        LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_arch_mbox_fetch:mbox rx msg=%p\n", (*msg)));
         break;
       }
 
@@ -348,13 +352,15 @@ sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
 void
 sys_mbox_free(sys_mbox_t *mbox)
 {
-  uint8_t count = 0;
+#define MAX_POLL_CNT 100
+#define PER_POLL_DELAY 20
+  uint16_t count = 0;
   bool post_null = true;
 
   LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free: set alive false\n"));
   (*mbox)->alive = false;
 
-  while ( count++ < 10 ){
+  while ( count++ < MAX_POLL_CNT ){ //ESP32_WORKAROUND
     LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:try lock=%d\n", count));
     if (!sys_mutex_trylock( &(*mbox)->lock )){
       LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:get lock ok %d\n", count));
@@ -372,10 +378,10 @@ sys_mbox_free(sys_mbox_t *mbox)
       }
     }
 
-    if (count == 10){
+    if (count == (MAX_POLL_CNT-1)){
       printf("WARNING: mbox %p had a consumer who never unblocked. Leaking!\n", (*mbox)->os_mbox);
     }
-    sys_delay_ms(20);
+    sys_delay_ms(PER_POLL_DELAY);
   }
 
   LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sys_mbox_free:free mbox\n"));
@@ -428,6 +434,7 @@ sys_now(void)
   return xTaskGetTickCount();
 }
 
+static portMUX_TYPE g_lwip_mux = portMUX_INITIALIZER_UNLOCKED;
 /*
   This optional function does a "fast" critical region protection and returns
   the previous protection level. This function is only called during very short
@@ -444,7 +451,10 @@ sys_now(void)
 sys_prot_t
 sys_arch_protect(void)
 {
-//  vTaskEnterCritical();
+#if 1//ESP32_WORKAROUND
+  //vTaskEnterCritical();
+  portENTER_CRITICAL(&g_lwip_mux);
+#endif
   return (sys_prot_t) 1;
 }
 
@@ -459,7 +469,10 @@ void
 sys_arch_unprotect(sys_prot_t pval)
 {
   (void) pval;
-//  vTaskExitCritical();
+#if 1 //ESP32_WORKAROUND
+  //vTaskExitCritical();
+  portEXIT_CRITICAL(&g_lwip_mux);
+#endif
 }
 
 /*-----------------------------------------------------------------------------------*/
@@ -475,15 +488,67 @@ sys_arch_assert(const char *file, int line)
   while(1);
 }
 
-/* This is a super hacky thread-local-storage repository
-   FreeRTOS 8.2.3 & up have thread local storage in the
-   OS, which is how we should do this. Once we upgrade FreeRTOS,
-   we can drop this hacky store and use the FreeRTOS TLS API.
-*/
-sys_sem_t* sys_thread_sem(void)
+#define SYS_TLS_INDEX CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX
+/* 
+ * get per thread semphore
+ */
+sys_sem_t* sys_thread_sem_get(void)
+{
+  sys_sem_t *sem = (sys_sem_t*)pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), SYS_TLS_INDEX);
+  if (!sem){
+    sem = sys_thread_sem_init();
+  }
+  LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem_get s=%p\n", sem));
+  return sem;
+}
+
+static void sys_thread_tls_free(int index, void* data)
+{
+  sys_sem_t *sem = (sys_sem_t*)(data);
+
+  if (sem && *sem){
+    LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem del, i=%d sem=%p\n", index, *sem));
+    ets_printf("sem del:%p\n", *sem);
+    vSemaphoreDelete(*sem);
+  }
+
+  if (sem){
+    LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem pointer del, i=%d sem_p=%p\n", index, sem));
+    ets_printf("sem pointer del:%p\n", sem);
+    free(sem);
+  }
+}
+
+sys_sem_t* sys_thread_sem_init(void)
+{
+  sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
+
+  if (!sem){
+    printf("sem f1\n");
+    return 0;
+  }
+
+  *sem = xSemaphoreCreateBinary();
+  if (!(*sem)){
+    free(sem);
+    printf("sem f2\n");
+    return 0;
+  }
+
+  LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem init sem_p=%p sem=%p cb=%p\n", sem, *sem, sys_thread_tls_free));
+  vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), SYS_TLS_INDEX, sem, (TlsDeleteCallbackFunction_t)sys_thread_tls_free);
+
+  return sem;
+}
+
+void sys_thread_sem_deinit(void)
 {
-  extern void* xTaskGetLwipSem(void);
-  return (sys_sem_t*)(xTaskGetLwipSem());
+  sys_sem_t *sem = (sys_sem_t*)pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), SYS_TLS_INDEX);
+
+  sys_thread_tls_free(SYS_TLS_INDEX, (void*)sem);
+  vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), SYS_TLS_INDEX, 0, 0);
+
+  return;
 }
 
 void sys_delay_ms(uint32_t ms)

+ 15 - 0
components/tcpip_adapter/include/tcpip_adapter.h

@@ -20,15 +20,26 @@
 #include "esp_wifi.h"
 
 #define CONFIG_TCPIP_LWIP 1
+#define CONFIG_DHCP_STA_LIST 1
 
 #if CONFIG_TCPIP_LWIP
 #include "lwip/ip_addr.h"
+#include "rom/queue.h"
 
 struct ip_info {
     ip4_addr_t ip;
     ip4_addr_t netmask;
     ip4_addr_t gw;
 };
+
+#endif
+
+#if CONFIG_DHCP_STA_LIST 
+struct station_list {
+    STAILQ_ENTRY(station_list) next;
+    uint8_t mac[6];
+    ip4_addr_t ip;
+};
 #endif
 
 #define ESP_ERR_TCPIP_ADAPTER_BASE      0x5000      // base should be moved to esp_err.h
@@ -38,6 +49,7 @@ struct ip_info {
 #define ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED    ESP_ERR_TCPIP_ADAPTER_BASE + 0x02
 #define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED  ESP_ERR_TCPIP_ADAPTER_BASE + 0x03
 #define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPED   ESP_ERR_TCPIP_ADAPTER_BASE + 0x04
+#define ESP_ERR_TCPIP_ADAPTER_NO_MEM                ESP_ERR_TCPIP_ADAPTER_BASE + 0x05
 
 /* will add ethernet interface */
 typedef enum {
@@ -96,5 +108,8 @@ esp_err_t tcpip_adapter_output(tcpip_adapter_if_t tcpip_if, void *buffer, uint16
 
 wifi_interface_t tcpip_adapter_get_wifi_if(void *dev);
 
+esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list);
+esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list);
+
 #endif /*  _TCPIP_ADAPTER_H_ */
 

+ 69 - 9
components/tcpip_adapter/tcpip_adapter_lwip.c

@@ -27,6 +27,8 @@
 
 #include "apps/dhcpserver.h"
 
+#include "esp_event.h"
+
 static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
 static struct ip_info esp_ip[TCPIP_ADAPTER_IF_MAX];
 
@@ -36,7 +38,7 @@ static tcpip_adapter_dhcp_status_t dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
 
 static esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif);
 
-#define TCPIP_ADAPTER_DEBUG  ets_printf
+#define TCPIP_ADAPTER_DEBUG  printf
 
 void tcpip_adapter_init(void)
 {
@@ -137,7 +139,7 @@ esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
 esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
 {
     if (tcpip_if == TCPIP_ADAPTER_IF_STA) {
-        if (esp_netif[tcpip_if] == NULL){
+        if (esp_netif[tcpip_if] == NULL) {
             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
         }
 
@@ -145,11 +147,18 @@ esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
             dhcp_release(esp_netif[tcpip_if]);
             dhcp_stop(esp_netif[tcpip_if]);
             dhcp_cleanup(esp_netif[tcpip_if]);
-            dhcpc_status = TCPIP_ADAPTER_DHCP_STOPED;
+
+            if (dhcpc_status != TCPIP_ADAPTER_DHCP_STOPED) {
+                dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
+            }
         } else {
             netif_set_down(esp_netif[tcpip_if]);
             netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
         }
+
+        ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
+        ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
+        ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
     }
 
     return ESP_OK;
@@ -183,6 +192,7 @@ esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, struct ip_info
 esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif)
 {
     tcpip_adapter_if_t tcpip_if;
+    system_event_t evt;
 
     if (!netif) {
         TCPIP_ADAPTER_DEBUG("null netif=%p\n", netif);
@@ -208,11 +218,16 @@ esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif)
         ip4_addr_set(&esp_ip[tcpip_if].gw, ip_2_ip4(&netif->gw));
 
         //notify event
-        printf("ip: %s, ", inet_ntoa(esp_ip[tcpip_if].ip));
-        printf("mask: %s, ", inet_ntoa(esp_ip[tcpip_if].netmask));
-        printf("gw: %s\n", inet_ntoa(esp_ip[tcpip_if].gw));
-
-        if (ip_2_ip4(&netif->ip_addr) != IP4_ADDR_ANY) {
+        if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) {
+            evt.event_id = SYSTEM_EVENT_STA_GOTIP;
+            memcpy(&evt.event_info.got_ip.ip, &esp_ip[tcpip_if].ip, sizeof(evt.event_info.got_ip.ip));
+            memcpy(&evt.event_info.got_ip.netmask, &esp_ip[tcpip_if].netmask, sizeof(evt.event_info.got_ip.netmask));
+            memcpy(&evt.event_info.got_ip.gw, &esp_ip[tcpip_if].gw, sizeof(evt.event_info.got_ip.gw));
+            esp_event_send(&evt);
+
+            printf("ip: %s, ", inet_ntoa(esp_ip[tcpip_if].ip));
+            printf("mask: %s, ", inet_ntoa(esp_ip[tcpip_if].netmask));
+            printf("gw: %s\n", inet_ntoa(esp_ip[tcpip_if].gw));
         }
     } else {
         TCPIP_ADAPTER_DEBUG("ip unchanged\n");
@@ -388,7 +403,7 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
     return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
 }
 
-esp_err_t tcpip_dep_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
+esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
 {
     /* only support sta now, need to support ethernet */
     if (tcpip_if != TCPIP_ADAPTER_IF_STA || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
@@ -447,4 +462,49 @@ wifi_interface_t tcpip_adapter_get_wifi_if(void *dev)
 
     return WIFI_IF_MAX;
 }
+
+esp_err_t tcpip_adapter_get_sta_list(struct station_info *sta_info, struct station_list **sta_list)
+{
+    struct station_info *info = sta_info;
+    struct station_list *list;
+    STAILQ_HEAD(, station_list) list_head;
+
+    if (sta_list == NULL)
+        return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
+
+    STAILQ_INIT(&list_head);
+
+    while (info != NULL) {
+        list = (struct station_list *)malloc(sizeof(struct station_list));
+        memset(list, 0, sizeof (struct station_list));
+
+        if (list == NULL) {
+            return ESP_ERR_TCPIP_ADAPTER_NO_MEM;
+        }
+
+        memcpy(list->mac, info->bssid, 6);
+        dhcp_search_ip_on_mac(list->mac, &list->ip);
+        STAILQ_INSERT_TAIL(&list_head, list, next);
+      
+        info = STAILQ_NEXT(info, next);
+    }
+
+    *sta_list = STAILQ_FIRST(&list_head);
+
+    return ESP_OK;
+}
+
+esp_err_t tcpip_adapter_free_sta_list(struct station_list *sta_list)
+{
+    struct station_list *list = sta_list;
+
+    while (sta_list != NULL) {
+        list = sta_list;
+        sta_list = STAILQ_NEXT(sta_list, next);
+        free(list);
+    }
+
+    return ESP_OK;
+}
+
 #endif