Bladeren bron

Merge branch 'feature/initial_examples' into 'master'

Basic examples

Basic examples, contributor information & README clarifications.

See merge request !102

Ivan Grokhotkov 9 jaren geleden
bovenliggende
commit
e78da3093d
45 gewijzigde bestanden met toevoegingen van 1469 en 192 verwijderingen
  1. 10 0
      .gitignore
  2. 17 0
      .gitlab-ci.yml
  3. 37 0
      CONTRIBUTING.md
  4. 16 2
      README.md
  5. 3 1
      components/bt/component.mk
  6. 1 1
      components/esp32/cpu_start.c
  7. 3 2
      components/esp32/include/esp_event.h
  8. 10 173
      components/esp32/include/esp_wifi.h
  9. 190 0
      components/esp32/include/esp_wifi_types.h
  10. 1 1
      components/esp32/lib
  11. 37 0
      components/mbedtls/Kconfig
  12. 5 1
      components/mbedtls/port/include/mbedtls/esp_config.h
  13. 18 1
      components/nvs_flash/include/nvs_flash.h
  14. 7 1
      components/nvs_flash/src/nvs_api.cpp
  15. 7 7
      components/nvs_flash/test/test_nvs.cpp
  16. 1 1
      components/tcpip_adapter/include/tcpip_adapter.h
  17. 196 0
      docs/contributor-agreement.rst
  18. 10 0
      docs/partition-tables.rst
  19. 9 0
      examples/01_hello_world/Makefile
  20. 5 0
      examples/01_hello_world/README.md
  21. 0 0
      examples/01_hello_world/main/component.mk
  22. 32 0
      examples/01_hello_world/main/hello_world_main.c
  23. 1 1
      examples/02_blink/Makefile
  24. 5 0
      examples/02_blink/README.md
  25. 14 0
      examples/02_blink/main/Kconfig.projbuild
  26. 48 0
      examples/02_blink/main/blink.c
  27. 10 0
      examples/02_blink/main/component.mk
  28. 9 0
      examples/03_http_request/Makefile
  29. 5 0
      examples/03_http_request/README.md
  30. 17 0
      examples/03_http_request/main/Kconfig.projbuild
  31. 10 0
      examples/03_http_request/main/component.mk
  32. 181 0
      examples/03_http_request/main/http_request_main.c
  33. 9 0
      examples/04_https_request/Makefile
  34. 5 0
      examples/04_https_request/README.md
  35. 17 0
      examples/04_https_request/main/Kconfig.projbuild
  36. 44 0
      examples/04_https_request/main/cert.c
  37. 10 0
      examples/04_https_request/main/component.mk
  38. 363 0
      examples/04_https_request/main/https_request_main.c
  39. 16 0
      examples/05_ble_adv/Makefile
  40. 0 0
      examples/05_ble_adv/README.rst
  41. 0 0
      examples/05_ble_adv/main/app_bt.c
  42. 10 0
      examples/05_ble_adv/main/component.mk
  43. 14 0
      examples/05_ble_adv/sdkconfig.defaults
  44. 35 0
      examples/README.md
  45. 31 0
      make/build_examples.sh

+ 10 - 0
.gitignore

@@ -7,8 +7,18 @@ GTAGS
 GRTAGS
 GPATH
 
+# emacs
+.dir-locals.el
+
 # emacs temp file suffixes
 *~
 .#*
 \#*#
 
+# Example project files
+examples/*/sdkconfig
+examples/*/sdkconfig.old
+examples/*/build
+
+# Bootloader files
+components/bootloader/src/sdkconfig.old

+ 17 - 0
.gitlab-ci.yml

@@ -69,6 +69,23 @@ build_ssc:
     - chmod +x gen_misc_ng.sh
     - ./gen_misc_ng.sh
 
+build_examples:
+  <<: *build_template
+  artifacts:
+    paths:
+      - build_examples/*/*/build/*.bin
+      - build_examples/*/*/build/*.elf
+      - build_examples/*/*/build/*.map
+      - build_examples/*/*/build/bootloader/*.bin
+    expire_in: 6 mos
+
+  script:
+    # it's not possible to build 100% out-of-tree and have the "artifacts"
+    # mechanism work, but this is the next best thing
+    - mkdir build_examples
+    - cd build_examples
+    - ${IDF_PATH}/make/build_examples.sh
+
 test_nvs_on_host:
   stage: test
   image: espressif/esp32-ci-env

+ 37 - 0
CONTRIBUTING.md

@@ -0,0 +1,37 @@
+# Contributions Guide
+
+We welcome contributions to the esp-idf project!
+
+## How to Contribute
+
+Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/).
+
+## Before Contributing
+
+Before sending us a Pull Request, please consider this list of points:
+
+* Is the contribution entirely your own work, or already licensed under an Apache License 2.0 compatible Open Source License? If not then we unfortunately cannot accept it.
+
+* Does any new code conform to the esp-idf Style Guide? (Style Guide currently pending).
+
+* Is the code adequately commented for people to understand how it is structured?
+
+* Is there documentation or examples that go with code contributions? [There are additional suggestions for writing good examples in the examples README](examples/README.md).
+
+* Are comments and documentation written in clear English, with no spelling or grammar errors?
+
+* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)?
+
+* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
+
+## Pull Request Process
+
+After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
+
+Once the Pull Request is ready to merge, it will first be merged into our internal git system for in-house automated testing.
+
+If this process passes, it will be merged onto the public github repository.
+
+## Legal Part
+
+Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process.

+ 16 - 2
README.md

@@ -1,6 +1,18 @@
 # Using Espressif IoT Development Framework with the ESP32
 
-# Prerequisites
+# Setting Up ESP-IDF
+
+In the [docs](docs) directory you will find per-platform setup guides:
+
+* [Windows Setup Guide](docs/windows-setup.rst)
+* [Mac OS Setup Guide](docs/macos-setup.rst)
+* [Linux Setup Guide](docs/linux-setup.rst)
+
+# Finding A Project
+
+As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory.
+
+Once you've found the project you want to work with, change to its directory and you can configure and build it:
 
 # Configuring your project
 
@@ -52,8 +64,10 @@ For more details about partition tables and how to create custom variations, vie
 
 # Resources
 
-* The [docs directory of the esp-idf repository](https://github.com/espressif/esp-idf/tree/master/docs) contains esp-idf documentation.
+* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation.
 
 * The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources.
 
 * [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
+
+* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.

+ 3 - 1
components/bt/component.mk

@@ -16,8 +16,10 @@ COMPONENT_ADD_LDFLAGS := -lbt -L$(abspath lib) \
                            $(addprefix -l,$(LIBS)) \
                           $(LINKER_SCRIPTS)
 
+include $(IDF_PATH)/make/component_common.mk
 
 ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
 $(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
 
-include $(IDF_PATH)/make/component_common.mk
+# automatically trigger a git submodule update if BT library is missing
+$(eval $(call SubmoduleRequiredForFiles,$(ALL_LIB_FILES)))

+ 1 - 1
components/esp32/cpu_start.c

@@ -55,7 +55,7 @@ static bool app_cpu_started = false;
 static void do_global_ctors(void);
 static void main_task(void* args);
 extern void ets_setup_syscalls(void);
-extern int app_main(void);
+extern void app_main(void);
 
 extern int _bss_start;
 extern int _bss_end;

+ 3 - 2
components/esp32/include/esp_event.h

@@ -19,8 +19,7 @@
 #include <stdbool.h>
 
 #include "esp_err.h"
-#include "esp_wifi.h"
-
+#include "esp_wifi_types.h"
 #include "tcpip_adapter.h"
 
 #ifdef __cplusplus
@@ -105,6 +104,8 @@ typedef struct {
     system_event_info_t   event_info;    /**< event information */
 } system_event_t;
 
