Merge branch 'feature/mqtt_mutual_auth' into 'master'
MQTT: Added client cert ssl example per PR from GitHub See merge request idf/esp-idf!3473
This commit is contained in:
commit
e4369aaed4
14 changed files with 368 additions and 14 deletions
|
@ -204,6 +204,9 @@ static void mbedtls_cleanup(esp_tls_t *tls)
|
||||||
mbedtls_x509_crt_free(tls->cacert_ptr);
|
mbedtls_x509_crt_free(tls->cacert_ptr);
|
||||||
}
|
}
|
||||||
tls->cacert_ptr = NULL;
|
tls->cacert_ptr = NULL;
|
||||||
|
mbedtls_x509_crt_free(&tls->cacert);
|
||||||
|
mbedtls_x509_crt_free(&tls->clientcert);
|
||||||
|
mbedtls_pk_free(&tls->clientkey);
|
||||||
mbedtls_entropy_free(&tls->entropy);
|
mbedtls_entropy_free(&tls->entropy);
|
||||||
mbedtls_ssl_config_free(&tls->conf);
|
mbedtls_ssl_config_free(&tls->conf);
|
||||||
mbedtls_ctr_drbg_free(&tls->ctr_drbg);
|
mbedtls_ctr_drbg_free(&tls->ctr_drbg);
|
||||||
|
@ -274,7 +277,34 @@ static int create_ssl_handle(esp_tls_t *tls, const char *hostname, size_t hostle
|
||||||
} else {
|
} else {
|
||||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
|
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfg->clientcert_pem_buf != NULL && cfg->clientkey_pem_buf != NULL) {
|
||||||
|
mbedtls_x509_crt_init(&tls->clientcert);
|
||||||
|
mbedtls_pk_init(&tls->clientkey);
|
||||||
|
|
||||||
|
ret = mbedtls_x509_crt_parse(&tls->clientcert, cfg->clientcert_pem_buf, cfg->clientcert_pem_bytes);
|
||||||
|
if (ret < 0) {
|
||||||
|
ESP_LOGE(TAG, "mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_pk_parse_key(&tls->clientkey, cfg->clientkey_pem_buf, cfg->clientkey_pem_bytes,
|
||||||
|
cfg->clientkey_password, cfg->clientkey_password_len);
|
||||||
|
if (ret < 0) {
|
||||||
|
ESP_LOGE(TAG, "mbedtls_pk_parse_keyfile returned -0x%x\n\n", -ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->clientcert, &tls->clientkey);
|
||||||
|
if (ret < 0) {
|
||||||
|
ESP_LOGE(TAG, "mbedtls_ssl_conf_own_cert returned -0x%x\n\n", -ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
} else if (cfg->clientcert_pem_buf != NULL || cfg->clientkey_pem_buf != NULL) {
|
||||||
|
ESP_LOGE(TAG, "You have to provide both clientcert_pem_buf and clientkey_pem_buf for mutual authentication\n\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg);
|
mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg);
|
||||||
|
|
||||||
#ifdef CONFIG_MBEDTLS_DEBUG
|
#ifdef CONFIG_MBEDTLS_DEBUG
|
||||||
|
@ -502,4 +532,4 @@ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_t
|
||||||
/* Connect to host */
|
/* Connect to host */
|
||||||
return esp_tls_conn_new_async(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len,
|
return esp_tls_conn_new_async(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len,
|
||||||
get_port(url, &u), cfg, tls);
|
get_port(url, &u), cfg, tls);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,22 @@ typedef struct esp_tls_cfg {
|
||||||
|
|
||||||
unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate
|
unsigned int cacert_pem_bytes; /*!< Size of Certificate Authority certificate
|
||||||
pointed to by cacert_pem_buf */
|
pointed to by cacert_pem_buf */
|
||||||
|
|
||||||
|
const unsigned char *clientcert_pem_buf;/*!< Client certificate in a buffer */
|
||||||
|
|
||||||
|
unsigned int clientcert_pem_bytes; /*!< Size of client certificate pointed to by
|
||||||
|
clientcert_pem_buf */
|
||||||
|
|
||||||
|
const unsigned char *clientkey_pem_buf; /*!< Client key in a buffer */
|
||||||
|
|
||||||
|
unsigned int clientkey_pem_bytes; /*!< Size of client key pointed to by
|
||||||
|
clientkey_pem_buf */
|
||||||
|
|
||||||
|
const unsigned char *clientkey_password;/*!< Client key decryption password string */
|
||||||
|
|
||||||
|
unsigned int clientkey_password_len; /*!< String length of the password pointed to by
|
||||||
|
clientkey_password */
|
||||||
|
|
||||||
bool non_block; /*!< Configure non-blocking mode. If set to true the
|
bool non_block; /*!< Configure non-blocking mode. If set to true the
|
||||||
underneath socket will be configured in non
|
underneath socket will be configured in non
|
||||||
blocking mode after tls session is established */
|
blocking mode after tls session is established */
|
||||||
|
@ -89,10 +104,15 @@ typedef struct esp_tls {
|
||||||
|
|
||||||
mbedtls_net_context server_fd; /*!< mbedTLS wrapper type for sockets */
|
mbedtls_net_context server_fd; /*!< mbedTLS wrapper type for sockets */
|
||||||
|
|
||||||
mbedtls_x509_crt cacert; /*!< Container for an X.509 certificate */
|
mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */
|
||||||
|
|
||||||
mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */
|
mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */
|
||||||
|
|
||||||
|
mbedtls_x509_crt clientcert; /*!< Container for the X.509 client certificate */
|
||||||
|
|
||||||
|
mbedtls_pk_context clientkey; /*!< Container for the private key of the client
|
||||||
|
certificate */
|
||||||
|
|
||||||
int sockfd; /*!< Underlying socket file descriptor. */
|
int sockfd; /*!< Underlying socket file descriptor. */
|
||||||
|
|
||||||
ssize_t (*read)(struct esp_tls *tls, char *data, size_t datalen); /*!< Callback function for reading data from TLS/SSL
|
ssize_t (*read)(struct esp_tls *tls, char *data, size_t datalen); /*!< Callback function for reading data from TLS/SSL
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 85ee406d03fd84f5613c6dead1ea653e384b9559
|
Subproject commit a7b1cea5b3e246298607a8c64447765297626f36
|
|
@ -32,7 +32,7 @@ esp_transport_handle_t esp_transport_ssl_init();
|
||||||
/**
|
/**
|
||||||
* @brief Set SSL certificate data (as PEM format).
|
* @brief Set SSL certificate data (as PEM format).
|
||||||
* Note that, this function stores the pointer to data, rather than making a copy.
|
* Note that, this function stores the pointer to data, rather than making a copy.
|
||||||
* So we need to make sure to keep the data lifetime before cleanup the connection
|
* So this data must remain valid until after the connection is cleaned up
|
||||||
*
|
*
|
||||||
* @param t ssl transport
|
* @param t ssl transport
|
||||||
* @param[in] data The pem data
|
* @param[in] data The pem data
|
||||||
|
@ -40,6 +40,27 @@ esp_transport_handle_t esp_transport_ssl_init();
|
||||||
*/
|
*/
|
||||||
void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, int len);
|
void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set SSL client certificate data for mutual authentication (as PEM format).
|
||||||
|
* Note that, this function stores the pointer to data, rather than making a copy.
|
||||||
|
* So this data must remain valid until after the connection is cleaned up
|
||||||
|
*
|
||||||
|
* @param t ssl transport
|
||||||
|
* @param[in] data The pem data
|
||||||
|
* @param[in] len The length
|
||||||
|
*/
|
||||||
|
void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char *data, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set SSL client key data for mutual authentication (as PEM format).
|
||||||
|
* Note that, this function stores the pointer to data, rather than making a copy.
|
||||||
|
* So this data must remain valid until after the connection is cleaned up
|
||||||
|
*
|
||||||
|
* @param t ssl transport
|
||||||
|
* @param[in] data The pem data
|
||||||
|
* @param[in] len The length
|
||||||
|
*/
|
||||||
|
void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char *data, int len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ typedef struct {
|
||||||
esp_tls_t *tls;
|
esp_tls_t *tls;
|
||||||
esp_tls_cfg_t cfg;
|
esp_tls_cfg_t cfg;
|
||||||
bool ssl_initialized;
|
bool ssl_initialized;
|
||||||
bool verify_server;
|
|
||||||
transport_ssl_conn_state_t conn_state;
|
transport_ssl_conn_state_t conn_state;
|
||||||
} transport_ssl_t;
|
} transport_ssl_t;
|
||||||
|
|
||||||
|
@ -49,9 +48,6 @@ static int ssl_connect_async(esp_transport_handle_t t, const char *host, int por
|
||||||
{
|
{
|
||||||
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||||
if (ssl->conn_state == TRANS_SSL_INIT) {
|
if (ssl->conn_state == TRANS_SSL_INIT) {
|
||||||
if (ssl->cfg.cacert_pem_buf) {
|
|
||||||
ssl->verify_server = true;
|
|
||||||
}
|
|
||||||
ssl->cfg.timeout_ms = timeout_ms;
|
ssl->cfg.timeout_ms = timeout_ms;
|
||||||
ssl->cfg.non_block = true;
|
ssl->cfg.non_block = true;
|
||||||
ssl->ssl_initialized = true;
|
ssl->ssl_initialized = true;
|
||||||
|
@ -70,9 +66,7 @@ static int ssl_connect_async(esp_transport_handle_t t, const char *host, int por
|
||||||
static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
||||||
{
|
{
|
||||||
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||||
if (ssl->cfg.cacert_pem_buf) {
|
|
||||||
ssl->verify_server = true;
|
|
||||||
}
|
|
||||||
ssl->cfg.timeout_ms = timeout_ms;
|
ssl->cfg.timeout_ms = timeout_ms;
|
||||||
ssl->ssl_initialized = true;
|
ssl->ssl_initialized = true;
|
||||||
ssl->tls = esp_tls_conn_new(host, strlen(host), port, &ssl->cfg);
|
ssl->tls = esp_tls_conn_new(host, strlen(host), port, &ssl->cfg);
|
||||||
|
@ -146,7 +140,6 @@ static int ssl_close(esp_transport_handle_t t)
|
||||||
if (ssl->ssl_initialized) {
|
if (ssl->ssl_initialized) {
|
||||||
esp_tls_conn_delete(ssl->tls);
|
esp_tls_conn_delete(ssl->tls);
|
||||||
ssl->ssl_initialized = false;
|
ssl->ssl_initialized = false;
|
||||||
ssl->verify_server = false;
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +161,24 @@ void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char *data, int len)
|
||||||
|
{
|
||||||
|
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||||
|
if (t && ssl) {
|
||||||
|
ssl->cfg.clientcert_pem_buf = (void *)data;
|
||||||
|
ssl->cfg.clientcert_pem_bytes = len + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char *data, int len)
|
||||||
|
{
|
||||||
|
transport_ssl_t *ssl = esp_transport_get_context_data(t);
|
||||||
|
if (t && ssl) {
|
||||||
|
ssl->cfg.clientkey_pem_buf = (void *)data;
|
||||||
|
ssl->cfg.clientkey_pem_bytes = len + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_transport_handle_t esp_transport_ssl_init()
|
esp_transport_handle_t esp_transport_ssl_init()
|
||||||
{
|
{
|
||||||
esp_transport_handle_t t = esp_transport_init();
|
esp_transport_handle_t t = esp_transport_init();
|
||||||
|
|
10
examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt
Normal file
10
examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# The following four lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
project(mqtt_ssl_mutual_auth)
|
||||||
|
|
||||||
|
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "main/client.crt" TEXT)
|
||||||
|
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "main/client.key" TEXT)
|
7
examples/protocols/mqtt/ssl_mutual_auth/Makefile
Normal file
7
examples/protocols/mqtt/ssl_mutual_auth/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||||
|
# project subdirectory.
|
||||||
|
#
|
||||||
|
PROJECT_NAME := mqtt_ssl_mutual_auth
|
||||||
|
|
||||||
|
include $(IDF_PATH)/make/project.mk
|
81
examples/protocols/mqtt/ssl_mutual_auth/README.md
Normal file
81
examples/protocols/mqtt/ssl_mutual_auth/README.md
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# ESP-MQTT SSL Sample application (mutual authentication)
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
This example connects to the broker test.mosquitto.org using ssl transport with client certificate and as a demonstration subscribes/unsubscribes and send a message on certain topic.
|
||||||
|
|
||||||
|
It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker.
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
### Hardware Required
|
||||||
|
|
||||||
|
This example can be executed on any ESP32 board, the only required interface is WiFi and connection to internet.
|
||||||
|
|
||||||
|
### Configure the project
|
||||||
|
|
||||||
|
```
|
||||||
|
make menuconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set serial port under Serial Flasher Options.
|
||||||
|
|
||||||
|
* Set ssid and password for the board to connect to AP.
|
||||||
|
|
||||||
|
* Generate your client keys and certificate
|
||||||
|
|
||||||
|
Navigate to the main directory
|
||||||
|
|
||||||
|
```
|
||||||
|
cd main
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate a client key and a CSR. When you are generating the CSR, do not use the default values. At a minimum, the CSR must include the Country, Organisation and Common Name fields.
|
||||||
|
|
||||||
|
```
|
||||||
|
openssl genrsa -out client.key
|
||||||
|
openssl req -out client.csr -key client.key -new
|
||||||
|
```
|
||||||
|
|
||||||
|
Paste the generated CSR in the [Mosquitto test certificate signer](https://test.mosquitto.org/ssl/index.php), click Submit and copy the downloaded `client.crt` in the `main` directory.
|
||||||
|
|
||||||
|
Please note, that the supplied files `client.crt` and `client.key` in the `main` directory are only placeholders for your client certificate and key (i.e. the example "as is" would compile but would not connect to the broker)
|
||||||
|
|
||||||
|
### Build and Flash
|
||||||
|
|
||||||
|
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||||
|
|
||||||
|
```
|
||||||
|
make -j4 flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
I (3714) event: sta ip: 192.168.0.139, mask: 255.255.255.0, gw: 192.168.0.2
|
||||||
|
I (3714) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
|
||||||
|
I (3964) MQTT_CLIENT: Sending MQTT CONNECT message, type: 1, id: 0000
|
||||||
|
I (4164) MQTTS_EXAMPLE: MQTT_EVENT_CONNECTED
|
||||||
|
I (4174) MQTTS_EXAMPLE: sent publish successful, msg_id=41464
|
||||||
|
I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=17886
|
||||||
|
I (4174) MQTTS_EXAMPLE: sent subscribe successful, msg_id=42970
|
||||||
|
I (4184) MQTTS_EXAMPLE: sent unsubscribe successful, msg_id=50241
|
||||||
|
I (4314) MQTTS_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=41464
|
||||||
|
I (4484) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=17886
|
||||||
|
I (4484) MQTTS_EXAMPLE: sent publish successful, msg_id=0
|
||||||
|
I (4684) MQTTS_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=42970
|
||||||
|
I (4684) MQTTS_EXAMPLE: sent publish successful, msg_id=0
|
||||||
|
I (4884) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
|
||||||
|
I (4884) MQTTS_EXAMPLE: MQTT_EVENT_DATA
|
||||||
|
TOPIC=/topic/qos0
|
||||||
|
DATA=data
|
||||||
|
I (5194) MQTT_CLIENT: deliver_publish, message_length_read=19, message_length=19
|
||||||
|
I (5194) MQTTS_EXAMPLE: MQTT_EVENT_DATA
|
||||||
|
TOPIC=/topic/qos0
|
||||||
|
DATA=data
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
set(COMPONENT_SRCS "app_main.c")
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||||
|
|
||||||
|
register_component()
|
|
@ -0,0 +1,15 @@
|
||||||
|
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 "mypassword"
|
||||||
|
help
|
||||||
|
WiFi password (WPA or WPA2) for the example to use.
|
||||||
|
|
||||||
|
endmenu
|
152
examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c
Normal file
152
examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "esp_event_loop.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
|
#include "lwip/netdb.h"
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "mqtt_client.h"
|
||||||
|
|
||||||
|
static const char *TAG = "MQTTS_EXAMPLE";
|
||||||
|
|
||||||
|
static EventGroupHandle_t wifi_event_group;
|
||||||
|
const static int CONNECTED_BIT = BIT0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static esp_err_t wifi_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:
|
||||||
|
esp_wifi_connect();
|
||||||
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wifi_init(void)
|
||||||
|
{
|
||||||
|
tcpip_adapter_init();
|
||||||
|
wifi_event_group = xEventGroupCreate();
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_init(wifi_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 = CONFIG_WIFI_SSID,
|
||||||
|
.password = CONFIG_WIFI_PASSWORD,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
|
||||||
|
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
ESP_LOGI(TAG, "Waiting for wifi");
|
||||||
|
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start");
|
||||||
|
extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end");
|
||||||
|
extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start");
|
||||||
|
extern const uint8_t client_key_pem_end[] asm("_binary_client_key_end");
|
||||||
|
|
||||||
|
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
|
||||||
|
{
|
||||||
|
esp_mqtt_client_handle_t client = event->client;
|
||||||
|
int msg_id;
|
||||||
|
// your_context_t *context = event->context;
|
||||||
|
switch (event->event_id) {
|
||||||
|
case MQTT_EVENT_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||||
|
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTT_EVENT_SUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||||
|
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_UNSUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_PUBLISHED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DATA:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||||
|
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||||
|
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_ERROR:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqtt_app_start(void)
|
||||||
|
{
|
||||||
|
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||||
|
.uri = "mqtts://test.mosquitto.org:8884",
|
||||||
|
.event_handle = mqtt_event_handler,
|
||||||
|
.client_cert_pem = (const char *)client_cert_pem_start,
|
||||||
|
.client_key_pem = (const char *)client_key_pem_start,
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
|
||||||
|
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
|
esp_mqtt_client_start(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main()
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "[APP] Startup..");
|
||||||
|
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
|
||||||
|
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||||
|
|
||||||
|
esp_log_level_set("*", ESP_LOG_INFO);
|
||||||
|
esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
|
||||||
|
esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);
|
||||||
|
esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);
|
||||||
|
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
|
||||||
|
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
|
||||||
|
|
||||||
|
nvs_flash_init();
|
||||||
|
wifi_init();
|
||||||
|
mqtt_app_start();
|
||||||
|
|
||||||
|
}
|
1
examples/protocols/mqtt/ssl_mutual_auth/main/client.crt
Normal file
1
examples/protocols/mqtt/ssl_mutual_auth/main/client.crt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Please paste your client certificate here (follow instructions in README.md)
|
1
examples/protocols/mqtt/ssl_mutual_auth/main/client.key
Normal file
1
examples/protocols/mqtt/ssl_mutual_auth/main/client.key
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Please paste here your client key (follow instructions in README.md)
|
|
@ -0,0 +1 @@
|
||||||
|
COMPONENT_EMBED_TXTFILES := client.crt client.key
|
Loading…
Reference in a new issue