diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index aff9bea8d1..ad5a13ad03 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,7 @@
stages:
- build
- test
+ - test_report
- deploy
before_script:
@@ -92,6 +93,20 @@ build_examples:
- cd build_examples
- ${IDF_PATH}/make/build_examples.sh
+build_docs:
+ stage: build
+ image: espressif/esp32-ci-env
+ tags:
+ - build_docs
+ script:
+ - cd docs
+ - make html
+ artifacts:
+ paths:
+ - docs/_build/html
+ expire_in: 1 mos
+
+
test_nvs_on_host:
stage: test
image: espressif/esp32-ci-env
@@ -112,13 +127,12 @@ test_build_system:
- ./make/test_build_system.sh
test_report:
- stage: deploy
+ stage: test_report
only:
- master
- triggers
tags:
- test_report
- allow_failure: true
variables:
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
@@ -127,7 +141,7 @@ test_report:
when: always
paths:
- $REPORT_PATH
- expire_in: 6 mos
+ expire_in: 12 mos
script:
# clone test bench
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
@@ -159,6 +173,31 @@ push_master_to_github:
- git push --follow-tags github HEAD:master
+deploy_docs:
+ before_script:
+ - echo "Not setting up GitLab key, not fetching submodules"
+ stage: deploy
+ only:
+ - master
+ - triggers
+ tags:
+ - deploy
+ image: espressif/esp32-ci-env
+ script:
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+ - echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64
+ - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
+ - chmod 600 ~/.ssh/id_rsa
+ - echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config
+ - export GIT_VER=$(git describe --always)
+ - cd docs/_build/
+ - mv html $GIT_VER
+ - tar czvf $GIT_VER.tar.gz $GIT_VER
+ - scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH
+ - ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
+
+
# AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW
# template for test jobs
.test_template: &test_template
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.rst
similarity index 61%
rename from CONTRIBUTING.md
rename to CONTRIBUTING.rst
index b0af761d53..3bf43f6dbe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.rst
@@ -1,12 +1,15 @@
-# Contributions Guide
+Contributions Guide
+===================
We welcome contributions to the esp-idf project!
-## How to Contribute
+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/).
+Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests `_.
-## Before Contributing
+Before Contributing
+-------------------
Before sending us a Pull Request, please consider this list of points:
@@ -16,15 +19,16 @@ Before sending us a Pull Request, please consider this list of points:
* 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).
+* Is there documentation or examples that go with code contributions? `There are additional suggestions for writing good examples in the examples README `_.
* 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 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 `_?
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
-## Pull Request Process
+Pull Request Process
+--------------------
After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
@@ -32,6 +36,9 @@ Once the Pull Request is ready to merge, it will first be merged into our intern
If this process passes, it will be merged onto the public github repository.
-## Legal Part
+Legal Part
+----------
+
+Before a contribution can be accepted, you will need to sign our `Contributor Agreement `_. You will be prompted for this automatically as part of the Pull Request process.
+
-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.
diff --git a/README.md b/README.md
index ff645c3392..c01e314f11 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Using Espressif IoT Development Framework with the ESP32
+[](http://esp-idf.readthedocs.io/en/latest/?badge=latest)
+
# Setting Up ESP-IDF
In the [docs](docs) directory you will find per-platform setup guides:
@@ -60,14 +62,15 @@ 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.
-For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file.
+For more details about partition tables and how to create custom variations, view the `docs/partition-tables.rst` file.
# Resources
-* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation.
+* The [docs directory of the esp-idf repository](docs) contains source of [esp-idf](http://esp-idf.readthedocs.io/) 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.
+* If you're interested in contributing to esp-idf, please check the [Contributions Guide](http://esp-idf.readthedocs.io/en/latest/contributing.html>).
+
diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h
index 1e89f96aa1..f476334b12 100644
--- a/components/bt/include/bt.h
+++ b/components/bt/include/bt.h
@@ -28,37 +28,36 @@ extern "C" {
*
* This function should be called only once, before any other BT functions are called.
*/
-void bt_controller_init();
+void bt_controller_init(void);
-/** @brief: vhci_host_callback
+/** @brief vhci_host_callback
* used for vhci call host function to notify what host need to do
*
* notify_host_send_available: notify host can send packet to controller
* notify_host_recv: notify host that controller has packet send to host
*/
typedef struct vhci_host_callback {
-
void (*notify_host_send_available)(void);
int (*notify_host_recv)(uint8_t *data, uint16_t len);
} vhci_host_callback_t;
-/** @brief: API_vhci_host_check_send_available
+/** @brief API_vhci_host_check_send_available
* used for check actively if the host can send packet to controller or not.
- * return true for ready to send, false means cannot send packet
+ * @return true for ready to send, false means cannot send packet
*/
bool API_vhci_host_check_send_available(void);
-/** @brief: API_vhci_host_send_packet
+/** @brief API_vhci_host_send_packet
* host send packet to controller
- * param data is the packet point, the param len is the packet length
- * return void
+ * @param data the packet point
+ *,@param len the packet length
*/
void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
-/** @brief: API_vhci_host_register_callback
+/** @brief API_vhci_host_register_callback
* register the vhci referece callback, the call back
* struct defined by vhci_host_callback structure.
- * param is the vhci_host_callback type variable
+ * @param callback vhci_host_callback type variable
*/
void API_vhci_host_register_callback(const vhci_host_callback_t *callback);
diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h
index 5ed99e5976..a31c2f64b7 100644
--- a/components/driver/include/driver/gpio.h
+++ b/components/driver/include/driver/gpio.h
@@ -27,46 +27,44 @@
#ifdef __cplusplus
extern "C" {
#endif
-
extern const char* GPIO_TAG;
+#define GPIO_SEL_0 (BIT(0)) /*!< Pin 0 selected */
+#define GPIO_SEL_1 (BIT(1)) /*!< Pin 1 selected */
+#define GPIO_SEL_2 (BIT(2)) /*!< Pin 2 selected */
+#define GPIO_SEL_3 (BIT(3)) /*!< Pin 3 selected */
+#define GPIO_SEL_4 (BIT(4)) /*!< Pin 4 selected */
+#define GPIO_SEL_5 (BIT(5)) /*!< Pin 5 selected */
+#define GPIO_SEL_6 (BIT(6)) /*!< Pin 6 selected */
+#define GPIO_SEL_7 (BIT(7)) /*!< Pin 7 selected */
+#define GPIO_SEL_8 (BIT(8)) /*!< Pin 8 selected */
+#define GPIO_SEL_9 (BIT(9)) /*!< Pin 9 selected */
+#define GPIO_SEL_10 (BIT(10)) /*!< Pin 10 selected */
+#define GPIO_SEL_11 (BIT(11)) /*!< Pin 11 selected */
+#define GPIO_SEL_12 (BIT(12)) /*!< Pin 12 selected */
+#define GPIO_SEL_13 (BIT(13)) /*!< Pin 13 selected */
+#define GPIO_SEL_14 (BIT(14)) /*!< Pin 14 selected */
+#define GPIO_SEL_15 (BIT(15)) /*!< Pin 15 selected */
+#define GPIO_SEL_16 (BIT(16)) /*!< Pin 16 selected */
+#define GPIO_SEL_17 (BIT(17)) /*!< Pin 17 selected */
+#define GPIO_SEL_18 (BIT(18)) /*!< Pin 18 selected */
+#define GPIO_SEL_19 (BIT(19)) /*!< Pin 19 selected */
-#define GPIO_SEL_0 (BIT(0)) /* Pin 0 selected */
-#define GPIO_SEL_1 (BIT(1)) /* Pin 1 selected */
-#define GPIO_SEL_2 (BIT(2)) /* Pin 2 selected */
-#define GPIO_SEL_3 (BIT(3)) /* Pin 3 selected */
-#define GPIO_SEL_4 (BIT(4)) /* Pin 4 selected */
-#define GPIO_SEL_5 (BIT(5)) /* Pin 5 selected */
-#define GPIO_SEL_6 (BIT(6)) /* Pin 6 selected */
-#define GPIO_SEL_7 (BIT(7)) /* Pin 7 selected */
-#define GPIO_SEL_8 (BIT(8)) /* Pin 8 selected */
-#define GPIO_SEL_9 (BIT(9)) /* Pin 9 selected */
-#define GPIO_SEL_10 (BIT(10)) /* Pin 10 selected */
-#define GPIO_SEL_11 (BIT(11)) /* Pin 11 selected */
-#define GPIO_SEL_12 (BIT(12)) /* Pin 12 selected */
-#define GPIO_SEL_13 (BIT(13)) /* Pin 13 selected */
-#define GPIO_SEL_14 (BIT(14)) /* Pin 14 selected */
-#define GPIO_SEL_15 (BIT(15)) /* Pin 15 selected */
-#define GPIO_SEL_16 (BIT(16)) /* Pin 16 selected */
-#define GPIO_SEL_17 (BIT(17)) /* Pin 17 selected */
-#define GPIO_SEL_18 (BIT(18)) /* Pin 18 selected */
-#define GPIO_SEL_19 (BIT(19)) /* Pin 19 selected */
+#define GPIO_SEL_21 (BIT(21)) /*!< Pin 21 selected */
+#define GPIO_SEL_22 (BIT(22)) /*!< Pin 22 selected */
+#define GPIO_SEL_23 (BIT(23)) /*!< Pin 23 selected */
-#define GPIO_SEL_21 (BIT(21)) /* Pin 21 selected */
-#define GPIO_SEL_22 (BIT(22)) /* Pin 22 selected */
-#define GPIO_SEL_23 (BIT(23)) /* Pin 23 selected */
+#define GPIO_SEL_25 (BIT(25)) /*!< Pin 25 selected */
+#define GPIO_SEL_26 (BIT(26)) /*!< Pin 26 selected */
+#define GPIO_SEL_27 (BIT(27)) /*!< Pin 27 selected */
-#define GPIO_SEL_25 (BIT(25)) /* Pin 25 selected */
-#define GPIO_SEL_26 (BIT(26)) /* Pin 26 selected */
-#define GPIO_SEL_27 (BIT(27)) /* Pin 27 selected */
-
-#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /* Pin 32 selected */
-#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /* Pin 33 selected */
-#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /* Pin 34 selected */
-#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /* Pin 35 selected */
-#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /* Pin 36 selected */
-#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /* Pin 37 selected */
-#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /* Pin 38 selected */
-#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /* Pin 39 selected */
+#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /*!< Pin 32 selected */
+#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /*!< Pin 33 selected */
+#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /*!< Pin 34 selected */
+#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /*!< Pin 35 selected */
+#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /*!< Pin 36 selected */
+#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /*!< Pin 37 selected */
+#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */
+#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
@@ -120,222 +118,193 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode
typedef enum {
- GPIO_NUM_0 = 0,
- GPIO_NUM_1 = 1,
- GPIO_NUM_2 = 2,
- GPIO_NUM_3 = 3,
- GPIO_NUM_4 = 4,
- GPIO_NUM_5 = 5,
- GPIO_NUM_6 = 6,
- GPIO_NUM_7 = 7,
- GPIO_NUM_8 = 8,
- GPIO_NUM_9 = 9,
- GPIO_NUM_10 = 10,
- GPIO_NUM_11 = 11,
- GPIO_NUM_12 = 12,
- GPIO_NUM_13 = 13,
- GPIO_NUM_14 = 14,
- GPIO_NUM_15 = 15,
- GPIO_NUM_16 = 16,
- GPIO_NUM_17 = 17,
- GPIO_NUM_18 = 18,
- GPIO_NUM_19 = 19,
+ GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
+ GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
+ GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
+ GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
+ GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
+ GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
+ GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
+ GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
+ GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
+ GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
+ GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
+ GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
+ GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
+ GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
+ GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
+ GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
+ GPIO_NUM_16 = 16, /*!< GPIO16, input and output */
+ GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
+ GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
+ GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
- GPIO_NUM_21 = 21,
- GPIO_NUM_22 = 22,
- GPIO_NUM_23 = 23,
+ GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
+ GPIO_NUM_22 = 22, /*!< GPIO22, input and output */
+ GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
- GPIO_NUM_25 = 25,
- GPIO_NUM_26 = 26,
- GPIO_NUM_27 = 27,
+ GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
+ GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
+ GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
- GPIO_NUM_32 = 32,
- GPIO_NUM_33 = 33,
- GPIO_NUM_34 = 34, /*input mode only */
- GPIO_NUM_35 = 35, /*input mode only */
- GPIO_NUM_36 = 36, /*input mode only */
- GPIO_NUM_37 = 37, /*input mode only */
- GPIO_NUM_38 = 38, /*input mode only */
- GPIO_NUM_39 = 39, /*input mode only */
+ GPIO_NUM_32 = 32, /*!< GPIO32, input and output */
+ GPIO_NUM_33 = 33, /*!< GPIO32, input and output */
+ GPIO_NUM_34 = 34, /*!< GPIO34, input mode only */
+ GPIO_NUM_35 = 35, /*!< GPIO35, input mode only */
+ GPIO_NUM_36 = 36, /*!< GPIO36, input mode only */
+ GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */
+ GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */
+ GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */
} gpio_num_t;
typedef enum {
- GPIO_INTR_DISABLE = 0, /* disable GPIO interrupt */
- GPIO_INTR_POSEDGE = 1, /* GPIO interrupt type : rising edge */
- GPIO_INTR_NEGEDGE = 2, /* GPIO interrupt type : falling edge */
- GPIO_INTR_ANYEDGE = 3, /* GPIO interrupt type : both rising and falling edge */
- GPIO_INTR_LOW_LEVEL = 4, /* GPIO interrupt type : input low level trigger */
- GPIO_INTR_HIGH_LEVEL = 5, /* GPIO interrupt type : input high level trigger */
+ GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */
+ GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */
+ GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */
+ GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */
+ GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */
+ GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */
GPIO_INTR_MAX,
} gpio_int_type_t;
typedef enum {
- GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /* GPIO mode : input only */
- GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /* GPIO mode : output only mode */
- GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output only with open-drain mode */
- GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output and input with open-drain mode*/
- GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /* GPIO mode : output and input mode */
+ GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */
+ GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */
+ GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */
+ GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
+ GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /*!< GPIO mode : output and input mode */
} gpio_mode_t;
typedef enum {
- GPIO_PULLUP_DISABLE = 0x0, /* disable GPIO pull-up resistor */
- GPIO_PULLUP_ENABLE = 0x1, /* enable GPIO pull-up resistor */
+ GPIO_PULLUP_DISABLE = 0x0, /*!< Disable GPIO pull-up resistor */
+ GPIO_PULLUP_ENABLE = 0x1, /*!< Enable GPIO pull-up resistor */
} gpio_pullup_t;
typedef enum {
- GPIO_PULLDOWN_DISABLE = 0x0, /* disable GPIO pull-down resistor */
- GPIO_PULLDOWN_ENABLE = 0x1, /* enable GPIO pull-down resistor */
+ GPIO_PULLDOWN_DISABLE = 0x0, /*!< Disable GPIO pull-down resistor */
+ GPIO_PULLDOWN_ENABLE = 0x1, /*!< Enable GPIO pull-down resistor */
} gpio_pulldown_t;
typedef struct {
- uint64_t pin_bit_mask; /* GPIO pin: set with bit mask, each bit maps to a GPIO */
- gpio_mode_t mode; /* GPIO mode: set input/output mode */
- gpio_pullup_t pull_up_en; /* GPIO pull-up */
- gpio_pulldown_t pull_down_en; /* GPIO pull-down */
- gpio_int_type_t intr_type; /* GPIO interrupt type */
+ uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
+ gpio_mode_t mode; /*!< GPIO mode: set input/output mode */
+ gpio_pullup_t pull_up_en; /*!< GPIO pull-up */
+ gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */
+ gpio_int_type_t intr_type; /*!< GPIO interrupt type */
} gpio_config_t;
typedef enum {
- GPIO_LOW_LEVEL = 0,
- GPIO_HIGH_LEVEL = 1,
- GPIO_LEVEL_ERR,
-} gpio_level_t;
-
-typedef enum {
- GPIO_PULLUP_ONLY, /* Pad pull up */
- GPIO_PULLDOWN_ONLY, /* Pad pull down */
- GPIO_PULLUP_PULLDOWN, /* Pad pull up + pull down*/
- GPIO_FLOATING, /* Pad floating */
+ GPIO_PULLUP_ONLY, /*!< Pad pull up */
+ GPIO_PULLDOWN_ONLY, /*!< Pad pull down */
+ GPIO_PULLUP_PULLDOWN, /*!< Pad pull up + pull down*/
+ GPIO_FLOATING, /*!< Pad floating */
} gpio_pull_mode_t;
typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num);
-/** \defgroup Driver_APIs Driver APIs
- * @brief Driver APIs
- */
-
-/** @addtogroup Driver_APIs
- * @{
- */
-
-/** \defgroup GPIO_Driver_APIs GPIO Driver APIs
- * @brief GPIO APIs
- */
-
-/** @addtogroup GPIO_Driver_APIs
- * @{
- */
-
/**
- * @brief GPIO common configuration
+ * @brief GPIO common configuration
*
- * Use this Function ,Configure GPIO's Mode,pull-up,PullDown,IntrType
+ * Configure GPIO's Mode,pull-up,PullDown,IntrType
*
- * @parameter[in] pGPIOConfig
- * pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask.
- * If you want to configure GPIO34 and GPIO16, pin_bit_mask=GPIO_Pin_16|GPIO_Pin_34;
- * pGPIOConfig.mode : Configure GPIO mode,such as output ,input...
- * pGPIOConfig.pull_up_en : Enable or Disable pull-up
- * pGPIOConfig.pull_down_en : Enable or Disable pull-down
- * pGPIOConfig.intr_type : Configure GPIO interrupt trigger type
- * @return ESP_OK: success ;
- * ESP_ERR_INVALID_ARG: parameter error
- * ESP_FAIL : GPIO error
+ * @param pGPIOConfig Pointer to GPIO configure struct
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t gpio_config(gpio_config_t *pGPIOConfig);
/**
- * @brief GPIO set interrupt trigger type
+ * @brief GPIO set interrupt trigger type
*
- * @parameter[in] gpio_num : GPIO number.
- * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
- * @parameter[in] intr_type: interrupt type, select from gpio_int_type_t
+ * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param intr_type Interrupt type, select from gpio_int_type_t
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
- * @brief enable GPIO module interrupt signal
+ * @brief Enable GPIO module interrupt signal
*
- * @parameter[in] gpio_num : GPIO number.
- * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);
/**
- * @brief disable GPIO module interrupt signal
+ * @brief Disable GPIO module interrupt signal
*
- * @parameter[in] gpio_num : GPIO number.
- * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
/**
- * @brief GPIO set output level
+ * @brief GPIO set output level
*
- * @parameter[in] gpio_num : GPIO number.
- * If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
- * @parameter[in] level : Output level. 0: low ; 1: high
+ * @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param level Output level. 0: low ; 1: high
*
- * @return ESP_OK : success
- * ESP_FAIL : GPIO error
+ * @return
+ * - ESP_OK Success
+ * - GPIO_IS_VALID_GPIO GPIO number error
*
*/
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
/**
- * @brief GPIO get input level
+ * @brief GPIO get input level
*
- * @parameter[in] gpio_num : GPIO number.
- * If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param gpio_num GPIO number. If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
*
- * @return 0 : the GPIO input level is 0
- * 1 : the GPIO input level is 1
+ * @return
+ * - 0 the GPIO input level is 0
+ * - 1 the GPIO input level is 1
*
*/
int gpio_get_level(gpio_num_t gpio_num);
/**
- * @brief GPIO set direction
+ * @brief GPIO set direction
*
* Configure GPIO direction,such as output_only,input_only,output_and_input
*
- * @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
- * If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16);
- * @parameter[in] mode : Configure GPIO direction,such as output_only,input_only,...
+ * @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16);
+ * @param mode GPIO direction
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG : fail
- * ESP_FAIL : GPIO error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG GPIO error
*
*/
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
/**
- * @brief GPIO set pull
+ * @brief GPIO set pull
*
* User this Function,configure GPIO pull mode,such as pull-up,pull-down
*
- * @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
- * If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16);
- * @parameter[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,...
+ * @param gpio_num GPIO number. If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16);
+ * @param pull GPIO pull up/down mode.
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG : fail
- * ESP_FAIL : GPIO error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG : Parameter error
*
*/
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
@@ -343,121 +312,140 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
/**
* @brief enable GPIO wake-up function.
*
- * @param gpio_num_t gpio_num : GPIO number.
+ * @param gpio_num GPIO number.
*
- * @param gpio_int_type_t intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used
+ * @param intr_type GPIO wake-up type. Only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
- * @brief disable GPIO wake-up function.
+ * @brief Disable GPIO wake-up function.
*
- * @param gpio_num_t gpio_num: GPIO number
+ * @param gpio_num GPIO number
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
/**
* @brief register GPIO interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
+ * @note
* Users should know that which CPU is running and then pick a INUM that is not used by system.
* We can find the information of INUM and interrupt level in soc.h.
- * TODO: to move INUM options to menu_config
- * @parameter uint32_t gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
- * @parameter void (* fn)(void* ) : interrupt handler function.
- * Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
- * @parameter void * arg : parameter for handler function
*
- * @return ESP_OK : success ;
- * ESP_FAIL: gpio error
+ * @param gpio_intr_num GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
+ * @param fn Interrupt handler function.
+ *
+ * @note
+ * Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
+ *
+ * @param arg Parameter for handler function
+ *
+ * @return
+ * - ESP_OK Success ;
+ * - ESP_ERR_INVALID_ARG GPIO error
*/
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg);
/**
* *************** ATTENTION ********************/
/**
- *
- * Each GPIO has its own separate configuration register, so we do not use
- * a lock to serialize access to them. This works under the assumption that
- * no situation will occur where two tasks try to configure the same GPIO
- * pin simultaneously. It is up to the application developer to guarantee this.
+ *@attention
+ * Each GPIO has its own separate configuration register, so we do not use
+ * a lock to serialize access to them. This works under the assumption that
+ * no situation will occur where two tasks try to configure the same GPIO
+ * pin simultaneously. It is up to the application developer to guarantee this.
*/
-
-/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
-/* gpio_config_t io_conf;
+/**
+ *----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
+ * @code{c}
+ * gpio_config_t io_conf;
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
* io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
* io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19
* io_conf.pull_down_en = 0; //disable pull-down mode
* io_conf.pull_up_en = 0; //disable pull-up mode
* gpio_config(&io_conf); //configure GPIO with the given settings
+ * @endcode
**/
-/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
-/* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
+
+/**
+ *----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
+ * @code{c}
+ * io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
* io_conf.mode = GPIO_MODE_INPUT; //set as input
* io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5
* io_conf.pull_down_en = 0; //disable pull-down mode
* io_conf.pull_up_en = 1; //enable pull-up mode
* gpio_config(&io_conf); //configure GPIO with the given settings
- *----------EXAMPLE TO SET ISR HANDLER ----------------------*/
-/* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
- * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
- * //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
- * //NOTE2:do not pick the INUM that already occupied by the system.
- * //NOTE3:refer to soc.h to check which INUMs that can be used.
- *-------------EXAMPLE OF HANDLER FUNCTION-------------------*/
-/*#include "esp_attr.h"
+ * @endcode
+ */
+/**
+ *----------EXAMPLE TO SET ISR HANDLER ----------------------
+ * @code{c}
+ * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
+ * gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
+ * @endcode
+ * @note
+ * 1. user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
+ * 2. do not pick the INUM that already occupied by the system.
+ * 3. refer to soc.h to check which INUMs that can be used.
+ */
+/**
+ *-------------EXAMPLE OF HANDLER FUNCTION-------------------*
+ * @code{c}
+ * #include "esp_attr.h"
* void IRAM_ATTR gpio_intr_test(void* arg)
- *{
- * //GPIO intr process
- * ets_printf("in gpio_intr\n");
- * uint32_t gpio_num = 0;
- * uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31
- * uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
- * SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31
- * SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
- * do {
- * if(gpio_num < 32) {
- * if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
- * ets_printf("Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num));
- * //This is an isr handler, you should post an event to process it in RTOS queue.
- * }
- * } else {
- * if(gpio_intr_status_h & BIT(gpio_num - 32)) {
- * ets_printf("Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num));
- * //This is an isr handler, you should post an event to process it in RTOS queue.
- * }
- * }
- * } while(++gpio_num < GPIO_PIN_COUNT);
- *}
- *----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*/
-/* gpio_config_t io_conf;
- * io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
- * io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode
- * io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22
- * io_conf.pull_down_en = 0; //disable pull-down mode
- * io_conf.pull_up_en = 1; //enable pull-up mode
- * gpio_config(&io_conf); //configure GPIO with the given settings
- * gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix
- * gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix
- * gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix
+ * {
+ * //GPIO intr process
+ * ets_printf("in gpio_intr\n");
+ * uint32_t gpio_num = 0;
+ * uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31
+ * uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
+ * SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31
+ * SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
+ * do {
+ * if(gpio_num < 32) {
+ * if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
+ * ets_printf("Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num));
+ * //This is an isr handler, you should post an event to process it in RTOS queue.
+ * }
+ * } else {
+ * if(gpio_intr_status_h & BIT(gpio_num - 32)) {
+ * ets_printf("Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num));
+ * //This is an isr handler, you should post an event to process it in RTOS queue.
+ * }
+ * }
+ * } while(++gpio_num < GPIO_PIN_COUNT);
+ * }
+ * @endcode
+ */
+
+/**
+ *----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*
+ * @code{c}
+ * gpio_config_t io_conf;
+ * io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
+ * io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode
+ * io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22
+ * io_conf.pull_down_en = 0; //disable pull-down mode
+ * io_conf.pull_up_en = 1; //enable pull-up mode
+ * gpio_config(&io_conf); //configure GPIO with the given settings
+ * gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix
+ * gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix
+ * gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix
+ * @endcode
*
*/
-/**
- * @}
- */
-
-/**
- * @}
- */
-
#ifdef __cplusplus
}
#endif
diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h
index d6ce9b86c9..ac29eaf56a 100644
--- a/components/driver/include/driver/ledc.h
+++ b/components/driver/include/driver/ledc.h
@@ -31,68 +31,68 @@ extern const char* LEDC_TAG;
#define LEDC_REF_CLK_HZ (1*1000000)
typedef enum {
- LEDC_HIGH_SPEED_MODE = 0, /*LEDC high speed speed_mode */
+ LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */
//in this version, we only support high speed speed_mode. We will access low speed speed_mode later
- //LEDC_LOW_SPEED_MODE, /*LEDC low speed speed_mode */
- LEDC_SPEED_MODE_MAX,
+ //LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */
+ LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */
} ledc_mode_t;
typedef enum {
- LEDC_INTR_DISABLE = 0, /*Disable LEDC interrupt */
- LEDC_INTR_FADE_END, /*Enable LEDC interrupt */
+ LEDC_INTR_DISABLE = 0, /*!< Disable LEDC interrupt */
+ LEDC_INTR_FADE_END, /*!< Enable LEDC interrupt */
} ledc_intr_type_t;
typedef enum {
- LEDC_DUTY_DIR_DECREASE = 0, /*LEDC duty decrease direction */
- LEDC_DUTY_DIR_INCREASE = 1, /*LEDC duty increase direction */
+ LEDC_DUTY_DIR_DECREASE = 0, /*!< LEDC duty decrease direction */
+ LEDC_DUTY_DIR_INCREASE = 1, /*!< LEDC duty increase direction */
} ledc_duty_direction_t;
typedef enum {
- LEDC_REF_TICK = 0, /*LEDC timer clock divided from reference tick(1Mhz) */
- LEDC_APB_CLK, /*LEDC timer clock divided from APB clock(80Mhz)*/
+ LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick(1Mhz) */
+ LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock(80Mhz)*/
} ledc_clk_src_t;
typedef enum {
- LEDC_TIMER_0 = 0, /*LEDC source timer TIMER0 */
- LEDC_TIMER_1, /*LEDC source timer TIMER1 */
- LEDC_TIMER_2, /*LEDC source timer TIMER2 */
- LEDC_TIMER_3, /*LEDC source timer TIMER3 */
+ LEDC_TIMER_0 = 0, /*!< LEDC source timer TIMER0 */
+ LEDC_TIMER_1, /*!< LEDC source timer TIMER1 */
+ LEDC_TIMER_2, /*!< LEDC source timer TIMER2 */
+ LEDC_TIMER_3, /*!< LEDC source timer TIMER3 */
} ledc_timer_t;
typedef enum {
- LEDC_CHANNEL_0 = 0, /*LEDC channel 0 */
- LEDC_CHANNEL_1, /*LEDC channel 1 */
- LEDC_CHANNEL_2, /*LEDC channel 2 */
- LEDC_CHANNEL_3, /*LEDC channel 3 */
- LEDC_CHANNEL_4, /*LEDC channel 4 */
- LEDC_CHANNEL_5, /*LEDC channel 5 */
- LEDC_CHANNEL_6, /*LEDC channel 6 */
- LEDC_CHANNEL_7, /*LEDC channel 7 */
+ LEDC_CHANNEL_0 = 0, /*!< LEDC channel 0 */
+ LEDC_CHANNEL_1, /*!< LEDC channel 1 */
+ LEDC_CHANNEL_2, /*!< LEDC channel 2 */
+ LEDC_CHANNEL_3, /*!< LEDC channel 3 */
+ LEDC_CHANNEL_4, /*!< LEDC channel 4 */
+ LEDC_CHANNEL_5, /*!< LEDC channel 5 */
+ LEDC_CHANNEL_6, /*!< LEDC channel 6 */
+ LEDC_CHANNEL_7, /*!< LEDC channel 7 */
} ledc_channel_t;
typedef enum {
- LEDC_TIMER_10_BIT = 10, /*LEDC PWM depth 10Bit */
- LEDC_TIMER_11_BIT = 11, /*LEDC PWM depth 11Bit */
- LEDC_TIMER_12_BIT = 12, /*LEDC PWM depth 12Bit */
- LEDC_TIMER_13_BIT = 13, /*LEDC PWM depth 13Bit */
- LEDC_TIMER_14_BIT = 14, /*LEDC PWM depth 14Bit */
- LEDC_TIMER_15_BIT = 15, /*LEDC PWM depth 15Bit */
+ LEDC_TIMER_10_BIT = 10, /*!< LEDC PWM depth 10Bit */
+ LEDC_TIMER_11_BIT = 11, /*!< LEDC PWM depth 11Bit */
+ LEDC_TIMER_12_BIT = 12, /*!< LEDC PWM depth 12Bit */
+ LEDC_TIMER_13_BIT = 13, /*!< LEDC PWM depth 13Bit */
+ LEDC_TIMER_14_BIT = 14, /*!< LEDC PWM depth 14Bit */
+ LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */
} ledc_timer_bit_t;
typedef struct {
- int gpio_num; /*the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/
- ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
- ledc_channel_t channel; /*LEDC channel(0 - 7)*/
- ledc_intr_type_t intr_type; /*configure interrupt, Fade interrupt enable or Fade interrupt disable*/
- ledc_timer_t timer_sel; /*Select the timer source of channel (0 - 3)*/
- uint32_t duty; /*LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */
+ int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/
+ ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/
+ ledc_channel_t channel; /*!< LEDC channel(0 - 7)*/
+ ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable*/
+ ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3)*/
+ uint32_t duty; /*!< LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */
} ledc_channel_config_t;
typedef struct {
- ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
- ledc_timer_bit_t bit_num; /*LEDC channel duty depth*/
- ledc_timer_t timer_num; /*The timer source of channel (0 - 3)*/
- uint32_t freq_hz; /*LEDC timer frequency(Hz)*/
+ ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/
+ ledc_timer_bit_t bit_num; /*!< LEDC channel duty depth*/
+ ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3)*/
+ uint32_t freq_hz; /*!< LEDC timer frequency(Hz)*/
} ledc_timer_config_t;
@@ -101,15 +101,10 @@ typedef struct {
*
* User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth
*
- * @param[in] ledc_channel_config_t
- * ledc_channel_config_t.speed_mode : LEDC speed speed_mode
- * ledc_channel_config_t.gpio_num : LEDC output gpio_num, if you want to use gpio16, ledc_channel_config_t.gpio_num = 16
- * ledc_channel_config_t.channel : LEDC channel(0 - 7)
- * ledc_channel_config_t.intr_type : configure interrupt, Fade interrupt enable or Fade interrupt disable
- * ledc_channel_config_t.timer_sel : Select the timer source of channel (0 - 3), high speed channel must bind with high speed timer.
- * ledc_channel_config_t.duty : LEDC channel duty, the duty range is [0, (2**timer_bit_num) - 1],
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @param ledc_conf Pointer of LEDC channel configure struct
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
@@ -119,14 +114,13 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
*
* User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num
*
- * @param[in] ledc_timer_config_t
- * ledc_timer_config_t.speed_mode : LEDC speed speed_mode
- * ledc_timer_config_t.timer_num : Select the timer source of channel (0 - 3)
- * ledc_timer_config_t.freq_hz : LEDC channel frequency(Hz),
- * ledc_timer_config_t.bit_num : LEDC channel duty depth
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
- * ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
+ * @param timer_conf Pointer of LEDC timer configure struct
+ *
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num.
*
*/
esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
@@ -137,12 +131,13 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
* Call this function to activate the LEDC updated parameters.
* After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings.
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
+ * @param channel LEDC channel(0-7), select from ledc_channel_t
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*
*/
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
@@ -152,12 +147,13 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
*
* Disable LEDC output, and set idle level
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
+ * @param channel LEDC channel(0-7), select from ledc_channel_t
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level);
@@ -166,27 +162,29 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl
*
* Set LEDC frequency(Hz)
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_num LEDC timer index(0-3), select from ledc_timer_t
*
- * @param[in] freq_hz : set the LEDC frequency
+ * @param freq_hz Set the LEDC frequency
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
- * ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num.
*/
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz);
/**
* @brief LEDC get channel frequency(Hz)
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_num LEDC timer index(0-3), select from ledc_timer_t
*
- * @return 0 : error
- * others : current LEDC frequency
+ * @return
+ * - 0 error
+ * - Others Current LEDC frequency
*
*/
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
@@ -196,27 +194,29 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
*
* Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect.
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
+ * @param channel LEDC channel(0-7), select from ledc_channel_t
*
- * @param[in] duty : set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
+ * @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
*
- * @return ESP_OK: success
- * ESP_ERR_INVALID_ARG: parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
/**
* @brief LEDC get duty
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
+ * @param channel LEDC channel(0-7), select from ledc_channel_t
*
*
- * @return -1: parameter error
- * other value: current LEDC duty
+ * @return
+ * - (-1) parameter error
+ * - Others Current LEDC duty
*
*/
int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
@@ -226,22 +226,23 @@ int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
*
* Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
+ * @param channel LEDC channel(0-7), select from ledc_channel_t
*
- * @param[in] duty : set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
+ * @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
*
- * @param[in] gradule_direction : set the direction of the gradient
+ * @param gradule_direction Set the direction of the gradient
*
- * @param[in] step_num : set the number of the gradient
+ * @param step_num Set the number of the gradient
*
- * @param[in] duty_cyle_num : set how many LEDC tick each time the gradient lasts
+ * @param duty_cyle_num Set how many LEDC tick each time the gradient lasts
*
- * @param[in] duty_scale : set gradient change amplitude
+ * @param duty_scale Set gradient change amplitude
*
- * @return ESP_OK : success
- * ESP_ERR_INVALID_ARG : parameter error
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t gradule_direction,
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale);
@@ -249,34 +250,37 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty,
/**
* @brief register LEDC interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
- * Users should know that which CPU is running and then pick a INUM that is not used by system.
- * We can find the information of INUM and interrupt level in soc.h.
- * TODO: to move INUM options to menu_config
- * @param[in] uint32_t ledc_intr_num : LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
- * @param[in] void (* fn)(void* ) : interrupt handler function.
- * Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
- * @param[in] void * arg : parameter for handler function
+ * @note
+ * Users should know that which CPU is running and then pick a INUM that is not used by system.
+ * We can find the information of INUM and interrupt level in soc.h.
+ * @param ledc_intr_num LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
+ * @param fn Interrupt handler function.
+ * @note
+ * Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
+ * @param arg Parameter for handler function
*
- * @return ESP_OK : success ;
- * ESP_ERR_INVALID_ARG : function ptr error.
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Function pointer error.
*/
esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg);
/**
* @brief configure LEDC settings
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_sel : timer index(0-3), there are 4 timers in LEDC module
+ * @param timer_sel Timer index(0-3), there are 4 timers in LEDC module
*
- * @param[in] div_num : timer clock divide number, the timer clock is divided from the selected clock source
+ * @param div_num Timer clock divide number, the timer clock is divided from the selected clock source
*
- * @param[in] bit_num : the count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
+ * @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
*
- * @param[in] clk_src : select LEDC source clock.
+ * @param clk_src Select LEDC source clock.
*
- * @return -1: parameter error
- * other value: current LEDC duty
+ * @return
+ * - (-1) Parameter error
+ * - Other Current LEDC duty
*
*/
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src);
@@ -284,13 +288,14 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_
/**
* @brief reset LEDC timer
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
*
- * @return ESP_ERR_INVALID_ARG: parameter error
- * ESP_OK: success
+ * @return
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_OK Success
*
*/
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
@@ -298,13 +303,14 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief pause LEDC timer counter
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
*
- * @return ESP_ERR_INVALID_ARG: parameter error
- * ESP_OK: success
+ * @return
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_OK Success
*
*/
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
@@ -312,13 +318,14 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief pause LEDC timer resume
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
*
*
- * @return ESP_ERR_INVALID_ARG: parameter error
- * ESP_OK: success
+ * @return
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_OK Success
*
*/
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
@@ -326,77 +333,74 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
/**
* @brief bind LEDC channel with the selected timer
*
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
+ * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
*
- * @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t
+ * @param channel LEDC channel index(0-7), select from ledc_channel_t
*
- * @param[in] timer_idx : LEDC timer index(0-3), select from ledc_timer_t
+ * @param timer_idx LEDC timer index(0-3), select from ledc_timer_t
*
*
- * @return ESP_ERR_INVALID_ARG: parameter error
- * ESP_OK: success
+ * @return
+ * - ESP_ERR_INVALID_ARG Parameter error
+ * - ESP_OK Success
*
*/
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx);
-/**
- * @brief Set LEDC output signal to GPIO
- *
- * @param[in] gpio_num : GPIO number for LEDC signal output
- *
- * @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
- *
- * @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t
- *
- *
- * @return ESP_ERR_INVALID_ARG: parameter error
- * ESP_OK: success
- *
- */
-esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_channel);
-
/***************************EXAMPLE**********************************
*
*
* ----------------EXAMPLE OF LEDC SETTING ---------------------
- * //1. enable LEDC
- * periph_module_enable(PERIPH_LEDC_MODULE); //enable LEDC module, or you can not set any register of it.
+ * @code{c}
+ * //1. enable LEDC
+ * //enable LEDC module, or you can not set any register of it.
+ * periph_module_enable(PERIPH_LEDC_MODULE);
+ * @endcode
*
- * //2. set LEDC timer
- * ledc_timer_config_t timer_conf = {
- * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number
- * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz
- * .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode,
- * .timer_num = LEDC_TIMER_0, //timer number
- * };
- * ledc_timer_config(&timer_conf); //setup timer.
+ * @code{c}
+ * //2. set LEDC timer
+ * ledc_timer_config_t timer_conf = {
+ * .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number
+ * .freq_hz = 1000, //set frequency of pwm, here, 1000Hz
+ * .speed_mode = LEDC_HIGH_SPEED_MODE, //timer mode,
+ * .timer_num = LEDC_TIMER_0, //timer number
+ * };
+ * ledc_timer_config(&timer_conf); //setup timer.
+ * @endcode
*
- * //3. set LEDC channel
- * ledc_channel_config_t ledc_conf = {
- * .channel = LEDC_CHANNEL_0, //set LEDC channel 0
- * .duty = 1000, //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
- * .gpio_num = 16, //GPIO number
- * .intr_type = LEDC_INTR_FADE_END, //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
- * .speed_mode = LEDC_HIGH_SPEED_MODE, //set LEDC mode, from ledc_mode_t
- * .timer_sel = LEDC_TIMER_0, //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
- * }
- * ledc_channel_config(&ledc_conf); //setup the configuration
+ * @code{c}
+ * //3. set LEDC channel
+ * ledc_channel_config_t ledc_conf = {
+ * .channel = LEDC_CHANNEL_0; //set LEDC channel 0
+ * .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
+ * .gpio_num = 16; //GPIO number
+ * .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
+ * .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t
+ * .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
+ * }
+ * ledc_channel_config(&ledc_conf); //setup the configuration
*
* ----------------EXAMPLE OF SETTING DUTY --- -----------------
- * uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73)
- * uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1)
- * LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty.
- * ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings.
- *
+ * @code{c}
+ * uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73)
+ * uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1)
+ * LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty.
+ * ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings.
+ * @endcode
*
* ----------------EXAMPLE OF LEDC INTERRUPT ------------------
- * //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
- * ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt
- * //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
- * //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
- * //NOTE2:do not pick the INUM that already occupied by the system.
- * //NOTE3:refer to soc.h to check which INUMs that can be used.
+ * @code{c}
+ * //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
+ * ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt
+ * @endcode
+ * @note
+ * 1. the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
+ * 2. user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
+ * 3. do not pick the INUM that already occupied by the system.
+ * 4. refer to soc.h to check which INUMs that can be used.
+ *
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
+ * @code{c}
* #include "esp_attr.h"
* void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function
* {
@@ -408,7 +412,7 @@ esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_
*
* LEDC.int_clr.val = intr_st; //clear LEDC interrupt status.
* }
- *
+ * @endcode
*
*--------------------------END OF EXAMPLE --------------------------
*/
diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig
index b5a8d2f2dd..1f04cf4bb7 100644
--- a/components/esp32/Kconfig
+++ b/components/esp32/Kconfig
@@ -319,6 +319,49 @@ config BROWNOUT_DET_RESETDELAY
before trying to restart the chip. You can set the delay here.
+choice ESP32_TIME_SYSCALL
+ prompt "Timers used for gettimeofday function"
+ default ESP32_TIME_SYSCALL_USE_RTC_FRC1
+ help
+ This setting defines which hardware timers are used to
+ implement 'gettimeofday' and 'time' functions in C library.
+
+ - If only FRC1 timer is used, gettimeofday will provide time at
+ microsecond resolution. Time will not be preserved when going
+ into deep sleep mode.
+ - If both FRC1 and RTC timers are used, timekeeping will
+ continue in deep sleep. Time will be reported at 1 microsecond
+ resolution.
+ - If only RTC timer is used, timekeeping will continue in
+ deep sleep, but time will be measured at 6.(6) microsecond
+ resolution. Also the gettimeofday function itself may take
+ longer to run.
+ - If no timers are used, gettimeofday and time functions
+ return -1 and set errno to ENOSYS.
+
+config ESP32_TIME_SYSCALL_USE_RTC
+ bool "RTC"
+config ESP32_TIME_SYSCALL_USE_RTC_FRC1
+ bool "RTC and FRC1"
+config ESP32_TIME_SYSCALL_USE_FRC1
+ bool "FRC1"
+config ESP32_TIME_SYSCALL_USE_NONE
+ bool "None"
+endchoice
+choice ESP32_RTC_CLOCK_SOURCE
+ prompt "RTC clock source"
+ default ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
+ help
+ Choose which clock is used as RTC clock source.
+ The only available option for now is to use internal
+ 150kHz RC oscillator.
+
+config ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
+ bool "Internal RC"
+config ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
+ bool "External 32kHz crystal"
+ depends on DOCUMENTATION_FOR_RTC_CNTL
+endchoice
endmenu
diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c
index d94a4e6e79..c82c528597 100644
--- a/components/esp32/cpu_start.c
+++ b/components/esp32/cpu_start.c
@@ -19,6 +19,7 @@
#include "rom/ets_sys.h"
#include "rom/uart.h"
+#include "rom/rtc.h"
#include "soc/cpu.h"
#include "soc/dport_reg.h"
@@ -65,6 +66,8 @@ extern void app_main(void);
extern int _bss_start;
extern int _bss_end;
+extern int _rtc_bss_start;
+extern int _rtc_bss_end;
extern int _init_start;
extern void (*__init_array_start)(void);
extern void (*__init_array_end)(void);
@@ -95,6 +98,11 @@ void IRAM_ATTR call_start_cpu0()
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
+ /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
+ if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
+ memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start));
+ }
+
// Initialize heap allocator
heap_alloc_caps_init();
@@ -161,7 +169,8 @@ void start_cpu0_default(void)
#if CONFIG_TASK_WDT
esp_task_wdt_init();
#endif
- esp_setup_syscalls();
+ esp_setup_syscall_table();
+ esp_setup_time_syscalls();
esp_vfs_dev_uart_register();
esp_reent_init(_GLOBAL_REENT);
const char* default_uart_dev = "/dev/uart/0";
diff --git a/components/esp32/deepsleep.c b/components/esp32/deepsleep.c
index 61268bce6b..742ff8cf40 100644
--- a/components/esp32/deepsleep.c
+++ b/components/esp32/deepsleep.c
@@ -40,8 +40,7 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
}
void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) {
- //
- //mmu_init(0);
+ /* Clear MMU for CPU 0 */
REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
}
diff --git a/components/esp32/gdbstub.c b/components/esp32/gdbstub.c
index d75fced4cd..a43793f835 100644
--- a/components/esp32/gdbstub.c
+++ b/components/esp32/gdbstub.c
@@ -351,7 +351,7 @@ static int gdbReadCommand() {
-void gdbstubPanicHandler(XtExcFrame *frame) {
+void esp_gdbstub_panic_handler(XtExcFrame *frame) {
dumpHwToRegfile(frame);
//Make sure txd/rxd are enabled
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
diff --git a/components/esp32/include/esp_attr.h b/components/esp32/include/esp_attr.h
index 156d2957f9..78aa3bd190 100644
--- a/components/esp32/include/esp_attr.h
+++ b/components/esp32/include/esp_attr.h
@@ -20,22 +20,21 @@
//and all variables in shared RAM. These macros can be used to redirect
//particular functions/variables to other memory regions.
-// Forces code into IRAM instead of flash
+// Forces code into IRAM instead of flash.
#define IRAM_ATTR __attribute__((section(".iram1")))
// Forces data into DRAM instead of flash
#define DRAM_ATTR __attribute__((section(".dram1")))
-// Forces code into RTC fast memory
+// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst"
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
-// Forces data into RTC slow memory
+// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
// Any variable marked with this attribute will keep its value
// during a deep sleep / wake cycle.
#define RTC_DATA_ATTR __attribute__((section(".rtc.data")))
-// Forces read-only data into RTC slow memory
-// Makes constant data available to RTC wake stubs (see esp_deepsleep.h)
+// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst"
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
#endif /* __ESP_ATTR_H__ */
diff --git a/components/esp32/include/esp_deepsleep.h b/components/esp32/include/esp_deepsleep.h
index 3683a8eeab..59b3129185 100644
--- a/components/esp32/include/esp_deepsleep.h
+++ b/components/esp32/include/esp_deepsleep.h
@@ -54,37 +54,7 @@ void system_deep_sleep(uint64_t time_in_us);
* to run code immediately when the chip wakes from
* sleep.
*
- * For example:
- * @code
- * void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
- * esp_default_wake_deep_sleep();
- * // Add additional functionality here
- * }
- *
- * (Implementing this function is not required for normal operation,
- * in the usual case your app will start normally when waking from
- * deep sleep.)
- *
- * esp_wake_deep_sleep() functionality is limited:
- *
- * - Runs immediately on wake, so most of the SoC is freshly reset -
- * flash is unmapped and hardware is otherwise uninitialised.
- *
- * - Can only call functions implemented in ROM, or marked RTC_IRAM_ATTR.
- *
- * - Static variables marked RTC_DATA_ATTR will have initial values on
- * cold boot, and maintain these values between sleep/wake cycles.
- *
- * - Read-only data should be marked RTC_RODATA_ATTR. Strings must be
- * declared as variables also using RTC_RODATA_ATTR, like this:
- * RTC_RODATA_ATTR const char message[] = "Hello from very early boot!\n";
- *
- * - Any other static memory will not be initialised (either to zero,
- * or to any predefined value).
- *
- *
- * - If you implement your own stub, the first call the stub makes
- should be to esp_default_wake_deep_sleep().
+ * See docs/deep-sleep-stub.rst for details.
*/
void esp_wake_deep_sleep(void);
@@ -115,9 +85,7 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
/* The default esp-idf-provided esp_wake_deep_sleep() stub.
- If you replace esp_wake_deep_sleep() in your program, or use
- esp_set_deep_sleep_wake_stub(), then it is recommended you call
- esp_default_wake_deep_sleep() as the first function in your stub.
+ See docs/deep-sleep-stub.rst for details.
*/
void esp_default_wake_deep_sleep(void);
diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h
index 84133366d7..8c6564c55b 100644
--- a/components/esp32/include/esp_system.h
+++ b/components/esp32/include/esp_system.h
@@ -16,6 +16,7 @@
#define __ESP_SYSTEM_H__
#include
+#include
#include "esp_err.h"
#include "esp_deepsleep.h"
diff --git a/components/esp32/include/soc/frc_timer_reg.h b/components/esp32/include/soc/frc_timer_reg.h
new file mode 100644
index 0000000000..d76199c4f3
--- /dev/null
+++ b/components/esp32/include/soc/frc_timer_reg.h
@@ -0,0 +1,49 @@
+// 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 _SOC_FRC_TIMER_REG_H_
+#define _SOC_FRC_TIMER_REG_H_
+
+#include "soc.h"
+
+/**
+ * These are the register definitions for "legacy" timers
+ */
+
+#define REG_FRC_TIMER_BASE(i) (DR_REG_FRC_TIMER_BASE + i*0x20)
+
+#define FRC_TIMER_LOAD_REG(i) (REG_FRC_TIMER_BASE(i) + 0x0) // timer load value (23 bit for i==0, 32 bit for i==1)
+#define FRC_TIMER_LOAD_VALUE(i) ((i == 0)?0x007FFFFF:0xffffffff)
+#define FRC_TIMER_LOAD_VALUE_S 0
+
+#define FRC_TIMER_COUNT_REG(i) (REG_FRC_TIMER_BASE(i) + 0x4) // timer count value (23 bit for i==0, 32 bit for i==1)
+#define FRC_TIMER_COUNT ((i == 0)?0x007FFFFF:0xffffffff)
+#define FRC_TIMER_COUNT_S 0
+
+#define FRC_TIMER_CTRL_REG(i) (REG_FRC_TIMER_BASE(i) + 0x8)
+#define FRC_TIMER_INT_ENABLE (BIT(8)) // enable interrupt
+#define FRC_TIMER_ENABLE (BIT(7)) // enable timer
+#define FRC_TIMER_AUTOLOAD (BIT(6)) // enable autoload
+#define FRC_TIMER_PRESCALER 0x00000007 // 0: divide by 1, 2: divide by 16, 4: divide by 256
+#define FRC_TIMER_PRESCALER_S 1
+#define FRC_TIMER_EDGE_INT (BIT(0)) // 0: level, 1: edge
+
+#define FRC_TIMER_INT_REG(i) (REG_FRC_TIMER_BASE(i) + 0xC)
+#define FRC_TIMER_INT_CLR (BIT(0)) // clear interrupt
+
+#define FRC_TIMER_ALARM_REG(i) (REG_FRC_TIMER_BASE(i) + 0x10) // timer alarm value; register only present for i == 1
+#define FRC_TIMER_ALARM 0xFFFFFFFF
+#define FRC_TIMER_ALARM_S 0
+
+#endif //_SOC_FRC_TIMER_REG_H_
diff --git a/components/esp32/include/soc/rtc_cntl_reg.h b/components/esp32/include/soc/rtc_cntl_reg.h
index bb4e2afced..d99cec1864 100644
--- a/components/esp32/include/soc/rtc_cntl_reg.h
+++ b/components/esp32/include/soc/rtc_cntl_reg.h
@@ -239,6 +239,9 @@
#define RTC_CNTL_TIME_VALID_V 0x1
#define RTC_CNTL_TIME_VALID_S 30
+/* frequency of RTC slow clock, Hz */
+#define RTC_CTNL_SLOWCLK_FREQ 150000
+
#define RTC_CNTL_TIME0_REG (DR_REG_RTCCNTL_BASE + 0x10)
/* RTC_CNTL_TIME_LO : RO ;bitpos:[31:0] ;default: 32'h0 ; */
/*description: RTC timer low 32 bits*/
diff --git a/components/esp32/include/soc/soc.h b/components/esp32/include/soc/soc.h
index 4ffdfb069e..8ab9f027c5 100755
--- a/components/esp32/include/soc/soc.h
+++ b/components/esp32/include/soc/soc.h
@@ -148,6 +148,7 @@
#define DR_REG_GPIO_SD_BASE 0x3ff44f00
#define DR_REG_FE2_BASE 0x3ff45000
#define DR_REG_FE_BASE 0x3ff46000
+#define DR_REG_FRC_TIMER_BASE 0x3ff47000
#define DR_REG_RTCCNTL_BASE 0x3ff48000
#define DR_REG_RTCIO_BASE 0x3ff48400
#define DR_REG_SARADC_BASE 0x3ff48800
@@ -281,9 +282,9 @@
* 19 2 extern level
* 20 2 extern level
* 21 2 extern level
- * 22 3 extern edge
+ * 22 3 extern edge FRC1 timer
* 23 3 extern level
- * 24 4 extern level
+ * 24 4 extern level TG1_WDT
* 25 4 extern level Reserved Reserved
* 26 5 extern level Reserved Reserved
* 27 3 extern level Reserved Reserved
@@ -301,8 +302,10 @@
#define ETS_T0_WDT_INUM 3
#define ETS_WBB_INUM 4
#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/
+#define ETS_FRC1_INUM 22
+#define ETS_T1_WDT_INUM 24
-//CPU0 Intrrupt number used in ROM, should be cancelled in SDK
+//CPU0 Interrupt number used in ROM, should be cancelled in SDK
#define ETS_SLC_INUM 1
#define ETS_UART0_INUM 5
#define ETS_UART1_INUM 5
diff --git a/components/esp32/ld/esp32.common.ld b/components/esp32/ld/esp32.common.ld
index 7b14b6da1f..aafafbb495 100644
--- a/components/esp32/ld/esp32.common.ld
+++ b/components/esp32/ld/esp32.common.ld
@@ -3,8 +3,38 @@ ENTRY(call_start_cpu0);
SECTIONS
{
+ /* RTC fast memory holds RTC wake stub code,
+ including from any source file named rtc_wake_stub*.c
+ */
+ .rtc.text :
+ {
+ . = ALIGN(4);
+ *(.rtc.literal .rtc.text)
+ *rtc_wake_stub*.o(.literal .text .literal.* .text.*)
+ } >rtc_iram_seg
+
+ /* RTC slow memory holds RTC wake stub
+ data/rodata, including from any source file
+ named rtc_wake_stub*.c
+ */
+ .rtc.data :
+ {
+ *(.rtc.data)
+ *(.rtc.rodata)
+ *rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
+ } > rtc_slow_seg
+
+ /* RTC bss, from any source file named rtc_wake_stub*.c */
+ .rtc.bss (NOLOAD) :
+ {
+ _rtc_bss_start = ABSOLUTE(.);
+ *rtc_wake_stub*.o(.bss .bss.*)
+ *rtc_wake_stub*.o(COMMON)
+ _rtc_bss_end = ABSOLUTE(.);
+ } > rtc_slow_seg
+
/* Send .iram0 code to iram */
- .iram0.vectors :
+ .iram0.vectors :
{
/* Vectors go to IRAM */
_init_start = ABSOLUTE(.);
@@ -155,16 +185,4 @@ SECTIONS
_text_end = ABSOLUTE(.);
_etext = .;
} >iram0_2_seg
-
- .rtc.text :
- {
- . = ALIGN(4);
- *(.rtc.literal .rtc.text)
- } >rtc_iram_seg
-
- .rtc.data :
- {
- *(.rtc.data)
- *(.rtc.rodata)
- } > rtc_slow_seg
}
diff --git a/components/esp32/lib b/components/esp32/lib
index 9d18fd1a8f..b3090d8854 160000
--- a/components/esp32/lib
+++ b/components/esp32/lib
@@ -1 +1 @@
-Subproject commit 9d18fd1a8f7610130e69f8be74ec68f6399221b1
+Subproject commit b3090d885413fb78c86e7b88116cdb5c8c5e9e68
diff --git a/components/log/README.rst b/components/log/README.rst
new file mode 100644
index 0000000000..d378179c8f
--- /dev/null
+++ b/components/log/README.rst
@@ -0,0 +1,61 @@
+Logging library
+===============
+
+Overview
+--------
+
+Log library has two ways of managing log verbosity: compile time, set via menuconfig; and runtime, using ``esp_log_set_level`` function.
+
+At compile time, filtering is done using ``CONFIG_LOG_DEFAULT_LEVEL`` macro, set via menuconfig. All logging statments for levels higher than ``CONFIG_LOG_DEFAULT_LEVEL`` will be removed by the preprocessor.
+
+At run time, all logs below ``CONFIG_LOG_DEFAULT_LEVEL`` are enabled by default. ``esp_log_set_level`` function may be used to set logging level per module. Modules are identified by their tags, which are human-readable ASCII zero-terminated strings.
+
+How to use this library
+-----------------------
+
+In each C file which uses logging functionality, define TAG variable like this:
+
+.. code-block:: c
+
+ static const char* TAG = "MyModule";
+
+then use one of logging macros to produce output, e.g:
+
+.. code-block:: c
+
+ ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real);
+
+Several macros are available for different verbosity levels:
+
+* ``ESP_LOGE`` - error
+* ``ESP_LOGW`` - warning
+* ``ESP_LOGI`` - info
+* ``ESP_LOGD`` - debug
+* ``ESP_LOGV`` - verbose
+
+Additionally there is an _EARLY_ variant for each of these macros (e.g. ``ESP_EARLY_LOGE`` ).These variants can run in startup code, before heap allocator and syscalls have been initialized. When compiling bootloader, normal ``ESP_LOGx`` macros fall back to the same implementation as ``ESP_EARLY_LOGx`` macros. So the only place where ``ESP_EARLY_LOGx`` have to be used explicitly is the early startup code, such as heap allocator initialization code.
+
+(Note that such distinction would not have been necessary if we would have an ``ets_vprintf`` function in the ROM. Then it would be possible to switch implementation from _EARLY_ version to normal version on the fly. Unfortunately, ``ets_vprintf`` in ROM has been inlined by the compiler into ``ets_printf``, so it is not accessible outside.)
+
+To override default verbosity level at file or component scope, define ``LOG_LOCAL_LEVEL`` macro. At file scope, define it before including ``esp_log.h``, e.g.:
+
+.. code-block:: c
+
+ #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
+ #include "esp_log.h"
+
+
+At component scope, define it in component makefile:
+
+.. code-block:: make
+
+ CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
+
+To configure logging output per module at runtime, add calls to ``esp_log_set_level`` function:
+
+.. code-block:: c
+
+ esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level
+ esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack
+ esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
+
diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h
index 8ca6e241d4..6716f6e10f 100644
--- a/components/log/include/esp_log.h
+++ b/components/log/include/esp_log.h
@@ -24,76 +24,16 @@ extern "C" {
#endif
/**
- * @brief Logging library
- *
- * Log library has two ways of managing log verbosity: compile time, set via
- * menuconfig, and runtime, using esp_log_set_level function.
- *
- * At compile time, filtering is done using CONFIG_LOG_DEFAULT_LEVEL macro, set via
- * menuconfig. All logging statments for levels higher than CONFIG_LOG_DEFAULT_LEVEL
- * will be removed by the preprocessor.
- *
- * At run time, all logs below CONFIG_LOG_DEFAULT_LEVEL are enabled by default.
- * esp_log_set_level function may be used to set logging level per module.
- * Modules are identified by their tags, which are human-readable ASCII
- * zero-terminated strings.
- *
- * How to use this library:
- *
- * In each C file which uses logging functionality, define TAG variable like this:
- *
- * static const char* TAG = "MyModule";
- *
- * then use one of logging macros to produce output, e.g:
- *
- * ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real);
- *
- * Several macros are available for different verbosity levels:
- *
- * ESP_LOGE — error
- * ESP_LOGW — warning
- * ESP_LOGI — info
- * ESP_LOGD - debug
- * ESP_LOGV - verbose
- *
- * Additionally there is an _EARLY_ variant for each of these macros (e.g. ESP_EARLY_LOGE).
- * These variants can run in startup code, before heap allocator and syscalls
- * have been initialized.
- * When compiling bootloader, normal ESP_LOGx macros fall back to the same implementation
- * as ESP_EARLY_LOGx macros. So the only place where ESP_EARLY_LOGx have to be used explicitly
- * is the early startup code, such as heap allocator initialization code.
- *
- * (Note that such distinction would not have been necessary if we would have an
- * ets_vprintf function in the ROM. Then it would be possible to switch implementation
- * from _EARLY version to normal version on the fly. Unfortunately, ets_vprintf in ROM
- * has been inlined by the compiler into ets_printf, so it is not accessible outside.)
- *
- * To override default verbosity level at file or component scope, define LOG_LOCAL_LEVEL macro.
- * At file scope, define it before including esp_log.h, e.g.:
- *
- * #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
- * #include "esp_log.h"
- *
- * At component scope, define it in component makefile:
- *
- * CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
- *
- * To configure logging output per module at runtime, add calls to esp_log_set_level function:
- *
- * esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level
- * esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack
- * esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
+ * @brief Log level
*
*/
-
-
typedef enum {
- ESP_LOG_NONE, // No log output
- ESP_LOG_ERROR, // Critical errors, software module can not recover on its own
- ESP_LOG_WARN, // Error conditions from which recovery measures have been taken
- ESP_LOG_INFO, // Information messages which describe normal flow of events
- ESP_LOG_DEBUG, // Extra information which is not necessary for normal use (values, pointers, sizes, etc).
- ESP_LOG_VERBOSE // Bigger chunks of debugging information, or frequent messages which can potentially flood the output.
+ ESP_LOG_NONE, /*!< No log output */
+ ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */
+ ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */
+ ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */
+ ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
+ ESP_LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
} esp_log_level_t;
typedef int (*vprintf_like_t)(const char *, va_list);
@@ -120,17 +60,6 @@ void esp_log_level_set(const char* tag, esp_log_level_t level);
*/
void esp_log_set_vprintf(vprintf_like_t func);
-/**
- * @brief Write message into the log
- *
- * This function is not intended to be used directly. Instead, use one of
- * ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros.
- *
- * This function or these macros should not be used from an interrupt.
- */
-void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4)));
-
-
/**
* @brief Function which returns timestamp to be used in log output
*
@@ -143,7 +72,17 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, .
*
* @return timestamp, in milliseconds
*/
-uint32_t esp_log_timestamp();
+uint32_t esp_log_timestamp(void);
+
+/**
+ * @brief Write message into the log
+ *
+ * This function is not intended to be used directly. Instead, use one of
+ * ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros.
+ *
+ * This function or these macros should not be used from an interrupt.
+ */
+void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4)));
#if CONFIG_LOG_COLORS
diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig
index 15c94c66ba..801fa0b51c 100644
--- a/components/lwip/Kconfig
+++ b/components/lwip/Kconfig
@@ -24,6 +24,15 @@ config LWIP_SO_REUSE
Enabling this option allows binding to a port which remains in
TIME_WAIT.
+config LWIP_DHCP_MAX_NTP_SERVERS
+ int "Maximum number of NTP servers"
+ default 1
+ range 1 16
+ help
+ Set maxumum number of NTP servers used by LwIP SNTP module.
+ First argument of sntp_setserver/sntp_setservername functions
+ is limited to this value.
+
endmenu
diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c
index 455d007ea7..1529382f50 100755
--- a/components/lwip/api/sockets.c
+++ b/components/lwip/api/sockets.c
@@ -382,31 +382,6 @@ static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr,
static void lwip_socket_drop_registered_memberships(int s);
#endif /* LWIP_IGMP */
-#if ESP_LWIP
-#include "esp_wifi_internal.h"
-#include "esp_system.h"
-
-/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue.
- * Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket
- * sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped
- * in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here.
- * However, current solution is just a workaround, we need to consider the return value of wifi tx interface,
- * and feedback the return value to lwip and let lwip do the flow control itself.
- */
-static inline void esp32_tx_flow_ctrl(void)
-{
- uint8_t _wait_delay = 1;
-
- while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){
- vTaskDelay(_wait_delay/portTICK_RATE_MS);
- if (_wait_delay < 64) _wait_delay *= 2;
- }
-}
-
-#else
-#define esp32_tx_flow_ctrl()
-#endif
-
/** The global array of available sockets */
static struct lwip_sock sockets[NUM_SOCKETS];
#if ESP_THREAD_SAFE
@@ -1208,8 +1183,6 @@ lwip_send(int s, const void *data, size_t size, int flags)
#endif /* (LWIP_UDP || LWIP_RAW) */
}
- esp32_tx_flow_ctrl();
-
write_flags = NETCONN_COPY |
((flags & MSG_MORE) ? NETCONN_MORE : 0) |
((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
@@ -1391,8 +1364,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
#endif /* LWIP_TCP */
}
- esp32_tx_flow_ctrl();
-
if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
sock_set_errno(sock, err_to_errno(ERR_VAL));
diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h
index 67a62b8227..f705887508 100755
--- a/components/lwip/include/lwip/port/lwipopts.h
+++ b/components/lwip/include/lwip/port/lwipopts.h
@@ -33,6 +33,8 @@
#define __LWIPOPTS_H__
#include
+#include
+#include
#include "esp_task.h"
#include "sdkconfig.h"
@@ -523,7 +525,6 @@ extern unsigned long os_random(void);
#define ESP_IP4_ATON 1
#define ESP_LIGHT_SLEEP 1
-
#define TCP_WND_DEFAULT (4*TCP_MSS)
#define TCP_SND_BUF_DEFAULT (2*TCP_MSS)
@@ -550,12 +551,25 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
#define CHECKSUM_CHECK_UDP 0
#define CHECKSUM_CHECK_IP 0
-#define HEAP_HIGHWAT 20*1024
-
#define LWIP_NETCONN_FULLDUPLEX 1
#define LWIP_NETCONN_SEM_PER_THREAD 1
+#define LWIP_DHCP_MAX_NTP_SERVERS CONFIG_LWIP_DHCP_MAX_NTP_SERVERS
+#define LWIP_TIMEVAL_PRIVATE 0
+#define SNTP_SET_SYSTEM_TIME_US(sec, us) \
+ do { \
+ struct timeval tv = { .tv_sec = sec, .tv_usec = us }; \
+ settimeofday(&tv, NULL); \
+ } while (0);
+
+#define SNTP_GET_SYSTEM_TIME(sec, us) \
+ do { \
+ struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; \
+ gettimeofday(&tv, NULL); \
+ (sec) = tv.tv_sec; \
+ (us) = tv.tv_usec; \
+ } while (0);
#define SOC_SEND_LOG //printf
diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c
index 548bb7f970..ffad69cd46 100755
--- a/components/lwip/port/netif/wlanif.c
+++ b/components/lwip/port/netif/wlanif.c
@@ -142,16 +142,13 @@ low_level_output(struct netif *netif, struct pbuf *p)
}
}
- esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len);
- return ERR_OK;
-
+ return esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len);
#else
for(q = p; q != NULL; q = q->next) {
esp_wifi_internal_tx(wifi_if, q->payload, q->len);
}
-#endif
-
return ERR_OK;
+#endif
}
/**
diff --git a/components/newlib/platform_include/esp_newlib.h b/components/newlib/platform_include/esp_newlib.h
index 468f2ae34f..eac3544259 100644
--- a/components/newlib/platform_include/esp_newlib.h
+++ b/components/newlib/platform_include/esp_newlib.h
@@ -31,7 +31,13 @@ void esp_reent_init(struct _reent* r);
* Called from the startup code, not intended to be called from application
* code.
*/
-void esp_setup_syscalls();
+void esp_setup_syscall_table();
+/**
+ * Initialize hardware timer used as time source for newlib time functions.
+ *
+ * Called from the startup code, not intended to be called from application.
+ */
+void esp_setup_time_syscalls();
#endif //__ESP_NEWLIB_H__
diff --git a/components/newlib/syscall_table.c b/components/newlib/syscall_table.c
index b6414af554..feed768172 100644
--- a/components/newlib/syscall_table.c
+++ b/components/newlib/syscall_table.c
@@ -24,6 +24,7 @@
#include
#include "rom/libc_stubs.h"
#include "esp_vfs.h"
+#include "esp_newlib.h"
static struct _reent s_reent;
@@ -79,7 +80,7 @@ static struct syscall_stub_table s_stub_table = {
._scanf_float = &_scanf_float,
};
-void esp_setup_syscalls()
+void esp_setup_syscall_table()
{
syscall_table_ptr_pro = &s_stub_table;
syscall_table_ptr_app = &s_stub_table;
diff --git a/components/newlib/time.c b/components/newlib/time.c
index 021b295451..5f60e1d7b2 100644
--- a/components/newlib/time.c
+++ b/components/newlib/time.c
@@ -14,22 +14,169 @@
#include
#include
+#include
+#include
#include
#include
#include
#include
+#include
#include "esp_attr.h"
+#include "soc/soc.h"
+#include "soc/rtc_cntl_reg.h"
+#include "soc/frc_timer_reg.h"
+#include "rom/ets_sys.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/task.h"
+#include "sdkconfig.h"
+#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 )
+#define WITH_RTC 1
+#endif
-clock_t _times_r(struct _reent *r, struct tms *ptms)
+#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 )
+#define WITH_FRC1 1
+#endif
+
+#ifdef WITH_RTC
+static uint64_t get_rtc_time_us()
{
- __errno_r(r) = ENOSYS;
- return (clock_t) -1;
+ SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M);
+ while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID_M) == 0) {
+ ;
+ }
+ CLEAR_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M);
+ uint64_t low = READ_PERI_REG(RTC_CNTL_TIME0_REG);
+ uint64_t high = READ_PERI_REG(RTC_CNTL_TIME1_REG);
+ uint64_t ticks = (high << 32) | low;
+ return ticks * 100 / (RTC_CTNL_SLOWCLK_FREQ / 10000); // scale RTC_CTNL_SLOWCLK_FREQ to avoid overflow
+}
+#endif // WITH_RTC
+
+
+// time from Epoch to the first boot time
+#ifdef WITH_RTC
+static RTC_DATA_ATTR struct timeval s_boot_time;
+#else
+static struct timeval s_boot_time;
+#endif
+static _lock_t s_boot_time_lock;
+
+
+#ifdef WITH_FRC1
+#define FRC1_PRESCALER 16
+#define FRC1_PRESCALER_CTL 2
+#define FRC1_TICK_FREQ (APB_CLK_FREQ / FRC1_PRESCALER)
+#define FRC1_TICKS_PER_US (FRC1_TICK_FREQ / 1000000)
+#define FRC1_ISR_PERIOD_US (FRC_TIMER_LOAD_VALUE(0) / FRC1_TICKS_PER_US)
+// Counter frequency will be APB_CLK_FREQ / 16 = 5 MHz
+// 1 tick = 0.2 us
+// Timer has 23 bit counter, so interrupt will fire each 1677721.6 microseconds.
+// This is not a whole number, so timer will drift by 0.3 ppm due to rounding error.
+
+static volatile uint64_t s_microseconds = 0;
+
+static void IRAM_ATTR frc_timer_isr()
+{
+ WRITE_PERI_REG(FRC_TIMER_INT_REG(0), FRC_TIMER_INT_CLR);
+ s_microseconds += FRC1_ISR_PERIOD_US;
}
-// TODO: read time from RTC
-int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz)
+#endif // WITH_FRC1
+
+void esp_setup_time_syscalls()
{
+#if defined( WITH_FRC1 )
+#if defined( WITH_RTC )
+ // initialize time from RTC clock
+ s_microseconds = get_rtc_time_us();
+#endif //WITH_RTC
+
+ // set up timer
+ WRITE_PERI_REG(FRC_TIMER_CTRL_REG(0), \
+ FRC_TIMER_AUTOLOAD | \
+ (FRC1_PRESCALER_CTL << FRC_TIMER_PRESCALER_S) | \
+ FRC_TIMER_EDGE_INT);
+
+ WRITE_PERI_REG(FRC_TIMER_LOAD_REG(0), FRC_TIMER_LOAD_VALUE(0));
+ SET_PERI_REG_MASK(FRC_TIMER_CTRL_REG(0),
+ FRC_TIMER_ENABLE | \
+ FRC_TIMER_INT_ENABLE);
+ intr_matrix_set(xPortGetCoreID(), ETS_TIMER1_INTR_SOURCE, ETS_FRC1_INUM);
+ xt_set_interrupt_handler(ETS_FRC1_INUM, &frc_timer_isr, NULL);
+ xt_ints_on(1 << ETS_FRC1_INUM);
+#endif // WITH_FRC1
+}
+
+clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms)
+{
+ clock_t t = xTaskGetTickCount() * (portTICK_PERIOD_MS * CLK_TCK / 1000);
+ ptms->tms_cstime = t;
+ ptms->tms_cutime = 0;
+ ptms->tms_stime = t;
+ ptms->tms_utime = 0;
+ struct timeval tv = {0, 0};
+ _gettimeofday_r(r, &tv, NULL);
+ return (clock_t) tv.tv_sec;
+}
+
+static uint64_t get_time_since_boot()
+{
+ uint64_t microseconds = 0;
+#ifdef WITH_FRC1
+ uint32_t timer_ticks_before = READ_PERI_REG(FRC_TIMER_COUNT_REG(0));
+ microseconds = s_microseconds;
+ uint32_t timer_ticks_after = READ_PERI_REG(FRC_TIMER_COUNT_REG(0));
+ if (timer_ticks_after > timer_ticks_before) {
+ // overflow happened at some point between getting
+ // timer_ticks_before and timer_ticks_after
+ // microseconds value is ambiguous, get a new one
+ microseconds = s_microseconds;
+ }
+ microseconds += (FRC_TIMER_LOAD_VALUE(0) - timer_ticks_after) / FRC1_TICKS_PER_US;
+#elif defined(WITH_RTC)
+ microseconds = get_rtc_time_us();
+#endif
+ return microseconds;
+}
+
+int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz)
+{
+ (void) tz;
+#if defined( WITH_FRC1 ) || defined( WITH_RTC )
+ uint64_t microseconds = get_time_since_boot();
+ if (tv) {
+ _lock_acquire(&s_boot_time_lock);
+ microseconds += s_boot_time.tv_usec;
+ tv->tv_sec = s_boot_time.tv_sec + microseconds / 1000000;
+ tv->tv_usec = microseconds % 1000000;
+ _lock_release(&s_boot_time_lock);
+ }
+ return 0;
+#else
__errno_r(r) = ENOSYS;
return -1;
+#endif // defined( WITH_FRC1 ) || defined( WITH_RTC )
+}
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+ (void) tz;
+#if defined( WITH_FRC1 ) || defined( WITH_RTC )
+ if (tv) {
+ _lock_acquire(&s_boot_time_lock);
+ uint64_t now = ((uint64_t) tv->tv_sec) * 1000000LL + tv->tv_usec;
+ uint64_t since_boot = get_time_since_boot();
+ uint64_t boot_time = now - since_boot;
+
+ s_boot_time.tv_sec = boot_time / 1000000;
+ s_boot_time.tv_usec = boot_time % 1000000;
+ _lock_release(&s_boot_time_lock);
+ }
+ return 0;
+#else
+ __errno_r(r) = ENOSYS;
+ return -1;
+#endif
}
diff --git a/components/nvs_flash/README.rst b/components/nvs_flash/README.rst
index 2f1c469135..ade5518aa5 100644
--- a/components/nvs_flash/README.rst
+++ b/components/nvs_flash/README.rst
@@ -7,14 +7,14 @@ Introduction
Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This sections introduces some concepts used by NVS.
Underlying storage
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
Currently NVS uses a portion of main flash memory through ``spi_flash_{read|write|erase}`` APIs. The range of flash sectors to be used by the library is provided to ``nvs_flash_init`` function.
Future versions of this library may add other storage backends to keep data in another flash chip (SPI or I2C), RTC, FRAM, etc.
Keys and values
-~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^
NVS operates on key-value pairs. Keys are ASCII strings, maximum key length is currently 15 characters. Values can have one of the following types:
@@ -32,12 +32,12 @@ Keys are required to be unique. Writing a value for a key which already exists b
Data type check is also performed when reading a value. An error is returned if data type of read operation doesn’t match the data type of the value.
Namespaces
-~~~~~~~~~~
+^^^^^^^^^^
To mitigate potential conflicts in key names between different components, NVS assigns each key-value pair to one of namespaces. Namespace names follow the same rules as key names, i.e. 15 character maximum length. Namespace name is specified in the ``nvs_open`` call. This call returns an opaque handle, which is used in subsequent calls to ``nvs_read_*``, ``nvs_write_*``, and ``nvs_commit`` functions. This way, handle is associated with a namespace, and key names will not collide with same names in other namespaces.
Security, tampering, and robustness
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
NVS library doesn't implement tamper prevention measures. It is possible for anyone with physical access to the flash chip to alter, erase, or add key-value pairs.
@@ -59,12 +59,12 @@ Internals
---------
Log of key-value pairs
-~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^
NVS stores key-value pairs sequentially, with new key-value pairs being added at the end. When a value of any given key has to be updated, new key-value pair is added at the end of the log and old key-value pair is marked as erased.
Pages and entries
-~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^
NVS library uses two main entities in its operation: pages and entries. Page is a logical structure which stores a portion of the overall log. Logical page corresponds to one physical sector of flash memory. Pages which are in use have a *sequence number* associated with them. Sequence numbers impose an ordering on pages. Higher sequence numbers correspond to pages which were created later. Each page can be in one of the following states:
@@ -101,7 +101,7 @@ Mapping from flash sectors to logical pages doesn't have any particular order. L
+----------+ +----------+ +----------+ +----------+
Structure of a page
-~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^
For now we assume that flash sector size is 4096 bytes and that ESP32 flash encryption hardware operates on 32-byte blocks. It is possible to introduce some settings configurable at compile-time (e.g. via menuconfig) to accommodate flash chips with different sector sizes (although it is not clear if other components in the system, e.g. SPI flash driver and SPI flash cache can support these other sizes).
@@ -133,7 +133,7 @@ CRC32 value in header is calculated over the part which doesn't include state va
The following sections describe structure of entry state bitmap and entry itself.
Entry and entry state bitmap
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Each entry can be in one of the following three states. Each state is represented with two bits in the entry state bitmap. Final four bits in the bitmap (256 - 2 * 126) are unused.
@@ -148,7 +148,7 @@ Erased (2'b00)
Structure of entry
-~~~~~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^^^^^
For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and blob types, entry holds part of the whole key-value pair. In case when a key-value pair spans multiple entries, all entries are stored in the same page.
@@ -200,7 +200,7 @@ Variable length values (strings and blobs) are written into subsequent entries,
Namespaces
-~~~~~~~~~~
+^^^^^^^^^^
As mentioned above, each key-value pair belongs to one of the namespaces. Namespaces identifiers (strings) are stored as keys of key-value pairs in namespace with index 0. Values corresponding to these keys are indexes of these namespaces.
@@ -218,10 +218,9 @@ As mentioned above, each key-value pair belongs to one of the namespaces. Namesp
Item hash list
-~~~~~~~~~~~~~~
+^^^^^^^^^^^^^^
To reduce the number of reads performed from flash memory, each member of Page class maintains a list of pairs: (item index; item hash). This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, ``Page::findItem`` first performs search for item hash in the hash list. This gives the item index within the page, if such an item exists. Due to a hash collision it is possible that a different item will be found. This is handled by falling back to iteration over items in flash.
Each node in hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace and key name. CRC32 is used for calculation, result is truncated to 24 bits. To reduce overhead of storing 32-bit entries in a linked list, list is implemented as a doubly-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and 32-bit count field. Minimal amount of extra RAM useage per page is therefore 128 bytes, maximum is 640 bytes.
-
diff --git a/components/nvs_flash/include/nvs.h b/components/nvs_flash/include/nvs.h
index 912ea22103..8418959793 100644
--- a/components/nvs_flash/include/nvs.h
+++ b/components/nvs_flash/include/nvs.h
@@ -28,23 +28,27 @@ extern "C" {
*/
typedef uint32_t nvs_handle;
-#define ESP_ERR_NVS_BASE 0x1100
-#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01)
-#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02)
-#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03)
-#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04)
-#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05)
-#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06)
-#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07)
-#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08)
-#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09)
-#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a)
-#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b)
-#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c)
+#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */
+#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) /*!< The storage driver is not initialized */
+#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */
+#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) /*!< TBA */
+#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) /*!< Storage handle was opened as read only */
+#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) /*!< There is not enough space in the underlying storage to save the value */
+#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) /*!< Namespace name doesn’t satisfy constraints */
+#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) /*!< Handle has been closed or is NULL */
+#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) /*!< The value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again. */
+#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) /*!< TBA */
+#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) /*!< TBA */
+#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< TBA */
+#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< TBA */
+/**
+ * @brief Mode of opening the non-volatile storage
+ *
+ */
typedef enum {
- NVS_READONLY,
- NVS_READWRITE
+ NVS_READONLY, /*!< Read only */
+ NVS_READWRITE /*!< Read and write */
} nvs_open_mode;
/**
@@ -58,12 +62,13 @@ typedef enum {
* underlying implementation, but is guaranteed to be
* at least 16 characters. Shouldn't be empty.
* @param[in] open_mode NVS_READWRITE or NVS_READONLY. If NVS_READONLY, will
- * open a handle for reading only. All write requests will
- * be rejected for this handle.
+ * open a handle for reading only. All write requests will
+ * be rejected for this handle.
* @param[out] out_handle If successful (return code is zero), handle will be
* returned in this argument.
*
- * @return - ESP_OK if storage handle was opened successfully
+ * @return
+ * - ESP_OK if storage handle was opened successfully
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized
* - ESP_ERR_NVS_NOT_FOUND id namespace doesn't exist yet and
* mode is NVS_READONLY
@@ -86,7 +91,8 @@ esp_err_t nvs_open(const char* name, nvs_open_mode open_mode, nvs_handle *out_ha
* @param[in] value The value to set.
* @param[in] length For nvs_set_blob: length of binary value to set, in bytes.
*
- * @return - ESP_OK if value was set successfully
+ * @return
+ * - ESP_OK if value was set successfully
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
* - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
@@ -129,24 +135,26 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si
* It is suggested that nvs_get/set_str is used for zero-terminated C strings, and
* nvs_get/set_blob used for arbitrary data structures.
*
- * Example of using nvs_get_i32:
+ * \code{c}
+ * // Example of using nvs_get_i32:
* int32_t max_buffer_size = 4096; // default value
* esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size);
* assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND);
* // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still
* // have its default value.
*
- * Example (without error checking) of using nvs_get_str to get a string into dynamic array:
+ * // Example (without error checking) of using nvs_get_str to get a string into dynamic array:
* size_t required_size;
* nvs_get_str(my_handle, "server_name", NULL, &required_size);
* char* server_name = malloc(required_size);
* nvs_get_str(my_handle, "server_name", server_name, &required_size);
*
- * Example (without error checking) of using nvs_get_blob to get a binary data
+ * // Example (without error checking) of using nvs_get_blob to get a binary data
* into a static array:
* uint8_t mac_addr[6];
* size_t size = sizeof(mac_addr);
* nvs_get_blob(my_handle, "dst_mac_addr", mac_addr, &size);
+ * \endcode
*
* @param[in] handle Handle obtained from nvs_open function.
* @param[in] key Key name. Maximal length is determined by the underlying
@@ -162,7 +170,8 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si
* zero, will be set to the actual length of the value
* written. For nvs_get_str this includes zero terminator.
*
- * @return - ESP_OK if the value was retrieved successfully
+ * @return
+ * - ESP_OK if the value was retrieved successfully
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
@@ -191,7 +200,8 @@ esp_err_t nvs_get_blob(nvs_handle handle, const char* key, void* out_value, size
* implementation, but is guaranteed to be at least
* 16 characters. Shouldn't be empty.
*
- * @return - ESP_OK if erase operation was successful
+ * @return
+ * - ESP_OK if erase operation was successful
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
@@ -207,7 +217,8 @@ esp_err_t nvs_erase_key(nvs_handle handle, const char* key);
* @param[in] handle Storage handle obtained with nvs_open.
* Handles that were opened read only cannot be used.
*
- * @return - ESP_OK if erase operation was successful
+ * @return
+ * - ESP_OK if erase operation was successful
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
* - other error codes from the underlying storage driver
@@ -224,7 +235,8 @@ esp_err_t nvs_erase_all(nvs_handle handle);
* @param[in] handle Storage handle obtained with nvs_open.
* Handles that were opened read only cannot be used.
*
- * @return - ESP_OK if the changes have been written successfully
+ * @return
+ * - ESP_OK if the changes have been written successfully
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
* - other error codes from the underlying storage driver
*/
@@ -249,3 +261,4 @@ void nvs_close(nvs_handle handle);
#endif
#endif //ESP_NVS_H
+
diff --git a/components/nvs_flash/include/nvs_flash.h b/components/nvs_flash/include/nvs_flash.h
index ce98f39407..1cade0e956 100644
--- a/components/nvs_flash/include/nvs_flash.h
+++ b/components/nvs_flash/include/nvs_flash.h
@@ -22,6 +22,8 @@ extern "C" {
Temporarily, this region is hardcoded as a 12KB (0x3000 byte)
region starting at 24KB (0x6000 byte) offset in flash.
+
+ @return ESP_OK if flash was successfully initialised.
*/
esp_err_t nvs_flash_init(void);
diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp
index fae1f6f1b7..23cefd1aad 100644
--- a/components/nvs_flash/src/nvs_page.cpp
+++ b/components/nvs_flash/src/nvs_page.cpp
@@ -3,7 +3,7 @@
// 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
@@ -131,8 +131,12 @@ esp_err_t Page::writeEntryData(const uint8_t* data, size_t size)
esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, const void* data, size_t dataSize)
{
Item item;
-
esp_err_t err;
+
+ if (mState == PageState::INVALID) {
+ return ESP_ERR_NVS_INVALID_STATE;
+ }
+
if (mState == PageState::UNINITIALIZED) {
err = initialize();
if (err != ESP_OK) {
@@ -166,7 +170,6 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c
}
// write first item
-
size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE;
item = Item(nsIndex, datatype, span, key);
mHashList.insert(item, mNextFreeEntry);
@@ -215,6 +218,11 @@ esp_err_t Page::readItem(uint8_t nsIndex, ItemType datatype, const char* key, vo
{
size_t index = 0;
Item item;
+
+ if (mState == PageState::INVALID) {
+ return ESP_ERR_NVS_INVALID_STATE;
+ }
+
esp_err_t rc = findItem(nsIndex, datatype, key, index, item);
if (rc != ESP_OK) {
return rc;
@@ -293,6 +301,8 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
}
if (item.calculateCrc32() != item.crc32) {
rc = alterEntryState(index, EntryState::ERASED);
+ --mUsedEntryCount;
+ ++mErasedEntryCount;
if (rc != ESP_OK) {
return rc;
}
@@ -465,7 +475,9 @@ esp_err_t Page::mLoadEntryTable()
if (end > ENTRY_COUNT) {
end = ENTRY_COUNT;
}
- for (size_t i = 0; i < end; ++i) {
+ size_t span;
+ for (size_t i = 0; i < end; i += span) {
+ span = 1;
if (mEntryTable.get(i) == EntryState::ERASED) {
lastItemIndex = INVALID_ENTRY;
continue;
@@ -478,6 +490,11 @@ esp_err_t Page::mLoadEntryTable()
mState = PageState::INVALID;
return err;
}
+
+ mHashList.insert(item, i);
+
+ // search for potential duplicate item
+ size_t duplicateIndex = mHashList.find(0, item);
if (item.crc32 != item.calculateCrc32()) {
err = eraseEntryAndSpan(i);
@@ -488,25 +505,26 @@ esp_err_t Page::mLoadEntryTable()
continue;
}
- mHashList.insert(item, i);
-
- if (item.datatype != ItemType::BLOB && item.datatype != ItemType::SZ) {
- continue;
- }
-
- size_t span = item.span;
- bool needErase = false;
- for (size_t j = i; j < i + span; ++j) {
- if (mEntryTable.get(j) != EntryState::WRITTEN) {
- needErase = true;
- lastItemIndex = INVALID_ENTRY;
- break;
+
+ if (item.datatype == ItemType::BLOB || item.datatype == ItemType::SZ) {
+ span = item.span;
+ bool needErase = false;
+ for (size_t j = i; j < i + span; ++j) {
+ if (mEntryTable.get(j) != EntryState::WRITTEN) {
+ needErase = true;
+ lastItemIndex = INVALID_ENTRY;
+ break;
+ }
+ }
+ if (needErase) {
+ eraseEntryAndSpan(i);
+ continue;
}
}
- if (needErase) {
- eraseEntryAndSpan(i);
+
+ if (duplicateIndex < i) {
+ eraseEntryAndSpan(duplicateIndex);
}
- i += span - 1;
}
// check that last item is not duplicate
@@ -785,8 +803,12 @@ void Page::debugDump() const
Item item;
readEntry(i, item);
if (skip == 0) {
- printf("W ns=%2u type=%2u span=%3u key=\"%s\"\n", item.nsIndex, static_cast(item.datatype), item.span, item.key);
- skip = item.span - 1;
+ printf("W ns=%2u type=%2u span=%3u key=\"%s\" len=%d\n", item.nsIndex, static_cast(item.datatype), item.span, item.key, (item.span != 1)?((int)item.varLength.dataSize):-1);
+ if (item.span > 0 && item.span <= ENTRY_COUNT - i) {
+ skip = item.span - 1;
+ } else {
+ skip = 0;
+ }
} else {
printf("D\n");
skip--;
diff --git a/components/nvs_flash/test/crc.cpp b/components/nvs_flash/test/crc.cpp
index 288b58a323..4cbb9be9ec 100644
--- a/components/nvs_flash/test/crc.cpp
+++ b/components/nvs_flash/test/crc.cpp
@@ -14,25 +14,51 @@
#include
#include
-extern "C" unsigned long crc32_le(unsigned long crc_in, unsigned char const* data, unsigned int length)
-{
- uint32_t i;
- bool bit;
- uint8_t c;
- uint32_t crc = (uint32_t) crc_in;
+static const unsigned int crc32_le_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
+ 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
+ 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
+ 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
+ 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
+ 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
+ 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
+ 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
+ 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
+ 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
+ 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
+ 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
+ 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
+
+ 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
+ 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
+ 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
+ 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
+ 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
+ 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
+ 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
+ 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
+ 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
+ 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
+ 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
+ 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
+ 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
+};
- while (length--) {
- c = *data++;
- for (i = 0x80; i > 0; i >>= 1) {
- bit = crc & 0x80000000;
- if (c & i) {
- bit = !bit;
- }
- crc <<= 1;
- if (bit) {
- crc ^= 0x04c11db7;
- }
- }
+
+
+extern "C" unsigned int crc32_le(unsigned int crc, unsigned char const * buf,unsigned int len)
+{
+ unsigned int i;
+ crc = ~crc;
+ for(i=0;i>8);
}
- return crc;
+ return ~crc;
}
+
diff --git a/components/nvs_flash/test/spi_flash_emulation.h b/components/nvs_flash/test/spi_flash_emulation.h
index ba50c4f9e4..14e56bab6e 100644
--- a/components/nvs_flash/test/spi_flash_emulation.h
+++ b/components/nvs_flash/test/spi_flash_emulation.h
@@ -74,11 +74,11 @@ public:
return false;
}
- if (mFailCountdown != SIZE_MAX && mFailCountdown-- == 0) {
- return false;
- }
-
for (size_t i = 0; i < size / 4; ++i) {
+ if (mFailCountdown != SIZE_MAX && mFailCountdown-- == 0) {
+ return false;
+ }
+
uint32_t sv = src[i];
size_t pos = dstAddr / 4 + i;
uint32_t& dv = mData[pos];
@@ -141,6 +141,18 @@ public:
{
return reinterpret_cast(mData.data());
}
+
+ void load(const char* filename)
+ {
+ FILE* f = fopen(filename, "rb");
+ fseek(f, 0, SEEK_END);
+ off_t size = ftell(f);
+ assert(size % SPI_FLASH_SEC_SIZE == 0);
+ mData.resize(size);
+ fseek(f, 0, SEEK_SET);
+ auto s = fread(mData.data(), SPI_FLASH_SEC_SIZE, size / SPI_FLASH_SEC_SIZE, f);
+ assert(s == static_cast(size / SPI_FLASH_SEC_SIZE));
+ }
void clearStats()
{
diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp
index ce552578db..528c9df686 100644
--- a/components/nvs_flash/test/test_nvs.cpp
+++ b/components/nvs_flash/test/test_nvs.cpp
@@ -894,7 +894,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
size_t totalOps = 0;
int lastPercent = -1;
- for (uint32_t errDelay = 4; ; ++errDelay) {
+ for (uint32_t errDelay = 0; ; ++errDelay) {
INFO(errDelay);
emu.randomize(seed);
emu.clearStats();
@@ -903,23 +903,25 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
if (totalOps != 0) {
int percent = errDelay * 100 / totalOps;
- if (percent != lastPercent) {
+ if (percent > lastPercent) {
printf("%d/%d (%d%%)\r\n", errDelay, static_cast(totalOps), percent);
lastPercent = percent;
}
}
- 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));
-
size_t count = iter_count;
- if(test.doRandomThings(handle, gen, count) != ESP_ERR_FLASH_OP_FAIL) {
- nvs_close(handle);
- break;
+
+ if (nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN) == ESP_OK) {
+ if (nvs_open("namespace1", NVS_READWRITE, &handle) == ESP_OK) {
+ if(test.doRandomThings(handle, gen, count) != ESP_ERR_FLASH_OP_FAIL) {
+ nvs_close(handle);
+ break;
+ }
+ nvs_close(handle);
+ }
}
- nvs_close(handle);
TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
@@ -929,7 +931,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
CHECK(0);
}
nvs_close(handle);
- totalOps = emu.getEraseOps() + emu.getWriteOps();
+ totalOps = emu.getEraseOps() + emu.getWriteBytes() / 4;
}
}
@@ -951,6 +953,108 @@ TEST_CASE("test for memory leaks in open/set", "[leaks]")
}
}
+TEST_CASE("duplicate items are removed", "[nvs][dupes]")
+{
+ SpiFlashEmulator emu(3);
+ {
+ // create one item
+ nvs::Page p;
+ p.load(0);
+ p.writeItem(1, "opmode", 3);
+ }
+ {
+ // add another two without deleting the first one
+ nvs::Item item(1, ItemType::U8, 1, "opmode");
+ item.data[0] = 2;
+ item.crc32 = item.calculateCrc32();
+ emu.write(3 * 32, reinterpret_cast(&item), sizeof(item));
+ emu.write(4 * 32, reinterpret_cast(&item), sizeof(item));
+ uint32_t mask = 0xFFFFFFEA;
+ emu.write(32, &mask, 4);
+ }
+ {
+ // load page and check that second item persists
+ nvs::Storage s;
+ s.init(0, 3);
+ uint8_t val;
+ ESP_ERROR_CHECK(s.readItem(1, "opmode", val));
+ CHECK(val == 2);
+ }
+ {
+ Page p;
+ p.load(0);
+ CHECK(p.getErasedEntryCount() == 2);
+ CHECK(p.getUsedEntryCount() == 1);
+ }
+}
+
+TEST_CASE("recovery after failure to write data", "[nvs]")
+{
+ SpiFlashEmulator emu(3);
+ const char str[] = "value 0123456789abcdef012345678value 0123456789abcdef012345678";
+
+ // make flash write fail exactly in Page::writeEntryData
+ emu.failAfter(17);
+ {
+ Storage storage;
+ TEST_ESP_OK(storage.init(0, 3));
+
+ TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_FLASH_OP_FAIL);
+
+ // check that repeated operations cause an error
+ TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_NVS_INVALID_STATE);
+
+ uint8_t val;
+ TEST_ESP_ERR(storage.readItem(1, ItemType::U8, "key", &val, sizeof(val)), ESP_ERR_NVS_NOT_FOUND);
+ }
+ {
+ // load page and check that data was erased
+ Page p;
+ p.load(0);
+ CHECK(p.getErasedEntryCount() == 3);
+ CHECK(p.getUsedEntryCount() == 0);
+
+ // try to write again
+ TEST_ESP_OK(p.writeItem(1, ItemType::SZ, "key", str, strlen(str)));
+ }
+}
+
+TEST_CASE("crc error in variable length item is handled", "[nvs]")
+{
+ SpiFlashEmulator emu(3);
+ const uint64_t before_val = 0xbef04e;
+ const uint64_t after_val = 0xaf7e4;
+ // write some data
+ {
+ Page p;
+ p.load(0);
+ TEST_ESP_OK(p.writeItem(0, "before", before_val));
+ const char* str = "foobar";
+ TEST_ESP_OK(p.writeItem(0, ItemType::SZ, "key", str, strlen(str)));
+ TEST_ESP_OK(p.writeItem(0, "after", after_val));
+ }
+ // corrupt some data
+ uint32_t w;
+ CHECK(emu.read(&w, 32 * 3 + 8, sizeof(w)));
+ w &= 0xf000000f;
+ CHECK(emu.write(32 * 3 + 8, &w, sizeof(w)));
+ // load and check
+ {
+ Page p;
+ p.load(0);
+ CHECK(p.getUsedEntryCount() == 2);
+ CHECK(p.getErasedEntryCount() == 2);
+
+ uint64_t val;
+ TEST_ESP_OK(p.readItem(0, "before", val));
+ CHECK(val == before_val);
+ TEST_ESP_ERR(p.findItem(0, ItemType::SZ, "key"), ESP_ERR_NVS_NOT_FOUND);
+ TEST_ESP_OK(p.readItem(0, "after", val));
+ CHECK(val == after_val);
+ }
+}
+
+
TEST_CASE("dump all performance data", "[nvs]")
{
std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl;
diff --git a/components/openssl/OpenSSL-APIs.rst b/components/openssl/OpenSSL-APIs.rst
new file mode 100644
index 0000000000..93e438dcf9
--- /dev/null
+++ b/components/openssl/OpenSSL-APIs.rst
@@ -0,0 +1,1797 @@
+OpenSSL-APIs
+------------
+
+This directory does not contain OpenSSL itself, but the code here can be used as a wrapper for applications using the OpenSSL API.
+It uses mbedTLS to do the actual work, so anyone compiling openssl code needs the mbedtls library and header file.
+
+OpenSSL APIs not mentioned in this article are not open to public for the time,
+also do not have the corresponding function.
+If user calls it directly, it will always return an error or may show cannot link at compiling time.
+
+Chapter Introduction
+====================
+
+- Chapter 1. SSL Context Method Create
+- Chapter 2. SSL Context Fucntion
+- Chapter 3. SSL Fucntion
+- Chapter 4. SSL X509 Certification and Private Key Function
+
+
+Chapter 1. SSL Context Method Create
+====================================
+
+1.1 const SSL_METHOD* ``SSLv3_client_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ SSLV3.0 version SSL context client method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = SSLv3_client_method();
+
+ ...
+ }
+
+1.2 const SSL_METHOD* ``TLSv1_client_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.0 version SSL context client method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_client_method();
+
+ ...
+ }
+
+1.3 const SSL_METHOD* ``TLSv1_1_client_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.1 version SSL context client method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_1_client_method();
+
+ ...
+ }
+
+1.4 const SSL_METHOD* ``TLSv1_2_client_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.2 version SSL context client method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_2_client_method();
+
+ ...
+ }
+
+1.5 const SSL_METHOD* ``TLS_client_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.2 version SSL context client method point
+
+ Description::
+
+ create the default SSL context method, it's always to be TLSV1.2
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_2_client_method();
+
+ ...
+ }
+
+1.6 const SSL_METHOD* ``SSLv3_server_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ SSLV3.0 version SSL context server method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = SSLv3_server_method();
+
+ ...
+ }
+
+1.7 const SSL_METHOD* ``TLSv1_server_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.0 version SSL context server method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_server_method();
+
+ ...
+ }
+
+1.8 const SSL_METHOD* ``TLSv1_1_server_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.1 version SSL context server method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example :
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_1_server_method();
+
+ ...
+ }
+
+
+1.9 const SSL_METHOD* ``TLSv1_2_server_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.2 version SSL context server method point
+
+ Description::
+
+ create the target SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_2_server_method();
+
+ ...
+ }
+
+1.10 const SSL_METHOD* ``TLS_server_method`` (void)
+
+ Arguments::
+
+ none
+
+ Return::
+
+ TLSV1.2 version SSL context server method point
+
+ Description::
+
+ create the default SSL context method, it's always to be TLSV1.2
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method = TLSv1_2_server_method();
+
+ ...
+ }
+
+
+Chapter 2. SSL Context Fucntion
+===============================
+
+
+2.1 SSL_CTX* ``SSL_CTX_new`` (const SSL_METHOD *method)
+
+ Arguments::
+
+ method - the SSL context method point
+
+ Return::
+
+ context point
+
+ Description::
+
+ create a SSL context
+
+ Example::
+
+ void example(void)
+ {
+ SSL_CTX *ctx = SSL_CTX_new(SSLv3_server_method());
+
+ ...
+ }
+
+
+2.2 ``void SSL_CTX_free`` (SSL_CTX *ctx)
+
+ Arguments::
+
+ ctx - the SSL context point
+
+ Return::
+
+ none
+
+ Description::
+
+ free a SSL context
+
+ Example::
+
+ void example(void)
+ {
+ SSL_CTX *ctx;
+
+ ... ...
+
+ SSL_CTX_free(ctx);
+ }
+
+
+2.3 ``int SSL_CTX_set_ssl_version`` (SSL_CTX *ctx, const SSL_METHOD *meth)
+
+ Arguments::
+
+ ctx - SSL context point
+ meth - SSL method point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ set the SSL context version
+
+ Example::
+
+ void example(void)
+ {
+ SSL_CTX *ctx;
+ const SSL_METHOD *meth;
+
+ ... ...
+
+ SSL_CTX_set_ssl_version(ctx, meth);
+ }
+
+
+2.4 const SSL_METHOD* ``SSL_CTX_get_ssl_method`` (SSL_CTX *ctx)
+
+ Arguments::
+
+ ctx - SSL context point
+
+ Return::
+
+ SSL context method
+
+ Description::
+
+ get the SSL context method
+
+ Example::
+
+ void example(void)
+ {
+ const SSL_METHOD *method;
+ SSL_CTX *ctx;
+
+ ... ...
+
+ method = SSL_CTX_get_ssl_method(ctx);
+ }
+
+
+
+Chapter 3. SSL Fucntion
+=======================
+
+
+3.1 SSL* ``SSL_new`` (SSL_CTX *ctx)
+
+ Arguments::
+
+ ctx - SSL context point
+
+ Return::
+
+ SSL method
+
+ Description::
+
+ create a SSL
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ SSL_CTX *ctx;
+
+ ... ...
+
+ ssl = SSL_new(ctx);
+ }
+
+
+3.2 void ``SSL_free`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ none
+
+ Description::
+
+ free SSL
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+
+ ... ...
+
+ SSL_free(ssl);
+ }
+
+
+3.3 int ``SSL_do_handshake`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : OK
+ 0 : failed, connect is close by remote
+ -1 : a error catch
+
+ Description::
+
+ perform the SSL handshake
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_do_handshake(ssl);
+ }
+
+
+3.4 int ``SSL_connect`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : OK
+ 0 : failed, connect is close by remote
+ -1 : a error catch
+
+ Description::
+
+ connect to the remote SSL server
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_connect(ssl);
+ }
+
+
+3.5 int ``SSL_accept`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : OK
+ 0 : failed, connect is close by remote
+ -1 : a error catch
+
+ Description::
+
+ accept the remote connection
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_accept(ssl);
+ }
+
+
+3.6 int ``SSL_shutdown`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : OK
+ 0 : failed, connect is close by remote
+ -1 : a error catch
+
+ Description::
+
+ shutdown the connection
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_shutdown(ssl);
+ }
+
+
+3.7 int ``SSL_clear`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ shutdown the connection
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_clear(ssl);
+ }
+
+
+3.8 int ``SSL_read`` (SSL *ssl, void *buffer, int len)
+
+ Arguments::
+
+ ssl - point
+ buffer - data buffer point
+ len - data length
+
+ Return::
+
+ > 0 : OK, and return received data bytes
+ = 0 : no data received or connection is closed
+ < 0 : an error catch
+
+ Description::
+
+ read data from remote
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ char *buf;
+ int len;
+ int ret;
+
+ ... ...
+
+ ret = SSL_read(ssl, buf, len);
+ }
+
+3.9 int ``SSL_write`` (SSL *ssl, const void *buffer, int len)
+
+ Arguments::
+
+ ssl - SSL point
+ buffer - data buffer point
+ len - data length
+
+ Return::
+
+ > 0 : OK, and return received data bytes
+ = 0 : no data sent or connection is closed
+ < 0 : an error catch
+
+ Description::
+
+ send the data to remote
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ char *buf;
+ int len;
+ int ret;
+
+ ... ...
+
+ ret = SSL_write(ssl, buf, len);
+ }
+
+
+3.10 ``SSL_CTX *SSL_get_SSL_CTX`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL context
+
+ Description::
+
+ get SSL context of the SSL
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ SSL_CTX *ctx;
+
+ ... ...
+
+ ctx = SSL_get_SSL_CTX(ssl);
+ }
+
+
+3.11 int ``SSL_get_shutdown`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ shutdown mode
+
+ Description::
+
+ get SSL shutdown mode
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int mode;
+
+ ... ...
+
+ mode = SSL_get_SSL_CTX(ssl);
+ }
+
+
+3.12 void ``SSL_set_shutdown`` (SSL *ssl, int mode)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ shutdown mode
+
+ Description::
+
+ set SSL shutdown mode
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int mode = 0;
+
+ ... ...
+
+ SSL_set_shutdown(ssl, mode);
+ }
+
+
+3.13 const SSL_METHOD* ``SSL_get_ssl_method`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL method
+
+ Description::
+
+ set SSL shutdown mode
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ const SSL_METHOD *method;
+
+ ... ...
+
+ method = SSL_get_ssl_method(ssl);
+ }
+
+
+3.14 int ``SSL_set_ssl_method`` (SSL *ssl, const SSL_METHOD *method)
+
+ Arguments::
+
+ ssl - SSL point
+ meth - SSL method point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ set the SSL method
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ const SSL_METHOD *method;
+
+ ... ...
+
+ ret = SSL_set_ssl_method(ssl, method);
+ }
+
+
+3.15 int ``SSL_pending`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ data bytes
+
+ Description::
+
+ get received data bytes
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+
+ ... ...
+
+ ret = SSL_pending(ssl);
+ }
+
+
+3.16 int ``SSL_has_pending`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 1 : Yes
+ 0 : No
+
+ Description::
+
+ check if data is received
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+
+ ... ...
+
+ ret = SSL_has_pending(ssl);
+ }
+
+
+3.17 int ``SSL_get_fd`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ >= 0 : socket id
+ < 0 : a error catch
+
+ Description::
+
+ get the socket of the SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+
+ ... ...
+
+ ret = SSL_get_fd(ssl);
+ }
+
+
+3.18 int ``SSL_get_rfd`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ >= 0 : socket id
+ < 0 : a error catch
+
+ Description::
+
+ get the read only socket of the SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+
+ ... ...
+
+ ret = SSL_get_rfd(ssl);
+ }
+
+
+3.19 int ``SSL_get_wfd`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ >= 0 : socket id
+ < 0 : a error catch
+
+ Description::
+
+ get the write only socket of the SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+
+ ... ...
+
+ ret = SSL_get_wfd(ssl);
+ }
+
+
+3.20 int ``SSL_set_fd`` (SSL *ssl, int fd)
+
+ Arguments::
+
+ ssl - SSL point
+ fd - socket id
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ set socket to SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ int socket;
+
+ ... ...
+
+ ret = SSL_set_fd(ssl, socket);
+ }
+
+
+3.21 int ``SSL_set_rfd`` (SSL *ssl, int fd)
+
+ Arguments::
+
+ ssl - SSL point
+ fd - socket id
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ set read only socket to SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ int socket;
+
+ ... ...
+
+ ret = SSL_set_rfd(ssl, socket);
+ }
+
+
+3.22 int ``SSL_set_wfd`` (SSL *ssl, int fd)
+
+ Arguments::
+
+ ssl - SSL point
+ fd - socket id
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ set write only socket to SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ int socket;
+
+ ... ...
+
+ ret = SSL_set_wfd(ssl, socket);
+ }
+
+
+3.23 int ``SSL_version`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL version
+
+ Description::
+
+ get SSL version
+
+ Example::
+
+ void example(void)
+ {
+ int version;
+ SSL *ssl;
+
+ ... ...
+
+ version = SSL_version(ssl);
+ }
+
+
+3.24 const char* ``SSL_get_version`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL version string
+
+ Description::
+
+ get the SSL current version string
+
+ Example::
+
+ void example(void)
+ {
+ char *version;
+ SSL *ssl;
+
+ ... ...
+
+ version = SSL_get_version(ssl);
+ }
+
+
+3.25 OSSL_HANDSHAKE_STATE ``SSL_get_state`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL state
+
+ Description::
+
+ get the SSL state
+
+ Example::
+
+ void example(void)
+ {
+ OSSL_HANDSHAKE_STATE state;
+ SSL *ssl;
+
+ ... ...
+
+ state = SSL_get_state(ssl);
+ }
+
+
+3.26 const char* ``SSL_alert_desc_string`` (int value)
+
+ Arguments::
+
+ value - SSL description
+
+ Return::
+
+ alert value string
+
+ Description::
+
+ get alert description string
+
+ Example::
+
+ void example(void)
+ {
+ int val;
+ char *str;
+
+ ... ...
+
+ str = SSL_alert_desc_string(val);
+ }
+
+
+3.27 const char* ``SSL_alert_desc_string_long`` (int value)
+
+ Arguments::
+
+ value - SSL description
+
+ Return::
+
+ alert value long string
+
+ Description::
+
+ get alert description long string
+
+ Example::
+
+ void example(void)
+ {
+ int val;
+ char *str;
+
+ ... ...
+
+ str = SSL_alert_desc_string_long(val);
+ }
+
+
+3.28 const char* ``SSL_alert_type_string`` (int value)
+
+ Arguments::
+
+ value - SSL type description
+
+ Return::
+
+ alert type string
+
+ Description::
+
+ get alert type string
+
+ Example::
+
+ void example(void)
+ {
+ int val;
+ char *str;
+
+ ... ...
+
+ str = SSL_alert_type_string(val);
+ }
+
+
+3.29 const char* ``SSL_alert_type_string_long`` (int value)
+
+ Arguments::
+
+ value - SSL type description
+
+ Return::
+
+ alert type long string
+
+ Description::
+
+ get alert type long string
+
+ Example::
+
+ void example(void)
+ {
+ int val;
+ char *str;
+
+ ... ...
+
+ str = SSL_alert_type_string_long(val);
+ }
+
+3.30 const char* ``SSL_rstate_string`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ state string
+
+ Description::
+
+ get the state string where SSL is reading
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ char *str;
+
+ ... ...
+
+ str = SSL_rstate_string(ssl);
+ }
+
+
+3.31 const char* ``SSL_rstate_string_long`` (SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ state long string
+
+ Description::
+
+ get the state long string where SSL is reading
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ char *str;
+
+ ... ...
+
+ str = SSL_rstate_string_long(ssl);
+ }
+
+
+3.32 const char* ``SSL_state_string`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ state string
+
+ Description::
+
+ get the state string
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ const char *str;
+
+ ... ...
+
+ str = SSL_state_string(ssl);
+ }
+
+
+3.33 char* ``SSL_state_string_long`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ state long string
+
+ Description::
+
+ get the state long string
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ char *str;
+
+ ... ...
+
+ str = SSL_state_string(ssl);
+ }
+
+
+3.34 int ``SSL_get_error`` (const SSL *ssl, int ret_code)
+
+ Arguments::
+
+ ssl - SSL point
+ ret_code - SSL return code
+
+ Return::
+
+ SSL error number
+
+ Description::
+
+ get SSL error code
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+ int err;
+
+ ... ...
+
+ err = SSL_get_error(ssl, ret);
+ }
+
+3.35 int ``SSL_want`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ specifical statement
+
+ Description::
+
+ get the SSL specifical statement
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int state;
+
+ ... ...
+
+ state = SSL_want(ssl);
+ }
+
+
+3.36 int ``SSL_want_nothing`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 0 : false
+ 1 : true
+
+ Description::
+
+ check if SSL want nothing
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_want(ssl);
+ }
+
+
+3.37 int ``SSL_want_read`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 0 : false
+ 1 : true
+
+ Description::
+
+ check if SSL want to read
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_want_read(ssl);
+ }
+
+
+3.38 int ``SSL_want_write`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ 0 : false
+ 1 : true
+
+ Description::
+
+ check if SSL want to write
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ int ret;
+
+ ... ...
+
+ ret = SSL_want_write(ssl);
+ }
+
+
+Chapter 4. SSL X509 Certification and Private Key Function
+==========================================================
+
+
+4.1 X509* ``d2i_X509`` (X509 **cert, const unsigned char *buffer, long len)
+
+ Arguments::
+
+ cert - a point pointed to X509 certification
+ buffer - a point pointed to the certification context memory point
+ length - certification bytes
+
+ Return::
+
+ X509 certification object point
+
+ Description::
+
+ load a character certification context into system context. If '*cert' is pointed to the
+ certification, then load certification into it. Or create a new X509 certification object
+
+ Example::
+
+ void example(void)
+ {
+ X509 *new;
+ X509 *cert;
+ unsigned char *buffer;
+ long len;
+ ... ...
+
+ new = d2i_X509(&cert, buffer, len);
+ }
+
+
+4.2 int ``SSL_add_client_CA`` (SSL *ssl, X509 *x)
+
+ Arguments::
+
+ ssl - SSL point
+ x - CA certification point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ add CA client certification into the SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ X509 *new;
+
+ ... ...
+
+ ret = SSL_add_client_CA(ssl, new);
+ }
+
+
+4.3 int ``SSL_CTX_add_client_CA`` (SSL_CTX *ctx, X509 *x)
+
+ Arguments::
+
+ ctx - SSL context point
+ x - CA certification point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ add CA client certification into the SSL context
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL_CTX *ctx;
+ X509 *new;
+
+ ... ...
+
+ ret = SSL_add_clSSL_CTX_add_client_CAient_CA(ctx, new);
+ }
+
+
+4.4 X509* ``SSL_get_certificate`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ SSL certification point
+
+ Description::
+
+ get the SSL certification point
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ X509 *cert;
+
+ ... ...
+
+ cert = SSL_get_certificate(ssl);
+ }
+
+
+4.5 long ``SSL_get_verify_result`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ the result of verifying
+
+ Description::
+
+ get the verifying result of the SSL certification
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ long ret;
+
+ ... ...
+
+ ret = SSL_get_verify_result(ssl);
+ }
+
+
+4.6 int ``SSL_CTX_use_certificate`` (SSL_CTX *ctx, X509 *x)
+
+ Arguments::
+
+ ctx - the SSL context point
+ pkey - certification object point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load the certification into the SSL_CTX or SSL object
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL_CTX *ctx
+ X509 *new;
+
+ ... ...
+
+ ret = SSL_CTX_use_certificate(ctx, new);
+ }
+
+
+4.7 int ``SSL_CTX_use_certificate_ASN1`` (SSL_CTX *ctx, int len, const unsigned char *d)
+
+ Arguments::
+
+ ctx - SSL context point
+ len - certification length
+ d - data point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load the ASN1 certification into SSL context
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL_CTX *ctx;
+ const unsigned char *buf;
+ int len;
+
+ ... ...
+
+ ret = SSL_CTX_use_certificate_ASN1(ctx, len, buf);
+ }
+
+
+4.8 int ``SSL_CTX_use_PrivateKey`` (SSL_CTX *ctx, EVP_PKEY *pkey)
+
+ Arguments::
+
+ ctx - SSL context point
+ pkey - private key object point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load the private key into the context object
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL_CTX *ctx;
+ EVP_PKEY *pkey;
+
+ ... ...
+
+ ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ }
+
+
+4.9 int ``SSL_CTX_use_PrivateKey_ASN1`` (int pk, SSL_CTX *ctx, const unsigned char *d, long len)
+
+ Arguments::
+
+ ctx - SSL context point
+ d - data point
+ len - private key length
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load the ASN1 private key into SSL context
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ int pk;
+ SSL_CTX *ctx;
+ const unsigned char *buf;
+ long len;
+
+ ... ...
+
+ ret = SSL_CTX_use_PrivateKey_ASN1(pk, ctx, buf, len);
+ }
+
+
+4.10 int ``SSL_CTX_use_RSAPrivateKey_ASN1`` (SSL_CTX *ctx, const unsigned char *d, long len)
+
+ Arguments::
+
+ ctx - SSL context point
+ d - data point
+ len - private key length
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load the RSA ASN1 private key into SSL context
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL_CTX *ctx;
+ const unsigned char *buf;
+ long len;
+
+ ... ...
+
+ ret = SSL_CTX_use_RSAPrivateKey_ASN1(ctx, buf, len);
+ }
+
+
+4.11 int ``SSL_use_certificate_ASN1`` (SSL *ssl, int len, const unsigned char *d)
+
+ Arguments::
+
+ ssl - SSL point
+ len - data bytes
+ d - data point
+
+ Return::
+
+ 1 : OK
+ 0 : failed
+
+ Description::
+
+ load certification into the SSL
+
+ Example::
+
+ void example(void)
+ {
+ int ret;
+ SSL *ssl;
+ const unsigned char *buf;
+ long len;
+
+ ... ...
+
+ ret = SSL_use_certificate_ASN1(ssl, len, buf);
+ }
+
+
+4.12 X509* ``SSL_get_peer_certificate`` (const SSL *ssl)
+
+ Arguments::
+
+ ssl - SSL point
+
+ Return::
+
+ peer certification
+
+ Description::
+
+ get peer certification
+
+ Example::
+
+ void example(void)
+ {
+ SSL *ssl;
+ X509 *peer;
+
+ ... ...
+
+ peer = SSL_get_peer_certificate(ssl);
+ }
+
diff --git a/components/openssl/component.mk b/components/openssl/component.mk
new file mode 100644
index 0000000000..2dfcc6b38d
--- /dev/null
+++ b/components/openssl/component.mk
@@ -0,0 +1,10 @@
+#
+# Component Makefile
+#
+
+COMPONENT_ADD_INCLUDEDIRS := include
+COMPONENT_PRIV_INCLUDEDIRS := include/internal include/platform include/openssl
+
+COMPONENT_SRCDIRS := library platform
+
+include $(IDF_PATH)/make/component_common.mk
diff --git a/components/openssl/include/internal/ssl3.h b/components/openssl/include/internal/ssl3.h
new file mode 100644
index 0000000000..007b392f3e
--- /dev/null
+++ b/components/openssl/include/internal/ssl3.h
@@ -0,0 +1,44 @@
+// 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 _SSL3_H_
+#define _SSL3_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+# define SSL3_AD_CLOSE_NOTIFY 0
+# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */
+# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */
+# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */
+# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */
+# define SSL3_AD_NO_CERTIFICATE 41
+# define SSL3_AD_BAD_CERTIFICATE 42
+# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
+# define SSL3_AD_CERTIFICATE_REVOKED 44
+# define SSL3_AD_CERTIFICATE_EXPIRED 45
+# define SSL3_AD_CERTIFICATE_UNKNOWN 46
+# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */
+
+# define SSL3_AL_WARNING 1
+# define SSL3_AL_FATAL 2
+
+#define SSL3_VERSION 0x0300
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h
new file mode 100644
index 0000000000..86cf31ad51
--- /dev/null
+++ b/components/openssl/include/internal/ssl_cert.h
@@ -0,0 +1,55 @@
+// 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 _SSL_CERT_H_
+#define _SSL_CERT_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+
+/**
+ * @brief create a certification object include private key object according to input certification
+ *
+ * @param ic - input certification point
+ *
+ * @return certification object point
+ */
+CERT *__ssl_cert_new(CERT *ic);
+
+/**
+ * @brief create a certification object include private key object
+ *
+ * @param none
+ *
+ * @return certification object point
+ */
+CERT* ssl_cert_new(void);
+
+/**
+ * @brief free a certification object
+ *
+ * @param cert - certification object point
+ *
+ * @return none
+ */
+void ssl_cert_free(CERT *cert);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h
new file mode 100644
index 0000000000..80fdbb20f3
--- /dev/null
+++ b/components/openssl/include/internal/ssl_code.h
@@ -0,0 +1,124 @@
+// 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 _SSL_CODE_H_
+#define _SSL_CODE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl3.h"
+#include "tls1.h"
+#include "x509_vfy.h"
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+# define SSL_SENT_SHUTDOWN 1
+# define SSL_RECEIVED_SHUTDOWN 2
+
+# define SSL_VERIFY_NONE 0x00
+# define SSL_VERIFY_PEER 0x01
+# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+# define SSL_VERIFY_CLIENT_ONCE 0x04
+
+/*
+ * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you
+ * should not need these
+ */
+# define SSL_ST_READ_HEADER 0xF0
+# define SSL_ST_READ_BODY 0xF1
+# define SSL_ST_READ_DONE 0xF2
+
+# define SSL_NOTHING 1
+# define SSL_WRITING 2
+# define SSL_READING 3
+# define SSL_X509_LOOKUP 4
+# define SSL_ASYNC_PAUSED 5
+# define SSL_ASYNC_NO_JOBS 6
+
+
+# define SSL_ERROR_NONE 0
+# define SSL_ERROR_SSL 1
+# define SSL_ERROR_WANT_READ 2
+# define SSL_ERROR_WANT_WRITE 3
+# define SSL_ERROR_WANT_X509_LOOKUP 4
+# define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */
+# define SSL_ERROR_ZERO_RETURN 6
+# define SSL_ERROR_WANT_CONNECT 7
+# define SSL_ERROR_WANT_ACCEPT 8
+# define SSL_ERROR_WANT_ASYNC 9
+# define SSL_ERROR_WANT_ASYNC_JOB 10
+
+/* Message flow states */
+typedef enum {
+ /* No handshake in progress */
+ MSG_FLOW_UNINITED,
+ /* A permanent error with this connection */
+ MSG_FLOW_ERROR,
+ /* We are about to renegotiate */
+ MSG_FLOW_RENEGOTIATE,
+ /* We are reading messages */
+ MSG_FLOW_READING,
+ /* We are writing messages */
+ MSG_FLOW_WRITING,
+ /* Handshake has finished */
+ MSG_FLOW_FINISHED
+} MSG_FLOW_STATE;
+
+/* SSL subsystem states */
+typedef enum {
+ TLS_ST_BEFORE,
+ TLS_ST_OK,
+ DTLS_ST_CR_HELLO_VERIFY_REQUEST,
+ TLS_ST_CR_SRVR_HELLO,
+ TLS_ST_CR_CERT,
+ TLS_ST_CR_CERT_STATUS,
+ TLS_ST_CR_KEY_EXCH,
+ TLS_ST_CR_CERT_REQ,
+ TLS_ST_CR_SRVR_DONE,
+ TLS_ST_CR_SESSION_TICKET,
+ TLS_ST_CR_CHANGE,
+ TLS_ST_CR_FINISHED,
+ TLS_ST_CW_CLNT_HELLO,
+ TLS_ST_CW_CERT,
+ TLS_ST_CW_KEY_EXCH,
+ TLS_ST_CW_CERT_VRFY,
+ TLS_ST_CW_CHANGE,
+ TLS_ST_CW_NEXT_PROTO,
+ TLS_ST_CW_FINISHED,
+ TLS_ST_SW_HELLO_REQ,
+ TLS_ST_SR_CLNT_HELLO,
+ DTLS_ST_SW_HELLO_VERIFY_REQUEST,
+ TLS_ST_SW_SRVR_HELLO,
+ TLS_ST_SW_CERT,
+ TLS_ST_SW_KEY_EXCH,
+ TLS_ST_SW_CERT_REQ,
+ TLS_ST_SW_SRVR_DONE,
+ TLS_ST_SR_CERT,
+ TLS_ST_SR_KEY_EXCH,
+ TLS_ST_SR_CERT_VRFY,
+ TLS_ST_SR_NEXT_PROTO,
+ TLS_ST_SR_CHANGE,
+ TLS_ST_SR_FINISHED,
+ TLS_ST_SW_SESSION_TICKET,
+ TLS_ST_SW_CERT_STATUS,
+ TLS_ST_SW_CHANGE,
+ TLS_ST_SW_FINISHED
+} OSSL_HANDSHAKE_STATE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h
new file mode 100644
index 0000000000..887fe2e82b
--- /dev/null
+++ b/components/openssl/include/internal/ssl_dbg.h
@@ -0,0 +1,92 @@
+// 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 _SSL_DEBUG_H_
+#define _SSL_DEBUG_H_
+
+#include "platform/ssl_opt.h"
+#include "platform/ssl_port.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef SSL_DEBUG_ENBALE
+#define SSL_DEBUG_ENBALE 0
+#endif
+
+#ifndef SSL_DEBUG_LEVEL
+#define SSL_DEBUG_LEVEL 0
+#endif
+
+#ifndef SSL_ASSERT_ENABLE
+#define SSL_ASSERT_ENABLE 0
+#endif
+
+#ifndef SSL_DEBUG_LOCATION_ENABLE
+#define SSL_DEBUG_LOCATION_ENABLE 0
+#endif
+
+#if SSL_DEBUG_ENBALE
+ #if !defined(SSL_PRINT_LOG) || !defined(SSL_ERROR_LOG) || !defined(SSL_LOCAL_LOG)
+ #include "stdio.h"
+ extern int printf(const char *fmt, ...);
+ #ifndef SSL_PRINT_LOG
+ #define SSL_PRINT_LOG printf
+ #endif
+ #ifndef SSL_ERROR_LOG
+ #define SSL_ERROR_LOG printf
+ #endif
+ #ifndef SSL_LOCAL_LOG
+ #define SSL_LOCAL_LOG printf
+ #endif
+ #endif
+#else
+ #ifdef SSL_PRINT_LOG
+ #undef SSL_PRINT_LOG
+ #define SSL_PRINT_LOG(...)
+ #endif
+ #ifdef SSL_ERROR_LOG
+ #undef SSL_ERROR_LOG
+ #define SSL_ERROR_LOG(...)
+ #endif
+ #ifdef SSL_LOCAL_LOG
+ #undef SSL_LOCAL_LOG
+ #define SSL_LOCAL_LOG(...)
+ #endif
+#endif
+
+#if SSL_DEBUG_LOCATION_ENABLE
+ #define SSL_DEBUG_LOCATION() SSL_LOCAL_LOG("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__)
+#else
+ #define SSL_DEBUG_LOCATION()
+#endif
+
+#if SSL_ASSERT_ENABLE
+ #define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } }
+#else
+ #define SSL_ASSERT(s)
+#endif
+
+#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); ret = err; goto go; }
+
+#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); goto go; }
+
+#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT_LOG(fmt, ##__VA_ARGS__);} }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h
new file mode 100644
index 0000000000..bf7de22fdf
--- /dev/null
+++ b/components/openssl/include/internal/ssl_lib.h
@@ -0,0 +1,28 @@
+// 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 _SSL_LIB_H_
+#define _SSL_LIB_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h
new file mode 100644
index 0000000000..cd2f8c0533
--- /dev/null
+++ b/components/openssl/include/internal/ssl_methods.h
@@ -0,0 +1,121 @@
+// 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 _SSL_METHODS_H_
+#define _SSL_METHODS_H_
+
+#include "ssl_types.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ * TLS method function implement
+ */
+#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \
+ new, free, \
+ handshake, shutdown, clear, \
+ read, send, pending, \
+ set_fd, get_fd, \
+ set_bufflen, \
+ get_verify_result, \
+ get_state) \
+ static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \
+ new, \
+ free, \
+ handshake, \
+ shutdown, \
+ clear, \
+ read, \
+ send, \
+ pending, \
+ set_fd, \
+ get_fd, \
+ set_bufflen, \
+ get_verify_result, \
+ get_state \
+ };
+
+#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \
+ const SSL_METHOD* func_name(void) { \
+ static const SSL_METHOD func_name##_data LOCAL_ATRR = { \
+ ver, \
+ mode, \
+ &(fun), \
+ }; \
+ return &func_name##_data; \
+ }
+
+#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \
+ const SSL_METHOD* func_name(void) { \
+ static const SSL_METHOD func_name##_data LOCAL_ATRR = { \
+ ver, \
+ mode, \
+ &(fun), \
+ }; \
+ return &func_name##_data; \
+ }
+
+#define IMPLEMENT_X509_METHOD(func_name, \
+ new, \
+ free, \
+ load, \
+ show_info) \
+ const X509_METHOD* func_name(void) { \
+ static const X509_METHOD func_name##_data LOCAL_ATRR = { \
+ new, \
+ free, \
+ load, \
+ show_info \
+ }; \
+ return &func_name##_data; \
+ }
+
+#define IMPLEMENT_PKEY_METHOD(func_name, \
+ new, \
+ free, \
+ load) \
+ const PKEY_METHOD* func_name(void) { \
+ static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \
+ new, \
+ free, \
+ load \
+ }; \
+ return &func_name##_data; \
+ }
+
+/**
+ * @brief get X509 object method
+ *
+ * @param none
+ *
+ * @return X509 object method point
+ */
+const X509_METHOD* X509_method(void);
+
+/**
+ * @brief get private key object method
+ *
+ * @param none
+ *
+ * @return private key object method point
+ */
+const PKEY_METHOD* EVP_PKEY_method(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h
new file mode 100644
index 0000000000..e790fcc995
--- /dev/null
+++ b/components/openssl/include/internal/ssl_pkey.h
@@ -0,0 +1,86 @@
+// 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 _SSL_PKEY_H_
+#define _SSL_PKEY_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+
+/**
+ * @brief create a private key object according to input private key
+ *
+ * @param ipk - input private key point
+ *
+ * @return new private key object point
+ */
+EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk);
+
+/**
+ * @brief create a private key object
+ *
+ * @param none
+ *
+ * @return private key object point
+ */
+EVP_PKEY* EVP_PKEY_new(void);
+
+/**
+ * @brief load a character key context into system context. If '*a' is pointed to the
+ * private key, then load key into it. Or create a new private key object
+ *
+ * @param type - private key type
+ * @param a - a point pointed to a private key point
+ * @param pp - a point pointed to the key context memory point
+ * @param length - key bytes
+ *
+ * @return private key object point
+ */
+EVP_PKEY* d2i_PrivateKey(int type,
+ EVP_PKEY **a,
+ const unsigned char **pp,
+ long length);
+
+/**
+ * @brief free a private key object
+ *
+ * @param pkey - private key object point
+ *
+ * @return none
+ */
+void EVP_PKEY_free(EVP_PKEY *x);
+
+/**
+ * @brief load private key into the SSL
+ *
+ * @param type - private key type
+ * @param ssl - SSL point
+ * @param len - data bytes
+ * @param d - data point
+ *
+ * @return result
+ * 0 : failed
+ * 1 : OK
+ */
+ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_stack.h b/components/openssl/include/internal/ssl_stack.h
new file mode 100644
index 0000000000..7a7051a026
--- /dev/null
+++ b/components/openssl/include/internal/ssl_stack.h
@@ -0,0 +1,52 @@
+#ifndef _SSL_STACK_H_
+#define _SSL_STACK_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+
+#define STACK_OF(type) struct stack_st_##type
+
+#define SKM_DEFINE_STACK_OF(t1, t2, t3) \
+ STACK_OF(t1); \
+ static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \
+ { \
+ return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \
+ } \
+
+#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t)
+
+/**
+ * @brief create a openssl stack object
+ *
+ * @param c - stack function
+ *
+ * @return openssl stack object point
+ */
+OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c);
+
+/**
+ * @brief create a NULL function openssl stack object
+ *
+ * @param none
+ *
+ * @return openssl stack object point
+ */
+OPENSSL_STACK *OPENSSL_sk_new_null(void);
+
+/**
+ * @brief free openssl stack object
+ *
+ * @param openssl stack object point
+ *
+ * @return none
+ */
+void OPENSSL_sk_free(OPENSSL_STACK *stack);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h
new file mode 100644
index 0000000000..5aaee94176
--- /dev/null
+++ b/components/openssl/include/internal/ssl_types.h
@@ -0,0 +1,288 @@
+// 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 _SSL_TYPES_H_
+#define _SSL_TYPES_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_code.h"
+
+typedef void SSL_CIPHER;
+
+typedef void X509_STORE_CTX;
+typedef void X509_STORE;
+
+typedef void RSA;
+
+typedef void STACK;
+typedef void BIO;
+
+#define ossl_inline inline
+
+#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__)
+#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__)
+#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__)
+
+typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
+
+struct stack_st;
+typedef struct stack_st OPENSSL_STACK;
+
+struct ssl_method_st;
+typedef struct ssl_method_st SSL_METHOD;
+
+struct ssl_method_func_st;
+typedef struct ssl_method_func_st SSL_METHOD_FUNC;
+
+struct record_layer_st;
+typedef struct record_layer_st RECORD_LAYER;
+
+struct ossl_statem_st;
+typedef struct ossl_statem_st OSSL_STATEM;
+
+struct ssl_session_st;
+typedef struct ssl_session_st SSL_SESSION;
+
+struct ssl_ctx_st;
+typedef struct ssl_ctx_st SSL_CTX;
+
+struct ssl_st;
+typedef struct ssl_st SSL;
+
+struct cert_st;
+typedef struct cert_st CERT;
+
+struct x509_st;
+typedef struct x509_st X509;
+
+struct X509_VERIFY_PARAM_st;
+typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM;
+
+struct evp_pkey_st;
+typedef struct evp_pkey_st EVP_PKEY;
+
+struct x509_method_st;
+typedef struct x509_method_st X509_METHOD;
+
+struct pkey_method_st;
+typedef struct pkey_method_st PKEY_METHOD;
+
+struct stack_st {
+
+ char **data;
+
+ int num_alloc;
+
+ OPENSSL_sk_compfunc c;
+};
+
+struct evp_pkey_st {
+
+ void *pkey_pm;
+
+ const PKEY_METHOD *method;
+};
+
+struct x509_st {
+
+ /* X509 certification platform private point */
+ void *x509_pm;
+
+ const X509_METHOD *method;
+};
+
+struct cert_st {
+
+ int sec_level;
+
+ X509 *x509;
+
+ EVP_PKEY *pkey;
+
+};
+
+struct ossl_statem_st {
+
+ MSG_FLOW_STATE state;
+
+ int hand_state;
+};
+
+struct record_layer_st {
+
+ int rstate;
+
+ int read_ahead;
+};
+
+struct ssl_session_st {
+
+ long timeout;
+
+ long time;
+
+ X509 *peer;
+};
+
+struct X509_VERIFY_PARAM_st {
+
+ int depth;
+
+};
+
+struct ssl_ctx_st
+{
+ int version;
+
+ int references;
+
+ unsigned long options;
+
+ #if 0
+ struct alpn_protocols alpn_protocol;
+ #endif
+
+ const SSL_METHOD *method;
+
+ CERT *cert;
+
+ X509 *client_CA;
+
+ int verify_mode;
+
+ int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
+
+ long session_timeout;
+
+ int read_ahead;
+
+ int read_buffer_len;
+
+ X509_VERIFY_PARAM param;
+};
+
+struct ssl_st
+{
+ /* protocol version(one of SSL3.0, TLS1.0, etc.) */
+ int version;
+
+ unsigned long options;
+
+ /* shut things down(0x01 : sent, 0x02 : received) */
+ int shutdown;
+
+ CERT *cert;
+
+ X509 *client_CA;
+
+ SSL_CTX *ctx;
+
+ const SSL_METHOD *method;
+
+ RECORD_LAYER rlayer;
+
+ /* where we are */
+ OSSL_STATEM statem;
+
+ SSL_SESSION *session;
+
+ int verify_mode;
+
+ int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
+
+ int rwstate;
+
+ long verify_result;
+
+ X509_VERIFY_PARAM param;
+
+ int err;
+
+ void (*info_callback) (const SSL *ssl, int type, int val);
+
+ /* SSL low-level system arch point */
+ void *ssl_pm;
+};
+
+struct ssl_method_st {
+ /* protocol version(one of SSL3.0, TLS1.0, etc.) */
+ int version;
+
+ /* SSL mode(client(0) , server(1), not known(-1)) */
+ int endpoint;
+
+ const SSL_METHOD_FUNC *func;
+};
+
+struct ssl_method_func_st {
+
+ int (*ssl_new)(SSL *ssl);
+
+ void (*ssl_free)(SSL *ssl);
+
+ int (*ssl_handshake)(SSL *ssl);
+
+ int (*ssl_shutdown)(SSL *ssl);
+
+ int (*ssl_clear)(SSL *ssl);
+
+ int (*ssl_read)(SSL *ssl, void *buffer, int len);
+
+ int (*ssl_send)(SSL *ssl, const void *buffer, int len);
+
+ int (*ssl_pending)(const SSL *ssl);
+
+ void (*ssl_set_fd)(SSL *ssl, int fd, int mode);
+
+ int (*ssl_get_fd)(const SSL *ssl, int mode);
+
+ void (*ssl_set_bufflen)(SSL *ssl, int len);
+
+ long (*ssl_get_verify_result)(const SSL *ssl);
+
+ OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl);
+};
+
+struct x509_method_st {
+
+ int (*x509_new)(X509 *x, X509 *m_x);
+
+ void (*x509_free)(X509 *x);
+
+ int (*x509_load)(X509 *x, const unsigned char *buf, int len);
+
+ int (*x509_show_info)(X509 *x);
+};
+
+struct pkey_method_st {
+
+ int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey);
+
+ void (*pkey_free)(EVP_PKEY *pkey);
+
+ int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len);
+};
+
+typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out,
+ unsigned char *outlen, const unsigned char *in,
+ unsigned int inlen, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h
new file mode 100644
index 0000000000..840fbf1ec1
--- /dev/null
+++ b/components/openssl/include/internal/ssl_x509.h
@@ -0,0 +1,108 @@
+// 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 _SSL_X509_H_
+#define _SSL_X509_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+#include "ssl_stack.h"
+
+DEFINE_STACK_OF(X509_NAME)
+
+/**
+ * @brief create a X509 certification object according to input X509 certification
+ *
+ * @param ix - input X509 certification point
+ *
+ * @return new X509 certification object point
+ */
+X509* __X509_new(X509 *ix);
+
+/**
+ * @brief create a X509 certification object
+ *
+ * @param none
+ *
+ * @return X509 certification object point
+ */
+X509* X509_new(void);
+
+/**
+ * @brief load a character certification context into system context. If '*cert' is pointed to the
+ * certification, then load certification into it. Or create a new X509 certification object
+ *
+ * @param cert - a point pointed to X509 certification
+ * @param buffer - a point pointed to the certification context memory point
+ * @param length - certification bytes
+ *
+ * @return X509 certification object point
+ */
+X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len);
+
+/**
+ * @brief free a X509 certification object
+ *
+ * @param x - X509 certification object point
+ *
+ * @return none
+ */
+void X509_free(X509 *x);
+
+/**
+ * @brief set SSL context client CA certification
+ *
+ * @param ctx - SSL context point
+ * @param x - X509 certification point
+ *
+ * @return result
+ * 0 : failed
+ * 1 : OK
+ */
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
+
+/**
+ * @brief add CA client certification into the SSL
+ *
+ * @param ssl - SSL point
+ * @param x - X509 certification point
+ *
+ * @return result
+ * 0 : failed
+ * 1 : OK
+ */
+int SSL_add_client_CA(SSL *ssl, X509 *x);
+
+/**
+ * @brief load certification into the SSL
+ *
+ * @param ssl - SSL point
+ * @param len - data bytes
+ * @param d - data point
+ *
+ * @return result
+ * 0 : failed
+ * 1 : OK
+ *
+ */
+int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/tls1.h b/components/openssl/include/internal/tls1.h
new file mode 100644
index 0000000000..a9da53e063
--- /dev/null
+++ b/components/openssl/include/internal/tls1.h
@@ -0,0 +1,55 @@
+// 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 _TLS1_H_
+#define _TLS1_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+# define TLS1_AD_DECRYPTION_FAILED 21
+# define TLS1_AD_RECORD_OVERFLOW 22
+# define TLS1_AD_UNKNOWN_CA 48/* fatal */
+# define TLS1_AD_ACCESS_DENIED 49/* fatal */
+# define TLS1_AD_DECODE_ERROR 50/* fatal */
+# define TLS1_AD_DECRYPT_ERROR 51
+# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */
+# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */
+# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */
+# define TLS1_AD_INTERNAL_ERROR 80/* fatal */
+# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */
+# define TLS1_AD_USER_CANCELLED 90
+# define TLS1_AD_NO_RENEGOTIATION 100
+/* codes 110-114 are from RFC3546 */
+# define TLS1_AD_UNSUPPORTED_EXTENSION 110
+# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+# define TLS1_AD_UNRECOGNIZED_NAME 112
+# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */
+# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */
+
+/* Special value for method supporting multiple versions */
+#define TLS_ANY_VERSION 0x10000
+
+#define TLS1_VERSION 0x0301
+#define TLS1_1_VERSION 0x0302
+#define TLS1_2_VERSION 0x0303
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/internal/x509_vfy.h b/components/openssl/include/internal/x509_vfy.h
new file mode 100644
index 0000000000..d5b0d1a213
--- /dev/null
+++ b/components/openssl/include/internal/x509_vfy.h
@@ -0,0 +1,111 @@
+// 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 _X509_VFY_H_
+#define _X509_VFY_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define X509_V_OK 0
+#define X509_V_ERR_UNSPECIFIED 1
+#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
+#define X509_V_ERR_UNABLE_TO_GET_CRL 3
+#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
+#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
+#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
+#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
+#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
+#define X509_V_ERR_CERT_NOT_YET_VALID 9
+#define X509_V_ERR_CERT_HAS_EXPIRED 10
+#define X509_V_ERR_CRL_NOT_YET_VALID 11
+#define X509_V_ERR_CRL_HAS_EXPIRED 12
+#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
+#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
+#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
+#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
+#define X509_V_ERR_OUT_OF_MEM 17
+#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
+#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
+#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
+#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
+#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
+#define X509_V_ERR_CERT_REVOKED 23
+#define X509_V_ERR_INVALID_CA 24
+#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
+#define X509_V_ERR_INVALID_PURPOSE 26
+#define X509_V_ERR_CERT_UNTRUSTED 27
+#define X509_V_ERR_CERT_REJECTED 28
+/* These are 'informational' when looking for issuer cert */
+#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
+#define X509_V_ERR_AKID_SKID_MISMATCH 30
+#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
+#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
+#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
+#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
+#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
+#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
+#define X509_V_ERR_INVALID_NON_CA 37
+#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
+#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
+#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
+#define X509_V_ERR_INVALID_EXTENSION 41
+#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
+#define X509_V_ERR_NO_EXPLICIT_POLICY 43
+#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
+#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
+#define X509_V_ERR_UNNESTED_RESOURCE 46
+#define X509_V_ERR_PERMITTED_VIOLATION 47
+#define X509_V_ERR_EXCLUDED_VIOLATION 48
+#define X509_V_ERR_SUBTREE_MINMAX 49
+/* The application is not happy */
+#define X509_V_ERR_APPLICATION_VERIFICATION 50
+#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
+#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
+#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
+#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
+/* Another issuer check debug option */
+#define X509_V_ERR_PATH_LOOP 55
+/* Suite B mode algorithm violation */
+#define X509_V_ERR_SUITE_B_INVALID_VERSION 56
+#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57
+#define X509_V_ERR_SUITE_B_INVALID_CURVE 58
+#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
+#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
+#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+/* Host, email and IP check errors */
+#define X509_V_ERR_HOSTNAME_MISMATCH 62
+#define X509_V_ERR_EMAIL_MISMATCH 63
+#define X509_V_ERR_IP_ADDRESS_MISMATCH 64
+/* DANE TLSA errors */
+#define X509_V_ERR_DANE_NO_MATCH 65
+/* security level errors */
+#define X509_V_ERR_EE_KEY_TOO_SMALL 66
+#define X509_V_ERR_CA_KEY_TOO_SMALL 67
+#define X509_V_ERR_CA_MD_TOO_WEAK 68
+/* Caller error */
+#define X509_V_ERR_INVALID_CALL 69
+/* Issuer lookup error */
+#define X509_V_ERR_STORE_LOOKUP 70
+/* Certificate transparency */
+#define X509_V_ERR_NO_VALID_SCTS 71
+
+#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h
new file mode 100644
index 0000000000..7f8eb88302
--- /dev/null
+++ b/components/openssl/include/openssl/ssl.h
@@ -0,0 +1,1737 @@
+// 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 _SSL_H_
+#define _SSL_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "internal/ssl_x509.h"
+#include "internal/ssl_pkey.h"
+
+/*
+{
+*/
+
+/**
+ * @brief create a SSL context
+ *
+ * @param method - the SSL context method point
+ *
+ * @return the context point
+ */
+SSL_CTX* SSL_CTX_new(const SSL_METHOD *method);
+
+/**
+ * @brief free a SSL context
+ *
+ * @param method - the SSL context point
+ *
+ * @return none
+ */
+void SSL_CTX_free(SSL_CTX *ctx);
+
+/**
+ * @brief create a SSL
+ *
+ * @param ctx - the SSL context point
+ *
+ * @return the SSL point
+ */
+SSL* SSL_new(SSL_CTX *ctx);
+
+/**
+ * @brief free the SSL
+ *
+ * @param ssl - the SSL point
+ *
+ * @return none
+ */
+void SSL_free(SSL *ssl);
+
+/**
+ * @brief connect to the remote SSL server
+ *
+ * @param ssl - the SSL point
+ *
+ * @return result
+ * 1 : OK
+ * -1 : failed
+ */
+int SSL_connect(SSL *ssl);
+
+/**
+ * @brief accept the remote connection
+ *
+ * @param ssl - the SSL point
+ *
+ * @return result
+ * 1 : OK
+ * -1 : failed
+ */
+int SSL_accept(SSL *ssl);
+
+/**
+ * @brief read data from to remote
+ *
+ * @param ssl - the SSL point which has been connected
+ * @param buffer - the received data buffer point
+ * @param len - the received data length
+ *
+ * @return result
+ * > 0 : OK, and return received data bytes
+ * = 0 : connection is closed
+ * < 0 : an error catch
+ */
+int SSL_read(SSL *ssl, void *buffer, int len);
+
+/**
+ * @brief send the data to remote
+ *
+ * @param ssl - the SSL point which has been connected
+ * @param buffer - the send data buffer point
+ * @param len - the send data length
+ *
+ * @return result
+ * > 0 : OK, and return sent data bytes
+ * = 0 : connection is closed
+ * < 0 : an error catch
+ */
+int SSL_write(SSL *ssl, const void *buffer, int len);
+
+/**
+ * @brief get the verifying result of the SSL certification
+ *
+ * @param ssl - the SSL point
+ *
+ * @return the result of verifying
+ */
+long SSL_get_verify_result(const SSL *ssl);
+
+/**
+ * @brief shutdown the connection
+ *
+ * @param ssl - the SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : shutdown is not finished
+ * -1 : an error catch
+ */
+int SSL_shutdown(SSL *ssl);
+
+/**
+ * @brief bind the socket file description into the SSL
+ *
+ * @param ssl - the SSL point
+ * @param fd - socket handle
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_set_fd(SSL *ssl, int fd);
+
+/**
+ * @brief These functions load the private key into the SSL_CTX or SSL object
+ *
+ * @param ctx - the SSL context point
+ * @param pkey - private key object point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+
+/**
+ * @brief These functions load the certification into the SSL_CTX or SSL object
+ *
+ * @param ctx - the SSL context point
+ * @param pkey - certification object point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+
+/**
+ * @brief create the target SSL context client method
+ *
+ * @param none
+ *
+ * @return the SSLV2.3 version SSL context client method
+ */
+const SSL_METHOD* SSLv23_client_method(void);
+
+/**
+ * @brief create the target SSL context client method
+ *
+ * @param none
+ *
+ * @return the TLSV1.0 version SSL context client method
+ */
+const SSL_METHOD* TLSv1_client_method(void);
+
+/**
+ * @brief create the target SSL context client method
+ *
+ * @param none
+ *
+ * @return the SSLV1.0 version SSL context client method
+ */
+const SSL_METHOD* SSLv3_client_method(void);
+
+/**
+ * @brief create the target SSL context client method
+ *
+ * @param none
+ *
+ * @return the TLSV1.1 version SSL context client method
+ */
+const SSL_METHOD* TLSv1_1_client_method(void);
+
+/**
+ * @brief create the target SSL context client method
+ *
+ * @param none
+ *
+ * @return the TLSV1.2 version SSL context client method
+ */
+const SSL_METHOD* TLSv1_2_client_method(void);
+
+
+/**
+ * @brief create the target SSL context server method
+ *
+ * @param none
+ *
+ * @return the SSLV2.3 version SSL context server method
+ */
+const SSL_METHOD* SSLv23_server_method(void);
+
+/**
+ * @brief create the target SSL context server method
+ *
+ * @param none
+ *
+ * @return the TLSV1.1 version SSL context server method
+ */
+const SSL_METHOD* TLSv1_1_server_method(void);
+
+/**
+ * @brief create the target SSL context server method
+ *
+ * @param none
+ *
+ * @return the TLSV1.2 version SSL context server method
+ */
+const SSL_METHOD* TLSv1_2_server_method(void);
+
+/**
+ * @brief create the target SSL context server method
+ *
+ * @param none
+ *
+ * @return the TLSV1.0 version SSL context server method
+ */
+const SSL_METHOD* TLSv1_server_method(void);
+
+/**
+ * @brief create the target SSL context server method
+ *
+ * @param none
+ *
+ * @return the SSLV3.0 version SSL context server method
+ */
+const SSL_METHOD* SSLv3_server_method(void);
+
+/**
+ * @brief set the SSL context ALPN select callback function
+ *
+ * @param ctx - SSL context point
+ * @param cb - ALPN select callback function
+ * @param arg - ALPN select callback function entry private data point
+ *
+ * @return none
+ */
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
+ int (*cb) (SSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg),
+ void *arg);
+
+
+/**
+ * @brief set the SSL context ALPN select protocol
+ *
+ * @param ctx - SSL context point
+ * @param protos - ALPN protocol name
+ * @param protos_len - ALPN protocol name bytes
+ *
+ * @return result
+ * 0 : OK
+ * 1 : failed
+ */
+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len);
+
+/**
+ * @brief set the SSL context next ALPN select callback function
+ *
+ * @param ctx - SSL context point
+ * @param cb - ALPN select callback function
+ * @param arg - ALPN select callback function entry private data point
+ *
+ * @return none
+ */
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx,
+ int (*cb) (SSL *ssl,
+ unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg),
+ void *arg);
+
+/**
+ * @brief get SSL error code
+ *
+ * @param ssl - SSL point
+ * @param ret_code - SSL return code
+ *
+ * @return SSL error number
+ */
+int SSL_get_error(const SSL *ssl, int ret_code);
+
+/**
+ * @brief clear the SSL error code
+ *
+ * @param none
+ *
+ * @return none
+ */
+void ERR_clear_error(void);
+
+/**
+ * @brief get the current SSL error code
+ *
+ * @param none
+ *
+ * @return current SSL error number
+ */
+int ERR_get_error(void);
+
+/**
+ * @brief register the SSL error strings
+ *
+ * @param none
+ *
+ * @return none
+ */
+void ERR_load_SSL_strings(void);
+
+/**
+ * @brief initialize the SSL library
+ *
+ * @param none
+ *
+ * @return none
+ */
+void SSL_library_init(void);
+
+/**
+ * @brief generates a human-readable string representing the error code e
+ * and store it into the "ret" point memory
+ *
+ * @param e - error code
+ * @param ret - memory point to store the string
+ *
+ * @return the result string point
+ */
+char *ERR_error_string(unsigned long e, char *ret);
+
+/**
+ * @brief add the SSL context option
+ *
+ * @param ctx - SSL context point
+ * @param opt - new SSL context option
+ *
+ * @return the SSL context option
+ */
+unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt);
+
+/**
+ * @brief add the SSL context mode
+ *
+ * @param ctx - SSL context point
+ * @param mod - new SSL context mod
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_mode(SSL_CTX *ctx, int mod);
+
+/*
+}
+*/
+
+/**
+ * @brief perform the SSL handshake
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ * -1 : a error catch
+ */
+int SSL_do_handshake(SSL *ssl);
+
+/**
+ * @brief get the SSL current version
+ *
+ * @param ssl - SSL point
+ *
+ * @return the version string
+ */
+const char *SSL_get_version(const SSL *ssl);
+
+/**
+ * @brief set the SSL context version
+ *
+ * @param ctx - SSL context point
+ * @param meth - SSL method point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+/**
+ * @brief get the bytes numbers which are to be read
+ *
+ * @param ssl - SSL point
+ *
+ * @return bytes number
+ */
+int SSL_pending(const SSL *ssl);
+
+/**
+ * @brief check if SSL want nothing
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 0 : false
+ * 1 : true
+ */
+int SSL_want_nothing(const SSL *ssl);
+
+/**
+ * @brief check if SSL want to read
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 0 : false
+ * 1 : true
+ */
+int SSL_want_read(const SSL *ssl);
+
+/**
+ * @brief check if SSL want to write
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 0 : false
+ * 1 : true
+ */
+int SSL_want_write(const SSL *ssl);
+
+/**
+ * @brief get the SSL context current method
+ *
+ * @param ctx - SSL context point
+ *
+ * @return the SSL context current method
+ */
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
+
+/**
+ * @brief get the SSL current method
+ *
+ * @param ssl - SSL point
+ *
+ * @return the SSL current method
+ */
+const SSL_METHOD *SSL_get_ssl_method(SSL *ssl);
+
+/**
+ * @brief set the SSL method
+ *
+ * @param ssl - SSL point
+ * @param meth - SSL method point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method);
+
+/**
+ * @brief add CA client certification into the SSL
+ *
+ * @param ssl - SSL point
+ * @param x - CA certification point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_add_client_CA(SSL *ssl, X509 *x);
+
+/**
+ * @brief add CA client certification into the SSL context
+ *
+ * @param ctx - SSL context point
+ * @param x - CA certification point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
+
+/**
+ * @brief set the SSL CA certification list
+ *
+ * @param ssl - SSL point
+ * @param name_list - CA certification list
+ *
+ * @return none
+ */
+void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list);
+
+/**
+ * @brief set the SSL context CA certification list
+ *
+ * @param ctx - SSL context point
+ * @param name_list - CA certification list
+ *
+ * @return none
+ */
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+
+/**
+ * @briefget the SSL CA certification list
+ *
+ * @param ssl - SSL point
+ *
+ * @return CA certification list
+ */
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl);
+
+/**
+ * @brief get the SSL context CA certification list
+ *
+ * @param ctx - SSL context point
+ *
+ * @return CA certification list
+ */
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx);
+
+/**
+ * @brief get the SSL certification point
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL certification point
+ */
+X509 *SSL_get_certificate(const SSL *ssl);
+
+/**
+ * @brief get the SSL private key point
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL private key point
+ */
+EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
+
+/**
+ * @brief set the SSL information callback function
+ *
+ * @param ssl - SSL point
+ * @param cb - information callback function
+ *
+ * @return none
+ */
+void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val));
+
+/**
+ * @brief get the SSL state
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL state
+ */
+OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl);
+
+/**
+ * @brief set the SSL context read buffer length
+ *
+ * @param ctx - SSL context point
+ * @param len - read buffer length
+ *
+ * @return none
+ */
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len);
+
+/**
+ * @brief set the SSL read buffer length
+ *
+ * @param ssl - SSL point
+ * @param len - read buffer length
+ *
+ * @return none
+ */
+void SSL_set_default_read_buffer_len(SSL *ssl, size_t len);
+
+/**
+ * @brief set the SSL security level
+ *
+ * @param ssl - SSL point
+ * @param level - security level
+ *
+ * @return none
+ */
+void SSL_set_security_level(SSL *ssl, int level);
+
+/**
+ * @brief get the SSL security level
+ *
+ * @param ssl - SSL point
+ *
+ * @return security level
+ */
+int SSL_get_security_level(const SSL *ssl);
+
+/**
+ * @brief get the SSL verifying mode of the SSL context
+ *
+ * @param ctx - SSL context point
+ *
+ * @return verifying mode
+ */
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+
+/**
+ * @brief get the SSL verifying depth of the SSL context
+ *
+ * @param ctx - SSL context point
+ *
+ * @return verifying depth
+ */
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+
+/**
+ * @brief set the SSL context verifying of the SSL context
+ *
+ * @param ctx - SSL context point
+ * @param mode - verifying mode
+ * @param verify_callback - verifying callback function
+ *
+ * @return none
+ */
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *));
+
+/**
+ * @brief set the SSL verifying of the SSL context
+ *
+ * @param ctx - SSL point
+ * @param mode - verifying mode
+ * @param verify_callback - verifying callback function
+ *
+ * @return none
+ */
+void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *));
+
+/**
+ * @brief set the SSL verify depth of the SSL context
+ *
+ * @param ctx - SSL context point
+ * @param depth - verifying depth
+ *
+ * @return none
+ */
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+
+/**
+ * @brief certification verifying callback function
+ *
+ * @param preverify_ok - verifying result
+ * @param x509_ctx - X509 certification point
+ *
+ * @return verifying result
+ */
+int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
+
+/**
+ * @brief set the session timeout time
+ *
+ * @param ctx - SSL context point
+ * @param t - new session timeout time
+ *
+ * @return old session timeout time
+ */
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
+
+/**
+ * @brief get the session timeout time
+ *
+ * @param ctx - SSL context point
+ *
+ * @return current session timeout time
+ */
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+
+/**
+ * @brief set the SSL context cipher through the list string
+ *
+ * @param ctx - SSL context point
+ * @param str - cipher controller list string
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
+
+/**
+ * @brief set the SSL cipher through the list string
+ *
+ * @param ssl - SSL point
+ * @param str - cipher controller list string
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_set_cipher_list(SSL *ssl, const char *str);
+
+/**
+ * @brief get the SSL cipher list string
+ *
+ * @param ssl - SSL point
+ *
+ * @return cipher controller list string
+ */
+const char *SSL_get_cipher_list(const SSL *ssl, int n);
+
+/**
+ * @brief get the SSL cipher
+ *
+ * @param ssl - SSL point
+ *
+ * @return current cipher
+ */
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
+
+/**
+ * @brief get the SSL cipher string
+ *
+ * @param ssl - SSL point
+ *
+ * @return cipher string
+ */
+const char *SSL_get_cipher(const SSL *ssl);
+
+/**
+ * @brief get the SSL context object X509 certification storage
+ *
+ * @param ctx - SSL context point
+ *
+ * @return x509 certification storage
+ */
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx);
+
+/**
+ * @brief set the SSL context object X509 certification store
+ *
+ * @param ctx - SSL context point
+ * @param store - X509 certification store
+ *
+ * @return none
+ */
+void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store);
+
+/**
+ * @brief get the SSL specifical statement
+ *
+ * @param ssl - SSL point
+ *
+ * @return specifical statement
+ */
+int SSL_want(const SSL *ssl);
+
+/**
+ * @brief check if the SSL is SSL_X509_LOOKUP state
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_want_x509_lookup(const SSL *ssl);
+
+/**
+ * @brief reset the SSL
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_clear(SSL *ssl);
+
+/**
+ * @brief get the socket handle of the SSL
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * >= 0 : yes, and return socket handle
+ * < 0 : a error catch
+ */
+int SSL_get_fd(const SSL *ssl);
+
+/**
+ * @brief get the read only socket handle of the SSL
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * >= 0 : yes, and return socket handle
+ * < 0 : a error catch
+ */
+int SSL_get_rfd(const SSL *ssl);
+
+/**
+ * @brief get the write only socket handle of the SSL
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * >= 0 : yes, and return socket handle
+ * < 0 : a error catch
+ */
+int SSL_get_wfd(const SSL *ssl);
+
+/**
+ * @brief set the SSL if we can read as many as data
+ *
+ * @param ssl - SSL point
+ * @param yes - enable the function
+ *
+ * @return none
+ */
+void SSL_set_read_ahead(SSL *s, int yes);
+
+/**
+ * @brief set the SSL context if we can read as many as data
+ *
+ * @param ctx - SSL context point
+ * @param yes - enbale the function
+ *
+ * @return none
+ */
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+
+/**
+ * @brief get the SSL ahead signal if we can read as many as data
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL context ahead signal
+ */
+int SSL_get_read_ahead(const SSL *ssl);
+
+/**
+ * @brief get the SSL context ahead signal if we can read as many as data
+ *
+ * @param ctx - SSL context point
+ *
+ * @return SSL context ahead signal
+ */
+long SSL_CTX_get_read_ahead(SSL_CTX *ctx);
+
+/**
+ * @brief check if some data can be read
+ *
+ * @param ssl - SSL point
+ *
+ * @return
+ * 1 : there are bytes to be read
+ * 0 : no data
+ */
+int SSL_has_pending(const SSL *ssl);
+
+/**
+ * @brief load the X509 certification into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param x - X509 certification point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx
+
+/**
+ * @brief load the ASN1 certification into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param len - certification length
+ * @param d - data point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
+
+/**
+ * @brief load the certification file into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param file - certification file name
+ * @param type - certification encoding type
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+
+/**
+ * @brief load the certification chain file into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param file - certification chain file name
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+
+
+/**
+ * @brief load the ASN1 private key into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param d - data point
+ * @param len - private key length
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx
+
+/**
+ * @brief load the private key file into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param file - private key file name
+ * @param type - private key encoding type
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+
+/**
+ * @brief load the RSA private key into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param x - RSA private key point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+
+/**
+ * @brief load the RSA ASN1 private key into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param d - data point
+ * @param len - RSA private key length
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
+
+/**
+ * @brief load the RSA private key file into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param file - RSA private key file name
+ * @param type - private key encoding type
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+
+
+/**
+ * @brief check if the private key and certification is matched
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+
+/**
+ * @brief set the SSL context server information
+ *
+ * @param ctx - SSL context point
+ * @param serverinfo - server information string
+ * @param serverinfo_length - server information length
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length);
+
+/**
+ * @brief load the SSL context server infomation file into SSL context
+ *
+ * @param ctx - SSL context point
+ * @param file - server information file
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file);
+
+/**
+ * @brief SSL select next function
+ *
+ * @param out - point of output data point
+ * @param outlen - output data length
+ * @param in - input data
+ * @param inlen - input data length
+ * @param client - client data point
+ * @param client_len -client data length
+ *
+ * @return NPN state
+ * OPENSSL_NPN_UNSUPPORTED : not support
+ * OPENSSL_NPN_NEGOTIATED : negotiated
+ * OPENSSL_NPN_NO_OVERLAP : no overlap
+ */
+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ const unsigned char *client, unsigned int client_len);
+
+/**
+ * @brief load the extra certification chain into the SSL context
+ *
+ * @param ctx - SSL context point
+ * @param x509 - X509 certification
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *);
+
+/**
+ * @brief control the SSL context
+ *
+ * @param ctx - SSL context point
+ * @param cmd - command
+ * @param larg - parameter length
+ * @param parg - parameter point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg);
+
+/**
+ * @brief get the SSL context cipher
+ *
+ * @param ctx - SSL context point
+ *
+ * @return SSL context cipher
+ */
+STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx);
+
+/**
+ * @brief check if the SSL context can read as many as data
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx);
+
+/**
+ * @brief get the SSL context extra data
+ *
+ * @param ctx - SSL context point
+ * @param idx - index
+ *
+ * @return data point
+ */
+char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
+
+/**
+ * @brief get the SSL context quiet shutdown option
+ *
+ * @param ctx - SSL context point
+ *
+ * @return quiet shutdown option
+ */
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+
+/**
+ * @brief load the SSL context CA file
+ *
+ * @param ctx - SSL context point
+ * @param CAfile - CA certification file
+ * @param CApath - CA certification file path
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
+
+/**
+ * @brief add SSL context reference count by '1'
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_up_ref(SSL_CTX *ctx);
+
+/**
+ * @brief set SSL context application private data
+ *
+ * @param ctx - SSL context point
+ * @param arg - private data
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg);
+
+/**
+ * @brief set SSL context client certification callback function
+ *
+ * @param ctx - SSL context point
+ * @param cb - callback function
+ *
+ * @return none
+ */
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+
+/**
+ * @brief set the SSL context if we can read as many as data
+ *
+ * @param ctx - SSL context point
+ * @param m - enable the fuction
+ *
+ * @return none
+ */
+void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m);
+
+/**
+ * @brief set SSL context default verifying path
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+
+/**
+ * @brief set SSL context default verifying directory
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx);
+
+/**
+ * @brief set SSL context default verifying file
+ *
+ * @param ctx - SSL context point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_default_verify_file(SSL_CTX *ctx);
+
+/**
+ * @brief set SSL context extra data
+ *
+ * @param ctx - SSL context point
+ * @param idx - data index
+ * @param arg - data point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg);
+
+/**
+ * @brief clear the SSL context option bit of "op"
+ *
+ * @param ctx - SSL context point
+ * @param op - option
+ *
+ * @return SSL context option
+ */
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op);
+
+/**
+ * @brief get the SSL context option
+ *
+ * @param ctx - SSL context point
+ * @param op - option
+ *
+ * @return SSL context option
+ */
+unsigned long SSL_CTX_get_options(SSL_CTX *ctx);
+
+/**
+ * @brief set the SSL context quiet shutdown mode
+ *
+ * @param ctx - SSL context point
+ * @param mode - mode
+ *
+ * @return none
+ */
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+
+/**
+ * @brief get the SSL context X509 certification
+ *
+ * @param ctx - SSL context point
+ *
+ * @return X509 certification
+ */
+X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+
+/**
+ * @brief get the SSL context private key
+ *
+ * @param ctx - SSL context point
+ *
+ * @return private key
+ */
+EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+
+/**
+ * @brief set SSL context PSK identity hint
+ *
+ * @param ctx - SSL context point
+ * @param hint - PSK identity hint
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint);
+
+/**
+ * @brief set SSL context PSK server callback function
+ *
+ * @param ctx - SSL context point
+ * @param callback - callback function
+ *
+ * @return none
+ */
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+ unsigned int (*callback)(SSL *ssl,
+ const char *identity,
+ unsigned char *psk,
+ int max_psk_len));
+/**
+ * @brief get alert description string
+ *
+ * @param value - alert value
+ *
+ * @return alert description string
+ */
+const char *SSL_alert_desc_string(int value);
+
+/**
+ * @brief get alert description long string
+ *
+ * @param value - alert value
+ *
+ * @return alert description long string
+ */
+const char *SSL_alert_desc_string_long(int value);
+
+/**
+ * @brief get alert type string
+ *
+ * @param value - alert value
+ *
+ * @return alert type string
+ */
+const char *SSL_alert_type_string(int value);
+
+/**
+ * @brief get alert type long string
+ *
+ * @param value - alert value
+ *
+ * @return alert type long string
+ */
+const char *SSL_alert_type_string_long(int value);
+
+/**
+ * @brief get SSL context of the SSL
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL context
+ */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+
+/**
+ * @brief get SSL application data
+ *
+ * @param ssl - SSL point
+ *
+ * @return application data
+ */
+char *SSL_get_app_data(SSL *ssl);
+
+/**
+ * @brief get SSL cipher bits
+ *
+ * @param ssl - SSL point
+ * @param alg_bits - algorithm bits
+ *
+ * @return strength bits
+ */
+int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits);
+
+/**
+ * @brief get SSL cipher name
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL cipher name
+ */
+char *SSL_get_cipher_name(const SSL *ssl);
+
+/**
+ * @brief get SSL cipher version
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL cipher version
+ */
+char *SSL_get_cipher_version(const SSL *ssl);
+
+/**
+ * @brief get SSL extra data
+ *
+ * @param ssl - SSL point
+ * @param idx - data index
+ *
+ * @return extra data
+ */
+char *SSL_get_ex_data(const SSL *ssl, int idx);
+
+/**
+ * @brief get index of the SSL extra data X509 storage context
+ *
+ * @param none
+ *
+ * @return data index
+ */
+int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+/**
+ * @brief get peer certification chain
+ *
+ * @param ssl - SSL point
+ *
+ * @return certification chain
+ */
+STACK *SSL_get_peer_cert_chain(const SSL *ssl);
+
+/**
+ * @brief get peer certification
+ *
+ * @param ssl - SSL point
+ *
+ * @return certification
+ */
+X509 *SSL_get_peer_certificate(const SSL *ssl);
+
+/**
+ * @brief get SSL quiet shutdown mode
+ *
+ * @param ssl - SSL point
+ *
+ * @return quiet shutdown mode
+ */
+int SSL_get_quiet_shutdown(const SSL *ssl);
+
+/**
+ * @brief get SSL read only IO handle
+ *
+ * @param ssl - SSL point
+ *
+ * @return IO handle
+ */
+BIO *SSL_get_rbio(const SSL *ssl);
+
+/**
+ * @brief get SSL shared ciphers
+ *
+ * @param ssl - SSL point
+ * @param buf - buffer to store the ciphers
+ * @param len - buffer len
+ *
+ * @return shared ciphers
+ */
+char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len);
+
+/**
+ * @brief get SSL shutdown mode
+ *
+ * @param ssl - SSL point
+ *
+ * @return shutdown mode
+ */
+int SSL_get_shutdown(const SSL *ssl);
+
+/**
+ * @brief get SSL session time
+ *
+ * @param ssl - SSL point
+ *
+ * @return session time
+ */
+long SSL_get_time(const SSL *ssl);
+
+/**
+ * @brief get SSL session timeout time
+ *
+ * @param ssl - SSL point
+ *
+ * @return session timeout time
+ */
+long SSL_get_timeout(const SSL *ssl);
+
+/**
+ * @brief get SSL verifying mode
+ *
+ * @param ssl - SSL point
+ *
+ * @return verifying mode
+ */
+int SSL_get_verify_mode(const SSL *ssl);
+
+/**
+ * @brief get SSL write only IO handle
+ *
+ * @param ssl - SSL point
+ *
+ * @return IO handle
+ */
+BIO *SSL_get_wbio(const SSL *ssl);
+
+/**
+ * @brief load SSL client CA certification file
+ *
+ * @param file - file name
+ *
+ * @return certification loading object
+ */
+STACK *SSL_load_client_CA_file(const char *file);
+
+/**
+ * @brief add SSL reference by '1'
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_up_ref(SSL *ssl);
+
+/**
+ * @brief read and put data into buf, but not clear the SSL low-level storage
+ *
+ * @param ssl - SSL point
+ * @param buf - storage buffer point
+ * @param num - data bytes
+ *
+ * @return result
+ * > 0 : OK, and return read bytes
+ * = 0 : connect is closed
+ * < 0 : a error catch
+ */
+int SSL_peek(SSL *ssl, void *buf, int num);
+
+/**
+ * @brief make SSL renegotiate
+ *
+ * @param ssl - SSL point
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_renegotiate(SSL *ssl);
+
+/**
+ * @brief get the state string where SSL is reading
+ *
+ * @param ssl - SSL point
+ *
+ * @return state string
+ */
+const char *SSL_rstate_string(SSL *ssl);
+
+/**
+ * @brief get the statement long string where SSL is reading
+ *
+ * @param ssl - SSL point
+ *
+ * @return statement long string
+ */
+const char *SSL_rstate_string_long(SSL *ssl);
+
+/**
+ * @brief set SSL accept statement
+ *
+ * @param ssl - SSL point
+ *
+ * @return none
+ */
+void SSL_set_accept_state(SSL *ssl);
+
+/**
+ * @brief set SSL application data
+ *
+ * @param ssl - SSL point
+ * @param arg - SSL application data point
+ *
+ * @return none
+ */
+void SSL_set_app_data(SSL *ssl, char *arg);
+
+/**
+ * @brief set SSL BIO
+ *
+ * @param ssl - SSL point
+ * @param rbio - read only IO
+ * @param wbio - write only IO
+ *
+ * @return none
+ */
+void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
+
+/**
+ * @brief clear SSL option
+ *
+ * @param ssl - SSL point
+ * @param op - clear option
+ *
+ * @return SSL option
+ */
+unsigned long SSL_clear_options(SSL *ssl, unsigned long op);
+
+/**
+ * @brief get SSL option
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL option
+ */
+unsigned long SSL_get_options(SSL *ssl);
+
+/**
+ * @brief clear SSL option
+ *
+ * @param ssl - SSL point
+ * @param op - setting option
+ *
+ * @return SSL option
+ */
+unsigned long SSL_set_options(SSL *ssl, unsigned long op);
+
+/**
+ * @brief set SSL quiet shutdown mode
+ *
+ * @param ssl - SSL point
+ * @param mode - quiet shutdown mode
+ *
+ * @return none
+ */
+void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+
+/**
+ * @brief set SSL shutdown mode
+ *
+ * @param ssl - SSL point
+ * @param mode - shutdown mode
+ *
+ * @return none
+ */
+void SSL_set_shutdown(SSL *ssl, int mode);
+
+/**
+ * @brief set SSL session time
+ *
+ * @param ssl - SSL point
+ * @param t - session time
+ *
+ * @return session time
+ */
+void SSL_set_time(SSL *ssl, long t);
+
+/**
+ * @brief set SSL session timeout time
+ *
+ * @param ssl - SSL point
+ * @param t - session timeout time
+ *
+ * @return session timeout time
+ */
+void SSL_set_timeout(SSL *ssl, long t);
+
+/**
+ * @brief get SSL statement string
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL statement string
+ */
+char *SSL_state_string(const SSL *ssl);
+
+/**
+ * @brief get SSL statement long string
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL statement long string
+ */
+char *SSL_state_string_long(const SSL *ssl);
+
+/**
+ * @brief get SSL renegotiation count
+ *
+ * @param ssl - SSL point
+ *
+ * @return renegotiation count
+ */
+long SSL_total_renegotiations(SSL *ssl);
+
+/**
+ * @brief get SSL version
+ *
+ * @param ssl - SSL point
+ *
+ * @return SSL version
+ */
+int SSL_version(const SSL *ssl);
+
+/**
+ * @brief set SSL PSK identity hint
+ *
+ * @param ssl - SSL point
+ * @param hint - identity hint
+ *
+ * @return result
+ * 1 : OK
+ * 0 : failed
+ */
+int SSL_use_psk_identity_hint(SSL *ssl, const char *hint);
+
+/**
+ * @brief get SSL PSK identity hint
+ *
+ * @param ssl - SSL point
+ *
+ * @return identity hint
+ */
+const char *SSL_get_psk_identity_hint(SSL *ssl);
+
+/**
+ * @brief get SSL PSK identity
+ *
+ * @param ssl - SSL point
+ *
+ * @return identity
+ */
+const char *SSL_get_psk_identity(SSL *ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/openssl/include/platform/ssl_opt.h b/components/openssl/include/platform/ssl_opt.h
new file mode 100644
index 0000000000..01d438eb8a
--- /dev/null
+++ b/components/openssl/include/platform/ssl_opt.h
@@ -0,0 +1,48 @@
+// 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 _SSL_OPT_H_
+#define _SSL_OPT_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ * if not define "ESP32_IDF_PLATFORM", system will use esp8266 platform interface
+ */
+#define ESP32_IDF_PLATFORM
+
+/**
+ * openssl debug print function enable
+ */
+#define SSL_DEBUG_ENBALE 0
+
+/**
+ * openssl debug print function level. function whose level is lower that "SSL_DEBUG_LEVEL"
+ * will not print message
+ */
+#define SSL_DEBUG_LEVEL 0
+
+/**
+ * openssl assert function enable, it will check the input paramter and print the message
+ */
+#define SSL_ASSERT_ENABLE 0
+
+/**
+ * openssl location function enable, it will print location of the positioning error
+ */
+#define SSL_DEBUG_LOCATION_ENABLE 0
+
+#endif
diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h
new file mode 100644
index 0000000000..a516d57422
--- /dev/null
+++ b/components/openssl/include/platform/ssl_pm.h
@@ -0,0 +1,56 @@
+// 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 _SSL_PM_H_
+#define _SSL_PM_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ssl_types.h"
+#include "ssl_port.h"
+
+#define LOCAL_ATRR
+
+int ssl_pm_new(SSL *ssl);
+void ssl_pm_free(SSL *ssl);
+
+int ssl_pm_handshake(SSL *ssl);
+int ssl_pm_shutdown(SSL *ssl);
+int ssl_pm_clear(SSL *ssl);
+
+int ssl_pm_read(SSL *ssl, void *buffer, int len);
+int ssl_pm_send(SSL *ssl, const void *buffer, int len);
+int ssl_pm_pending(const SSL *ssl);
+
+void ssl_pm_set_fd(SSL *ssl, int fd, int mode);
+int ssl_pm_get_fd(const SSL *ssl, int mode);
+
+OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl);
+
+void ssl_pm_set_bufflen(SSL *ssl, int len);
+
+int x509_pm_show_info(X509 *x);
+int x509_pm_new(X509 *x, X509 *m_x);
+void x509_pm_free(X509 *x);
+int x509_pm_load(X509 *x, const unsigned char *buffer, int len);
+
+int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk);
+void pkey_pm_free(EVP_PKEY *pk);
+int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len);
+
+long ssl_pm_get_verify_result(const SSL *ssl);
+
+#endif
diff --git a/components/openssl/include/platform/ssl_port.h b/components/openssl/include/platform/ssl_port.h
new file mode 100644
index 0000000000..35c8dc18f9
--- /dev/null
+++ b/components/openssl/include/platform/ssl_port.h
@@ -0,0 +1,49 @@
+// 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 _SSL_PORT_H_
+#define _SSL_PORT_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "platform/ssl_opt.h"
+
+#ifdef ESP32_IDF_PLATFORM
+
+#include "esp_types.h"
+#include "esp_log.h"
+
+void *ssl_mem_zalloc(size_t size);
+void *ssl_mem_malloc(size_t size);
+void ssl_mem_free(void *p);
+
+void* ssl_memcpy(void *to, const void *from, size_t size);
+size_t ssl_strlen(const char *src);
+
+void ssl_speed_up_enter(void);
+void ssl_speed_up_exit(void);
+
+#define SSL_PRINT_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__)
+#define SSL_ERROR_LOG(fmt, ...) ESP_LOGE("openssl", fmt, ##__VA_ARGS__)
+#define SSL_LOCAL_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__)
+
+#elif defined(SSL_PLATFORM_USER_INCLUDE)
+
+SSL_PLATFORM_USER_INCLUDE
+
+#endif
+
+#endif
diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c
new file mode 100644
index 0000000000..0193a441e0
--- /dev/null
+++ b/components/openssl/library/ssl_cert.c
@@ -0,0 +1,79 @@
+// 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.
+
+#include "ssl_cert.h"
+#include "ssl_pkey.h"
+#include "ssl_x509.h"
+#include "ssl_dbg.h"
+#include "ssl_port.h"
+
+/**
+ * @brief create a certification object according to input certification
+ */
+CERT *__ssl_cert_new(CERT *ic)
+{
+ CERT *cert;
+
+ X509 *ix;
+ EVP_PKEY *ipk;
+
+ cert = ssl_mem_zalloc(sizeof(CERT));
+ if (!cert)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ if (ic) {
+ ipk = ic->pkey;
+ ix = ic->x509;
+ } else {
+ ipk = NULL;
+ ix = NULL;
+ }
+
+ cert->pkey = __EVP_PKEY_new(ipk);
+ if (!cert->pkey)
+ SSL_RET(failed2, "__EVP_PKEY_new\n");
+
+ cert->x509 = __X509_new(ix);
+ if (!cert->x509)
+ SSL_RET(failed3, "__X509_new\n");
+
+ return cert;
+
+failed3:
+ EVP_PKEY_free(cert->pkey);
+failed2:
+ ssl_mem_free(cert);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief create a certification object include private key object
+ */
+CERT *ssl_cert_new(void)
+{
+ return __ssl_cert_new(NULL);
+}
+
+/**
+ * @brief free a certification object
+ */
+void ssl_cert_free(CERT *cert)
+{
+ X509_free(cert->x509);
+
+ EVP_PKEY_free(cert->pkey);
+
+ ssl_mem_free(cert);
+}
diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c
new file mode 100644
index 0000000000..23b8bf4cea
--- /dev/null
+++ b/components/openssl/library/ssl_lib.c
@@ -0,0 +1,1506 @@
+// 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.
+
+#include "ssl_lib.h"
+#include "ssl_pkey.h"
+#include "ssl_x509.h"
+#include "ssl_cert.h"
+#include "ssl_dbg.h"
+#include "ssl_port.h"
+
+#define SSL_SEND_DATA_MAX_LENGTH 1460
+
+/**
+ * @brief Discover whether the current connection is in the error state
+ */
+int ossl_statem_in_error(const SSL *ssl)
+{
+ if (ssl->statem.state == MSG_FLOW_ERROR)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * @brief get the SSL specifical statement
+ */
+int SSL_want(const SSL *ssl)
+{
+ return ssl->rwstate;
+}
+
+/**
+ * @brief check if SSL want nothing
+ */
+int SSL_want_nothing(const SSL *ssl)
+{
+ return (SSL_want(ssl) == SSL_NOTHING);
+}
+
+/**
+ * @brief check if SSL want to read
+ */
+int SSL_want_read(const SSL *ssl)
+{
+ return (SSL_want(ssl) == SSL_READING);
+}
+
+/**
+ * @brief check if SSL want to write
+ */
+int SSL_want_write(const SSL *ssl)
+{
+ return (SSL_want(ssl) == SSL_WRITING);
+}
+
+/**
+ * @brief check if SSL want to lookup X509 certification
+ */
+int SSL_want_x509_lookup(const SSL *ssl)
+{
+ return (SSL_want(ssl) == SSL_WRITING);
+}
+
+/**
+ * @brief get SSL error code
+ */
+int SSL_get_error(const SSL *ssl, int ret_code)
+{
+ int ret = SSL_ERROR_SYSCALL;
+
+ SSL_ASSERT(ssl);
+
+ if (ret_code > 0)
+ ret = SSL_ERROR_NONE;
+ else if (ret_code < 0)
+ {
+ if (SSL_want_read(ssl))
+ ret = SSL_ERROR_WANT_READ;
+ else if (SSL_want_write(ssl))
+ ret = SSL_ERROR_WANT_WRITE;
+ else
+ ret = SSL_ERROR_SYSCALL; //unknown
+ }
+ else // ret_code == 0
+ {
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN)
+ ret = SSL_ERROR_ZERO_RETURN;
+ else
+ ret = SSL_ERROR_SYSCALL;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief get the SSL state
+ */
+OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl)
+{
+ OSSL_HANDSHAKE_STATE state;
+
+ SSL_ASSERT(ssl);
+
+ state = SSL_METHOD_CALL(get_state, ssl);
+
+ return state;
+}
+
+/**
+ * @brief create a new SSL session object
+ */
+SSL_SESSION* SSL_SESSION_new(void)
+{
+ SSL_SESSION *session;
+
+ session = ssl_mem_zalloc(sizeof(SSL_SESSION));
+ if (!session)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ session->peer = X509_new();
+ if (!session->peer)
+ SSL_RET(failed2, "X509_new\n");
+
+ return session;
+
+failed2:
+ ssl_mem_free(session);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief free a new SSL session object
+ */
+void SSL_SESSION_free(SSL_SESSION *session)
+{
+ X509_free(session->peer);
+ ssl_mem_free(session);
+}
+
+/**
+ * @brief create a SSL context
+ */
+SSL_CTX* SSL_CTX_new(const SSL_METHOD *method)
+{
+ SSL_CTX *ctx;
+ CERT *cert;
+ X509 *client_ca;
+
+ if (!method) SSL_RET(go_failed1, "method:NULL\n");
+
+ client_ca = X509_new();
+ if (!client_ca)
+ SSL_RET(go_failed1, "X509_new\n");
+
+ cert = ssl_cert_new();
+ if (!cert)
+ SSL_RET(go_failed2, "ssl_cert_new\n");
+
+ ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX));
+ if (!ctx)
+ SSL_RET(go_failed3, "ssl_mem_zalloc:ctx\n");
+
+ ctx->method = method;
+ ctx->client_CA = client_ca;
+ ctx->cert = cert;
+
+ ctx->version = method->version;
+
+ return ctx;
+
+go_failed3:
+ ssl_cert_free(cert);
+go_failed2:
+ X509_free(client_ca);
+go_failed1:
+ return NULL;
+}
+
+/**
+ * @brief free a SSL context
+ */
+void SSL_CTX_free(SSL_CTX* ctx)
+{
+ SSL_ASSERT(ctx);
+
+ ssl_cert_free(ctx->cert);
+
+ X509_free(ctx->client_CA);
+
+ ssl_mem_free(ctx);
+}
+
+/**
+ * @brief set the SSL context version
+ */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
+{
+ SSL_ASSERT(ctx);
+ SSL_ASSERT(meth);
+
+ ctx->method = meth;
+
+ ctx->version = meth->version;
+
+ return 1;
+}
+
+/**
+ * @brief get the SSL context current method
+ */
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->method;
+}
+
+/**
+ * @brief create a SSL
+ */
+SSL *SSL_new(SSL_CTX *ctx)
+{
+ int ret = 0;
+ SSL *ssl;
+
+ if (!ctx)
+ SSL_RET(failed1, "ctx:NULL\n");
+
+ ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL));
+ if (!ssl)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ ssl->session = SSL_SESSION_new();
+ if (!ssl->session)
+ SSL_RET(failed2, "SSL_SESSION_new\n");
+
+ ssl->cert = __ssl_cert_new(ctx->cert);
+ if (!ssl->cert)
+ SSL_RET(failed3, "__ssl_cert_new\n");
+
+ ssl->client_CA = __X509_new(ctx->client_CA);
+ if (!ssl->client_CA)
+ SSL_RET(failed4, "__X509_new\n");
+
+ ssl->ctx = ctx;
+ ssl->method = ctx->method;
+
+ ssl->version = ctx->version;
+ ssl->options = ctx->options;
+
+ ssl->verify_mode = ctx->verify_mode;
+
+ ret = SSL_METHOD_CALL(new, ssl);
+ if (ret)
+ SSL_RET(failed5, "ssl_new\n");
+
+ ssl->rwstate = SSL_NOTHING;
+
+ return ssl;
+
+failed5:
+ X509_free(ssl->client_CA);
+failed4:
+ ssl_cert_free(ssl->cert);
+failed3:
+ SSL_SESSION_free(ssl->session);
+failed2:
+ ssl_mem_free(ssl);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief free the SSL
+ */
+void SSL_free(SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ SSL_METHOD_CALL(free, ssl);
+
+ X509_free(ssl->client_CA);
+
+ ssl_cert_free(ssl->cert);
+
+ SSL_SESSION_free(ssl->session);
+
+ ssl_mem_free(ssl);
+}
+
+/**
+ * @brief perform the SSL handshake
+ */
+int SSL_do_handshake(SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_METHOD_CALL(handshake, ssl);
+
+ return ret;
+}
+
+/**
+ * @brief connect to the remote SSL server
+ */
+int SSL_connect(SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return SSL_do_handshake(ssl);
+}
+
+/**
+ * @brief accept the remote connection
+ */
+int SSL_accept(SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return SSL_do_handshake(ssl);
+}
+
+/**
+ * @brief shutdown the connection
+ */
+int SSL_shutdown(SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ if (SSL_get_state(ssl) != TLS_ST_OK) return 1;
+
+ ret = SSL_METHOD_CALL(shutdown, ssl);
+
+ return ret;
+}
+
+/**
+ * @brief reset the SSL
+ */
+int SSL_clear(SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_shutdown(ssl);
+ if (1 != ret)
+ SSL_ERR(0, go_failed1, "SSL_shutdown\n");
+
+ SSL_METHOD_CALL(free, ssl);
+
+ ret = SSL_METHOD_CALL(new, ssl);
+ if (!ret)
+ SSL_ERR(0, go_failed1, "ssl_new\n");
+
+ return 1;
+
+go_failed1:
+ return ret;
+}
+
+/**
+ * @brief read data from to remote
+ */
+int SSL_read(SSL *ssl, void *buffer, int len)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(buffer);
+ SSL_ASSERT(len);
+
+ ssl->rwstate = SSL_READING;
+
+ ret = SSL_METHOD_CALL(read, ssl, buffer, len);
+
+ if (ret == len)
+ ssl->rwstate = SSL_NOTHING;
+
+ return ret;
+}
+
+/**
+ * @brief send the data to remote
+ */
+int SSL_write(SSL *ssl, const void *buffer, int len)
+{
+ int ret;
+ int send_bytes;
+ const unsigned char *pbuf;
+
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(buffer);
+ SSL_ASSERT(len);
+
+ ssl->rwstate = SSL_WRITING;
+
+ send_bytes = len;
+ pbuf = (const unsigned char *)buffer;
+
+ do {
+ int bytes;
+
+ if (send_bytes > SSL_SEND_DATA_MAX_LENGTH)
+ bytes = SSL_SEND_DATA_MAX_LENGTH;
+ else
+ bytes = send_bytes;
+
+ ret = SSL_METHOD_CALL(send, ssl, buffer, bytes);
+ if (ret > 0) {
+ pbuf += ret;
+ send_bytes -= ret;
+ }
+ } while (ret > 0 && send_bytes);
+
+ if (ret >= 0) {
+ ret = len - send_bytes;
+ ssl->rwstate = SSL_NOTHING;
+ } else
+ ret = -1;
+
+ return ret;
+}
+
+/**
+ * @brief get SSL context of the SSL
+ */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->ctx;
+}
+
+/**
+ * @brief get the SSL current method
+ */
+const SSL_METHOD *SSL_get_ssl_method(SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->method;
+}
+
+/**
+ * @brief set the SSL method
+ */
+int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(method);
+
+ if (ssl->version != method->version) {
+
+ ret = SSL_shutdown(ssl);
+ if (1 != ret)
+ SSL_ERR(0, go_failed1, "SSL_shutdown\n");
+
+ SSL_METHOD_CALL(free, ssl);
+
+ ssl->method = method;
+
+ ret = SSL_METHOD_CALL(new, ssl);
+ if (!ret)
+ SSL_ERR(0, go_failed1, "ssl_new\n");
+ } else {
+ ssl->method = method;
+ }
+
+
+ return 1;
+
+go_failed1:
+ return ret;
+}
+
+/**
+ * @brief get SSL shutdown mode
+ */
+int SSL_get_shutdown(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->shutdown;
+}
+
+/**
+ * @brief set SSL shutdown mode
+ */
+void SSL_set_shutdown(SSL *ssl, int mode)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->shutdown = mode;
+}
+
+
+/**
+ * @brief get the number of the bytes to be read
+ */
+int SSL_pending(const SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_METHOD_CALL(pending, ssl);
+
+ return ret;
+}
+
+/**
+ * @brief check if some data can be read
+ */
+int SSL_has_pending(const SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ if (SSL_pending(ssl))
+ ret = 1;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+/**
+ * @brief clear the SSL context option bit of "op"
+ */
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
+{
+ return ctx->options &= ~op;
+}
+
+/**
+ * @brief get the SSL context option
+ */
+unsigned long SSL_CTX_get_options(SSL_CTX *ctx)
+{
+ return ctx->options;
+}
+
+/**
+ * @brief set the option of the SSL context
+ */
+unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt)
+{
+ return ctx->options |= opt;
+}
+
+/**
+ * @brief clear SSL option
+ */
+unsigned long SSL_clear_options(SSL *ssl, unsigned long op)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->options & ~op;
+}
+
+/**
+ * @brief get SSL option
+ */
+unsigned long SSL_get_options(SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->options;
+}
+
+/**
+ * @brief clear SSL option
+ */
+unsigned long SSL_set_options(SSL *ssl, unsigned long op)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->options |= op;
+}
+
+/**
+ * @brief get the socket handle of the SSL
+ */
+int SSL_get_fd(const SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+ return ret;
+}
+
+/**
+ * @brief get the read only socket handle of the SSL
+ */
+int SSL_get_rfd(const SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+ return ret;
+}
+
+/**
+ * @brief get the write only socket handle of the SSL
+ */
+int SSL_get_wfd(const SSL *ssl)
+{
+ int ret;
+
+ SSL_ASSERT(ssl);
+
+ ret = SSL_METHOD_CALL(get_fd, ssl, 0);
+
+ return ret;
+}
+
+/**
+ * @brief bind the socket file description into the SSL
+ */
+int SSL_set_fd(SSL *ssl, int fd)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(fd >= 0);
+
+ SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+ return 1;
+}
+
+/**
+ * @brief bind the read only socket file description into the SSL
+ */
+int SSL_set_rfd(SSL *ssl, int fd)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(fd >= 0);
+
+ SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+ return 1;
+}
+
+/**
+ * @brief bind the write only socket file description into the SSL
+ */
+int SSL_set_wfd(SSL *ssl, int fd)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(fd >= 0);
+
+ SSL_METHOD_CALL(set_fd, ssl, fd, 0);
+
+ return 1;
+}
+
+/**
+ * @brief get SSL version
+ */
+int SSL_version(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->version;
+}
+
+/**
+ * @brief get the SSL version string
+ */
+static const char* ssl_protocol_to_string(int version)
+{
+ const char *str;
+
+ if (version == TLS1_2_VERSION)
+ str = "TLSv1.2";
+ else if (version == TLS1_1_VERSION)
+ str = "TLSv1.1";
+ else if (version == TLS1_VERSION)
+ str = "TLSv1";
+ else if (version == SSL3_VERSION)
+ str = "SSLv3";
+ else
+ str = "unknown";
+
+ return str;
+}
+
+/**
+ * @brief get the SSL current version
+ */
+const char *SSL_get_version(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl_protocol_to_string(SSL_version(ssl));
+}
+
+/**
+ * @brief get alert description string
+ */
+const char* SSL_alert_desc_string(int value)
+{
+ const char *str;
+
+ switch (value & 0xff)
+ {
+ case SSL3_AD_CLOSE_NOTIFY:
+ str = "CN";
+ break;
+ case SSL3_AD_UNEXPECTED_MESSAGE:
+ str = "UM";
+ break;
+ case SSL3_AD_BAD_RECORD_MAC:
+ str = "BM";
+ break;
+ case SSL3_AD_DECOMPRESSION_FAILURE:
+ str = "DF";
+ break;
+ case SSL3_AD_HANDSHAKE_FAILURE:
+ str = "HF";
+ break;
+ case SSL3_AD_NO_CERTIFICATE:
+ str = "NC";
+ break;
+ case SSL3_AD_BAD_CERTIFICATE:
+ str = "BC";
+ break;
+ case SSL3_AD_UNSUPPORTED_CERTIFICATE:
+ str = "UC";
+ break;
+ case SSL3_AD_CERTIFICATE_REVOKED:
+ str = "CR";
+ break;
+ case SSL3_AD_CERTIFICATE_EXPIRED:
+ str = "CE";
+ break;
+ case SSL3_AD_CERTIFICATE_UNKNOWN:
+ str = "CU";
+ break;
+ case SSL3_AD_ILLEGAL_PARAMETER:
+ str = "IP";
+ break;
+ case TLS1_AD_DECRYPTION_FAILED:
+ str = "DC";
+ break;
+ case TLS1_AD_RECORD_OVERFLOW:
+ str = "RO";
+ break;
+ case TLS1_AD_UNKNOWN_CA:
+ str = "CA";
+ break;
+ case TLS1_AD_ACCESS_DENIED:
+ str = "AD";
+ break;
+ case TLS1_AD_DECODE_ERROR:
+ str = "DE";
+ break;
+ case TLS1_AD_DECRYPT_ERROR:
+ str = "CY";
+ break;
+ case TLS1_AD_EXPORT_RESTRICTION:
+ str = "ER";
+ break;
+ case TLS1_AD_PROTOCOL_VERSION:
+ str = "PV";
+ break;
+ case TLS1_AD_INSUFFICIENT_SECURITY:
+ str = "IS";
+ break;
+ case TLS1_AD_INTERNAL_ERROR:
+ str = "IE";
+ break;
+ case TLS1_AD_USER_CANCELLED:
+ str = "US";
+ break;
+ case TLS1_AD_NO_RENEGOTIATION:
+ str = "NR";
+ break;
+ case TLS1_AD_UNSUPPORTED_EXTENSION:
+ str = "UE";
+ break;
+ case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+ str = "CO";
+ break;
+ case TLS1_AD_UNRECOGNIZED_NAME:
+ str = "UN";
+ break;
+ case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+ str = "BR";
+ break;
+ case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+ str = "BH";
+ break;
+ case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+ str = "UP";
+ break;
+ default:
+ str = "UK";
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get alert description long string
+ */
+const char* SSL_alert_desc_string_long(int value)
+{
+ const char *str;
+
+ switch (value & 0xff)
+ {
+ case SSL3_AD_CLOSE_NOTIFY:
+ str = "close notify";
+ break;
+ case SSL3_AD_UNEXPECTED_MESSAGE:
+ str = "unexpected_message";
+ break;
+ case SSL3_AD_BAD_RECORD_MAC:
+ str = "bad record mac";
+ break;
+ case SSL3_AD_DECOMPRESSION_FAILURE:
+ str = "decompression failure";
+ break;
+ case SSL3_AD_HANDSHAKE_FAILURE:
+ str = "handshake failure";
+ break;
+ case SSL3_AD_NO_CERTIFICATE:
+ str = "no certificate";
+ break;
+ case SSL3_AD_BAD_CERTIFICATE:
+ str = "bad certificate";
+ break;
+ case SSL3_AD_UNSUPPORTED_CERTIFICATE:
+ str = "unsupported certificate";
+ break;
+ case SSL3_AD_CERTIFICATE_REVOKED:
+ str = "certificate revoked";
+ break;
+ case SSL3_AD_CERTIFICATE_EXPIRED:
+ str = "certificate expired";
+ break;
+ case SSL3_AD_CERTIFICATE_UNKNOWN:
+ str = "certificate unknown";
+ break;
+ case SSL3_AD_ILLEGAL_PARAMETER:
+ str = "illegal parameter";
+ break;
+ case TLS1_AD_DECRYPTION_FAILED:
+ str = "decryption failed";
+ break;
+ case TLS1_AD_RECORD_OVERFLOW:
+ str = "record overflow";
+ break;
+ case TLS1_AD_UNKNOWN_CA:
+ str = "unknown CA";
+ break;
+ case TLS1_AD_ACCESS_DENIED:
+ str = "access denied";
+ break;
+ case TLS1_AD_DECODE_ERROR:
+ str = "decode error";
+ break;
+ case TLS1_AD_DECRYPT_ERROR:
+ str = "decrypt error";
+ break;
+ case TLS1_AD_EXPORT_RESTRICTION:
+ str = "export restriction";
+ break;
+ case TLS1_AD_PROTOCOL_VERSION:
+ str = "protocol version";
+ break;
+ case TLS1_AD_INSUFFICIENT_SECURITY:
+ str = "insufficient security";
+ break;
+ case TLS1_AD_INTERNAL_ERROR:
+ str = "internal error";
+ break;
+ case TLS1_AD_USER_CANCELLED:
+ str = "user canceled";
+ break;
+ case TLS1_AD_NO_RENEGOTIATION:
+ str = "no renegotiation";
+ break;
+ case TLS1_AD_UNSUPPORTED_EXTENSION:
+ str = "unsupported extension";
+ break;
+ case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+ str = "certificate unobtainable";
+ break;
+ case TLS1_AD_UNRECOGNIZED_NAME:
+ str = "unrecognized name";
+ break;
+ case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+ str = "bad certificate status response";
+ break;
+ case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+ str = "bad certificate hash value";
+ break;
+ case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+ str = "unknown PSK identity";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get alert type string
+ */
+const char *SSL_alert_type_string(int value)
+{
+ const char *str;
+
+ switch (value >> 8)
+ {
+ case SSL3_AL_WARNING:
+ str = "W";
+ break;
+ case SSL3_AL_FATAL:
+ str = "F";
+ break;
+ default:
+ str = "U";
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get alert type long string
+ */
+const char *SSL_alert_type_string_long(int value)
+{
+ const char *str;
+
+ switch (value >> 8)
+ {
+ case SSL3_AL_WARNING:
+ str = "warning";
+ break;
+ case SSL3_AL_FATAL:
+ str = "fatal";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get the state string where SSL is reading
+ */
+const char *SSL_rstate_string(SSL *ssl)
+{
+ const char *str;
+
+ SSL_ASSERT(ssl);
+
+ switch (ssl->rlayer.rstate)
+ {
+ case SSL_ST_READ_HEADER:
+ str = "RH";
+ break;
+ case SSL_ST_READ_BODY:
+ str = "RB";
+ break;
+ case SSL_ST_READ_DONE:
+ str = "RD";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get the statement long string where SSL is reading
+ */
+const char *SSL_rstate_string_long(SSL *ssl)
+{
+ const char *str = "unknown";
+
+ SSL_ASSERT(ssl);
+
+ switch (ssl->rlayer.rstate)
+ {
+ case SSL_ST_READ_HEADER:
+ str = "read header";
+ break;
+ case SSL_ST_READ_BODY:
+ str = "read body";
+ break;
+ case SSL_ST_READ_DONE:
+ str = "read done";
+ break;
+ default:
+ break;
+ }
+
+ return str;
+}
+
+/**
+ * @brief get SSL statement string
+ */
+char *SSL_state_string(const SSL *ssl)
+{
+ char *str = "UNKWN ";
+
+ SSL_ASSERT(ssl);
+
+ if (ossl_statem_in_error(ssl))
+ str = "SSLERR";
+ else
+ {
+ switch (SSL_get_state(ssl))
+ {
+ case TLS_ST_BEFORE:
+ str = "PINIT ";
+ break;
+ case TLS_ST_OK:
+ str = "SSLOK ";
+ break;
+ case TLS_ST_CW_CLNT_HELLO:
+ str = "TWCH";
+ break;
+ case TLS_ST_CR_SRVR_HELLO:
+ str = "TRSH";
+ break;
+ case TLS_ST_CR_CERT:
+ str = "TRSC";
+ break;
+ case TLS_ST_CR_KEY_EXCH:
+ str = "TRSKE";
+ break;
+ case TLS_ST_CR_CERT_REQ:
+ str = "TRCR";
+ break;
+ case TLS_ST_CR_SRVR_DONE:
+ str = "TRSD";
+ break;
+ case TLS_ST_CW_CERT:
+ str = "TWCC";
+ break;
+ case TLS_ST_CW_KEY_EXCH:
+ str = "TWCKE";
+ break;
+ case TLS_ST_CW_CERT_VRFY:
+ str = "TWCV";
+ break;
+ case TLS_ST_SW_CHANGE:
+ case TLS_ST_CW_CHANGE:
+ str = "TWCCS";
+ break;
+ case TLS_ST_SW_FINISHED:
+ case TLS_ST_CW_FINISHED:
+ str = "TWFIN";
+ break;
+ case TLS_ST_SR_CHANGE:
+ case TLS_ST_CR_CHANGE:
+ str = "TRCCS";
+ break;
+ case TLS_ST_SR_FINISHED:
+ case TLS_ST_CR_FINISHED:
+ str = "TRFIN";
+ break;
+ case TLS_ST_SW_HELLO_REQ:
+ str = "TWHR";
+ break;
+ case TLS_ST_SR_CLNT_HELLO:
+ str = "TRCH";
+ break;
+ case TLS_ST_SW_SRVR_HELLO:
+ str = "TWSH";
+ break;
+ case TLS_ST_SW_CERT:
+ str = "TWSC";
+ break;
+ case TLS_ST_SW_KEY_EXCH:
+ str = "TWSKE";
+ break;
+ case TLS_ST_SW_CERT_REQ:
+ str = "TWCR";
+ break;
+ case TLS_ST_SW_SRVR_DONE:
+ str = "TWSD";
+ break;
+ case TLS_ST_SR_CERT:
+ str = "TRCC";
+ break;
+ case TLS_ST_SR_KEY_EXCH:
+ str = "TRCKE";
+ break;
+ case TLS_ST_SR_CERT_VRFY:
+ str = "TRCV";
+ break;
+ case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+ str = "DRCHV";
+ break;
+ case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+ str = "DWCHV";
+ break;
+ default:
+ break;
+ }
+ }
+
+ return str;
+}
+
+/**
+ * @brief get SSL statement long string
+ */
+char *SSL_state_string_long(const SSL *ssl)
+{
+ char *str = "UNKWN ";
+
+ SSL_ASSERT(ssl);
+
+ if (ossl_statem_in_error(ssl))
+ str = "SSLERR";
+ else
+ {
+ switch (SSL_get_state(ssl))
+ {
+ case TLS_ST_BEFORE:
+ str = "before SSL initialization";
+ break;
+ case TLS_ST_OK:
+ str = "SSL negotiation finished successfully";
+ break;
+ case TLS_ST_CW_CLNT_HELLO:
+ str = "SSLv3/TLS write client hello";
+ break;
+ case TLS_ST_CR_SRVR_HELLO:
+ str = "SSLv3/TLS read server hello";
+ break;
+ case TLS_ST_CR_CERT:
+ str = "SSLv3/TLS read server certificate";
+ break;
+ case TLS_ST_CR_KEY_EXCH:
+ str = "SSLv3/TLS read server key exchange";
+ break;
+ case TLS_ST_CR_CERT_REQ:
+ str = "SSLv3/TLS read server certificate request";
+ break;
+ case TLS_ST_CR_SESSION_TICKET:
+ str = "SSLv3/TLS read server session ticket";
+ break;
+ case TLS_ST_CR_SRVR_DONE:
+ str = "SSLv3/TLS read server done";
+ break;
+ case TLS_ST_CW_CERT:
+ str = "SSLv3/TLS write client certificate";
+ break;
+ case TLS_ST_CW_KEY_EXCH:
+ str = "SSLv3/TLS write client key exchange";
+ break;
+ case TLS_ST_CW_CERT_VRFY:
+ str = "SSLv3/TLS write certificate verify";
+ break;
+ case TLS_ST_CW_CHANGE:
+ case TLS_ST_SW_CHANGE:
+ str = "SSLv3/TLS write change cipher spec";
+ break;
+ case TLS_ST_CW_FINISHED:
+ case TLS_ST_SW_FINISHED:
+ str = "SSLv3/TLS write finished";
+ break;
+ case TLS_ST_CR_CHANGE:
+ case TLS_ST_SR_CHANGE:
+ str = "SSLv3/TLS read change cipher spec";
+ break;
+ case TLS_ST_CR_FINISHED:
+ case TLS_ST_SR_FINISHED:
+ str = "SSLv3/TLS read finished";
+ break;
+ case TLS_ST_SR_CLNT_HELLO:
+ str = "SSLv3/TLS read client hello";
+ break;
+ case TLS_ST_SW_HELLO_REQ:
+ str = "SSLv3/TLS write hello request";
+ break;
+ case TLS_ST_SW_SRVR_HELLO:
+ str = "SSLv3/TLS write server hello";
+ break;
+ case TLS_ST_SW_CERT:
+ str = "SSLv3/TLS write certificate";
+ break;
+ case TLS_ST_SW_KEY_EXCH:
+ str = "SSLv3/TLS write key exchange";
+ break;
+ case TLS_ST_SW_CERT_REQ:
+ str = "SSLv3/TLS write certificate request";
+ break;
+ case TLS_ST_SW_SESSION_TICKET:
+ str = "SSLv3/TLS write session ticket";
+ break;
+ case TLS_ST_SW_SRVR_DONE:
+ str = "SSLv3/TLS write server done";
+ break;
+ case TLS_ST_SR_CERT:
+ str = "SSLv3/TLS read client certificate";
+ break;
+ case TLS_ST_SR_KEY_EXCH:
+ str = "SSLv3/TLS read client key exchange";
+ break;
+ case TLS_ST_SR_CERT_VRFY:
+ str = "SSLv3/TLS read certificate verify";
+ break;
+ case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+ str = "DTLS1 read hello verify request";
+ break;
+ case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+ str = "DTLS1 write hello verify request";
+ break;
+ default:
+ break;
+ }
+ }
+
+ return str;
+}
+
+/**
+ * @brief set the SSL context read buffer length
+ */
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len)
+{
+ SSL_ASSERT(ctx);
+ SSL_ASSERT(len);
+
+ ctx->read_buffer_len = len;
+}
+
+/**
+ * @brief set the SSL read buffer length
+ */
+void SSL_set_default_read_buffer_len(SSL *ssl, size_t len)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(len);
+
+ SSL_METHOD_CALL(set_bufflen, ssl, len);
+}
+
+/**
+ * @brief set the SSL information callback function
+ */
+void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val))
+{
+ SSL_ASSERT(ssl);
+
+ ssl->info_callback = cb;
+}
+
+/**
+ * @brief add SSL context reference count by '1'
+ */
+int SSL_CTX_up_ref(SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ /**
+ * no support multi-thread SSL here
+ */
+ ctx->references++;
+
+ return 1;
+}
+
+/**
+ * @brief set the SSL security level
+ */
+void SSL_set_security_level(SSL *ssl, int level)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->cert->sec_level = level;
+}
+
+/**
+ * @brief get the SSL security level
+ */
+int SSL_get_security_level(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->cert->sec_level;
+}
+
+/**
+ * @brief get the SSL verifying mode of the SSL context
+ */
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->verify_mode;
+}
+
+/**
+ * @brief set the session timeout time
+ */
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long t)
+{
+ long l;
+
+ SSL_ASSERT(ctx);
+
+ l = ctx->session_timeout;
+ ctx->session_timeout = t;
+
+ return l;
+}
+
+/**
+ * @brief get the session timeout time
+ */
+long SSL_CTX_get_timeout(const SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->session_timeout;
+}
+
+/**
+ * @brief set the SSL if we can read as many as data
+ */
+void SSL_set_read_ahead(SSL *ssl, int yes)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->rlayer.read_ahead = yes;
+}
+
+/**
+ * @brief set the SSL context if we can read as many as data
+ */
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes)
+{
+ SSL_ASSERT(ctx);
+
+ ctx->read_ahead = yes;
+}
+
+/**
+ * @brief get the SSL ahead signal if we can read as many as data
+ */
+int SSL_get_read_ahead(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->rlayer.read_ahead;
+}
+
+/**
+ * @brief get the SSL context ahead signal if we can read as many as data
+ */
+long SSL_CTX_get_read_ahead(SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->read_ahead;
+}
+
+/**
+ * @brief check if the SSL context can read as many as data
+ */
+long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->read_ahead;
+}
+
+/**
+ * @brief set SSL session time
+ */
+long SSL_set_time(SSL *ssl, long t)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->session->time = t;
+
+ return t;
+}
+
+/**
+ * @brief set SSL session timeout time
+ */
+long SSL_set_timeout(SSL *ssl, long t)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->session->timeout = t;
+
+ return t;
+}
+
+/**
+ * @brief get the verifying result of the SSL certification
+ */
+long SSL_get_verify_result(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return SSL_METHOD_CALL(get_verify_result, ssl);
+}
+
+/**
+ * @brief get the SSL verifying depth of the SSL context
+ */
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
+{
+ SSL_ASSERT(ctx);
+
+ return ctx->param.depth;
+}
+
+/**
+ * @brief set the SSL verify depth of the SSL context
+ */
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
+{
+ SSL_ASSERT(ctx);
+
+ ctx->param.depth = depth;
+}
+
+/**
+ * @brief get the SSL verifying depth of the SSL
+ */
+int SSL_get_verify_depth(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->param.depth;
+}
+
+/**
+ * @brief set the SSL verify depth of the SSL
+ */
+void SSL_set_verify_depth(SSL *ssl, int depth)
+{
+ SSL_ASSERT(ssl);
+
+ ssl->param.depth = depth;
+}
+
+/**
+ * @brief set the SSL context verifying of the SSL context
+ */
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *))
+{
+ SSL_ASSERT(ctx);
+
+ ctx->verify_mode = mode;
+ ctx->default_verify_callback = verify_callback;
+}
+
+/**
+ * @brief set the SSL verifying of the SSL context
+ */
+void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *))
+{
+ SSL_ASSERT(ssl);
+
+ ssl->verify_mode = mode;
+ ssl->verify_callback = verify_callback;
+}
diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c
new file mode 100644
index 0000000000..0002360846
--- /dev/null
+++ b/components/openssl/library/ssl_methods.c
@@ -0,0 +1,81 @@
+// 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.
+
+#include "ssl_methods.h"
+#include "ssl_pm.h"
+
+/**
+ * TLS method function collection
+ */
+IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func,
+ ssl_pm_new, ssl_pm_free,
+ ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear,
+ ssl_pm_read, ssl_pm_send, ssl_pm_pending,
+ ssl_pm_set_fd, ssl_pm_get_fd,
+ ssl_pm_set_bufflen,
+ ssl_pm_get_verify_result,
+ ssl_pm_get_state);
+
+/**
+ * TLS or SSL client method collection
+ */
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method);
+
+/**
+ * TLS or SSL server method collection
+ */
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method);
+
+IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method);
+
+/**
+ * TLS or SSL method collection
+ */
+IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method);
+
+IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method);
+
+IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method);
+
+/**
+ * @brief get X509 object method
+ */
+IMPLEMENT_X509_METHOD(X509_method,
+ x509_pm_new, x509_pm_free,
+ x509_pm_load, x509_pm_show_info);
+
+/**
+ * @brief get private key object method
+ */
+IMPLEMENT_PKEY_METHOD(EVP_PKEY_method,
+ pkey_pm_new, pkey_pm_free,
+ pkey_pm_load);
diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c
new file mode 100644
index 0000000000..dbd82dc9c2
--- /dev/null
+++ b/components/openssl/library/ssl_pkey.c
@@ -0,0 +1,220 @@
+// 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.
+
+#include "ssl_pkey.h"
+#include "ssl_methods.h"
+#include "ssl_dbg.h"
+#include "ssl_port.h"
+
+/**
+ * @brief create a private key object according to input private key
+ */
+EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk)
+{
+ int ret;
+ EVP_PKEY *pkey;
+
+ pkey = ssl_mem_zalloc(sizeof(EVP_PKEY));
+ if (!pkey)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ if (ipk) {
+ pkey->method = ipk->method;
+ } else {
+ pkey->method = EVP_PKEY_method();
+ }
+
+ ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk);
+ if (ret)
+ SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n");
+
+ return pkey;
+
+failed2:
+ ssl_mem_free(pkey);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief create a private key object
+ */
+EVP_PKEY* EVP_PKEY_new(void)
+{
+ return __EVP_PKEY_new(NULL);
+}
+
+/**
+ * @brief free a private key object
+ */
+void EVP_PKEY_free(EVP_PKEY *pkey)
+{
+ EVP_PKEY_METHOD_CALL(free, pkey);
+
+ ssl_mem_free(pkey);
+}
+
+/**
+ * @brief load a character key context into system context. If '*a' is pointed to the
+ * private key, then load key into it. Or create a new private key object
+ */
+EVP_PKEY *d2i_PrivateKey(int type,
+ EVP_PKEY **a,
+ const unsigned char **pp,
+ long length)
+{
+ int m = 0;
+ int ret;
+ EVP_PKEY *pkey;
+
+ SSL_ASSERT(pp);
+ SSL_ASSERT(*pp);
+ SSL_ASSERT(length);
+
+ if (a && *a) {
+ pkey = *a;
+ } else {
+ pkey = EVP_PKEY_new();;
+ if (!pkey)
+ SSL_RET(failed1, "EVP_PKEY_new\n");
+ m = 1;
+ }
+
+ ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length);
+ if (ret)
+ SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n");
+
+ if (a)
+ *a = pkey;
+
+ return pkey;
+
+failed2:
+ if (m)
+ EVP_PKEY_free(pkey);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief set the SSL context private key
+ */
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
+{
+ SSL_ASSERT(ctx);
+ SSL_ASSERT(pkey);
+
+ if (ctx->cert->pkey == pkey)
+ return 1;
+
+ if (ctx->cert->pkey)
+ EVP_PKEY_free(ctx->cert->pkey);
+
+ ctx->cert->pkey = pkey;
+
+ return 1;
+}
+
+/**
+ * @brief set the SSL private key
+ */
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(pkey);
+
+ if (ssl->cert->pkey == pkey)
+ return 1;
+
+ if (ssl->cert->pkey)
+ EVP_PKEY_free(ssl->cert->pkey);
+
+ ssl->cert->pkey = pkey;
+
+ return 1;
+}
+
+/**
+ * @brief load private key into the SSL context
+ */
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
+ const unsigned char *d, long len)
+{
+ int ret;
+ EVP_PKEY *pk;
+
+ pk = d2i_PrivateKey(0, NULL, &d, len);
+ if (!pk)
+ SSL_RET(failed1, "d2i_PrivateKey\n");
+
+ ret = SSL_CTX_use_PrivateKey(ctx, pk);
+ if (!ret)
+ SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n");
+
+ return 1;
+
+failed2:
+ EVP_PKEY_free(pk);
+failed1:
+ return 0;
+}
+
+/**
+ * @brief load private key into the SSL
+ */
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
+ const unsigned char *d, long len)
+{
+ int ret;
+ EVP_PKEY *pk;
+
+ pk = d2i_PrivateKey(0, NULL, &d, len);
+ if (!pk)
+ SSL_RET(failed1, "d2i_PrivateKey\n");
+
+ ret = SSL_use_PrivateKey(ssl, pk);
+ if (!ret)
+ SSL_RET(failed2, "SSL_use_PrivateKey\n");
+
+ return 1;
+
+failed2:
+ EVP_PKEY_free(pk);
+failed1:
+ return 0;
+}
+
+/**
+ * @brief load the private key file into SSL context
+ */
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+ return 0;
+}
+
+/**
+ * @brief load the private key file into SSL
+ */
+int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+ return 0;
+}
+
+/**
+ * @brief load the RSA ASN1 private key into SSL context
+ */
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
+{
+ return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len);
+}
diff --git a/components/openssl/library/ssl_stack.c b/components/openssl/library/ssl_stack.c
new file mode 100644
index 0000000000..5dbb69af9d
--- /dev/null
+++ b/components/openssl/library/ssl_stack.c
@@ -0,0 +1,70 @@
+// 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.
+
+#include "ssl_stack.h"
+#include "ssl_dbg.h"
+#include "ssl_port.h"
+
+#ifndef CONFIG_MIN_NODES
+ #define MIN_NODES 4
+#else
+ #define MIN_NODES CONFIG_MIN_NODES
+#endif
+
+/**
+ * @brief create a openssl stack object
+ */
+OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c)
+{
+ OPENSSL_STACK *stack;
+ char **data;
+
+ stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK));
+ if (!stack)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES);
+ if (!data)
+ SSL_RET(failed2, "ssl_mem_zalloc\n");
+
+ stack->data = data;
+ stack->num_alloc = MIN_NODES;
+ stack->c = c;
+
+ return stack;
+
+failed2:
+ ssl_mem_free(stack);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief create a NULL function openssl stack object
+ */
+OPENSSL_STACK *OPENSSL_sk_new_null(void)
+{
+ return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
+}
+
+/**
+ * @brief free openssl stack object
+ */
+void OPENSSL_sk_free(OPENSSL_STACK *stack)
+{
+ SSL_ASSERT(stack);
+
+ ssl_mem_free(stack->data);
+ ssl_mem_free(stack);
+}
diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c
new file mode 100644
index 0000000000..d0426db18c
--- /dev/null
+++ b/components/openssl/library/ssl_x509.c
@@ -0,0 +1,267 @@
+// 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.
+
+#include "ssl_x509.h"
+#include "ssl_methods.h"
+#include "ssl_dbg.h"
+#include "ssl_port.h"
+
+/**
+ * @brief show X509 certification information
+ */
+int __X509_show_info(X509 *x)
+{
+ return X509_METHOD_CALL(show_info, x);
+}
+
+/**
+ * @brief create a X509 certification object according to input X509 certification
+ */
+X509* __X509_new(X509 *ix)
+{
+ int ret;
+ X509 *x;
+
+ x = ssl_mem_zalloc(sizeof(X509));
+ if (!x)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ if (ix)
+ x->method = ix->method;
+ else
+ x->method = X509_method();
+
+ ret = X509_METHOD_CALL(new, x, ix);
+ if (ret)
+ SSL_RET(failed2, "x509_new\n");
+
+ return x;
+
+failed2:
+ ssl_mem_free(x);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief create a X509 certification object
+ */
+X509* X509_new(void)
+{
+ return __X509_new(NULL);
+}
+
+/**
+ * @brief free a X509 certification object
+ */
+void X509_free(X509 *x)
+{
+ X509_METHOD_CALL(free, x);
+
+ ssl_mem_free(x);
+};
+
+/**
+ * @brief load a character certification context into system context. If '*cert' is pointed to the
+ * certification, then load certification into it. Or create a new X509 certification object
+ */
+X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len)
+{
+ int m = 0;
+ int ret;
+ X509 *x;
+
+ SSL_ASSERT(buffer);
+ SSL_ASSERT(len);
+
+ if (cert && *cert) {
+ x = *cert;
+ } else {
+ x = X509_new();
+ if (!x)
+ SSL_RET(failed1, "X509_new\n");
+ m = 1;
+ }
+
+ ret = X509_METHOD_CALL(load, x, buffer, len);
+ if (ret)
+ SSL_RET(failed2, "x509_load\n");
+
+ return x;
+
+failed2:
+ if (m)
+ X509_free(x);
+failed1:
+ return NULL;
+}
+
+/**
+ * @brief set SSL context client CA certification
+ */
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
+{
+ SSL_ASSERT(ctx);
+ SSL_ASSERT(x);
+
+ if (ctx->client_CA == x)
+ return 1;
+
+ X509_free(ctx->client_CA);
+
+ ctx->client_CA = x;
+
+ return 1;
+}
+
+/**
+ * @brief add CA client certification into the SSL
+ */
+int SSL_add_client_CA(SSL *ssl, X509 *x)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(x);
+
+ if (ssl->client_CA == x)
+ return 1;
+
+ X509_free(ssl->client_CA);
+
+ ssl->client_CA = x;
+
+ return 1;
+}
+
+/**
+ * @brief set the SSL context certification
+ */
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
+{
+ SSL_ASSERT(ctx);
+ SSL_ASSERT(x);
+
+ if (ctx->cert->x509 == x)
+ return 1;
+
+ X509_free(ctx->cert->x509);
+
+ ctx->cert->x509 = x;
+
+ return 1;
+}
+
+/**
+ * @brief set the SSL certification
+ */
+int SSL_use_certificate(SSL *ssl, X509 *x)
+{
+ SSL_ASSERT(ssl);
+ SSL_ASSERT(x);
+
+ if (ssl->cert->x509 == x)
+ return 1;
+
+ X509_free(ssl->cert->x509);
+
+ ssl->cert->x509 = x;
+
+ return 1;
+}
+
+/**
+ * @brief get the SSL certification point
+ */
+X509 *SSL_get_certificate(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->cert->x509;
+}
+
+/**
+ * @brief load certification into the SSL context
+ */
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+ const unsigned char *d)
+{
+ int ret;
+ X509 *x;
+
+ x = d2i_X509(NULL, d, len);
+ if (!x)
+ SSL_RET(failed1, "d2i_X509\n");
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+ if (!ret)
+ SSL_RET(failed2, "SSL_CTX_use_certificate\n");
+
+ return 1;
+
+failed2:
+ X509_free(x);
+failed1:
+ return 0;
+}
+
+/**
+ * @brief load certification into the SSL
+ */
+int SSL_use_certificate_ASN1(SSL *ssl, int len,
+ const unsigned char *d)
+{
+ int ret;
+ X509 *x;
+
+ x = d2i_X509(NULL, d, len);
+ if (!x)
+ SSL_RET(failed1, "d2i_X509\n");
+
+ ret = SSL_use_certificate(ssl, x);
+ if (!ret)
+ SSL_RET(failed2, "SSL_use_certificate\n");
+
+ return 1;
+
+failed2:
+ X509_free(x);
+failed1:
+ return 0;
+}
+
+/**
+ * @brief load the certification file into SSL context
+ */
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
+{
+ return 0;
+}
+
+/**
+ * @brief load the certification file into SSL
+ */
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
+{
+ return 0;
+}
+
+/**
+ * @brief get peer certification
+ */
+X509 *SSL_get_peer_certificate(const SSL *ssl)
+{
+ SSL_ASSERT(ssl);
+
+ return ssl->session->peer;
+}
+
diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c
new file mode 100644
index 0000000000..92e72bfdb8
--- /dev/null
+++ b/components/openssl/platform/ssl_pm.c
@@ -0,0 +1,597 @@
+// 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.
+
+#include "ssl_pm.h"
+#include "ssl_port.h"
+#include "ssl_dbg.h"
+
+/* mbedtls include */
+#include "mbedtls/platform.h"
+#include "mbedtls/net.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/certs.h"
+
+#if 0
+ #define DEBUG_LOAD_BUF_STRING(str) SSL_DEBUG(1, "%s\n", str)
+#else
+ #define DEBUG_LOAD_BUF_STRING(str)
+#endif
+
+#define X509_INFO_STRING_LENGTH 1024
+
+struct ssl_pm
+{
+ /* local socket file description */
+ mbedtls_net_context fd;
+ /* remote client socket file description */
+ mbedtls_net_context cl_fd;
+
+ mbedtls_ssl_config conf;
+
+ mbedtls_ctr_drbg_context ctr_drbg;
+
+ mbedtls_ssl_context ssl;
+
+ mbedtls_entropy_context entropy;
+};
+
+struct x509_pm
+{
+ mbedtls_x509_crt *x509_crt;
+
+ mbedtls_x509_crt *ex_crt;
+};
+
+struct pkey_pm
+{
+ mbedtls_pk_context *pkey;
+
+ mbedtls_pk_context *ex_pkey;
+};
+
+
+unsigned int max_content_len;
+
+
+/*********************************************************************************************/
+/************************************ SSL arch interface *************************************/
+
+/**
+ * @brief create SSL low-level object
+ */
+int ssl_pm_new(SSL *ssl)
+{
+ struct ssl_pm *ssl_pm;
+ int ret;
+
+ const unsigned char pers[] = "OpenSSL PM";
+ size_t pers_len = sizeof(pers);
+
+ int endpoint;
+ int version;
+
+ const SSL_METHOD *method = ssl->method;
+
+ ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm));
+ if (!ssl_pm)
+ SSL_ERR(ret, failed1, "ssl_mem_zalloc\n");
+
+ if (ssl->ctx->read_buffer_len < 2048 ||
+ ssl->ctx->read_buffer_len > 8192)
+ return -1;
+
+ max_content_len = ssl->ctx->read_buffer_len;
+
+ mbedtls_net_init(&ssl_pm->fd);
+ mbedtls_net_init(&ssl_pm->cl_fd);
+
+ mbedtls_ssl_config_init(&ssl_pm->conf);
+ mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg);
+ mbedtls_entropy_init(&ssl_pm->entropy);
+ mbedtls_ssl_init(&ssl_pm->ssl);
+
+ ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len);
+ if (ret)
+ SSL_ERR(ret, failed2, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret);
+
+ if (method->endpoint) {
+ endpoint = MBEDTLS_SSL_IS_SERVER;
+ } else {
+ endpoint = MBEDTLS_SSL_IS_CLIENT;
+ }
+ ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+ if (ret)
+ SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret);
+
+ if (TLS_ANY_VERSION != ssl->version) {
+ if (TLS1_2_VERSION == ssl->version)
+ version = MBEDTLS_SSL_MINOR_VERSION_3;
+ else if (TLS1_1_VERSION == ssl->version)
+ version = MBEDTLS_SSL_MINOR_VERSION_2;
+ else if (TLS1_VERSION == ssl->version)
+ version = MBEDTLS_SSL_MINOR_VERSION_1;
+ else
+ version = MBEDTLS_SSL_MINOR_VERSION_0;
+
+ mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version);
+ mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version);
+ }
+
+ mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg);
+
+ mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL);
+
+ ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf);
+ if (ret)
+ SSL_ERR(ret, failed3, "mbedtls_ssl_setup:[-0x%x]\n", -ret);
+
+ mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL);
+
+ ssl->ssl_pm = ssl_pm;
+
+ return 0;
+
+failed3:
+ mbedtls_ssl_config_free(&ssl_pm->conf);
+ mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
+failed2:
+ mbedtls_entropy_free(&ssl_pm->entropy);
+ ssl_mem_free(ssl_pm);
+failed1:
+ return -1;
+}
+
+/**
+ * @brief free SSL low-level object
+ */
+void ssl_pm_free(SSL *ssl)
+{
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
+ mbedtls_entropy_free(&ssl_pm->entropy);
+ mbedtls_ssl_config_free(&ssl_pm->conf);
+ mbedtls_ssl_free(&ssl_pm->ssl);
+
+ ssl_mem_free(ssl_pm);
+ ssl->ssl_pm = NULL;
+}
+
+/**
+ * @brief reload SSL low-level certification object
+ */
+static int ssl_pm_reload_crt(SSL *ssl)
+{
+ int ret;
+ int mode;
+ struct ssl_pm *ssl_pm = ssl->ssl_pm;
+ struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm;
+
+ struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm;
+ struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
+
+ if (ssl->verify_mode == SSL_VERIFY_PEER)
+ mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+ else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+ mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+ else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+ mode = MBEDTLS_SSL_VERIFY_UNSET;
+ else
+ mode = MBEDTLS_SSL_VERIFY_NONE;
+
+ mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode);
+
+ if (ca_pm->x509_crt) {
+ mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL);
+ } else if (ca_pm->ex_crt) {
+ mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL);
+ }
+
+ if (crt_pm->x509_crt && pkey_pm->pkey) {
+ ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey);
+ } else if (crt_pm->ex_crt && pkey_pm->ex_pkey) {
+ ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->ex_crt, pkey_pm->ex_pkey);
+ } else {
+ ret = 0;
+ }
+
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+int ssl_pm_handshake(SSL *ssl)
+{
+ int ret, mbed_ret;
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ mbed_ret = ssl_pm_reload_crt(ssl);
+ if (mbed_ret)
+ return 0;
+
+ ssl_speed_up_enter();
+ while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) {
+ if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ break;
+ }
+ }
+ ssl_speed_up_exit();
+
+ if (!mbed_ret) {
+ struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
+
+ ret = 1;
+
+ x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl);
+ } else {
+ ret = 0;
+ SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret);
+ }
+
+ return ret;
+}
+
+int ssl_pm_shutdown(SSL *ssl)
+{
+ int ret, mbed_ret;
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl);
+ if (!mbed_ret) {
+ struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
+
+ ret = 0;
+
+ x509_pm->ex_crt = NULL;
+ }
+ else
+ ret = -1;
+
+ return ret;
+}
+
+int ssl_pm_clear(SSL *ssl)
+{
+ return ssl_pm_shutdown(ssl);
+}
+
+
+int ssl_pm_read(SSL *ssl, void *buffer, int len)
+{
+ int ret, mbed_ret;
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ mbed_ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len);
+ if (mbed_ret < 0)
+ ret = -1;
+ else if (mbed_ret == 0)
+ ret = 0;
+ else
+ ret = mbed_ret;
+
+ return ret;
+}
+
+int ssl_pm_send(SSL *ssl, const void *buffer, int len)
+{
+ int ret, mbed_ret;
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ mbed_ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len);
+ if (mbed_ret < 0)
+ ret = -1;
+ else if (mbed_ret == 0)
+ ret = 0;
+ else
+ ret = mbed_ret;
+
+ return ret;
+}
+
+int ssl_pm_pending(const SSL *ssl)
+{
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ return mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl);
+}
+
+void ssl_pm_set_fd(SSL *ssl, int fd, int mode)
+{
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ ssl_pm->fd.fd = fd;
+}
+
+int ssl_pm_get_fd(const SSL *ssl, int mode)
+{
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ return ssl_pm->fd.fd;
+}
+
+OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl)
+{
+ OSSL_HANDSHAKE_STATE state;
+
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ switch (ssl_pm->ssl.state)
+ {
+ case MBEDTLS_SSL_CLIENT_HELLO:
+ state = TLS_ST_CW_CLNT_HELLO;
+ break;
+ case MBEDTLS_SSL_SERVER_HELLO:
+ state = TLS_ST_SW_SRVR_HELLO;
+ break;
+ case MBEDTLS_SSL_SERVER_CERTIFICATE:
+ state = TLS_ST_SW_CERT;
+ break;
+ case MBEDTLS_SSL_SERVER_HELLO_DONE:
+ state = TLS_ST_SW_SRVR_DONE;
+ break;
+ case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
+ state = TLS_ST_CW_KEY_EXCH;
+ break;
+ case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
+ state = TLS_ST_CW_CHANGE;
+ break;
+ case MBEDTLS_SSL_CLIENT_FINISHED:
+ state = TLS_ST_CW_FINISHED;
+ break;
+ case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
+ state = TLS_ST_SW_CHANGE;
+ break;
+ case MBEDTLS_SSL_SERVER_FINISHED:
+ state = TLS_ST_SW_FINISHED;
+ break;
+ case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+ state = TLS_ST_CW_CERT;
+ break;
+ case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
+ state = TLS_ST_SR_KEY_EXCH;
+ break;
+ case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
+ state = TLS_ST_SW_SESSION_TICKET;
+ break;
+ case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
+ state = TLS_ST_SW_CERT_REQ;
+ break;
+ case MBEDTLS_SSL_HANDSHAKE_OVER:
+ state = TLS_ST_OK;
+ break;
+ default :
+ state = TLS_ST_BEFORE;
+ break;
+ }
+
+ return state;
+}
+
+int x509_pm_show_info(X509 *x)
+{
+ int ret;
+ char *buf;
+ mbedtls_x509_crt *x509_crt;
+ struct x509_pm *x509_pm = x->x509_pm;
+
+ if (x509_pm->x509_crt)
+ x509_crt = x509_pm->x509_crt;
+ else if (x509_pm->ex_crt)
+ x509_crt = x509_pm->ex_crt;
+ else
+ x509_crt = NULL;
+
+ if (!x509_crt)
+ return -1;
+
+ buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH);
+ if (!buf)
+ SSL_RET(failed1, "");
+
+ ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt);
+ if (ret <= 0)
+ SSL_RET(failed2, "");
+ buf[ret] = 0;
+
+ ssl_mem_free(buf);
+
+ SSL_DEBUG(1, "%s", buf);
+
+ return 0;
+
+failed2:
+ ssl_mem_free(buf);
+failed1:
+ return -1;
+}
+
+int x509_pm_new(X509 *x, X509 *m_x)
+{
+ struct x509_pm *x509_pm;
+
+ x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm));
+ if (!x509_pm)
+ SSL_RET(failed1, "ssl_mem_zalloc\n");
+
+ x->x509_pm = x509_pm;
+
+ if (m_x) {
+ struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm;
+
+ x509_pm->ex_crt = m_x509_pm->x509_crt;
+ }
+
+ return 0;
+
+failed1:
+ return -1;
+}
+
+void x509_pm_free(X509 *x)
+{
+ struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
+
+ if (x509_pm->x509_crt) {
+ mbedtls_x509_crt_free(x509_pm->x509_crt);
+
+ ssl_mem_free(x509_pm->x509_crt);
+ x509_pm->x509_crt = NULL;
+ }
+
+ ssl_mem_free(x->x509_pm);
+ x->x509_pm = NULL;
+}
+
+int x509_pm_load(X509 *x, const unsigned char *buffer, int len)
+{
+ int ret;
+ unsigned char *load_buf;
+ struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
+
+ if (x509_pm->x509_crt)
+ mbedtls_x509_crt_free(x509_pm->x509_crt);
+
+ if (!x509_pm->x509_crt) {
+ x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt));
+ if (!x509_pm->x509_crt)
+ SSL_RET(failed1, "ssl_mem_malloc\n");
+ }
+
+ load_buf = ssl_mem_malloc(len + 1);
+ if (!load_buf)
+ SSL_RET(failed2, "ssl_mem_malloc\n");
+
+ ssl_memcpy(load_buf, buffer, len);
+ load_buf[len] = '\0';
+
+ DEBUG_LOAD_BUF_STRING(load_buf);
+
+ mbedtls_x509_crt_init(x509_pm->x509_crt);
+
+ ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1);
+ ssl_mem_free(load_buf);
+
+ if (ret)
+ SSL_RET(failed2, "mbedtls_x509_crt_parse, return [-0x%x]\n", -ret);
+
+ return 0;
+
+failed2:
+ ssl_mem_free(x509_pm->x509_crt);
+ x509_pm->x509_crt = NULL;
+failed1:
+ return -1;
+}
+
+int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey)
+{
+ struct pkey_pm *pkey_pm;
+
+ pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm));
+ if (!pkey_pm)
+ return -1;
+
+ pk->pkey_pm = pkey_pm;
+
+ if (m_pkey) {
+ struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm;
+
+ pkey_pm->ex_pkey = m_pkey_pm->pkey;
+ }
+
+ return 0;
+}
+
+void pkey_pm_free(EVP_PKEY *pk)
+{
+ struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
+
+ if (pkey_pm->pkey) {
+ mbedtls_pk_free(pkey_pm->pkey);
+
+ ssl_mem_free(pkey_pm->pkey);
+ pkey_pm->pkey = NULL;
+ }
+
+ ssl_mem_free(pk->pkey_pm);
+ pk->pkey_pm = NULL;
+}
+
+int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len)
+{
+ int ret;
+ unsigned char *load_buf;
+ struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
+
+ if (pkey_pm->pkey)
+ mbedtls_pk_free(pkey_pm->pkey);
+
+ if (!pkey_pm->pkey) {
+ pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context));
+ if (!pkey_pm->pkey)
+ SSL_RET(failed1, "ssl_mem_malloc\n");
+ }
+
+ load_buf = ssl_mem_malloc(len + 1);
+ if (!load_buf)
+ SSL_RET(failed2, "ssl_mem_malloc\n");
+
+ ssl_memcpy(load_buf, buffer, len);
+ load_buf[len] = '\0';
+
+ DEBUG_LOAD_BUF_STRING(load_buf);
+
+ mbedtls_pk_init(pkey_pm->pkey);
+
+ ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0);
+ ssl_mem_free(load_buf);
+
+ if (ret)
+ SSL_RET(failed2, "mbedtls_pk_parse_key, return [-0x%x]\n", -ret);
+
+ return 0;
+
+failed2:
+ ssl_mem_free(pkey_pm->pkey);
+ pkey_pm->pkey = NULL;
+failed1:
+ return -1;
+}
+
+
+
+void ssl_pm_set_bufflen(SSL *ssl, int len)
+{
+ max_content_len = len;
+}
+
+long ssl_pm_get_verify_result(const SSL *ssl)
+{
+ long ret;
+ long verify_result;
+ struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
+
+ ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl);
+
+ if (!ret)
+ verify_result = X509_V_OK;
+ else
+ verify_result = X509_V_ERR_UNSPECIFIED;
+
+ return verify_result;
+}
diff --git a/components/openssl/platform/ssl_port.c b/components/openssl/platform/ssl_port.c
new file mode 100644
index 0000000000..ae3b849ca3
--- /dev/null
+++ b/components/openssl/platform/ssl_port.c
@@ -0,0 +1,66 @@
+// 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.
+
+#include "ssl_port.h"
+
+#ifdef ESP32_IDF_PLATFORM
+
+#include "string.h"
+#include "malloc.h"
+
+/*********************************************************************************************/
+/********************************* SSL general interface *************************************/
+
+void* ssl_mem_zalloc(size_t size)
+{
+ void *p = malloc(size);
+
+ if (p)
+ memset(p, 0, size);
+
+ return p;
+}
+
+void *ssl_mem_malloc(size_t size)
+{
+ return malloc(size);
+}
+
+void ssl_mem_free(void *p)
+{
+ free(p);
+}
+
+void* ssl_memcpy(void *to, const void *from, size_t size)
+{
+ return memcpy(to, from, size);
+}
+
+size_t ssl_strlen(const char *src)
+{
+ return strlen(src);
+}
+
+void ssl_speed_up_enter(void)
+{
+
+}
+
+void ssl_speed_up_exit(void)
+{
+
+}
+
+#endif
+
diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c
index ae72568aa5..134e1fe65b 100644
--- a/components/spi_flash/flash_ops.c
+++ b/components/spi_flash/flash_ops.c
@@ -39,7 +39,7 @@ static spi_flash_counters_t s_flash_stats;
#define COUNTER_STOP(counter) \
do{ \
s_flash_stats.counter.count++; \
- s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \\
+ s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \
} while(0)
#define COUNTER_ADD_BYTES(counter, size) \
@@ -126,10 +126,6 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size)
{
- // TODO: replace this check with code which deals with unaligned sources
- if (((ptrdiff_t) src) % 4 != 0) {
- return ESP_ERR_INVALID_ARG;
- }
// Destination alignment is also checked in ROM code, but we can give
// better error code here
// TODO: add handling of unaligned destinations
diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h
index c65eaa5836..840bbc4971 100644
--- a/components/spi_flash/include/esp_spi_flash.h
+++ b/components/spi_flash/include/esp_spi_flash.h
@@ -74,7 +74,7 @@ esp_err_t spi_flash_erase_range(size_t start_addr, size_t size);
/**
* @brief Write data to Flash.
*
- * @note Both des_addr and src_addr have to be 4-byte aligned.
+ * @note Address in flash, dest, has to be 4-byte aligned.
* This is a temporary limitation which will be removed.
*
* @param dest destination address in Flash
@@ -88,7 +88,7 @@ esp_err_t spi_flash_write(size_t dest, const void *src, size_t size);
/**
* @brief Read data from Flash.
*
- * @note Both des_addr and src_addr have to be 4-byte aligned.
+ * @note Both src and dest have to be 4-byte aligned.
* This is a temporary limitation which will be removed.
*
* @param src source address of the data in Flash.
diff --git a/docs/COPYRIGHT.rst b/docs/COPYRIGHT.rst
index da5f5b204a..67b3d9bf1c 100644
--- a/docs/COPYRIGHT.rst
+++ b/docs/COPYRIGHT.rst
@@ -1,3 +1,6 @@
+Copyrights and Licenses
+***********************
+
Software Copyrights
===================
@@ -87,8 +90,7 @@ developments under license policy of following terms.
Copyright (C) 2011, ChaN, all right reserved.
* The TJpgDec module is a free software and there is NO WARRANTY.
-* No restriction on use. You can use, modify and redistribute it for
-personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
+* No restriction on use. You can use, modify and redistribute it for personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
* Redistributions of source code must retain the above copyright notice.
diff --git a/docs/Doxyfile b/docs/Doxyfile
new file mode 100644
index 0000000000..9c53aff1f3
--- /dev/null
+++ b/docs/Doxyfile
@@ -0,0 +1,22 @@
+PROJECT_NAME = "ESP32 Programming Guide"
+
+INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include ../components/log/include ../components/vfs/include
+
+WARN_NO_PARAMDOC = YES
+
+RECURSIVE = NO
+CASE_SENSE_NAMES = NO
+EXTRACT_ALL = NO
+
+GENERATE_XML = YES
+XML_OUTPUT = xml
+
+GENERATE_HTML = NO
+HAVE_DOT = NO
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+
+QUIET = YES
+WARN_LOGFILE = "doxygen-warning-log.txt"
+
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000000..c04268ff1d
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/_static/doc-code-documentation-inline.png b/docs/_static/doc-code-documentation-inline.png
new file mode 100644
index 0000000000..72bf22f156
Binary files /dev/null and b/docs/_static/doc-code-documentation-inline.png differ
diff --git a/docs/_static/doc-code-documentation-rendered.png b/docs/_static/doc-code-documentation-rendered.png
new file mode 100644
index 0000000000..d287d3c2e1
Binary files /dev/null and b/docs/_static/doc-code-documentation-rendered.png differ
diff --git a/docs/_static/doc-code-function.png b/docs/_static/doc-code-function.png
new file mode 100644
index 0000000000..758971ce72
Binary files /dev/null and b/docs/_static/doc-code-function.png differ
diff --git a/docs/_static/doc-code-member.png b/docs/_static/doc-code-member.png
new file mode 100644
index 0000000000..eee897a496
Binary files /dev/null and b/docs/_static/doc-code-member.png differ
diff --git a/docs/_static/doc-code-void-function.png b/docs/_static/doc-code-void-function.png
new file mode 100644
index 0000000000..36eeced6b8
Binary files /dev/null and b/docs/_static/doc-code-void-function.png differ
diff --git a/docs/api/bt.rst b/docs/api/bt.rst
new file mode 100644
index 0000000000..72ab9fbd12
--- /dev/null
+++ b/docs/api/bt.rst
@@ -0,0 +1,31 @@
+Bluetooth API
+=============
+
+Overview
+--------
+
+`Instructions `_
+
+Application Example
+-------------------
+
+`Instructions `_
+
+Reference
+---------
+
+`Instructions `_
+
+Type Definitions
+^^^^^^^^^^^^^^^^
+
+.. doxygenstruct:: vhci_host_callback
+
+Functions
+^^^^^^^^^
+
+.. doxygenfunction:: API_vhci_host_check_send_available
+.. doxygenfunction:: API_vhci_host_register_callback
+.. doxygenfunction:: API_vhci_host_send_packet
+.. doxygenfunction:: bt_controller_init
+
diff --git a/docs/api/esp_wifi.rst b/docs/api/esp_wifi.rst
new file mode 100644
index 0000000000..e4ec59fc82
--- /dev/null
+++ b/docs/api/esp_wifi.rst
@@ -0,0 +1,74 @@
+Wi-Fi API
+=========
+
+Overview
+--------
+
+`Instructions `_
+
+Application Example
+-------------------
+
+`Instructions `_
+
+Reference
+---------
+
+`Instructions `_
+
+Macros
+------
+
+.. doxygendefine:: WIFI_INIT_CONFIG_DEFAULT
+
+
+Typedefs
+--------
+
+.. doxygentypedef:: wifi_promiscuous_cb_t
+.. doxygentypedef:: wifi_rxcb_t
+.. doxygentypedef:: esp_vendor_ie_cb_t
+
+
+Functions
+---------
+
+.. doxygenfunction:: esp_wifi_init
+.. doxygenfunction:: esp_wifi_deinit
+.. doxygenfunction:: esp_wifi_set_mode
+.. doxygenfunction:: esp_wifi_get_mode
+.. doxygenfunction:: esp_wifi_start
+.. doxygenfunction:: esp_wifi_stop
+.. doxygenfunction:: esp_wifi_connect
+.. doxygenfunction:: esp_wifi_disconnect
+.. doxygenfunction:: esp_wifi_clear_fast_connect
+.. doxygenfunction:: esp_wifi_kick_station
+.. doxygenfunction:: esp_wifi_scan_start
+.. doxygenfunction:: esp_wifi_scan_stop
+.. doxygenfunction:: esp_wifi_get_ap_num
+.. doxygenfunction:: esp_wifi_get_ap_list
+.. doxygenfunction:: esp_wifi_set_ps
+.. doxygenfunction:: esp_wifi_get_ps
+.. doxygenfunction:: esp_wifi_set_protocol
+.. doxygenfunction:: esp_wifi_get_protocol
+.. doxygenfunction:: esp_wifi_set_bandwidth
+.. doxygenfunction:: esp_wifi_get_bandwidth
+.. doxygenfunction:: esp_wifi_set_channel
+.. doxygenfunction:: esp_wifi_get_channel
+.. doxygenfunction:: esp_wifi_set_country
+.. doxygenfunction:: esp_wifi_get_country
+.. doxygenfunction:: esp_wifi_set_mac
+.. doxygenfunction:: esp_wifi_get_mac
+.. doxygenfunction:: esp_wifi_set_promiscuous_rx_cb
+.. doxygenfunction:: esp_wifi_set_promiscuous
+.. doxygenfunction:: esp_wifi_get_promiscuous
+.. doxygenfunction:: esp_wifi_set_config
+.. doxygenfunction:: esp_wifi_get_config
+.. doxygenfunction:: esp_wifi_get_station_list
+.. doxygenfunction:: esp_wifi_free_station_list
+.. doxygenfunction:: esp_wifi_set_storage
+.. doxygenfunction:: esp_wifi_reg_rxcb
+.. doxygenfunction:: esp_wifi_set_auto_connect
+.. doxygenfunction:: esp_wifi_get_auto_connect
+.. doxygenfunction:: esp_wifi_set_vendor_ie
+.. doxygenfunction:: esp_wifi_set_vendor_ie_cb
diff --git a/docs/api/gpio.rst b/docs/api/gpio.rst
new file mode 100644
index 0000000000..3c5c122921
--- /dev/null
+++ b/docs/api/gpio.rst
@@ -0,0 +1,90 @@
+GPIO API
+========
+
+Overview
+--------
+
+`Instructions `_
+
+Application Example
+-------------------
+
+`Instructions `_
+
+Reference
+---------
+
+`Instructions `_
+
+Enumerations
+^^^^^^^^^^^^
+
+.. doxygenenum:: gpio_int_type_t
+.. doxygenenum:: gpio_mode_t
+.. doxygenenum:: gpio_pull_mode_t
+
+Functions
+^^^^^^^^^
+
+.. doxygenfunction:: gpio_config
+.. doxygenfunction:: gpio_set_intr_type
+.. doxygenfunction:: gpio_intr_enable
+.. doxygenfunction:: gpio_intr_disable
+.. doxygenfunction:: gpio_set_level
+.. doxygenfunction:: gpio_get_level
+.. doxygenfunction:: gpio_set_direction
+.. doxygenfunction:: gpio_set_pull_mode
+.. doxygenfunction:: gpio_wakeup_enable
+.. doxygenfunction:: gpio_wakeup_disable
+.. doxygenfunction:: gpio_isr_register
+
+*Example code:* Configuration of GPIO as an output
+
+.. code-block:: c
+
+ gpio_config_t io_conf;
+ io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
+ io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
+ io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19
+ io_conf.pull_down_en = 0; //disable pull-down mode
+ io_conf.pull_up_en = 0; //disable pull-up mode
+ gpio_config(&io_conf); //configure GPIO with the given settings
+
+*Example code:* Configuration of GPIO as an input
+
+.. code-block:: c
+
+ gpio_config_t io_conf;
+ io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
+ io_conf.mode = GPIO_MODE_INPUT; //set as input
+ io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5
+ io_conf.pull_down_en = 0; //disable pull-down mode
+ io_conf.pull_up_en = 1; //enable pull-up mode
+ gpio_config(&io_conf); //configure GPIO with the given settings
+
+
+ROM GPIO functions
+^^^^^^^^^^^^^^^^^^
+
+.. doxygenfunction:: gpio_init
+.. doxygenfunction:: gpio_output_set
+.. doxygenfunction:: gpio_output_set_high
+.. doxygenfunction:: gpio_input_get
+.. doxygenfunction:: gpio_input_get_high
+.. doxygenfunction:: gpio_intr_handler_register
+.. doxygenfunction:: gpio_intr_pending
+.. doxygenfunction:: gpio_intr_pending_high
+.. doxygenfunction:: gpio_intr_ack
+.. doxygenfunction:: gpio_intr_ack_high
+.. doxygenfunction:: gpio_pin_wakeup_enable
+.. doxygenfunction:: gpio_pin_wakeup_disable
+.. doxygenfunction:: gpio_matrix_in
+.. doxygenfunction:: gpio_matrix_out
+.. doxygenfunction:: gpio_pad_select_gpio
+.. doxygenfunction:: gpio_pad_set_drv
+.. doxygenfunction:: gpio_pad_pullup
+.. doxygenfunction:: gpio_pad_pulldown
+.. doxygenfunction:: gpio_pad_unhold
+.. doxygenfunction:: gpio_pad_hold
+
+
diff --git a/docs/api/log.rst b/docs/api/log.rst
new file mode 100644
index 0000000000..dc76a30470
--- /dev/null
+++ b/docs/api/log.rst
@@ -0,0 +1,19 @@
+.. include:: ../../components/log/README.rst
+
+API Reference
+-------------
+
+Enumerations
+^^^^^^^^^^^^
+
+.. doxygenenum:: esp_log_level_t
+
+Functions
+^^^^^^^^^
+
+.. doxygenfunction:: esp_log_level_set
+.. doxygenfunction:: esp_log_set_vprintf
+.. doxygenfunction:: esp_log_timestamp
+.. doxygenfunction:: esp_log_write
+
+
diff --git a/docs/api/nvs.rst b/docs/api/nvs.rst
new file mode 100644
index 0000000000..fc2bba5a16
--- /dev/null
+++ b/docs/api/nvs.rst
@@ -0,0 +1,68 @@
+.. include:: ../../components/nvs_flash/README.rst
+
+API Reference
+-------------
+
+Enumerations
+^^^^^^^^^^^^
+
+.. doxygenenum:: nvs_open_mode
+
+Functions
+^^^^^^^^^
+
+.. doxygenfunction:: nvs_flash_init
+.. doxygenfunction:: nvs_flash_init_custom
+
+.. doxygenfunction:: nvs_open
+
+*Note: the following nvs_set_X function are "the same" except the data type accepted*
+
+.. doxygenfunction:: nvs_set_i8
+.. doxygenfunction:: nvs_set_u8
+.. doxygenfunction:: nvs_set_i16
+.. doxygenfunction:: nvs_set_u16
+.. doxygenfunction:: nvs_set_i32
+.. doxygenfunction:: nvs_set_u32
+.. doxygenfunction:: nvs_set_i64
+.. doxygenfunction:: nvs_set_u64
+.. doxygenfunction:: nvs_set_str
+.. doxygenfunction:: nvs_set_blob
+
+*Note: the following nvs_get_X functions are "the same" except the data type returned*
+
+.. doxygenfunction:: nvs_get_i8
+.. doxygenfunction:: nvs_get_u8
+.. doxygenfunction:: nvs_get_i16
+.. doxygenfunction:: nvs_get_u16
+.. doxygenfunction:: nvs_get_i32
+.. doxygenfunction:: nvs_get_u32
+.. doxygenfunction:: nvs_get_i64
+.. doxygenfunction:: nvs_get_u64
+.. doxygenfunction:: nvs_get_str
+.. doxygenfunction:: nvs_get_blob
+
+.. doxygenfunction:: nvs_erase_key
+.. doxygenfunction:: nvs_erase_all
+.. doxygenfunction:: nvs_commit
+.. doxygenfunction:: nvs_close
+
+Error codes
+^^^^^^^^^^^
+
+.. doxygendefine:: ESP_ERR_NVS_BASE
+.. doxygendefine:: ESP_ERR_NVS_NOT_INITIALIZED
+.. doxygendefine:: ESP_ERR_NVS_NOT_FOUND
+.. doxygendefine:: ESP_ERR_NVS_TYPE_MISMATCH
+.. doxygendefine:: ESP_ERR_NVS_READ_ONLY
+.. doxygendefine:: ESP_ERR_NVS_NOT_ENOUGH_SPACE
+.. doxygendefine:: ESP_ERR_NVS_INVALID_NAME
+.. doxygendefine:: ESP_ERR_NVS_INVALID_HANDLE
+.. doxygendefine:: ESP_ERR_NVS_REMOVE_FAILED
+.. doxygendefine:: ESP_ERR_NVS_KEY_TOO_LONG
+.. doxygendefine:: ESP_ERR_NVS_PAGE_FULL
+.. doxygendefine:: ESP_ERR_NVS_INVALID_STATE
+.. doxygendefine:: ESP_ERR_NVS_INVALID_LENGTH
+
+
+
diff --git a/docs/api/template.rst b/docs/api/template.rst
new file mode 100644
index 0000000000..0f2623c47f
--- /dev/null
+++ b/docs/api/template.rst
@@ -0,0 +1,70 @@
+Template API
+=============
+
+Overview
+--------
+
+INSTRUCTIONS: Provide overview where and how this API may be used. For large number of functions, break down description into groups.
+
+Use the folowing heading levels:
+
+* # with overline, for parts
+* \* with overline, for chapters
+* =, for sections
+* -, for subsections
+* ^, for subsubsections
+* ", for paragraphs
+
+
+Application Example
+-------------------
+
+INSTRUCTIONS: Provide one or more pratical examples to demonstrate functionality of this API.
+
+
+Reference
+---------
+
+INSTRUCTIONS: Provide list of API memebers divided into sections. Use coresponding **.. doxygen** directices, so member documentation is auto updated.
+
+* Data Structures **.. doxygenstruct**
+* Macros **.. doxygendefine**
+* Type Definitions **.. doxygentypedef**
+* Enumerations **.. doxygenenum**
+* Functions **.. doxygenfunction**
+* Variables **.. doxygenvariable**
+
+Include code snippotes to ilustrate functionality of particular functions where applicable. Skip section hearder if empty.
+
+
+Data Structures
+^^^^^^^^^^^^^^^
+
+.. Data Structures .. doxygenstruct
+
+Macros
+^^^^^^
+
+.. Macros .. doxygendefine
+
+Type Definitions
+^^^^^^^^^^^^^^^^
+
+.. Type Definitions .. doxygentypedef
+
+Enumerations
+^^^^^^^^^^^^
+
+.. Enumerations .. doxygenenum
+
+Functions
+^^^^^^^^^
+
+.. Functions .. doxygenfunction
+
+Variables
+^^^^^^^^^
+
+.. Variables .. doxygenvariable
+
+
diff --git a/docs/api/vfs.rst b/docs/api/vfs.rst
new file mode 100644
index 0000000000..97ea1a5848
--- /dev/null
+++ b/docs/api/vfs.rst
@@ -0,0 +1,27 @@
+.. include:: ../../components/vfs/README.rst
+
+API Reference
+-------------
+
+Defines
+^^^^^^^
+
+.. doxygendefine:: ESP_VFS_PATH_MAX
+.. doxygendefine:: ESP_VFS_FLAG_DEFAULT
+.. doxygendefine:: ESP_VFS_FLAG_CONTEXT_PTR
+
+
+Structures
+^^^^^^^^^^
+
+.. doxygenstruct:: esp_vfs_t
+
+Functions
+^^^^^^^^^
+
+.. doxygenfunction:: esp_vfs_dev_uart_register
+.. doxygenfunction:: esp_vfs_register
+
+
+
+
diff --git a/docs/build_system.rst b/docs/build_system.rst
index 4df65b1b5c..34db487e0a 100644
--- a/docs/build_system.rst
+++ b/docs/build_system.rst
@@ -1,5 +1,5 @@
Build System
-------------
+************
This document explains the Espressif IoT Development Framework build system and the
concept of "components"
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000000..8a4a275c8a
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,301 @@
+# -*- coding: utf-8 -*-
+#
+# Read the Docs Template documentation build configuration file, created by
+# sphinx-quickstart on Tue Aug 26 14:19:49 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- Run DoxyGen to prepare XML for Sphinx---------------------------------
+# ref. https://github.com/rtfd/readthedocs.org/issues/388
+#
+# added by krzychb, 24-Oct-2016
+#
+
+from subprocess import call, Popen, PIPE
+import shlex
+
+call('doxygen')
+
+# -- Function to get output of a command ----------------------------------
+def run_cmd_get_output(cmd):
+ process = Popen(shlex.split(cmd), stdout=PIPE)
+ (output, err) = process.communicate()
+ exit_code = process.wait()
+ if exit_code != 0:
+ raise RuntimeError('command line program has failed')
+ return output
+
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['breathe']
+
+# Breathe extension variables
+breathe_projects = { "esp32-idf": "xml/" }
+breathe_default_project = "esp32-idf"
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'ESP32 Programming Guide'
+copyright = u'2016, Espressif'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# This is supposed to be "the short X.Y version", but it's the only version
+# visible when you open index.html.
+# Display full version to make things less confusing.
+# If needed, nearest tag is returned by 'git describe --abbrev=0'.
+version = run_cmd_get_output('git describe')
+# The full version, including alpha/beta/rc tags.
+release = run_cmd_get_output('git describe')
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'ReadtheDocsTemplatedoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'ReadtheDocsTemplate.tex', u'Read the Docs Template Documentation',
+ u'Read the Docs', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'readthedocstemplate', u'Read the Docs Template Documentation',
+ [u'Read the Docs'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'ReadtheDocsTemplate', u'Read the Docs Template Documentation',
+ u'Read the Docs', 'ReadtheDocsTemplate', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+# -- Use sphinx_rtd_theme for local builds --------------------------------
+# ref. https://github.com/snide/sphinx_rtd_theme#using-this-theme-locally-then-building-on-read-the-docs
+#
+# added by krzychb, 24-Oct-2016
+#
+# on_rtd is whether we are on readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+if not on_rtd: # only import and set the theme if we're building docs locally
+ import sphinx_rtd_theme
+ html_theme = 'sphinx_rtd_theme'
+ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+
+# otherwise, readthedocs.org uses their theme by default, so no need to specify it
diff --git a/docs/contributing.rst b/docs/contributing.rst
new file mode 100644
index 0000000000..3bdd7dc21a
--- /dev/null
+++ b/docs/contributing.rst
@@ -0,0 +1 @@
+.. include:: ../CONTRIBUTING.rst
\ No newline at end of file
diff --git a/docs/contributor-agreement.rst b/docs/contributor-agreement.rst
index 7c194e7728..de294740c4 100644
--- a/docs/contributor-agreement.rst
+++ b/docs/contributor-agreement.rst
@@ -1,5 +1,5 @@
Contributor Agreement
----------------------
+=====================
Individual Contributor Non-Exclusive License Agreement
------------------------------------------------------
diff --git a/docs/deep-sleep-stub.rst b/docs/deep-sleep-stub.rst
new file mode 100644
index 0000000000..983f8bbf26
--- /dev/null
+++ b/docs/deep-sleep-stub.rst
@@ -0,0 +1,87 @@
+Deep Sleep Wake Stubs
+---------------------
+
+ESP32 supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally.
+
+Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep.
+
+Rules for Wake Stubs
+====================
+
+Wake stub code must be carefully written:
+
+* As the SoC has freshly woken from sleep, most of the peripherals are in reset states. The SPI flash is unmapped.
+
+* The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory (see below.)
+
+* The wake stub code can only access data loaded in RTC memory. All other RAM will be unintiailised and have random contents. The wake stub can use other RAM for temporary storage, but the contents will be overwritten when the SoC goes back to sleep or starts ESP-IDF.
+
+* RTC memory must include any read-only data (.rodata) used by the stub.
+
+* Data in RTC memory is initialised whenever the SoC restarts, except when waking from deep sleep. When waking from deep sleep, the values which were present before going to sleep are kept.
+
+* Wake stub code is a part of the main esp-idf app. During normal running of esp-idf, functions can call the wake stub functions or access RTC memory. It is as if these were regular parts of the app.
+
+Implementing A Stub
+===================
+
+The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()` then this will override the default.
+
+If supplying a custom wake stub, the first thing it does should be to call ``esp_default_wake_deep_sleep()``.
+
+It is not necessary to implement ``esp_wake_deep_sleep()`` in your app in order to use deep sleep. It is only necessary if you want to have special behaviour immediately on wake.
+
+If you want to swap between different deep sleep stubs at runtime, it is also possible to do this by calling the ``esp_set_deep_sleep_wake_stub()`` function. This is not necessary if you only use the default ``esp_wake_deep_sleep()`` function.
+
+All of these functions are declared in the ``esp_deepsleep.h`` header under components/esp32.
+
+Loading Code Into RTC Memory
+============================
+
+Wake stub code must be resident in RTC Fast Memory. This can be done in one of two ways.
+
+The first way is to use the ``RTC_IRAM_ATTR`` attribute to place a function into RTC memory::
+
+ void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
+ esp_default_wake_deep_sleep();
+ // Add additional functionality here
+ }
+
+The second way is to place the function into any source file whose name starts with ``rtc_wake_stub``. Files names ``rtc_wake_stub*`` have their contents automatically put into RTC memory by the linker.
+
+The first way is simpler for very short and simple code, or for source files where you want to mix "normal" and "RTC" code. The second way is simpler when you want to write longer pieces of code for RTC memory.
+
+
+Loading Data Into RTC Memory
+============================
+
+Data used by stub code must be resident in RTC Slow Memory. This memory is also used by the ULP.
+
+Specifying this data can be done in one of two ways:
+
+The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify any data (writeable or read-only, respectivley) which should be loaded into RTC slow memory::
+
+ RTC_DATA_ATTR int wake_count;
+
+ void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
+ esp_default_wake_deep_sleep();
+ static RTC_RODATA_ATTR const char fmt_str[] = "Wake count %d\n";
+ ets_printf(fmt_str, wake_count++);
+ }
+
+Unfortunately, any string constants used in this way must be declared as arrays and marked with RTC_RODATA_ATTR, as shown in the example above.
+
+The second way is to place the data into any source file whose name starts with ``rtc_wake_stub``.
+
+For example, the equivalent example in ``rtc_wake_stub_counter.c``::
+
+ int wake_count;
+
+ void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
+ esp_default_wake_deep_sleep();
+ ets_printf("Wake count %d\n", wake_count++);
+ }
+
+The second way is a better option if you need to use strings, or write other more complex code.
+
+
diff --git a/docs/documenting-code.rst b/docs/documenting-code.rst
new file mode 100644
index 0000000000..51a0dbf7d3
--- /dev/null
+++ b/docs/documenting-code.rst
@@ -0,0 +1,126 @@
+Documenting Code
+================
+
+Introduction
+------------
+
+When documenting code for this repository, please follow `Doxygen style `_. You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``.
+
+Doxygen is phrasing the code, extracting the commands together with subsequent text, and building documentation out of it.
+
+Typical comment block, that contains documentation of a function, looks like below.
+
+.. image:: _static/doc-code-documentation-inline.png
+ :align: center
+ :alt: Sample inline code documentation
+
+Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual `_.
+
+Why we need it?
+---------------
+
+The purpose of this description is to provide quick summary on documentation style used in `espressif/esp-idf `_ repository.
+
+The ultimate goal is to ensure that all the code is consistently documented, so we can use tools like `Sphinx `_ and `Breathe `_ to aid preparation and automatic updates of API documentation when the code changes. The above piece of code renders in Sphinx like below:
+
+.. image:: _static/doc-code-documentation-rendered.png
+ :align: center
+ :alt: Sample inline code after rendering
+
+
+Go for it!
+----------
+
+When writing code for this repository, please follow guidelines below.
+
+ 1. Document all building blocks of code: functions, structs, typedefs, enums, macros, etc. Provide enough information on purpose, functionality and limitations of documented items, as you would like to see them documented when reading the code by others.
+
+ 2. Documentation of function should describe what this function does. If it accepts input parameters and returns some value, all of them should be explained.
+
+ 3. Do not add a data type before parameter or any other characters besides spaces. All spaces and line breaks are compressed into a single space. If you like to break a line, then break it twice.
+
+ .. image:: _static/doc-code-function.png
+ :align: center
+ :alt: Sample function documented inline and after rendering
+
+ 4. If function has void input or does not return any value, then skip ``@param`` or ``@return``
+
+ .. image:: _static/doc-code-void-function.png
+ :align: center
+ :alt: Sample void function documented inline and after rendering
+
+ 5. When documenting members of a ``struct``, ``typedef`` or ``enum``, place specific comment like below after each member.
+
+ .. image:: _static/doc-code-member.png
+ :align: center
+ :alt: Sample of member documentation inline and after rendering
+
+ 6. To provide well formatted lists, break the line after command (like ``@return`` in example below).
+
+ ::
+
+ ...
+ *
+ * @return
+ * - ESP_OK if erase operation was successful
+ * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
+ * - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
+ * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
+ * - other error codes from the underlying storage driver
+ *
+ ...
+
+
+ 7. Overview of functionality of documented header file, or group of files that make a library, should be placed in separate ``README.rst`` file.
+
+Go one extra mile
+-----------------
+
+There are couple of tips how you can make your documentation even better and more useful to the reader.
+
+Add code snippets to illustrate implementation. To do so, enclose the snippet using ``@code{c}`` and ``@endcode`` commands.
+
+::
+
+ ...
+ *
+ * @code{c}
+ * // Example of using nvs_get_i32:
+ * int32_t max_buffer_size = 4096; // default value
+ * esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size);
+ * assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND);
+ * // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still
+ * // have its default value.
+ * @endcode
+ *
+ ...
+
+To highlight some information use command ``@attention`` or ``@note``. Example below also shows how to use a numbered list.
+
+::
+
+ ...
+ *
+ * @attention
+ * 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode
+ * 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect.
+ *
+ ...
+
+
+Use markdown to make your documentation even more readable. With markdown you can add headers, links, tables and more.
+
+::
+
+ ...
+ *
+ * [ESP32 Technical Reference](http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf)
+ *
+ ...
+
+Wrap up
+-------
+
+We love good code that is doing cool things.
+We love it even better, if it is well documented, so we can quickly make it run and also do the cool things.
+
diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst
index 21d83a7f06..fbad93be6c 100644
--- a/docs/eclipse-setup.rst
+++ b/docs/eclipse-setup.rst
@@ -1,3 +1,6 @@
+Build and Flash with Eclipse IDE
+********************************
+
Installing Eclipse IDE
======================
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000000..c973950615
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,78 @@
+ESP32 Programming Guide
+=======================
+
+.. caution::
+
+ Until ESP-IDF release 1.0, this documentation is a draft. It is incomplete and may have mistakes. Please mind your step!
+
+
+Contents:
+
+.. toctree::
+ :caption: Setup Toolchain
+ :maxdepth: 1
+
+ Windows
+ Linux
+ Mac OS
+
+.. Configure - TBA
+
+.. Connect - TBA
+
+.. toctree::
+ :caption: Build and Flash
+ :maxdepth: 1
+
+ Make
+ Eclipse IDE
+
+.. toctree::
+ :caption: What Else?
+ :maxdepth: 1
+
+ partition-tables
+ build_system
+ openocd
+
+.. toctree::
+ :caption: API Reference
+ :maxdepth: 1
+
+ Wi-Fi
+ Bluetooth
+ GPIO
+ Logging
+ Non-volatile storage
+ Virtual filesystem
+ Template
+
+.. toctree::
+ :caption: Technical Reference
+
+ Technical Reference
+
+.. Resources - TBA
+
+.. toctree::
+ :caption: Contribute
+ :maxdepth: 1
+
+ contributing
+ documenting-code
+ contributor-agreement
+
+.. toctree::
+ :caption: Legal
+ :maxdepth: 1
+
+ COPYRIGHT
+
+.. About - TBA
+
+
+Indices
+=======
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/docs/linux-setup.rst b/docs/linux-setup.rst
index 13e1b3a9c0..cf5e78b63d 100644
--- a/docs/linux-setup.rst
+++ b/docs/linux-setup.rst
@@ -1,3 +1,6 @@
+Set up of Toolchain for Linux
+*****************************
+
Step 0: Prerequisites
=====================
diff --git a/docs/macos-setup.rst b/docs/macos-setup.rst
index 8178a17ada..53c6fe54c8 100644
--- a/docs/macos-setup.rst
+++ b/docs/macos-setup.rst
@@ -1,3 +1,6 @@
+Set up of Toolchain for Mac OS
+******************************
+
Step 0: Prerequisites
=====================
diff --git a/docs/make-project.rst b/docs/make-project.rst
new file mode 100644
index 0000000000..e72bb81dd0
--- /dev/null
+++ b/docs/make-project.rst
@@ -0,0 +1,63 @@
+Build and Flash with Make
+=========================
+
+Finding a project
+-----------------
+
+As well as the `esp-idf-template `_ project mentioned in the setup guide, esp-idf comes with some example projects on github in the `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
+------------------------
+
+`make menuconfig`
+
+Compiling your project
+----------------------
+
+`make all`
+
+... will compile app, bootloader and generate a partition table based on the config.
+
+Flashing your project
+---------------------
+
+When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running:
+
+`make flash`
+
+This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
+
+You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
+
+Compiling & Flashing Just the App
+---------------------------------
+
+After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
+
+* `make app` - build just the app.
+* `make app-flash` - flash just the app.
+
+`make app-flash` will automatically rebuild the app if it needs it.
+
+(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
+
+The Partition Table
+-------------------
+
+Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
+
+A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash.
+
+Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
+
+The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
+
+* "Single factory app, no OTA"
+* "Factory app, two OTA definitions"
+
+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.
+
+For more details about :doc:`partition tables ` and how to create custom variations, view the :doc:`documentation `.
+
diff --git a/docs/openocd.rst b/docs/openocd.rst
index 57ee93db4a..2dcb55f0c5 100644
--- a/docs/openocd.rst
+++ b/docs/openocd.rst
@@ -1,11 +1,14 @@
+Debugging
+=========
+
OpenOCD setup for ESP32
-----------------------
-The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS
-OS that comes with ESP-IDF is capable multi-core pre-emptive multithreading, allowing for an intuitive way of writing software.
+The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great variety of program architectures. The FreeRTOS
+OS that comes with ESP-IDF is capable of multi-core pre-emptive multithreading, allowing for an intuitive way of writing software.
The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused
-by two threads, maybe even running simultaneously on two different CPU cures, can take a long time when all you have are printf
+by two threads, maybe even running simultaneously on two different CPU cores, can take a long time when all you have are printf
statements. A better and in many cases quicker way to debug such problems is by using a debugger, connected to the processors over
a debug port.
@@ -84,7 +87,7 @@ Connecting a debugger to OpenOCD
OpenOCD should now be ready to accept gdb connections. If you have compiled the ESP32 toolchain using Crosstool-NG, or
if you have downloaded a precompiled toolchain from the Espressif website, you should already have xtensa-esp32-elf-gdb,
a version of gdb that can be used for this. First, make sure the project you want to debug is compiled and flashed
-into the ESP32s SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the
+into the ESP32's SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the
template app, you would do this like such::
cd esp-idf-template
diff --git a/docs/partition-tables.rst b/docs/partition-tables.rst
index e0a39126b5..88597532d2 100644
--- a/docs/partition-tables.rst
+++ b/docs/partition-tables.rst
@@ -1,5 +1,8 @@
Partition Tables
-----------------
+================
+
+Overview
+--------
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash.
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000000..debed28677
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,6 @@
+# This is a list of python packages used to generate documentation. This file is used with pip:
+# pip install requirements.txt
+#
+sphinx
+sphinx-rtd-theme
+breathe
diff --git a/docs/windows-setup.rst b/docs/windows-setup.rst
index baea1ac40b..a425f5b3a0 100644
--- a/docs/windows-setup.rst
+++ b/docs/windows-setup.rst
@@ -1,5 +1,8 @@
-Step 1: Toolchain for Windows: Quick Steps
-==================================
+Set up of Toolchain for Windows
+*******************************
+
+Step 1: Quick Steps
+===================
Windows doesn't have a built-in "make" environment, so as well as installing the toolchain you will need a GNU-compatible environment. We use the MSYS2_ environment to provide.
You don't need to use this environment all the time (you can use Eclipse_ or some other front-end), but it runs behind the scenes.
diff --git a/examples/06_sntp/Makefile b/examples/06_sntp/Makefile
new file mode 100644
index 0000000000..e6ef17be14
--- /dev/null
+++ b/examples/06_sntp/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 := sntp
+
+include $(IDF_PATH)/make/project.mk
+
diff --git a/examples/06_sntp/README.md b/examples/06_sntp/README.md
new file mode 100644
index 0000000000..c5a153bbb2
--- /dev/null
+++ b/examples/06_sntp/README.md
@@ -0,0 +1,41 @@
+# Example: using LwIP SNTP module and time functions
+
+This example demonstrates the use of LwIP SNTP module to obtain time from Internet servers. See the README.md file in the upper level 'examples' directory for more information about examples.
+
+## Obtaining time using LwIP SNTP module
+
+When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP.
+See `initialize_sntp` function for details.
+
+## Timekeeping
+
+Once time is synchronized, ESP32 will perform timekeeping using built-in timers.
+
+- RTC clock is used to maintain accurate time when chip is in deep sleep mode
+
+- FRC1 timer is used to provide time at microsecond accuracy when ESP32 is running.
+
+Timekeeping using RTC timer is demonstrated in this example by going into deep sleep mode. After wake up, ESP32 will print current time without connecting to WiFi.
+
+To use this functionality, make sure "Timers used for gettimeofday function" option in "ESP32-specific config" menu of menuconfig is set to "RTC and FRC1" or "RTC".
+
+## Working with time
+
+To get current time, [`gettimeofday`](http://man7.org/linux/man-pages/man2/gettimeofday.2.html) function may be used. Additionally the following [standard C library functions](http://en.cppreference.com/w/cpp/header/ctime) can be used to obtain time and manipulate it:
+
+ gettimeofday
+ time
+ asctime
+ clock
+ ctime
+ difftime
+ gmtime
+ localtime
+ mktime
+ strftime
+
+To set time, [`settimeofday`](http://man7.org/linux/man-pages/man2/settimeofday.2.html) POSIX function can be used. It is used internally in LwIP SNTP library to set current time when response from NTP server is received.
+
+## Timezones
+
+To set local timezone, use [`setenv`](http://man7.org/linux/man-pages/man3/setenv.3.html) and [`tzset`](http://man7.org/linux/man-pages/man3/tzset.3.html) POSIX functions. First, call `setenv` to set `TZ` environment variable to the correct value depending on device location. Format of the time string is described in [libc documentation](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html). Next, call `tzset` to update C library runtime data for the new time zone. Once these steps are done, `localtime` function will return correct local time, taking time zone offset and daylight saving time into account.
diff --git a/examples/06_sntp/main/Kconfig.projbuild b/examples/06_sntp/main/Kconfig.projbuild
new file mode 100644
index 0000000000..c5d5523a9f
--- /dev/null
+++ b/examples/06_sntp/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
\ No newline at end of file
diff --git a/examples/06_sntp/main/component.mk b/examples/06_sntp/main/component.mk
new file mode 100644
index 0000000000..24356f23ed
--- /dev/null
+++ b/examples/06_sntp/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
diff --git a/examples/06_sntp/main/sntp_main.c b/examples/06_sntp/main/sntp_main.c
new file mode 100644
index 0000000000..7f516625e3
--- /dev/null
+++ b/examples/06_sntp/main/sntp_main.c
@@ -0,0 +1,163 @@
+/* LwIP SNTP 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
+#include
+#include
+#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 "esp_attr.h"
+#include "esp_deepsleep.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "apps/sntp/sntp.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;
+
+static const char *TAG = "example";
+
+/* Variable holding number of times ESP32 restarted since first boot.
+ * It is placed into RTC memory using RTC_DATA_ATTR and
+ * maintains its value when ESP32 wakes from deep sleep.
+ */
+RTC_DATA_ATTR static int boot_count = 0;
+
+static void obtain_time(void);
+static void initialize_sntp(void);
+static void initialise_wifi(void);
+static esp_err_t event_handler(void *ctx, system_event_t *event);
+
+
+void app_main()
+{
+ ++boot_count;
+ ESP_LOGI(TAG, "Boot count: %d", boot_count);
+
+ time_t now;
+ struct tm timeinfo;
+ time(&now);
+ localtime_r(&now, &timeinfo);
+ // Is time set? If not, tm_year will be (1970 - 1900).
+ if (timeinfo.tm_year < (2016 - 1900)) {
+ ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
+ obtain_time();
+ // update 'now' variable with current time
+ time(&now);
+ }
+ char strftime_buf[64];
+
+ // Set timezone to Eastern Standard Time and print local time
+ setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1);
+ tzset();
+ localtime_r(&now, &timeinfo);
+ strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
+ ESP_LOGI(TAG, "The current date/time in New York is: %s", strftime_buf);
+
+ // Set timezone to China Standard Time
+ setenv("TZ", "CST-8CDT-9,M4.2.0/2,M9.2.0/3", 1);
+ tzset();
+ localtime_r(&now, &timeinfo);
+ strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
+ ESP_LOGI(TAG, "The current date/time in Shanghai is: %s", strftime_buf);
+
+ const int deep_sleep_sec = 10;
+ ESP_LOGI(TAG, "Entering deep sleep for %d seconds", deep_sleep_sec);
+ system_deep_sleep(1000000LL * deep_sleep_sec);
+}
+
+static void obtain_time(void)
+{
+ nvs_flash_init();
+ system_init();
+ initialise_wifi();
+ xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
+ false, true, portMAX_DELAY);
+ initialize_sntp();
+
+ // wait for time to be set
+ time_t now = 0;
+ struct tm timeinfo = { 0 };
+ int retry = 0;
+ const int retry_count = 10;
+ while(timeinfo.tm_year < (2016 - 1900) && ++retry < retry_count) {
+ ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
+ vTaskDelay(2000 / portTICK_PERIOD_MS);
+ time(&now);
+ localtime_r(&now, &timeinfo);
+ }
+}
+
+static void initialize_sntp(void)
+{
+ ESP_LOGI(TAG, "Initializing SNTP");
+ sntp_setoperatingmode(SNTP_OPMODE_POLL);
+ sntp_setservername(0, "pool.ntp.org");
+ sntp_init();
+}
+
+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 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;
+}