+typedef esp_err_t (*system_event_handler_t)(system_event_t *event);
+
 /**
   * @brief  Send a event to event task
   *

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

@@ -61,98 +61,22 @@
 #include <stdbool.h>
 #include "freertos/FreeRTOS.h"
 #include "freertos/queue.h"
-#include "esp_err.h"
 #include "rom/queue.h"
+#include "esp_err.h"
+#include "esp_wifi_types.h"
+#include "esp_event.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef enum {
-    WIFI_MODE_NULL = 0,  /**< null mode */
-    WIFI_MODE_STA,       /**< WiFi station mode */
-    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
-    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
-    WIFI_MODE_MAX
-} wifi_mode_t;
-
-typedef enum {
-    WIFI_IF_STA = 0,     /**< ESP32 station interface */
-    WIFI_IF_AP,          /**< ESP32 soft-AP interface */
-    WIFI_IF_MAX
-} wifi_interface_t;
-
-typedef enum {
-    WIFI_COUNTRY_CN = 0, /**< country China, channel range [1, 14] */
-    WIFI_COUNTRY_JP,     /**< country Japan, channel range [1, 14] */
-    WIFI_COUNTRY_US,     /**< country USA, channel range [1, 11] */
-    WIFI_COUNTRY_EU,     /**< country Europe, channel range [1, 13] */
-    WIFI_COUNTRY_MAX
-} wifi_country_t;
-
-typedef enum {
-    WIFI_AUTH_OPEN = 0,      /**< authenticate mode : open */
-    WIFI_AUTH_WEP,           /**< authenticate mode : WEP */
-    WIFI_AUTH_WPA_PSK,       /**< authenticate mode : WPA_PSK */
-    WIFI_AUTH_WPA2_PSK,      /**< authenticate mode : WPA2_PSK */
-    WIFI_AUTH_WPA_WPA2_PSK,  /**< authenticate mode : WPA_WPA2_PSK */
-    WIFI_AUTH_MAX
-} wifi_auth_mode_t;
-
-enum {
-    WIFI_REASON_UNSPECIFIED              = 1,
-    WIFI_REASON_AUTH_EXPIRE              = 2,
-    WIFI_REASON_AUTH_LEAVE               = 3,
-    WIFI_REASON_ASSOC_EXPIRE             = 4,
-    WIFI_REASON_ASSOC_TOOMANY            = 5,
-    WIFI_REASON_NOT_AUTHED               = 6,
-    WIFI_REASON_NOT_ASSOCED              = 7,
-    WIFI_REASON_ASSOC_LEAVE              = 8,
-    WIFI_REASON_ASSOC_NOT_AUTHED         = 9,
-    WIFI_REASON_DISASSOC_PWRCAP_BAD      = 10,
-    WIFI_REASON_DISASSOC_SUPCHAN_BAD     = 11,
-    WIFI_REASON_IE_INVALID               = 13,
-    WIFI_REASON_MIC_FAILURE              = 14,
-    WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT   = 15,
-    WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,
-    WIFI_REASON_IE_IN_4WAY_DIFFERS       = 17,
-    WIFI_REASON_GROUP_CIPHER_INVALID     = 18,
-    WIFI_REASON_PAIRWISE_CIPHER_INVALID  = 19,
-    WIFI_REASON_AKMP_INVALID             = 20,
-    WIFI_REASON_UNSUPP_RSN_IE_VERSION    = 21,
-    WIFI_REASON_INVALID_RSN_IE_CAP       = 22,
-    WIFI_REASON_802_1X_AUTH_FAILED       = 23,
-    WIFI_REASON_CIPHER_SUITE_REJECTED    = 24,
-
-    WIFI_REASON_BEACON_TIMEOUT           = 200,
-    WIFI_REASON_NO_AP_FOUND              = 201,
-    WIFI_REASON_AUTH_FAIL                = 202,
-    WIFI_REASON_ASSOC_FAIL               = 203,
-    WIFI_REASON_HANDSHAKE_TIMEOUT        = 204,
-};
-
-typedef enum {
-    WIFI_SECOND_CHAN_NONE = 0,  /**< the channel width is HT20 */
-    WIFI_SECOND_CHAN_ABOVE,     /**< the channel width is HT40 and the second channel is above the primary channel */
-    WIFI_SECOND_CHAN_BELOW,     /**< the channel width is HT40 and the second channel is below the primary channel */
-} wifi_second_chan_t;
-
-
 typedef struct {
-    QueueHandle_t event_queue;        /**< WiFi event queue handle */
-    uint8_t rx_ba_win;                /**< TBC */
-    uint8_t tx_ba_win;                /**< TBC */
-    uint8_t rx_buf_cnt;               /**< TBC */
-    uint8_t tx_buf_cnt;               /**< TBC */
+    system_event_handler_t event_handler;  /**< WiFi event handler */
 } wifi_init_config_t;
 
 
-#define WIFI_INIT_CONFIG_DEFAULT(event_queue_) { \
-    .event_queue = event_queue_, \
-    .rx_ba_win = 0, \
-    .tx_ba_win = 0, \
-    .rx_buf_cnt = 0, \
-    .tx_buf_cnt = 0 \
+#define WIFI_INIT_CONFIG_DEFAULT() { \
+    .event_handler = &esp_event_send, \
 };
 
 /**
@@ -165,7 +89,6 @@ typedef struct {
   *               to this queue when event happens, such as, when station connects to WiFi, WiFi driver
   *               will post station connected event to this queue. If the queue is not initialized, WiFi
   *               will not post any events
-  * @attention 3. For other parameters, currently it's not ready, just ignore it.
   *
   * @param  wifi_init_config_t *config : provide WiFi init configuration
   *
@@ -277,13 +200,6 @@ esp_err_t esp_wifi_clear_fast_connect(void);
   */
 esp_err_t esp_wifi_kick_station(uint16_t aid);
 
-typedef struct {
-    char *ssid;          /**< SSID of AP */
-    uint8_t *bssid;      /**< MAC address of AP */
-    uint8_t channel;     /**< channel, scan the specific channel */
-    bool show_hidden;    /**< enable to scan AP whose SSID is hidden */
-} wifi_scan_config_t;
-
 /**
   * @brief     Scan all available APs.
   *
@@ -321,15 +237,6 @@ esp_err_t esp_wifi_scan_stop(void);
   */
 esp_err_t esp_wifi_get_ap_num(uint16_t *number);
 
-typedef struct {
-    uint8_t bssid[6];                     /**< MAC address of AP */
-    uint8_t ssid[32];                     /**< SSID of AP */
-    uint8_t primary;                      /**< channel of AP */
-    wifi_second_chan_t second;            /**< second channel of AP */
-    int8_t  rssi;                         /**< signal strength of AP */
-    wifi_auth_mode_t authmode;            /**< authmode of AP */
-} wifi_ap_list_t;
-
 /**
   * @brief     Get AP list found in last scan
   *
@@ -342,13 +249,6 @@ typedef struct {
   */
 esp_err_t esp_wifi_get_ap_list(uint16_t *number, wifi_ap_list_t *ap_list);
 
-typedef enum {
-    WIFI_PS_NONE,    /**< No power save */
-    WIFI_PS_MODEM,   /**< Modem power save */
-    WIFI_PS_LIGHT,   /**< Light power save */
-    WIFI_PS_MAC,     /**< MAC power save */
-} wifi_ps_type_t;
-
 /**
   * @brief     Set current power save type
   *
@@ -369,10 +269,6 @@ esp_err_t esp_wifi_set_ps(wifi_ps_type_t type);
   */
 esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type);
 
-#define WIFI_PROTOCOL_11B         1
-#define WIFI_PROTOCOL_11G         2
-#define WIFI_PROTOCOL_11N         4
-
 /**
   * @brief     Set protocol type of specified interface
   *            The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N)
@@ -398,11 +294,6 @@ esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap);
   */
 esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap);
 
-typedef enum {
-    WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */
-    WIFI_BW_HT40,     /* Bandwidth is HT40 */
-} wifi_bandwidth_t;
-
 /**
   * @brief     Set the bandwidth of ESP32 specified interface
   *
@@ -531,45 +422,22 @@ esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
 /**
   * @brief     Enable the promiscuous mode.
   *
-  * @param     uint8 promiscuous : 0 - disable / 1 - enable
+  * @param     bool promiscuous : false - disable / true - enable
   *
   * @return    ESP_OK : succeed
   * @return    others : fail
   */
-esp_err_t esp_wifi_set_promiscuous(uint8_t enable);
+esp_err_t esp_wifi_set_promiscuous(bool en);
 
 /**
   * @brief     Get the promiscuous mode.
   *
-  * @param     uint8 *enable : store the current status of promiscuous mode
+  * @param     bool *enable : store the current status of promiscuous mode
   *
   * @return    ESP_OK : succeed
   * @return    others : fail
   */
-esp_err_t esp_wifi_get_promiscuous(uint8_t *enable);
-
-typedef struct {
-    char ssid[32];              /**< SSID of ESP32 soft-AP */
-    char password[64];          /**< Password of ESP32 soft-AP */
-    uint8_t ssid_len;           /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */
-    uint8_t channel;            /**< Channel of ESP32 soft-AP */
-    wifi_auth_mode_t authmode;  /**< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode */
-    uint8_t ssid_hidden;        /**< Broadcast SSID or not, default 0, broadcast the SSID */
-    uint8_t max_connection;     /**< Max number of stations allowed to connect in, default 4, max 4 */
-    uint16_t beacon_interval;   /**< Beacon interval, 100 ~ 60000 ms, default 100 ms */
-} wifi_ap_config_t;
-
-typedef struct {
-    char ssid[32];         /**< SSID of target AP*/
-    char password[64];     /**< password of target AP*/
-    bool bssid_set;        /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/
-    uint8_t bssid[6];     /**< MAC address of target AP*/
-} wifi_sta_config_t;
-
-typedef union {
-    wifi_ap_config_t  ap;  /**< configuration of AP */
-    wifi_sta_config_t sta; /**< configuration of STA */
-} wifi_config_t;
+esp_err_t esp_wifi_get_promiscuous(bool *en);
 
 /**
   * @brief     Set the configuration of the ESP32 STA or AP
@@ -598,11 +466,6 @@ 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];
-};
-
 /**
   * @brief     Get STAs associated with soft-AP
   *
@@ -617,11 +480,6 @@ esp_err_t esp_wifi_get_station_list(struct station_info **station);
 
 esp_err_t esp_wifi_free_station_list(void);
 
-typedef enum {
-    WIFI_STORAGE_FLASH,  /**< all configuration will strore in both memory and flash */
-    WIFI_STORAGE_RAM,    /**< all configuration will only store in the memory */
-} wifi_storage_t;
-
 /**
   * @brief     Set the WiFi API configuration storage type
   *
@@ -678,27 +536,6 @@ esp_err_t esp_wifi_set_auto_connect(bool en);
   */
 esp_err_t esp_wifi_get_auto_connect(bool *en);
 
-/**
-  * @brief     Vendor IE type
-  *
-  */
-typedef enum {
-    WIFI_VND_IE_TYPE_BEACON,
-    WIFI_VND_IE_TYPE_PROBE_REQ,
-    WIFI_VND_IE_TYPE_PROBE_RESP,
-    WIFI_VND_IE_TYPE_ASSOC_REQ,
-    WIFI_VND_IE_TYPE_ASSOC_RESP,
-} wifi_vendor_ie_type_t;
-
-/**
-  * @brief     Vendor IE index
-  *
-  */
-typedef enum {
-    WIFI_VND_IE_ID_0,
-    WIFI_VND_IE_ID_1,
-} wifi_vendor_ie_id_t;
-
 /**
   * @brief     Set vendor specific element
   *

+ 190 - 0
components/esp32/include/esp_wifi_types.h

@@ -0,0 +1,190 @@
+// Copyright 2015-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_WIFI_TYPES_H__
+#define __ESP_WIFI_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "rom/queue.h"
+#include "esp_err.h"
+#include "esp_wifi_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    WIFI_MODE_NULL = 0,  /**< null mode */
+    WIFI_MODE_STA,       /**< WiFi station mode */
+    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
+    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
+    WIFI_MODE_MAX
+} wifi_mode_t;
+
+typedef enum {
+    WIFI_IF_STA = 0,     /**< ESP32 station interface */
+    WIFI_IF_AP,          /**< ESP32 soft-AP interface */
+    WIFI_IF_MAX
+} wifi_interface_t;
+
+typedef enum {
+    WIFI_COUNTRY_CN = 0, /**< country China, channel range [1, 14] */
+    WIFI_COUNTRY_JP,     /**< country Japan, channel range [1, 14] */
+    WIFI_COUNTRY_US,     /**< country USA, channel range [1, 11] */
+    WIFI_COUNTRY_EU,     /**< country Europe, channel range [1, 13] */
+    WIFI_COUNTRY_MAX
+} wifi_country_t;
+
+typedef enum {
+    WIFI_AUTH_OPEN = 0,      /**< authenticate mode : open */
+    WIFI_AUTH_WEP,           /**< authenticate mode : WEP */
+    WIFI_AUTH_WPA_PSK,       /**< authenticate mode : WPA_PSK */
+    WIFI_AUTH_WPA2_PSK,      /**< authenticate mode : WPA2_PSK */
+    WIFI_AUTH_WPA_WPA2_PSK,  /**< authenticate mode : WPA_WPA2_PSK */
+    WIFI_AUTH_MAX
+} wifi_auth_mode_t;
+
+enum {
+    WIFI_REASON_UNSPECIFIED              = 1,
+    WIFI_REASON_AUTH_EXPIRE              = 2,
+    WIFI_REASON_AUTH_LEAVE               = 3,
+    WIFI_REASON_ASSOC_EXPIRE             = 4,
+    WIFI_REASON_ASSOC_TOOMANY            = 5,
+    WIFI_REASON_NOT_AUTHED               = 6,
+    WIFI_REASON_NOT_ASSOCED              = 7,
+    WIFI_REASON_ASSOC_LEAVE              = 8,
+    WIFI_REASON_ASSOC_NOT_AUTHED         = 9,
+    WIFI_REASON_DISASSOC_PWRCAP_BAD      = 10,
+    WIFI_REASON_DISASSOC_SUPCHAN_BAD     = 11,
+    WIFI_REASON_IE_INVALID               = 13,
+    WIFI_REASON_MIC_FAILURE              = 14,
+    WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT   = 15,
+    WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,
+    WIFI_REASON_IE_IN_4WAY_DIFFERS       = 17,
+    WIFI_REASON_GROUP_CIPHER_INVALID     = 18,
+    WIFI_REASON_PAIRWISE_CIPHER_INVALID  = 19,
+    WIFI_REASON_AKMP_INVALID             = 20,
+    WIFI_REASON_UNSUPP_RSN_IE_VERSION    = 21,
+    WIFI_REASON_INVALID_RSN_IE_CAP       = 22,
+    WIFI_REASON_802_1X_AUTH_FAILED       = 23,
+    WIFI_REASON_CIPHER_SUITE_REJECTED    = 24,
+
+    WIFI_REASON_BEACON_TIMEOUT           = 200,
+    WIFI_REASON_NO_AP_FOUND              = 201,
+    WIFI_REASON_AUTH_FAIL                = 202,
+    WIFI_REASON_ASSOC_FAIL               = 203,
+    WIFI_REASON_HANDSHAKE_TIMEOUT        = 204,
+};
+
+typedef enum {
+    WIFI_SECOND_CHAN_NONE = 0,  /**< the channel width is HT20 */
+    WIFI_SECOND_CHAN_ABOVE,     /**< the channel width is HT40 and the second channel is above the primary channel */
+    WIFI_SECOND_CHAN_BELOW,     /**< the channel width is HT40 and the second channel is below the primary channel */
+} wifi_second_chan_t;
+
+typedef struct {
+    char *ssid;          /**< SSID of AP */
+    uint8_t *bssid;      /**< MAC address of AP */
+    uint8_t channel;     /**< channel, scan the specific channel */
+    bool show_hidden;    /**< enable to scan AP whose SSID is hidden */
+} wifi_scan_config_t;
+
+typedef struct {
+    uint8_t bssid[6];                     /**< MAC address of AP */
+    uint8_t ssid[32];                     /**< SSID of AP */
+    uint8_t primary;                      /**< channel of AP */
+    wifi_second_chan_t second;            /**< second channel of AP */
+    int8_t  rssi;                         /**< signal strength of AP */
+    wifi_auth_mode_t authmode;            /**< authmode of AP */
+} wifi_ap_list_t;
+
+typedef enum {
+    WIFI_PS_NONE,    /**< No power save */
+    WIFI_PS_MODEM,   /**< Modem power save */
+    WIFI_PS_LIGHT,   /**< Light power save */
+    WIFI_PS_MAC,     /**< MAC power save */
+} wifi_ps_type_t;
+
+#define WIFI_PROTOCOL_11B         1
+#define WIFI_PROTOCOL_11G         2
+#define WIFI_PROTOCOL_11N         4
+
+typedef enum {
+    WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */
+    WIFI_BW_HT40,     /* Bandwidth is HT40 */
+} wifi_bandwidth_t;
+
+typedef struct {
+    char ssid[32];              /**< SSID of ESP32 soft-AP */
+    char password[64];          /**< Password of ESP32 soft-AP */
+    uint8_t ssid_len;           /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */
+    uint8_t channel;            /**< Channel of ESP32 soft-AP */
+    wifi_auth_mode_t authmode;  /**< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode */
+    uint8_t ssid_hidden;        /**< Broadcast SSID or not, default 0, broadcast the SSID */
+    uint8_t max_connection;     /**< Max number of stations allowed to connect in, default 4, max 4 */
+    uint16_t beacon_interval;   /**< Beacon interval, 100 ~ 60000 ms, default 100 ms */
+} wifi_ap_config_t;
+
+typedef struct {
+    char ssid[32];         /**< SSID of target AP*/
+    char password[64];     /**< password of target AP*/
+    bool bssid_set;        /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/
+    uint8_t bssid[6];     /**< MAC address of target AP*/
+} wifi_sta_config_t;
+
+typedef union {
+    wifi_ap_config_t  ap;  /**< configuration of AP */
+    wifi_sta_config_t sta; /**< configuration of STA */
+} wifi_config_t;
+
+struct station_info {
+    STAILQ_ENTRY(station_info) next;
+    uint8_t bssid[6];
+};
+
+typedef enum {
+    WIFI_STORAGE_FLASH,  /**< all configuration will strore in both memory and flash */
+    WIFI_STORAGE_RAM,    /**< all configuration will only store in the memory */
+} wifi_storage_t;
+
+/**
+  * @brief     Vendor IE type
+  *
+  */
+typedef enum {
+    WIFI_VND_IE_TYPE_BEACON,
+    WIFI_VND_IE_TYPE_PROBE_REQ,
+    WIFI_VND_IE_TYPE_PROBE_RESP,
+    WIFI_VND_IE_TYPE_ASSOC_REQ,
+    WIFI_VND_IE_TYPE_ASSOC_RESP,
+} wifi_vendor_ie_type_t;
+
+/**
+  * @brief     Vendor IE index
+  *
+  */
+typedef enum {
+    WIFI_VND_IE_ID_0,
+    WIFI_VND_IE_ID_1,
+} wifi_vendor_ie_id_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __ESP_WIFI_TYPES_H__ */

+ 1 - 1
components/esp32/lib

@@ -1 +1 @@
-Subproject commit f6d558367a08b6c9b18c2de515bd0a6740d2c45c
+Subproject commit a6967f4c1bac9269eb6651e84f2cebf81eb5f982

+ 37 - 0
components/mbedtls/Kconfig

@@ -0,0 +1,37 @@
+menu "mbedTLS"
+
+config MBEDTLS_SSL_MAX_CONTENT_LEN
+    int "TLS maximum message content length"
+	default 16384
+    range 512 16384
+    help
+        Maximum TLS message length (in bytes) supported by mbedTLS.
+        
+        16384 is the default and this value is required to comply
+        fully with TLS standards.
+        
+        However you can set a lower value in order to save RAM. This
+        is safe if the other end of the connection supports Maximum
+        Fragment Length Negotiation Extension (max_fragment_length,
+        see RFC6066) or you know for certain that it will never send a
+        message longer than a certain number of bytes.
+        
+        If the value is set too low, symptoms are a failed TLS
+        handshake or a return value of MBEDTLS_ERR_SSL_INVALID_RECORD
+        (-0x7200).
+
+config MBEDTLS_DEBUG
+   bool "Enable mbedTLS debugging"
+   default "no"
+   help
+       Enable mbedTLS debugging functions.
+       
+       If this option is enabled, use the mbedtls_debug_set_threshold()
+       and mbedtls_ssl_conf_dbg() functions to obtain debugging output
+       from mbedTLS.
+       
+       Note thatm mbedTLS debugging is not related to the ESP logging
+       functionality. See the "https_request_main" example for a
+       sample function which connects the two together.
+
+endmenu

+ 5 - 1
components/mbedtls/port/include/mbedtls/esp_config.h

@@ -27,6 +27,8 @@
 #ifndef MBEDTLS_CONFIG_H
 #define MBEDTLS_CONFIG_H
 
+#include "sdkconfig.h"
+
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
@@ -1659,7 +1661,9 @@
  *
  * This module provides debugging functions.
  */
+#if CONFIG_MBEDTLS_DEBUG
 #define MBEDTLS_DEBUG_C
+#endif
 
 /**
  * \def MBEDTLS_DES_C
@@ -2481,7 +2485,7 @@
 
 /* SSL options */
 
-#define MBEDTLS_SSL_MAX_CONTENT_LEN             5120 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+#define MBEDTLS_SSL_MAX_CONTENT_LEN             CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
 //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
 //#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
 //#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */

+ 18 - 1
components/nvs_flash/include/nvs_flash.h

@@ -18,7 +18,24 @@
 extern "C" {
 #endif
 
-esp_err_t nvs_flash_init(uint32_t baseSector, uint32_t sectorCount);
+/** Initialise NVS flash storage with default flash sector layout
+
+    Temporarily, this region is hardcoded as a 12KB (0x3000 byte)
+    region starting at 24KB (0x6000 byte) offset in flash.
+*/
+esp_err_t nvs_flash_init(void);
+
+/** Initialise NVS flash storage with custom flash sector layout
+
+    @param baseSector Flash sector (units of 4096 bytes) offset to start NVS.
+    @param sectorCount Length (in flash sectors) of NVS region.
+
+    @return ESP_OK if flash was successfully initialised.
+
+    @note Use this parameter if you're not using the options in menuconfig for
+          configuring flash layout & partition table.
+*/
+esp_err_t nvs_flash_init_custom(uint32_t baseSector, uint32_t sectorCount);
 
 
 #ifdef __cplusplus

+ 7 - 1
components/nvs_flash/src/nvs_api.cpp

@@ -16,6 +16,7 @@
 #include "nvs_storage.hpp"
 #include "intrusive_list.h"
 #include "nvs_platform.hpp"
+#include "sdkconfig.h"
 
 #ifdef ESP_PLATFORM
 // Uncomment this line to force output from this module
@@ -60,7 +61,12 @@ extern "C" void nvs_dump()
     s_nvs_storage.debugDump();
 }
 
-extern "C" esp_err_t nvs_flash_init(uint32_t baseSector, uint32_t sectorCount)
+extern "C" esp_err_t nvs_flash_init(void)
+{
+    return nvs_flash_init_custom(6, 3);
+}
+
+extern "C" esp_err_t nvs_flash_init_custom(uint32_t baseSector, uint32_t sectorCount)
 {
     Lock::init();
     Lock lock;

+ 7 - 7
components/nvs_flash/test/test_nvs.cpp

@@ -425,7 +425,7 @@ TEST_CASE("nvs api tests", "[nvs]")
     for (uint16_t i = NVS_FLASH_SECTOR; i <NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; ++i) {
         spi_flash_erase_sector(i);
     }
-    TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+    TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
 
     TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND);
 
@@ -468,7 +468,7 @@ TEST_CASE("wifi test", "[nvs]")
     const uint32_t NVS_FLASH_SECTOR = 5;
     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
     emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
-    TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+    TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
     
     nvs_handle misc_handle;
     TEST_ESP_OK(nvs_open("nvs.net80211", NVS_READWRITE, &misc_handle));
@@ -610,7 +610,7 @@ TEST_CASE("can init storage from flash with random contents", "[nvs]")
     const uint32_t NVS_FLASH_SECTOR = 5;
     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
     emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
-    TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+    TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
     
     TEST_ESP_OK(nvs_open("nvs.net80211", NVS_READWRITE, &handle));
     
@@ -631,7 +631,7 @@ TEST_CASE("nvs api tests, starting with random data in flash", "[nvs][.][long]")
         const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
         emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
         
-        TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+        TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
         
         nvs_handle handle_1;
         TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND);
@@ -867,7 +867,7 @@ TEST_CASE("monkey test", "[nvs][monkey]")
     const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 3;
     emu.setBounds(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN);
     
-    TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+    TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
     
     nvs_handle handle;
     TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
@@ -909,7 +909,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
             }
         }
         
-        TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+        TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
 
         nvs_handle handle;
         TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
@@ -921,7 +921,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
         }
         nvs_close(handle);
         
-        TEST_ESP_OK(nvs_flash_init(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
+        TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
         TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
         auto res = test.doRandomThings(handle, gen, count);
         if (res != ESP_OK) {

+ 1 - 1
components/tcpip_adapter/include/tcpip_adapter.h

@@ -17,7 +17,7 @@
 
 #include <stdint.h>
 #include "rom/queue.h"
-#include "esp_wifi.h"
+#include "esp_wifi_types.h"
 
 #define CONFIG_TCPIP_LWIP 1
 #define CONFIG_DHCP_STA_LIST 1

+ 196 - 0
docs/contributor-agreement.rst

@@ -0,0 +1,196 @@
+Contributor Agreement
+---------------------
+
+Individual Contributor Non-Exclusive License Agreement
+------------------------------------------------------
+
+including the Traditional Patent License OPTION
+-----------------------------------------------
+
+Thank you for your interest in contributing to Espressif IoT Development
+Framework (esp-idf) ("We" or "Us").
+
+The purpose of this contributor agreement ("Agreement") is to clarify
+and document the rights granted by contributors to Us. To make this
+document effective, please follow the instructions at
+https://github.com/espressif/esp-idf/blob/master/CONTRIBUTING.md.
+
+1. DEFINITIONS
+~~~~~~~~~~~~~~
+
+**"You"** means the Individual Copyright owner who submits a
+Contribution to Us. If You are an employee and submit the Contribution
+as part of your employment, You have had Your employer approve this
+Agreement or sign the Entity version of this document.
+
+**"Contribution"** means any original work of authorship (software
+and/or documentation) including any modifications or additions to an
+existing work, Submitted by You to Us, in which You own the Copyright.
+If You do not own the Copyright in the entire work of authorship, please
+contact Us at angus@espressif.com.
+
+**"Copyright"** means all rights protecting works of authorship owned or
+controlled by You, including copyright, moral and neighboring rights, as
+appropriate, for the full term of their existence including any
+extensions by You.
+
+**"Material"** means the software or documentation made available by Us
+to third parties. When this Agreement covers more than one software
+project, the Material means the software or documentation to which the
+Contribution was Submitted. After You Submit the Contribution, it may be
+included in the Material.
+
+**"Submit"** means any form of physical, electronic, or written
+communication sent to Us, including but not limited to electronic
+mailing lists, source code control systems, and issue tracking systems
+that are managed by, or on behalf of, Us, but excluding communication
+that is conspicuously marked or otherwise designated in writing by You
+as "Not a Contribution."
+
+**"Submission Date"** means the date You Submit a Contribution to Us.
+
+**"Documentation"** means any non-software portion of a Contribution.
+
+2. LICENSE GRANT
+~~~~~~~~~~~~~~~~
+
+2.1 Copyright License to Us
+
+Subject to the terms and conditions of this Agreement, You hereby grant
+to Us a worldwide, royalty-free, NON-exclusive, perpetual and
+irrevocable license, with the right to transfer an unlimited number of
+non-exclusive licenses or to grant sublicenses to third parties, under
+the Copyright covering the Contribution to use the Contribution by all
+means, including, but not limited to:
+
+-  to publish the Contribution,
+-  to modify the Contribution, to prepare derivative works based upon or
+   containing the Contribution and to combine the Contribution with
+   other software code,
+-  to reproduce the Contribution in original or modified form,
+-  to distribute, to make the Contribution available to the public,
+   display and publicly perform the Contribution in original or modified
+   form.
+
+2.2 Moral Rights remain unaffected to the extent they are recognized and
+not waivable by applicable law. Notwithstanding, You may add your name
+in the header of the source code files of Your Contribution and We will
+respect this attribution when using Your Contribution.
+
+3. PATENTS
+~~~~~~~~~~
+
+3.1 Patent License
+
+Subject to the terms and conditions of this Agreement You hereby grant
+to us a worldwide, royalty-free, non-exclusive, perpetual and
+irrevocable (except as stated in Section 3.2) patent license, with the
+right to transfer an unlimited number of non-exclusive licenses or to
+grant sublicenses to third parties, to make, have made, use, sell, offer
+for sale, import and otherwise transfer the Contribution and the
+Contribution in combination with the Material (and portions of such
+combination). This license applies to all patents owned or controlled by
+You, whether already acquired or hereafter acquired, that would be
+infringed by making, having made, using, selling, offering for sale,
+importing or otherwise transferring of Your Contribution(s) alone or by
+combination of Your Contribution(s) with the Material.
+
+3.2 Revocation of Patent License
+
+You reserve the right to revoke the patent license stated in section 3.1
+if we make any infringement claim that is targeted at your Contribution
+and not asserted for a Defensive Purpose. An assertion of claims of the
+Patents shall be considered for a "Defensive Purpose" if the claims are
+asserted against an entity that has filed, maintained, threatened, or
+voluntarily participated in a patent infringement lawsuit against Us or
+any of Our licensees.
+
+
+4. DISCLAIMER
+~~~~~~~~~~~~~
+
+THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR
+IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU.
+TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH
+WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD PERMITTED BY LAW.
+
+5. Consequential Damage Waiver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU
+OR US BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS,
+LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY
+DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR
+EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS
+BASED.
+
+6. Approximation of Disclaimer and Damage Waiver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 4 AND SECTION 5
+CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING
+COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE
+WAIVER OF ALL CIVIL LIABILITY IN CONNECTION WITH THE CONTRIBUTION.
+
+7. Term
+~~~~~~~
+
+7.1 This Agreement shall come into effect upon Your acceptance of the
+terms and conditions.
+
+7.2 In the event of a termination of this Agreement Sections 4, 5, 6, 7
+and 8 shall survive such termination and shall remain in full force
+thereafter. For the avoidance of doubt, Contributions that are already
+licensed under a free and open source license at the date of the
+termination shall remain in full force after the termination of this
+Agreement.
+
+8. Miscellaneous
+~~~~~~~~~~~~~~~~
+
+8.1 This Agreement and all disputes, claims, actions, suits or other
+proceedings arising out of this agreement or relating in any way to it
+shall be governed by the laws of People's Republic of China excluding
+its private international law provisions.
+
+8.2 This Agreement sets out the entire agreement between You and Us for
+Your Contributions to Us and overrides all other agreements or
+understandings.
+
+8.3 If any provision of this Agreement is found void and unenforceable,
+such provision will be replaced to the extent possible with a provision
+that comes closest to the meaning of the original provision and that is
+enforceable. The terms and conditions set forth in this Agreement shall
+apply notwithstanding any failure of essential purpose of this Agreement
+or any limited remedy to the maximum extent possible under law.
+
+8.4 You agree to notify Us of any facts or circumstances of which you
+become aware that would make this Agreement inaccurate in any respect.
+
+.. rubric:: You
+   :name: you
+
++------------+----+
+| Date:      |    |
++------------+----+
+| Name:      |    |
++------------+----+
+| Title:     |    |
++------------+----+
+| Address:   |    |
++------------+----+
+
+.. rubric:: Us
+   :name: us
+
++------------+----+
+| Date:      |    |
++------------+----+
+| Name:      |    |
++------------+----+
+| Title:     |    |
++------------+----+
+| Address:   |    |
++------------+----+

+ 10 - 0
docs/partition-tables.rst

@@ -12,6 +12,16 @@ The simplest way to use the partition table is to `make menuconfig` and choose o
 
 In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
 
+Known Issues
+------------
+
+The below design document outlines the goals for the partition table system. At the moment, only some features are used:
+
+- data partition types "rf" & "wifi" are unused and can be entirely omitted to save space.
+- NVS (non-volatile-storage) uses a hardcoded 12KB (0x3000 byte) region at offset 0x6000.
+
+Once a full user API is in place for partition access, these limitations will be resolved and you'll be able to use the partition mechanism fully for storing data in flash.
+
 Built-in Partition Tables
 -------------------------
 

+ 9 - 0
examples/01_hello_world/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 := hello-world
+
+include $(IDF_PATH)/make/project.mk
+

+ 5 - 0
examples/01_hello_world/README.md

@@ -0,0 +1,5 @@
+# Hello World Example
+
+Starts a FreeRTOS task to print "Hello World"
+
+See the README.md file in the upper level 'examples' directory for more information about examples.

+ 0 - 0
examples/04_ble_adv/main/component.mk → examples/01_hello_world/main/component.mk


+ 32 - 0
examples/01_hello_world/main/hello_world_main.c

@@ -0,0 +1,32 @@
+/* Hello World Example
+
+   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 <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "nvs_flash.h"
+
+void hello_task(void *pvParameter)
+{
+    printf("Hello world!\n");
+    for (int i = 10; i >= 0; i--) {
+        printf("Restarting in %d seconds...\n", i);
+        vTaskDelay(1000 / portTICK_RATE_MS);
+    }
+    printf("Restarting now.\n");
+    fflush(stdout);
+    system_restart();
+}
+
+void app_main()
+{
+    nvs_flash_init();
+    system_init();
+    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
+}

+ 1 - 1
examples/04_ble_adv/Makefile → examples/02_blink/Makefile

@@ -3,7 +3,7 @@
 # project subdirectory.
 #
 
-PROJECT_NAME := ble_adv
+PROJECT_NAME := blink
 
 include $(IDF_PATH)/make/project.mk
 

+ 5 - 0
examples/02_blink/README.md

@@ -0,0 +1,5 @@
+# Blink Example
+
+Starts a FreeRTOS task to blink an LED
+
+See the README.md file in the upper level 'examples' directory for more information about examples.

+ 14 - 0
examples/02_blink/main/Kconfig.projbuild

@@ -0,0 +1,14 @@
+menu "Example Configuration"
+
+config BLINK_GPIO
+    int "Blink GPIO number"
+	range 0 34
+	default 5
+	help
+		GPIO number (IOxx) to blink on and off.
+
+		Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink.
+
+		GPIOs 35-39 are input-only so cannot be used as outputs.
+
+endmenu

+ 48 - 0
examples/02_blink/main/blink.c

@@ -0,0 +1,48 @@
+/* Blink Example
+
+   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 <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_system.h"
+#include "nvs_flash.h"
+#include "driver/gpio.h"
+#include "sdkconfig.h"
+
+/* Can run 'make menuconfig' to choose the GPIO to blink,
+   or you can edit the following line and set a number here.
+*/
+#define BLINK_GPIO CONFIG_BLINK_GPIO
+
+void blink_task(void *pvParameter)
+{
+    /* Configure the IOMUX register for pad BLINK_GPIO (some pads are
+       muxed to GPIO on reset already, but some default to other
+       functions and need to be switched to GPIO. Consult the
+       Technical Reference for a list of pads and their default
+       functions.)
+    */
+    gpio_pad_select_gpio(BLINK_GPIO);
+    /* Set the GPIO as a push/pull output */
+    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
+    while(1) {
+        /* Blink off (output low) */
+        gpio_set_level(BLINK_GPIO, 0);
+        vTaskDelay(1000 / portTICK_RATE_MS);
+        /* Blink on (output high) */
+        gpio_set_level(BLINK_GPIO, 1);
+        vTaskDelay(1000 / portTICK_RATE_MS);
+    }
+}
+
+void app_main()
+{
+    nvs_flash_init();
+    system_init();
+    xTaskCreate(&blink_task, "blink_task", 512, NULL, 5, NULL);
+}

+ 10 - 0
examples/02_blink/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this 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.
+#
+
+include $(IDF_PATH)/make/component_common.mk

+ 9 - 0
examples/03_http_request/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 := http-request
+
+include $(IDF_PATH)/make/project.mk
+

+ 5 - 0
examples/03_http_request/README.md

@@ -0,0 +1,5 @@
+# HTTP Request Example
+
+Uses a POSIX socket to make a very simple HTTP request.
+
+See the README.md file in the upper level 'examples' directory for more information about examples.

+ 17 - 0
examples/03_http_request/main/Kconfig.projbuild

@@ -0,0 +1,17 @@
+menu "Example Configuration"
+
+config WIFI_SSID
+    string "WiFi SSID"
+	default "myssid"
+	help
+		SSID (network name) for the example to connect to.
+
+config WIFI_PASSWORD
+    string "WiFi Password"
+	default "myssid"
+	help
+		WiFi password (WPA or WPA2) for the example to use.
+
+		Can be left blank if the network has no security set.
+
+endmenu

+ 10 - 0
examples/03_http_request/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this 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.
+#
+
+include $(IDF_PATH)/make/component_common.mk

+ 181 - 0
examples/03_http_request/main/http_request_main.c

@@ -0,0 +1,181 @@
+/* HTTP GET Example using plain POSIX sockets
+
+   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 "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include "lwip/netdb.h"
+#include "lwip/dns.h"
+
+/* The examples use simple WiFi configuration that you can set via
+   'make menuconfig'.
+
+   If you'd rather not, just change the below entries to strings with
+   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
+*/
+#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
+#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
+
+/* FreeRTOS event group to signal when we are connected & ready to make a request */
+static EventGroupHandle_t wifi_event_group;
+
+/* The event group allows multiple bits for each event,
+   but we only care about one event - are we connected
+   to the AP with an IP? */
+const int CONNECTED_BIT = BIT0;
+
+/* Constants that aren't configurable in menuconfig */
+#define WEB_SERVER "example.com"
+#define WEB_PORT 80
+#define WEB_URL "http://example.com/"
+
+static const char *TAG = "example";
+
+static const char *REQUEST = "GET " WEB_URL " HTTP/1.1\n"
+    "Host: "WEB_SERVER"\n"
+    "User-Agent: esp-idf/1.0 esp32\n"
+    "\n";
+
+static esp_err_t event_handler(void *ctx, system_event_t *event)
+{
+    switch(event->event_id) {
+    case SYSTEM_EVENT_STA_START:
+        esp_wifi_connect();
+        break;
+    case SYSTEM_EVENT_STA_GOT_IP:
+        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
+        break;
+    case SYSTEM_EVENT_STA_DISCONNECTED:
+        /* This is a workaround as ESP32 WiFi libs don't currently
+           auto-reassociate. */
+        esp_wifi_connect();
+        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
+        break;
+    default:
+        break;
+    }
+    return ESP_OK;
+}
+
+static void initialise_wifi(void)
+{
+    tcpip_adapter_init();
+    wifi_event_group = xEventGroupCreate();
+    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
+    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
+    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
+    wifi_config_t wifi_config = {
+        .sta = {
+            .ssid = EXAMPLE_WIFI_SSID,
+            .password = EXAMPLE_WIFI_PASS,
+        },
+    };
+    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
+    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
+    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
+    ESP_ERROR_CHECK( esp_wifi_start() );
+}
+
+static void http_get_task(void *pvParameters)
+{
+    const struct addrinfo hints = {
+        .ai_family = AF_INET,
+        .ai_socktype = SOCK_STREAM,
+    };
+    struct addrinfo *res;
+    struct in_addr *addr;
+    int s, r;
+    char recv_buf[64];
+
+    while(1) {
+        /* Wait for the callback to set the CONNECTED_BIT in the
+           event group.
+        */
+        xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
+                            false, true, portMAX_DELAY);
+        ESP_LOGI(TAG, "Connected to AP");
+
+        int err = getaddrinfo(WEB_SERVER, "80", &hints, &res);
+
+        if(err != 0 || res == NULL) {
+            ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
+            vTaskDelay(1000 / portTICK_RATE_MS);
+            continue;
+        }
+
+        /* Code to print the resolved IP.
+
+           Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
+        addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
+        ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));
+
+        s = socket(res->ai_family, res->ai_socktype, 0);
+        if(s < 0) {
+            ESP_LOGE(TAG, "... Failed to allocate socket.");
+            freeaddrinfo(res);
+            vTaskDelay(1000 / portTICK_RATE_MS);
+            continue;
+        }
+        ESP_LOGI(TAG, "... allocated socket\r\n");
+
+        if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
+            ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
+            close(s);
+            freeaddrinfo(res);
+            vTaskDelay(4000 / portTICK_RATE_MS);
+            continue;
+        }
+
+        ESP_LOGI(TAG, "... connected");
+        freeaddrinfo(res);
+
+        if (write(s, REQUEST, strlen(REQUEST)) < 0) {
+            ESP_LOGE(TAG, "... socket send failed");
+            close(s);
+            vTaskDelay(4000 / portTICK_RATE_MS);
+            continue;
+        }
+        ESP_LOGI(TAG, "... socket send success");
+
+        /* Read HTTP response */
+        do {
+            bzero(recv_buf, sizeof(recv_buf));
+            r = read(s, recv_buf, sizeof(recv_buf)-1);
+            for(int i = 0; i < r; i++) {
+                putchar(recv_buf[i]);
+            }
+        } while(r > 0);
+
+        ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
+        close(s);
+        for(int countdown = 10; countdown >= 0; countdown--) {
+            ESP_LOGI(TAG, "%d... ", countdown);
+            vTaskDelay(1000 / portTICK_RATE_MS);
+        }
+        ESP_LOGI(TAG, "Starting again!");
+    }
+}
+
+void app_main()
+{
+    nvs_flash_init();
+    system_init();
+    initialise_wifi();
+    xTaskCreate(&http_get_task, "http_get_task", 2048, NULL, 5, NULL);
+}

+ 9 - 0
examples/04_https_request/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 := https-request
+
+include $(IDF_PATH)/make/project.mk
+

+ 5 - 0
examples/04_https_request/README.md

@@ -0,0 +1,5 @@
+# HTTPS Request Example
+
+Uses an mbedTLS socket to make a very simple HTTPS request over a secure connection, including verifying the server TLS certificate.
+
+See the README.md file in the upper level 'examples' directory for more information about examples.

+ 17 - 0
examples/04_https_request/main/Kconfig.projbuild

@@ -0,0 +1,17 @@
+menu "Example Configuration"
+
+config WIFI_SSID
+    string "WiFi SSID"
+	default "myssid"
+	help
+		SSID (network name) for the example to connect to.
+
+config WIFI_PASSWORD
+    string "WiFi Password"
+	default "myssid"
+	help
+		WiFi password (WPA or WPA2) for the example to use.
+
+		Can be left blank if the network has no security set.
+
+endmenu

+ 44 - 0
examples/04_https_request/main/cert.c

@@ -0,0 +1,44 @@
+/* This is the CA certificate for the CA trust chain of
+   www.howsmyssl.com in PEM format, as dumped via:
+
+   openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
+
+   The CA cert is the last cert in the chain output by the server.
+*/
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+/*
+ 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
+   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
+ */
+const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n"
+"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\r\n"
+"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\r\n"
+"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\r\n"
+"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\r\n"
+"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n"
+"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\r\n"
+"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\r\n"
+"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\r\n"
+"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\r\n"
+"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\r\n"
+"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\r\n"
+"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\r\n"
+"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\r\n"
+"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\r\n"
+"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\r\n"
+"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\r\n"
+"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\r\n"
+"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\r\n"
+"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\r\n"
+"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\r\n"
+"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\r\n"
+"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\r\n"
+"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\r\n"
+"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\r\n"
+"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\r\n"
+"-----END CERTIFICATE-----\r\n";
+
+

+ 10 - 0
examples/04_https_request/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this 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.
+#
+
+include $(IDF_PATH)/make/component_common.mk

+ 363 - 0
examples/04_https_request/main/https_request_main.c

@@ -0,0 +1,363 @@
+/* HTTPS GET Example using plain mbedTLS sockets
+ *
+ * Contacts the howsmyssl.com API via TLS v1.2 and reads a JSON
+ * response.
+ *
+ * Adapted from the ssl_client1 example in mbedtls.
+ *
+ * Original Copyright (C) 2006-2016, ARM Limited, All Rights Reserved, Apache 2.0 License.
+ * Additions Copyright (C) Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License.
+ *
+ *
+ * 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.
+ */
+#include <string.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_wifi.h"
+#include "esp_event_loop.h"
+#include "esp_log.h"
+#include "esp_system.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include "lwip/netdb.h"
+#include "lwip/dns.h"
+
+#include "mbedtls/net.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/certs.h"
+
+/* The examples use simple WiFi configuration that you can set via
+   'make menuconfig'.
+
+   If you'd rather not, just change the below entries to strings with
+   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
+*/
+#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
+#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
+
+/* FreeRTOS event group to signal when we are connected & ready to make a request */
+static EventGroupHandle_t wifi_event_group;
+
+/* The event group allows multiple bits for each event,
+   but we only care about one event - are we connected
+   to the AP with an IP? */
+const int CONNECTED_BIT = BIT0;
+
+/* Constants that aren't configurable in menuconfig */
+#define WEB_SERVER "www.howsmyssl.com"
+#define WEB_PORT "443"
+#define WEB_URL "https://www.howsmyssl.com/a/check"
+
+static const char *TAG = "example";
+
+static const char *REQUEST = "GET " WEB_URL " HTTP/1.1\n"
+    "Host: "WEB_SERVER"\n"
+    "User-Agent: esp-idf/1.0 esp32\n"
+    "\n";
+
+/* Root cert for howsmyssl.com, found in cert.c */
+extern const char *server_root_cert;
+
+#ifdef MBEDTLS_DEBUG_C
+
+#define MBEDTLS_DEBUG_LEVEL 4
+
+/* mbedtls debug function that translates mbedTLS debug output
+   to ESP_LOGx debug output.
+
+   MBEDTLS_DEBUG_LEVEL 4 means all mbedTLS debug output gets sent here,
+   and then filtered to the ESP logging mechanism.
+*/
+static void mbedtls_debug(void *ctx, int level,
+                     const char *file, int line,
+                     const char *str)
+{
+    const char *MBTAG = "mbedtls";
+    char *file_sep;
+
+    /* Shorten 'file' from the whole file path to just the filename
+
+       This is a bit wasteful because the macros are compiled in with
+       the full _FILE_ path in each case.
+    */
+    file_sep = rindex(file, '/');
+    if(file_sep)
+        file = file_sep+1;
+
+    switch(level) {
+    case 1:
+        ESP_LOGI(MBTAG, "%s:%d %s", file, line, str);
+        break;
+    case 2:
+    case 3:
+        ESP_LOGD(MBTAG, "%s:%d %s", file, line, str);
+    case 4:
+        ESP_LOGV(MBTAG, "%s:%d %s", file, line, str);
+        break;
+    default:
+        ESP_LOGE(MBTAG, "Unexpected log level %d: %s", level, str);
+        break;
+    }
+}
+
+#endif
+
+static esp_err_t event_handler(void *ctx, system_event_t *event)
+{
+    switch(event->event_id) {
+    case SYSTEM_EVENT_STA_START:
+        esp_wifi_connect();
+        break;
+    case SYSTEM_EVENT_STA_GOT_IP:
+        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
+        break;
+    case SYSTEM_EVENT_STA_DISCONNECTED:
+        /* This is a workaround as ESP32 WiFi libs don't currently
+           auto-reassociate. */
+        esp_wifi_connect();
+        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
+        break;
+    default:
+        break;
+    }
+    return ESP_OK;
+}
+
+static void initialise_wifi(void)
+{
+    tcpip_adapter_init();
+    wifi_event_group = xEventGroupCreate();
+    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
+    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
+    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
+    wifi_config_t wifi_config = {
+        .sta = {
+            .ssid = EXAMPLE_WIFI_SSID,
+            .password = EXAMPLE_WIFI_PASS,
+        },
+    };
+    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
+    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
+    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
+    ESP_ERROR_CHECK( esp_wifi_start() );
+}
+
+static void https_get_task(void *pvParameters)
+{
+    char buf[512];
+    int ret, flags, len;
+
+    mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctr_drbg;
+    mbedtls_ssl_context ssl;
+    mbedtls_x509_crt cacert;
+    mbedtls_ssl_config conf;
+    mbedtls_net_context server_fd;
+
+    mbedtls_ssl_init(&ssl);
+    mbedtls_x509_crt_init(&cacert);
+    mbedtls_ctr_drbg_init(&ctr_drbg);
+    ESP_LOGI(TAG, "Seeding the random number generator");
+
+    mbedtls_ssl_config_init(&conf);
+
+    mbedtls_entropy_init(&entropy);
+    if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+                                    NULL, 0)) != 0)
+    {
+        ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret);
+        abort();
+    }
+
+    ESP_LOGI(TAG, "Loading the CA root certificate...");
+
+    ret = mbedtls_x509_crt_parse(&cacert, (uint8_t*)server_root_cert, strlen(server_root_cert)+1);
+    if(ret < 0)
+    {
+        ESP_LOGE(TAG, "mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
+        abort();
+    }
+
+    ESP_LOGI(TAG, "Setting hostname for TLS session...");
+
+     /* Hostname set here should match CN in server certificate */
+    if((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0)
+    {
+        ESP_LOGE(TAG, "mbedtls_ssl_set_hostname returned -0x%x", -ret);
+        abort();
+    }
+
+    ESP_LOGI(TAG, "Setting up the SSL/TLS structure...");
+
+    if((ret = mbedtls_ssl_config_defaults(&conf,
+                                          MBEDTLS_SSL_IS_CLIENT,
+                                          MBEDTLS_SSL_TRANSPORT_STREAM,
+                                          MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
+    {
+        ESP_LOGE(TAG, "mbedtls_ssl_config_defaults returned %d", ret);
+        goto exit;
+    }
+
+    /* MBEDTLS_SSL_VERIFY_OPTIONAL is bad for security, in this example it will print
+       a warning if CA verification fails but it will continue to connect.
+
+       You should consider using MBEDTLS_SSL_VERIFY_REQUIRED in your own code.
+    */
+    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
+    mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
+    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
+#ifdef MBEDTLS_DEBUG_C
+    mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL);
+    mbedtls_ssl_conf_dbg(&conf, mbedtls_debug, NULL);
+#endif
+
+    if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0)
+    {
+        ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x\n\n", -ret);
+        goto exit;
+    }
+
+    while(1) {
+        /* Wait for the callback to set the CONNECTED_BIT in the
+           event group.
+        */
+        xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
+                            false, true, portMAX_DELAY);
+        ESP_LOGI(TAG, "Connected to AP");
+
+        mbedtls_net_init(&server_fd);
+
+        ESP_LOGI(TAG, "Connecting to %s:%s...", WEB_SERVER, WEB_PORT);
+
+        if ((ret = mbedtls_net_connect(&server_fd, WEB_SERVER,
+                                      WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0)
+        {
+            ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret);
+            goto exit;
+        }
+
+        ESP_LOGI(TAG, "Connected.");
+
+        mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
+
+        ESP_LOGI(TAG, "Performing the SSL/TLS handshake...");
+
+        while ((ret = mbedtls_ssl_handshake(&ssl)) != 0)
+        {
+            if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
+            {
+                ESP_LOGE(TAG, "mbedtls_ssl_handshake returned -0x%x", -ret);
+                goto exit;
+            }
+        }
+
+        ESP_LOGI(TAG, "Verifying peer X.509 certificate...");
+
+        if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0)
+        {
+            /* In real life, we probably want to close connection if ret != 0 */
+            ESP_LOGW(TAG, "Failed to verify peer certificate!");
+            bzero(buf, sizeof(buf));
+            mbedtls_x509_crt_verify_info(buf, sizeof(buf), "  ! ", flags);
+            ESP_LOGW(TAG, "verification info: %s", buf);
+        }
+        else {
+            ESP_LOGI(TAG, "Certificate verified.");
+        }
+
+        ESP_LOGI(TAG, "Writing HTTP request...");
+
+        while((ret = mbedtls_ssl_write(&ssl, (const unsigned char *)REQUEST, strlen(REQUEST))) <= 0)
+        {
+            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
+            {
+                ESP_LOGE(TAG, "mbedtls_ssl_write returned -0x%x", -ret);
+                goto exit;
+            }
+        }
+
+        len = ret;
+        ESP_LOGI(TAG, "%d bytes written", len);
+        ESP_LOGI(TAG, "Reading HTTP response...");
+
+        do
+        {
+            len = sizeof(buf) - 1;
+            bzero(buf, sizeof(buf));
+            ret = mbedtls_ssl_read(&ssl, (unsigned char *)buf, len);
+
+            if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
+                continue;
+
+            if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+                ret = 0;
+                break;
+            }
+
+            if(ret < 0)
+            {
+                ESP_LOGE(TAG, "mbedtls_ssl_read returned -0x%x", -ret);
+                break;
+            }
+
+            if(ret == 0)
+            {
+                ESP_LOGI(TAG, "connection closed");
+                break;
+            }
+
+            len = ret;
+            ESP_LOGI(TAG, "%d bytes read", len);
+            /* Print response directly to stdout as it is read */
+            for(int i = 0; i < len; i++) {
+                putchar(buf[i]);
+            }
+        } while(1);
+
+        mbedtls_ssl_close_notify(&ssl);
+
+    exit:
+        mbedtls_ssl_session_reset(&ssl);
+        mbedtls_net_free(&server_fd);
+
+        if(ret != 0)
+        {
+            mbedtls_strerror(ret, buf, 100);
+            ESP_LOGE(TAG, "Last error was: -0x%x - %s", -ret, buf);
+        }
+
+        for(int countdown = 10; countdown >= 0; countdown--) {
+            ESP_LOGI(TAG, "%d...", countdown);
+            vTaskDelay(1000 / portTICK_RATE_MS);
+        }
+        ESP_LOGI(TAG, "Starting again!");
+    }
+}
+
+void app_main()
+{
+    nvs_flash_init();
+    system_init();
+    initialise_wifi();
+    xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
+}

+ 16 - 0
examples/05_ble_adv/Makefile

@@ -0,0 +1,16 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := ble_adv
+
+include $(IDF_PATH)/make/project.mk
+
+# Copy some defaults into the sdkconfig by default
+# so BT stack is enabled
+sdkconfig: sdkconfig.defaults
+	$(Q) cp $< $@
+
+menuconfig: sdkconfig
+defconfig: sdkconfig

+ 0 - 0
examples/04_ble_adv/README.rst → examples/05_ble_adv/README.rst


+ 0 - 0
examples/04_ble_adv/main/app_bt.c → examples/05_ble_adv/main/app_bt.c


+ 10 - 0
examples/05_ble_adv/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this 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.
+#
+
+include $(IDF_PATH)/make/component_common.mk

+ 14 - 0
examples/05_ble_adv/sdkconfig.defaults

@@ -0,0 +1,14 @@
+# Override some defaults so BT stack is enabled
+# in this example
+
+#
+# BT config
+#
+CONFIG_BT_ENABLED=y
+
+#
+# ESP32-specific config
+#
+CONFIG_ESP32_ENABLE_STACK_BT=y
+# CONFIG_ESP32_ENABLE_STACK_NONE is not set
+CONFIG_MEMMAP_BT=y

+ 35 - 0
examples/README.md

@@ -0,0 +1,35 @@
+# Examples
+
+This directory contains a growing number of simple example projects for esp-idf. These are intended to show basic esp-idf functionality, and to provide you can use for your own projects.
+
+# Using Examples
+
+Building examples is the same as building any other project:
+
+* Follow the setup instructions in the top-level esp-idf README.
+
+* Set `IDF_PATH` environment variable to point to the path to the esp-idf top-level directory.
+* Change into the directory of the example you'd like to build.
+* `make menuconfig` to configure the example. Most examples require a simple WiFi SSID & password via this configuration.
+* `make` to build the example.
+* Follow the printed instructions to flash, or run `make flash`.
+
+# Copying Examples
+
+Each example is a standalone project. The examples *do not have to be inside the esp-idf directory*. You can copy an example directory to anywhere on your computer in order to make a copy that you can modify and work with.
+
+The `IDF_PATH` environment variable is the only thing that connects the example to the rest of the `esp-idf` system.
+
+If you're looking for a more bare-bones project to start from, try [esp-idf-template](https://github.com/espressif/esp-idf-template).
+
+# Contributing Examples
+
+If you have a new example you think we'd like, please consider sending it to us as a Pull Request.
+
+Please read the esp-idf CONTRIBUTING.md file which lays out general contribution rules.
+
+In addition, here are some tips for creating good examples:
+
+* A good example is documented and the basic options can be configured.
+* A good example does not contain a lot of code. If there is a lot of generic code in the example, consider refactoring that code into a standalone component and then use the component's API in your example.
+* Examples must be licensed under the Apache License 2.0 or (preferably for examples) if possible you can declare the example to be Public Domain / Creative Commons Zero.

+ 31 - 0
make/build_examples.sh

@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# Build all examples from the examples directory, out of tree to
+# ensure they can run when copied to a new directory.
+#
+# Runs as part of CI process.
+#
+# Assumes CWD is an out-of-tree build directory, and will copy examples to individual subdirectories, one by one.
+#
+[ -z ${IDF_PATH} ] && echo "IDF_PATH is not set" && exit 1
+
+EXAMPLE_NUM=1
+RESULT=0
+
+set -e
+
+for example in ${IDF_PATH}/examples/*; do
+	[ -f ${example}/Makefile ] || continue
+	echo "Building ${example} as ${EXAMPLE_NUM}..."
+	mkdir ${EXAMPLE_NUM}
+	cp -r ${example} ${EXAMPLE_NUM}
+	pushd ${EXAMPLE_NUM}/`basename ${example}`
+	# can't do "make defconfig all" as this will trip menuconfig
+	# sometimes
+	make defconfig && make || RESULT=$?
+	popd
+	EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 ))
+done
+
+exit $RESULT
+