chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# The following 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.22)
|
||||
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(advanced_https_ota)
|
||||
@@ -0,0 +1,10 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# Advanced HTTPS OTA example
|
||||
|
||||
This example is based on `esp_https_ota` component's APIs.
|
||||
|
||||
## Configuration
|
||||
|
||||
Refer README.md in the parent directory for setup details
|
||||
@@ -0,0 +1,8 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
emul_efuse,data,efuse, , 0x2000,
|
||||
ota_0, app, ota_0, , 1500K,
|
||||
ota_1, app, ota_1, , 1500K,
|
||||
|
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
idf_component_register(SRCS "advanced_https_ota_example.c" "ble_helper/bluedroid_gatts.c" "ble_helper/nimble_gatts.c"
|
||||
"ble_helper/ble_api.c"
|
||||
INCLUDE_DIRS "." "./ble_helper/include/"
|
||||
PRIV_REQUIRES esp_http_client app_update esp_https_ota
|
||||
nvs_flash esp_netif esp_wifi efuse bt
|
||||
protocomm mbedtls
|
||||
# Embed the server root certificate into the final binary
|
||||
EMBED_TXTFILES ${project_dir}/server_certs/ca_cert.pem)
|
||||
@@ -0,0 +1,73 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_FIRMWARE_UPGRADE_URL
|
||||
string "Firmware Upgrade URL"
|
||||
default "https://192.168.2.106:8070/hello_world.bin"
|
||||
help
|
||||
URL of server which hosts the firmware image.
|
||||
|
||||
config EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||
bool
|
||||
default y if EXAMPLE_FIRMWARE_UPGRADE_URL = "FROM_STDIN"
|
||||
|
||||
config EXAMPLE_SKIP_COMMON_NAME_CHECK
|
||||
bool "Skip server certificate CN fieldcheck"
|
||||
default n
|
||||
help
|
||||
This allows you to skip the validation of OTA server certificate CN field.
|
||||
|
||||
config EXAMPLE_SKIP_VERSION_CHECK
|
||||
bool "Skip firmware version check"
|
||||
default n
|
||||
help
|
||||
This allows you to skip the firmware version check.
|
||||
|
||||
config EXAMPLE_OTA_RECV_TIMEOUT
|
||||
int "OTA Receive Timeout"
|
||||
default 5000
|
||||
help
|
||||
Maximum time for reception
|
||||
|
||||
config EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD
|
||||
bool "Enable partial HTTP download"
|
||||
default n
|
||||
select ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD
|
||||
select ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
help
|
||||
This enables use of Range header in esp_https_ota component.
|
||||
The firmware image will be downloaded over multiple HTTP requests,
|
||||
with session resumption enabled between them.
|
||||
|
||||
config EXAMPLE_HTTP_REQUEST_SIZE
|
||||
int "HTTP request size"
|
||||
default MBEDTLS_SSL_IN_CONTENT_LEN
|
||||
depends on EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD
|
||||
help
|
||||
This options specifies HTTP request size. Number of bytes specified
|
||||
in this option will be downloaded in single HTTP request.
|
||||
|
||||
config EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
bool "Enable OTA resumption"
|
||||
default n
|
||||
help
|
||||
This enables the OTA resumption feature.
|
||||
This option allows one to configure the OTA process to resume downloading the OTA image
|
||||
from where it left off in case of an error or reboot.
|
||||
|
||||
config EXAMPLE_OTA_BUF_SIZE
|
||||
int "OTA buffer size"
|
||||
default 1024
|
||||
range 1024 65536
|
||||
help
|
||||
Buffer size for OTA data transfers in bytes.
|
||||
|
||||
config EXAMPLE_USE_CERT_BUNDLE
|
||||
bool "Enable certificate bundle"
|
||||
default y
|
||||
depends on MBEDTLS_CERTIFICATE_BUNDLE
|
||||
help
|
||||
Enable trusted root certificate bundle. This approach allows to have
|
||||
OTA updates functional with any public server without requirement
|
||||
to explicitly add its server certificate.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,422 @@
|
||||
/* Advanced HTTPS OTA 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 <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_https_ota.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "protocol_examples_common.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
|
||||
#include "esp_crt_bundle.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
#include "esp_efuse.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "ble_api.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "advanced_https_ota_example";
|
||||
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
|
||||
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");
|
||||
|
||||
#define OTA_URL_SIZE 256
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
|
||||
#define NVS_NAMESPACE_OTA_RESUMPTION "ota_resumption"
|
||||
#define NVS_KEY_OTA_WR_LENGTH "nvs_ota_wr_len"
|
||||
#define NVS_KEY_SAVED_URL "nvs_ota_url"
|
||||
|
||||
static esp_err_t example_ota_res_get_ota_written_len_from_nvs(const nvs_handle_t nvs_ota_resumption_handle, const char *client_ota_url, uint32_t *nvs_ota_wr_len)
|
||||
{
|
||||
esp_err_t err;
|
||||
char saved_url[OTA_URL_SIZE] = {0};
|
||||
size_t url_len = sizeof(saved_url);
|
||||
|
||||
*nvs_ota_wr_len = 0;
|
||||
|
||||
// Retrieve the saved URL from NVS
|
||||
err = nvs_get_str(nvs_ota_resumption_handle, NVS_KEY_SAVED_URL, saved_url, &url_len);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
ESP_LOGD(TAG, "Saved URL is not initialized yet!");
|
||||
return err;
|
||||
} else if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error reading saved URL (%s)", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Compare the current URL with the saved URL
|
||||
if (strcmp(client_ota_url, saved_url) != 0) {
|
||||
ESP_LOGD(TAG, "URLs do not match. Restarting OTA from beginning.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// Fetch the saved write length only if URLs match
|
||||
uint16_t saved_wr_len_kb = 0;
|
||||
err = nvs_get_u16(nvs_ota_resumption_handle, NVS_KEY_OTA_WR_LENGTH, &saved_wr_len_kb);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
ESP_LOGD(TAG, "The write length is not initialized yet!");
|
||||
*nvs_ota_wr_len = 0;
|
||||
return err;
|
||||
} else if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error reading OTA write length (%s)", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Convert the saved value back to bytes
|
||||
*nvs_ota_wr_len = saved_wr_len_kb * 1024;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t example_ota_res_save_ota_cfg_to_nvs(const nvs_handle_t nvs_ota_resumption_handle, int nvs_ota_wr_len, const char *client_ota_url)
|
||||
{
|
||||
// Convert the write length to kilobytes to optimize NVS space utilization
|
||||
uint16_t wr_len_kb = nvs_ota_wr_len / 1024;
|
||||
|
||||
// Save the current OTA write length to NVS
|
||||
ESP_RETURN_ON_ERROR(nvs_set_u16(nvs_ota_resumption_handle, NVS_KEY_OTA_WR_LENGTH, wr_len_kb), TAG, "Failed to set OTA write length");
|
||||
|
||||
// Save the URL only if the OTA write length is non-zero and the URL is not already saved
|
||||
if (nvs_ota_wr_len) {
|
||||
char saved_url[OTA_URL_SIZE] = {0};
|
||||
size_t url_len = sizeof(saved_url);
|
||||
|
||||
esp_err_t err = nvs_get_str(nvs_ota_resumption_handle, NVS_KEY_SAVED_URL, saved_url, &url_len);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND || strcmp(saved_url, client_ota_url) != 0) {
|
||||
// URL not saved or changed; save it now
|
||||
ESP_RETURN_ON_ERROR(nvs_set_str(nvs_ota_resumption_handle, NVS_KEY_SAVED_URL, client_ota_url), TAG, "Failed to set URL in NVS");
|
||||
} else if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error reading OTA URL");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_RETURN_ON_ERROR(nvs_commit(nvs_ota_resumption_handle), TAG, "Failed to commit NVS");
|
||||
ESP_LOGD(TAG, "Saving state in NVS. Total image written so far : %d KB", wr_len_kb);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t example_ota_res_cleanup_ota_cfg_from_nvs(nvs_handle_t handle) {
|
||||
esp_err_t ret;
|
||||
|
||||
// Erase all keys in the NVS handle and commit changes
|
||||
ESP_GOTO_ON_ERROR(nvs_erase_all(handle), err, TAG, "Error in erasing NVS");
|
||||
ESP_GOTO_ON_ERROR(nvs_commit(handle), err, TAG, "Error in committing NVS");
|
||||
ret = ESP_OK;
|
||||
err:
|
||||
nvs_close(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Event handler for catching system events */
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
if (event_base == ESP_HTTPS_OTA_EVENT) {
|
||||
switch (event_id) {
|
||||
case ESP_HTTPS_OTA_START:
|
||||
ESP_LOGI(TAG, "OTA started");
|
||||
break;
|
||||
case ESP_HTTPS_OTA_CONNECTED:
|
||||
ESP_LOGI(TAG, "Connected to server");
|
||||
break;
|
||||
case ESP_HTTPS_OTA_GET_IMG_DESC:
|
||||
ESP_LOGI(TAG, "Reading Image Description");
|
||||
break;
|
||||
case ESP_HTTPS_OTA_VERIFY_CHIP_ID:
|
||||
ESP_LOGI(TAG, "Verifying chip id of new image: %d", *(esp_chip_id_t *)event_data);
|
||||
break;
|
||||
case ESP_HTTPS_OTA_VERIFY_CHIP_REVISION:
|
||||
ESP_LOGI(TAG, "Verifying chip revision of new image: %d", *(esp_chip_id_t *)event_data);
|
||||
break;
|
||||
case ESP_HTTPS_OTA_DECRYPT_CB:
|
||||
ESP_LOGI(TAG, "Callback to decrypt function");
|
||||
break;
|
||||
case ESP_HTTPS_OTA_WRITE_FLASH:
|
||||
ESP_LOGD(TAG, "Writing to flash: %d written", *(int *)event_data);
|
||||
break;
|
||||
case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION:
|
||||
ESP_LOGI(TAG, "Boot partition updated. Next Partition: %d", *(esp_partition_subtype_t *)event_data);
|
||||
break;
|
||||
case ESP_HTTPS_OTA_FINISH:
|
||||
ESP_LOGI(TAG, "OTA finish");
|
||||
break;
|
||||
case ESP_HTTPS_OTA_ABORT:
|
||||
ESP_LOGI(TAG, "OTA abort");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
|
||||
{
|
||||
if (new_app_info == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_app_desc_t running_app_info;
|
||||
if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK
|
||||
if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) {
|
||||
ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
/**
|
||||
* Secure version check from firmware image header prevents subsequent download and flash write of
|
||||
* entire firmware image. However this is optional because it is also taken care in API
|
||||
* esp_https_ota_finish at the end of OTA update procedure.
|
||||
*/
|
||||
const uint32_t hw_sec_version = esp_efuse_read_secure_version();
|
||||
if (new_app_info->secure_version < hw_sec_version) {
|
||||
ESP_LOGW(TAG, "New firmware security version is less than eFuse programmed, %"PRIu32" < %"PRIu32, new_app_info->secure_version, hw_sec_version);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t _http_client_init_cb(esp_http_client_handle_t http_client)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
/* Uncomment to add custom headers to HTTP request */
|
||||
// err = esp_http_client_set_header(http_client, "Custom-Header", "Value");
|
||||
return err;
|
||||
}
|
||||
|
||||
void advanced_ota_example_task(void *pvParameter)
|
||||
{
|
||||
ESP_LOGI(TAG, "Starting Advanced OTA example");
|
||||
|
||||
esp_err_t err;
|
||||
esp_err_t ota_finish_err = ESP_OK;
|
||||
esp_http_client_config_t config = {
|
||||
.url = CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL,
|
||||
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
|
||||
.crt_bundle_attach = esp_crt_bundle_attach,
|
||||
#else
|
||||
.cert_pem = (char *)server_cert_pem_start,
|
||||
#endif
|
||||
.timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,
|
||||
.keep_alive_enable = true,
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD
|
||||
.save_client_session = true,
|
||||
#endif
|
||||
.buffer_size = CONFIG_EXAMPLE_OTA_BUF_SIZE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
|
||||
char url_buf[OTA_URL_SIZE];
|
||||
if (strcmp(config.url, "FROM_STDIN") == 0) {
|
||||
example_configure_stdin_stdout();
|
||||
fgets(url_buf, OTA_URL_SIZE, stdin);
|
||||
int len = strlen(url_buf);
|
||||
url_buf[len - 1] = '\0';
|
||||
config.url = url_buf;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK
|
||||
config.skip_cert_common_name_check = true;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
nvs_handle_t nvs_ota_resumption_handle;
|
||||
err = nvs_open(NVS_NAMESPACE_OTA_RESUMPTION, NVS_READWRITE, &nvs_ota_resumption_handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error (%s) opening NVS handle!", esp_err_to_name(err));
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
uint32_t ota_wr_len = 0; // Variable to hold the written length
|
||||
err = example_ota_res_get_ota_written_len_from_nvs(nvs_ota_resumption_handle, config.url, &ota_wr_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGD(TAG, "Starting OTA from beginning");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "OTA write length fetched successfully");
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_https_ota_config_t ota_config = {
|
||||
.http_config = &config,
|
||||
.http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD
|
||||
.partial_http_download = true,
|
||||
.max_http_request_size = CONFIG_EXAMPLE_HTTP_REQUEST_SIZE,
|
||||
#endif
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
.ota_resumption = true,
|
||||
.ota_image_bytes_written = ota_wr_len,
|
||||
#endif
|
||||
};
|
||||
|
||||
esp_https_ota_handle_t https_ota_handle = NULL;
|
||||
err = esp_https_ota_begin(&ota_config, &https_ota_handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
esp_app_desc_t app_desc = {};
|
||||
err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_https_ota_get_img_desc failed");
|
||||
goto ota_end;
|
||||
}
|
||||
err = validate_image_header(&app_desc);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "image header verification failed");
|
||||
goto ota_end;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
err = esp_https_ota_perform(https_ota_handle);
|
||||
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
|
||||
break;
|
||||
}
|
||||
// esp_https_ota_perform returns after every read operation which gives user the ability to
|
||||
// monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image
|
||||
// data read so far.
|
||||
const size_t len = esp_https_ota_get_image_len_read(https_ota_handle);
|
||||
ESP_LOGD(TAG, "Image bytes read: %d", len);
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
err = example_ota_res_save_ota_cfg_to_nvs(nvs_ota_resumption_handle, len, config.url);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to save OTA config to NVS (%s).", esp_err_to_name(err));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) {
|
||||
// the OTA image was not completely received and user can customise the response to this situation.
|
||||
ESP_LOGE(TAG, "Complete data was not received.");
|
||||
} else {
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION
|
||||
err = example_ota_res_cleanup_ota_cfg_from_nvs(nvs_ota_resumption_handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to clean up OTA config from NVS (%s).", esp_err_to_name(err));
|
||||
}
|
||||
#endif
|
||||
ota_finish_err = esp_https_ota_finish(https_ota_handle);
|
||||
if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
|
||||
ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
} else {
|
||||
if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) {
|
||||
ESP_LOGE(TAG, "Image validation failed, image is corrupted");
|
||||
}
|
||||
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ota_end:
|
||||
esp_https_ota_abort(https_ota_handle);
|
||||
ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "OTA example app_main start");
|
||||
// Initialize NVS.
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
// 1.OTA app partition table has a smaller NVS partition size than the non-OTA
|
||||
// partition table. This size mismatch may cause NVS initialization to fail.
|
||||
// 2.NVS partition contains data in new format and cannot be recognized by this version of code.
|
||||
// If this happens, we erase NVS partition and initialize NVS again.
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( err );
|
||||
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE)
|
||||
/**
|
||||
* We are treating successful WiFi connection as a checkpoint to cancel rollback
|
||||
* process and mark newly updated firmware image as active. For production cases,
|
||||
* please tune the checkpoint behavior per end application requirement.
|
||||
*/
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_ota_img_states_t ota_state;
|
||||
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
|
||||
ESP_LOGI(TAG, "App is valid, rollback cancelled successfully");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to cancel rollback");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
#if !CONFIG_BT_ENABLED
|
||||
/* Ensure to disable any WiFi power save mode, this allows best throughput
|
||||
* and hence timings for overall OTA operation.
|
||||
*/
|
||||
esp_wifi_set_ps(WIFI_PS_NONE);
|
||||
#else
|
||||
/* WIFI_PS_MIN_MODEM is the default mode for WiFi Power saving. When both
|
||||
* WiFi and Bluetooth are running, WiFI modem has to go down, hence we
|
||||
* need WIFI_PS_MIN_MODEM. And as WiFi modem goes down, OTA download time
|
||||
* increases.
|
||||
*/
|
||||
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
|
||||
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
|
||||
ESP_ERROR_CHECK(esp_ble_helper_init());
|
||||
#endif
|
||||
|
||||
xTaskCreate(&advanced_ota_example_task, "advanced_ota_example_task", 1024 * 8, NULL, 5, NULL);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
|
||||
|
||||
#include "ble_api.h"
|
||||
#include "esp_log.h"
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "nimble_gatts.h"
|
||||
#elif CONFIG_BT_BLE_ENABLED
|
||||
#include "bluedroid_gatts.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "BLE_API";
|
||||
|
||||
esp_err_t esp_ble_helper_init(void)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
#if CONFIG_BT_BLE_ENABLED
|
||||
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
err = esp_bt_controller_init(&bt_cfg);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
err = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_bluedroid_config_t cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
|
||||
err = esp_bluedroid_init_with_cfg(&cfg);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
err = esp_bluedroid_enable();
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
err = esp_ble_gatts_register_callback(gatts_event_handler);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "gatts register error, error code = %x", err);
|
||||
return err;
|
||||
}
|
||||
err = esp_ble_gap_register_callback(gap_event_handler);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "gap register error, error code = %x", err);
|
||||
return err;
|
||||
}
|
||||
err = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "gatts app register error, error code = %x", err);
|
||||
return err;
|
||||
}
|
||||
esp_err_t local_mtu_err = esp_ble_gatt_set_local_mtu(500);
|
||||
if (local_mtu_err) {
|
||||
ESP_LOGE(TAG, "set local MTU failed, error code = %x", local_mtu_err);
|
||||
return local_mtu_err;
|
||||
}
|
||||
|
||||
#elif CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
err = nimble_port_init();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to init nimble %d ", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Initialize the NimBLE host configuration. */
|
||||
ble_hs_cfg.reset_cb = bleprph_on_reset;
|
||||
ble_hs_cfg.sync_cb = bleprph_on_sync;
|
||||
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||
|
||||
err = nimble_gatt_svr_init();
|
||||
assert(err == 0);
|
||||
|
||||
/* Set the default device name. */
|
||||
err = ble_svc_gap_device_name_set("ESP_OTA_GATTS");
|
||||
assert(err == 0);
|
||||
|
||||
ble_store_config_init();
|
||||
|
||||
nimble_port_freertos_init(bleprph_host_task);
|
||||
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "bluedroid_gatts.h"
|
||||
#include "esp_log.h"
|
||||
#include "string.h"
|
||||
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED
|
||||
|
||||
static const char *TAG = "bluedroid_gatts";
|
||||
static prepare_type_env_t a_prepare_write_env;
|
||||
|
||||
uint8_t adv_service_uuid128[32] = {
|
||||
/* LSB <--------------------------------------------------------------------------------> MSB */
|
||||
//first uuid, 16bit, [12],[13] is the value
|
||||
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00,
|
||||
//second uuid, 32bit, [12], [13], [14], [15] is the value
|
||||
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
// The length of adv data must be less than 31 bytes
|
||||
//adv data
|
||||
esp_ble_adv_data_t adv_data = {
|
||||
.set_scan_rsp = false,
|
||||
.include_name = true,
|
||||
.include_txpower = false,
|
||||
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
|
||||
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
|
||||
.appearance = 0x00,
|
||||
.manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN,
|
||||
.p_manufacturer_data = NULL, //&test_manufacturer[0],
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = sizeof(adv_service_uuid128),
|
||||
.p_service_uuid = adv_service_uuid128,
|
||||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||||
};
|
||||
// scan response data
|
||||
esp_ble_adv_data_t scan_rsp_data = {
|
||||
.set_scan_rsp = true,
|
||||
.include_name = true,
|
||||
.include_txpower = true,
|
||||
.appearance = 0x00,
|
||||
.manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN,
|
||||
.p_manufacturer_data = NULL, //&test_manufacturer[0],
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = sizeof(adv_service_uuid128),
|
||||
.p_service_uuid = adv_service_uuid128,
|
||||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||||
};
|
||||
esp_ble_adv_params_t adv_params = {
|
||||
.adv_int_min = 0x20,
|
||||
.adv_int_max = 0x40,
|
||||
.adv_type = ADV_TYPE_IND,
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.channel_map = ADV_CHNL_ALL,
|
||||
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
||||
};
|
||||
|
||||
|
||||
uint8_t char1_str[] = {0x11, 0x22, 0x33};
|
||||
|
||||
esp_attr_value_t gatts_demo_char1_val = {
|
||||
.attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
|
||||
.attr_len = sizeof(char1_str),
|
||||
.attr_value = char1_str,
|
||||
};
|
||||
|
||||
uint8_t adv_config_done = 0;
|
||||
|
||||
esp_gatt_char_prop_t a_property = 0;
|
||||
|
||||
static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
|
||||
[PROFILE_A_APP_ID] = {
|
||||
.gatts_cb = gatts_profile_a_event_handler,
|
||||
.gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
|
||||
},
|
||||
};
|
||||
|
||||
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
|
||||
ESP_LOG_BUFFER_HEX(TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "ESP_GATT_PREP_WRITE_CANCEL");
|
||||
}
|
||||
if (prepare_write_env->prepare_buf) {
|
||||
free(prepare_write_env->prepare_buf);
|
||||
prepare_write_env->prepare_buf = NULL;
|
||||
}
|
||||
prepare_write_env->prepare_len = 0;
|
||||
}
|
||||
|
||||
void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
esp_gatt_status_t status = ESP_GATT_OK;
|
||||
|
||||
// Check if a response is needed
|
||||
if (param->write.need_rsp) {
|
||||
// Check if the write operation is a prepared write
|
||||
if (param->write.is_prep) {
|
||||
// Check for invalid offset or attribute length
|
||||
if (param->write.offset > PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_OFFSET;
|
||||
} else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
|
||||
status = ESP_GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
// Allocate memory for the prepare buffer if not already allocated
|
||||
if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) {
|
||||
prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
|
||||
prepare_write_env->prepare_len = 0;
|
||||
|
||||
// Check for allocation failure
|
||||
if (prepare_write_env->prepare_buf == NULL) {
|
||||
ESP_LOGE(TAG, "Gatt_server prep no mem");
|
||||
status = ESP_GATT_NO_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate and configure the GATT response
|
||||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
|
||||
if (gatt_rsp != NULL) {
|
||||
gatt_rsp->attr_value.len = param->write.len;
|
||||
gatt_rsp->attr_value.handle = param->write.handle;
|
||||
gatt_rsp->attr_value.offset = param->write.offset;
|
||||
gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
|
||||
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
|
||||
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
|
||||
if (response_err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Send response error");
|
||||
}
|
||||
free(gatt_rsp);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "%s, malloc failed, and no resource to send response", __func__);
|
||||
status = ESP_GATT_NO_RESOURCES;
|
||||
}
|
||||
|
||||
if (status != ESP_GATT_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the prepare buffer with the received data
|
||||
memcpy(prepare_write_env->prepare_buf + param->write.offset,
|
||||
param->write.value,
|
||||
param->write.len);
|
||||
prepare_write_env->prepare_len += param->write.len;
|
||||
|
||||
} else {
|
||||
// Send a response for non-prepared write
|
||||
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GATTS_REG_EVT:
|
||||
ESP_LOGI(TAG, "REGISTER_APP_EVT, status %d, app_id %d", param->reg.status, param->reg.app_id);
|
||||
gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A;
|
||||
|
||||
esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(TEST_DEVICE_NAME);
|
||||
if (set_dev_name_ret) {
|
||||
ESP_LOGE(TAG, "set device name failed, error code = %x", set_dev_name_ret);
|
||||
}
|
||||
//config adv data
|
||||
esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "config adv data failed, error code = %x", ret);
|
||||
}
|
||||
adv_config_done |= adv_config_flag;
|
||||
//config scan response data
|
||||
ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "config scan response data failed, error code = %x", ret);
|
||||
}
|
||||
adv_config_done |= scan_rsp_config_flag;
|
||||
|
||||
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A);
|
||||
break;
|
||||
case ESP_GATTS_READ_EVT: {
|
||||
ESP_LOGI(TAG, "GATT_READ_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->read.conn_id, param->read.trans_id, param->read.handle);
|
||||
esp_gatt_rsp_t rsp;
|
||||
memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
|
||||
rsp.attr_value.handle = param->read.handle;
|
||||
rsp.attr_value.len = 4;
|
||||
rsp.attr_value.value[0] = 0xde;
|
||||
rsp.attr_value.value[1] = 0xed;
|
||||
rsp.attr_value.value[2] = 0xbe;
|
||||
rsp.attr_value.value[3] = 0xef;
|
||||
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
|
||||
ESP_GATT_OK, &rsp);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_WRITE_EVT: {
|
||||
ESP_LOGI(TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
|
||||
if (!param->write.is_prep) {
|
||||
ESP_LOGI(TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
|
||||
ESP_LOG_BUFFER_HEX(TAG, param->write.value, param->write.len);
|
||||
if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2) {
|
||||
uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
|
||||
if (descr_value == 0x0001) {
|
||||
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
|
||||
ESP_LOGI(TAG, "notify enable");
|
||||
uint8_t notify_data[15];
|
||||
for (int i = 0; i < sizeof(notify_data); ++i) {
|
||||
notify_data[i] = i % 0xff;
|
||||
}
|
||||
//the size of notify_data[] need less than MTU size
|
||||
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||||
sizeof(notify_data), notify_data, false);
|
||||
}
|
||||
} else if (descr_value == 0x0002) {
|
||||
if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) {
|
||||
ESP_LOGI(TAG, "indicate enable");
|
||||
uint8_t indicate_data[15];
|
||||
for (int i = 0; i < sizeof(indicate_data); ++i) {
|
||||
indicate_data[i] = i % 0xff;
|
||||
}
|
||||
//the size of indicate_data[] need less than MTU size
|
||||
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||||
sizeof(indicate_data), indicate_data, true);
|
||||
}
|
||||
} else if (descr_value == 0x0000) {
|
||||
ESP_LOGI(TAG, "notify/indicate disable ");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "unknown descr value");
|
||||
ESP_LOG_BUFFER_HEX(TAG, param->write.value, param->write.len);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
example_write_event_env(gatts_if, &a_prepare_write_env, param);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_EXEC_WRITE_EVT:
|
||||
ESP_LOGI(TAG, "ESP_GATTS_EXEC_WRITE_EVT");
|
||||
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
|
||||
example_exec_write_event_env(&a_prepare_write_env, param);
|
||||
break;
|
||||
case ESP_GATTS_MTU_EVT:
|
||||
ESP_LOGI(TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
|
||||
break;
|
||||
case ESP_GATTS_UNREG_EVT:
|
||||
break;
|
||||
case ESP_GATTS_CREATE_EVT:
|
||||
ESP_LOGI(TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d", param->create.status, param->create.service_handle);
|
||||
gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A;
|
||||
|
||||
esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle);
|
||||
a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
||||
esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
|
||||
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
|
||||
a_property,
|
||||
&gatts_demo_char1_val, NULL);
|
||||
if (add_char_ret) {
|
||||
ESP_LOGE(TAG, "add char failed, error code =%x", add_char_ret);
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_ADD_INCL_SRVC_EVT:
|
||||
break;
|
||||
case ESP_GATTS_ADD_CHAR_EVT: {
|
||||
uint16_t length = 0;
|
||||
const uint8_t *prf_char;
|
||||
|
||||
ESP_LOGI(TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d",
|
||||
param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
|
||||
gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
|
||||
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||||
esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
|
||||
if (get_attr_ret == ESP_FAIL) {
|
||||
ESP_LOGE(TAG, "ILLEGAL HANDLE");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "the gatts demo char length = %x", length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
ESP_LOGI(TAG, "prf_char[%x] =%x", i, prf_char[i]);
|
||||
}
|
||||
esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
|
||||
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
|
||||
if (add_descr_ret) {
|
||||
ESP_LOGE(TAG, "add char descr failed, error code =%x", add_descr_ret);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
|
||||
gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char_descr.attr_handle;
|
||||
ESP_LOGI(TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d",
|
||||
param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
|
||||
break;
|
||||
case ESP_GATTS_DELETE_EVT:
|
||||
break;
|
||||
case ESP_GATTS_START_EVT:
|
||||
ESP_LOGI(TAG, "SERVICE_START_EVT, status %d, service_handle %d",
|
||||
param->start.status, param->start.service_handle);
|
||||
break;
|
||||
case ESP_GATTS_STOP_EVT:
|
||||
break;
|
||||
case ESP_GATTS_CONNECT_EVT: {
|
||||
esp_ble_conn_update_params_t conn_params = {0};
|
||||
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
|
||||
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
|
||||
conn_params.latency = 0;
|
||||
conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
|
||||
conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
|
||||
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
|
||||
ESP_LOGI(TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
|
||||
param->connect.conn_id,
|
||||
param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
|
||||
param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
|
||||
gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id;
|
||||
//start sent the update connection parameters to the peer device.
|
||||
esp_ble_gap_update_conn_params(&conn_params);
|
||||
break;
|
||||
}
|
||||
case ESP_GATTS_DISCONNECT_EVT:
|
||||
ESP_LOGI(TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
|
||||
esp_ble_gap_start_advertising(&adv_params);
|
||||
break;
|
||||
case ESP_GATTS_CONF_EVT:
|
||||
ESP_LOGI(TAG, "ESP_GATTS_CONF_EVT, status %d attr_handle %d", param->conf.status, param->conf.handle);
|
||||
if (param->conf.status != ESP_GATT_OK) {
|
||||
ESP_LOG_BUFFER_HEX(TAG, param->conf.value, param->conf.len);
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_OPEN_EVT:
|
||||
case ESP_GATTS_CANCEL_OPEN_EVT:
|
||||
case ESP_GATTS_CLOSE_EVT:
|
||||
case ESP_GATTS_LISTEN_EVT:
|
||||
case ESP_GATTS_CONGEST_EVT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
adv_config_done &= (~adv_config_flag);
|
||||
if (adv_config_done == 0) {
|
||||
if (esp_ble_gap_start_advertising(&adv_params) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Started advertising.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
|
||||
adv_config_done &= (~scan_rsp_config_flag);
|
||||
if (adv_config_done == 0) {
|
||||
if (esp_ble_gap_start_advertising(&adv_params) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Started advertising.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
|
||||
//advertising start complete event to indicate advertising start successfully or failed
|
||||
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Advertising start failed");
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
|
||||
if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Advertising stop failed");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Stop adv successfully");
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
|
||||
ESP_LOGI(TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d",
|
||||
param->update_conn_params.status,
|
||||
param->update_conn_params.conn_int,
|
||||
param->update_conn_params.latency,
|
||||
param->update_conn_params.timeout);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||||
{
|
||||
/* If event is register event, store the gatts_if for each profile */
|
||||
if (event == ESP_GATTS_REG_EVT) {
|
||||
if (param->reg.status == ESP_GATT_OK) {
|
||||
gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Reg app failed, app_id %04x, status %d",
|
||||
param->reg.app_id,
|
||||
param->reg.status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the gatts_if equal to profile A, call profile A cb handler,
|
||||
* so here call each profile's callback */
|
||||
do {
|
||||
int idx;
|
||||
for (idx = 0; idx < PROFILE_NUM; idx++) {
|
||||
if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
|
||||
gatts_if == gl_profile_tab[idx].gatts_if) {
|
||||
if (gl_profile_tab[idx].gatts_cb) {
|
||||
gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED)
|
||||
esp_err_t esp_ble_helper_init(void);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef H_BLUEDROID_GATTS_
|
||||
#define H_BLUEDROID_GATTS_
|
||||
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_bt.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "esp_gatts_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_gatt_common_api.h"
|
||||
|
||||
#define PROFILE_NUM 1
|
||||
#define PROFILE_A_APP_ID 0
|
||||
|
||||
#define GATTS_SERVICE_UUID_TEST_A 0x00FF
|
||||
#define GATTS_CHAR_UUID_TEST_A 0xFF01
|
||||
#define GATTS_DESCR_UUID_TEST_A 0x3333
|
||||
#define GATTS_NUM_HANDLE_TEST_A 4
|
||||
|
||||
#define adv_config_flag (1 << 0)
|
||||
#define scan_rsp_config_flag (1 << 1)
|
||||
|
||||
#define TEST_DEVICE_NAME "ESP_OTA_GATTS"
|
||||
#define TEST_MANUFACTURER_DATA_LEN 17
|
||||
|
||||
#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
|
||||
|
||||
#define PREPARE_BUF_MAX_SIZE 1024
|
||||
|
||||
struct gatts_profile_inst {
|
||||
esp_gatts_cb_t gatts_cb;
|
||||
uint16_t gatts_if;
|
||||
uint16_t app_id;
|
||||
uint16_t conn_id;
|
||||
uint16_t service_handle;
|
||||
esp_gatt_srvc_id_t service_id;
|
||||
uint16_t char_handle;
|
||||
esp_bt_uuid_t char_uuid;
|
||||
esp_gatt_perm_t perm;
|
||||
esp_gatt_char_prop_t property;
|
||||
uint16_t descr_handle;
|
||||
esp_bt_uuid_t descr_uuid;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t *prepare_buf;
|
||||
int prepare_len;
|
||||
} prepare_type_env_t;
|
||||
|
||||
void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||
|
||||
void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
|
||||
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
|
||||
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
|
||||
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef H_NIMBLE_GATTS_
|
||||
#define H_NIMBLE_GATTS_
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "nimble/ble.h"
|
||||
#include "modlog/modlog.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "console/console.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
|
||||
struct ble_hs_cfg;
|
||||
struct ble_gatt_register_ctxt;
|
||||
|
||||
int bleprph_gap_event(struct ble_gap_event *event, void *arg);
|
||||
|
||||
/** GATT server. */
|
||||
#define GATT_SVR_SVC_ALERT_UUID 0x1811
|
||||
#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47
|
||||
#define GATT_SVR_CHR_NEW_ALERT 0x2A46
|
||||
#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48
|
||||
#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45
|
||||
#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44
|
||||
|
||||
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
|
||||
int nimble_gatt_svr_init(void);
|
||||
void ble_store_config_init(void);
|
||||
void print_addr(const void *addr);
|
||||
void bleprph_print_conn_desc(struct ble_gap_conn_desc *desc);
|
||||
void bleprph_advertise(void);
|
||||
int bleprph_gap_event(struct ble_gap_event *event, void *arg);
|
||||
void bleprph_host_task(void *param);
|
||||
void bleprph_on_reset(int reason);
|
||||
void bleprph_on_sync(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
#include "nimble_gatts.h"
|
||||
#include "esp_log.h"
|
||||
#include "services/gatt/ble_svc_gatt.h"
|
||||
|
||||
static const char *TAG = "nimble_gatts";
|
||||
static uint8_t own_addr_type;
|
||||
|
||||
static const ble_uuid128_t gatt_svr_svc_sec_test_uuid =
|
||||
BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12,
|
||||
0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
|
||||
|
||||
/* 5c3a659e-897e-45e1-b016-007107c96df6 */
|
||||
static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid =
|
||||
BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
|
||||
0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
|
||||
|
||||
/* 5c3a659e-897e-45e1-b016-007107c96df7 */
|
||||
static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid =
|
||||
BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
|
||||
0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg);
|
||||
|
||||
static uint8_t gatt_svr_sec_test_static_val;
|
||||
|
||||
|
||||
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
|
||||
{
|
||||
/*** Service: Security test. */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = &gatt_svr_svc_sec_test_uuid.u,
|
||||
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||
/*** Characteristic: Random number generator. */
|
||||
.uuid = &gatt_svr_chr_sec_test_rand_uuid.u,
|
||||
.access_cb = gatt_svr_chr_access_sec_test,
|
||||
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
|
||||
}, {
|
||||
0, /* No more characteristics in this service. */
|
||||
} },
|
||||
},
|
||||
|
||||
{
|
||||
0, /* No more services. */
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
|
||||
void *dst, uint16_t *len)
|
||||
{
|
||||
uint16_t om_len;
|
||||
int rc;
|
||||
|
||||
om_len = OS_MBUF_PKTLEN(om);
|
||||
if (om_len < min_len || om_len > max_len) {
|
||||
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||
}
|
||||
|
||||
rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
|
||||
if (rc != 0) {
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt,
|
||||
void *arg)
|
||||
{
|
||||
const ble_uuid_t *uuid;
|
||||
int rand_num;
|
||||
int rc;
|
||||
|
||||
uuid = ctxt->chr->uuid;
|
||||
|
||||
/* Determine which characteristic is being accessed by examining its
|
||||
* 128-bit UUID.
|
||||
*/
|
||||
|
||||
if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) {
|
||||
assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
|
||||
|
||||
/* Respond with a 32-bit random number. */
|
||||
rand_num = rand();
|
||||
rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) {
|
||||
switch (ctxt->op) {
|
||||
case BLE_GATT_ACCESS_OP_READ_CHR:
|
||||
rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
|
||||
sizeof gatt_svr_sec_test_static_val);
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
|
||||
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
||||
rc = gatt_svr_chr_write(ctxt->om,
|
||||
sizeof gatt_svr_sec_test_static_val,
|
||||
sizeof gatt_svr_sec_test_static_val,
|
||||
&gatt_svr_sec_test_static_val, NULL);
|
||||
return rc;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknown characteristic; the nimble stack should not have called this
|
||||
* function.
|
||||
*/
|
||||
assert(0);
|
||||
return BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_addr(const void *addr)
|
||||
{
|
||||
const uint8_t *u8p;
|
||||
|
||||
u8p = addr;
|
||||
MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables advertising with the following parameters:
|
||||
* o General discoverable mode.
|
||||
* o Undirected connectable mode.
|
||||
*/
|
||||
void
|
||||
bleprph_advertise(void)
|
||||
{
|
||||
struct ble_gap_adv_params adv_params;
|
||||
struct ble_hs_adv_fields fields;
|
||||
const char *name;
|
||||
int rc;
|
||||
|
||||
/**
|
||||
* Set the advertisement data included in our advertisements:
|
||||
* o Flags (indicates advertisement type and other general info).
|
||||
* o Advertising tx power.
|
||||
* o Device name.
|
||||
* o 16-bit service UUIDs (alert notifications).
|
||||
*/
|
||||
|
||||
memset(&fields, 0, sizeof fields);
|
||||
|
||||
/* Advertise two flags:
|
||||
* o Discoverability in forthcoming advertisement (general)
|
||||
* o BLE-only (BR/EDR unsupported).
|
||||
*/
|
||||
fields.flags = BLE_HS_ADV_F_DISC_GEN |
|
||||
BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
|
||||
/* Indicate that the TX power level field should be included; have the
|
||||
* stack fill this value automatically. This is done by assigning the
|
||||
* special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
|
||||
*/
|
||||
fields.tx_pwr_lvl_is_present = 1;
|
||||
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||
|
||||
name = ble_svc_gap_device_name();
|
||||
fields.name = (uint8_t *)name;
|
||||
fields.name_len = strlen(name);
|
||||
fields.name_is_complete = 1;
|
||||
|
||||
fields.uuids16 = (ble_uuid16_t[]) {
|
||||
BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)
|
||||
};
|
||||
fields.num_uuids16 = 1;
|
||||
fields.uuids16_is_complete = 1;
|
||||
|
||||
rc = ble_gap_adv_set_fields(&fields);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin advertising. */
|
||||
memset(&adv_params, 0, sizeof adv_params);
|
||||
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
|
||||
&adv_params, bleprph_gap_event, NULL);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bleprph_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_gap_conn_desc desc;
|
||||
int rc;
|
||||
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
/* A new connection was established or a connection attempt failed. */
|
||||
MODLOG_DFLT(INFO, "connection %s; status=%d ",
|
||||
event->connect.status == 0 ? "established" : "failed",
|
||||
event->connect.status);
|
||||
if (event->connect.status == 0) {
|
||||
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
bleprph_print_conn_desc(&desc);
|
||||
}
|
||||
MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
if (event->connect.status != 0) {
|
||||
/* Connection failed; resume advertising. */
|
||||
bleprph_advertise();
|
||||
}
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
|
||||
bleprph_print_conn_desc(&event->disconnect.conn);
|
||||
MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
/* Connection terminated; resume advertising. */
|
||||
bleprph_advertise();
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||
/* The central has updated the connection parameters. */
|
||||
MODLOG_DFLT(INFO, "connection updated; status=%d ",
|
||||
event->conn_update.status);
|
||||
rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
bleprph_print_conn_desc(&desc);
|
||||
MODLOG_DFLT(INFO, "\n");
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||
MODLOG_DFLT(INFO, "advertise complete; reason=%d",
|
||||
event->adv_complete.reason);
|
||||
bleprph_advertise();
|
||||
return 0;
|
||||
|
||||
case BLE_GAP_EVENT_MTU:
|
||||
MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.channel_id,
|
||||
event->mtu.value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs information about a connection to the console.
|
||||
*/
|
||||
void
|
||||
bleprph_print_conn_desc(struct ble_gap_conn_desc *desc)
|
||||
{
|
||||
MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
|
||||
desc->conn_handle, desc->our_ota_addr.type);
|
||||
print_addr(desc->our_ota_addr.val);
|
||||
MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
|
||||
desc->our_id_addr.type);
|
||||
print_addr(desc->our_id_addr.val);
|
||||
MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
|
||||
desc->peer_ota_addr.type);
|
||||
print_addr(desc->peer_ota_addr.val);
|
||||
MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
|
||||
desc->peer_id_addr.type);
|
||||
print_addr(desc->peer_id_addr.val);
|
||||
MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
|
||||
"encrypted=%d authenticated=%d bonded=%d\n",
|
||||
desc->conn_itvl, desc->conn_latency,
|
||||
desc->supervision_timeout,
|
||||
desc->sec_state.encrypted,
|
||||
desc->sec_state.authenticated,
|
||||
desc->sec_state.bonded);
|
||||
}
|
||||
|
||||
void
|
||||
bleprph_on_reset(int reason)
|
||||
{
|
||||
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
|
||||
}
|
||||
|
||||
void
|
||||
bleprph_on_sync(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_hs_util_ensure_addr(0);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Figure out address to use while advertising (no privacy for now) */
|
||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
if (rc != 0) {
|
||||
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Printing ADDR */
|
||||
uint8_t addr_val[6] = {0};
|
||||
rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
|
||||
|
||||
MODLOG_DFLT(INFO, "Device Address: ");
|
||||
print_addr(addr_val);
|
||||
MODLOG_DFLT(INFO, "\n");
|
||||
/* Begin advertising. */
|
||||
bleprph_advertise();
|
||||
}
|
||||
|
||||
void bleprph_host_task(void *param)
|
||||
{
|
||||
ESP_LOGI(TAG, "BLE Host Task Started");
|
||||
/* This function will return only when nimble_port_stop() is executed */
|
||||
nimble_port_run();
|
||||
|
||||
nimble_port_freertos_deinit();
|
||||
}
|
||||
|
||||
int
|
||||
nimble_gatt_svr_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ble_svc_gap_init();
|
||||
ble_svc_gatt_init();
|
||||
|
||||
rc = ble_gatts_count_cfg(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_gatts_add_svcs(gatt_svr_svcs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
protocol_examples_common:
|
||||
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
|
||||
@@ -0,0 +1,8 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, , 1600K,
|
||||
ota_1, app, ota_1, , 1600K,
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
CONFIG_LWIP_CHECK_THREAD_SAFETY=y
|
||||
@@ -0,0 +1,41 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="anti_rollback_partition.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="anti_rollback_partition.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xd000
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||
CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y
|
||||
CONFIG_BOOTLOADER_APP_SECURE_VERSION=1
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
|
||||
|
||||
# Default settings for testing this example in CI.
|
||||
# This configuration is not secure, don't use it in production!
|
||||
# See Flash Encryption API Guide for more details.
|
||||
|
||||
CONFIG_SECURE_FLASH_ENC_ENABLED=y
|
||||
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y
|
||||
CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y
|
||||
CONFIG_SECURE_BOOT_ALLOW_JTAG=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y
|
||||
CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y
|
||||
CONFIG_NVS_ENCRYPTION=n # this test combination is only for flash encryption and anti-rollback use-case and hence disabling it.
|
||||
CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC=y
|
||||
@@ -0,0 +1,23 @@
|
||||
# Enable Bluedroid BLE
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||
CONFIG_CTRL_BTDM_MODEM_SLEEP=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
CONFIG_BT_STACK_NO_LOG=y
|
||||
|
||||
# Partition Table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example_with_ble.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_example_with_ble.csv"
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=y
|
||||
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
@@ -0,0 +1,23 @@
|
||||
# Enable NimBLE
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||
CONFIG_BT_BLUEDROID_ENABLED=n
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
|
||||
# Partition Table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example_with_ble.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_example_with_ble.csv"
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=y
|
||||
CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
@@ -0,0 +1,20 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=15000
|
||||
CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION=y
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||
CONFIG_ETHERNET_RX_TASK_STACK_SIZE=3072
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
@@ -0,0 +1,39 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=15000
|
||||
CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION=y
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||
CONFIG_ETHERNET_RX_TASK_STACK_SIZE=3072
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xd000
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
|
||||
# Default settings for testing this example in CI.
|
||||
# This configuration is not secure, don't use it in production!
|
||||
# See Flash Encryption API Guide for more details.
|
||||
|
||||
CONFIG_SECURE_FLASH_ENC_ENABLED=y
|
||||
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y
|
||||
CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y
|
||||
CONFIG_SECURE_BOOT_ALLOW_JTAG=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y
|
||||
CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y
|
||||
CONFIG_NVS_ENCRYPTION=n # this test combination is only for flash encryption and ota resumption use-case and hence disabling it.
|
||||
CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC=y
|
||||
|
||||
# Custom OTA buffer size configuration
|
||||
CONFIG_EXAMPLE_OTA_BUF_SIZE=2047
|
||||
@@ -0,0 +1,22 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=15000
|
||||
CONFIG_ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD=y
|
||||
CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD=y
|
||||
CONFIG_EXAMPLE_ENABLE_OTA_RESUMPTION=y
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||
CONFIG_ETHERNET_RX_TASK_STACK_SIZE=3072
|
||||
|
||||
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=n
|
||||
@@ -0,0 +1,19 @@
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
CONFIG_ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD=y
|
||||
CONFIG_EXAMPLE_ENABLE_PARTIAL_HTTP_DOWNLOAD=y
|
||||
|
||||
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
|
||||
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=y
|
||||
CONFIG_ETHERNET_PHY_GENERIC=y
|
||||
CONFIG_ETHERNET_MDC_GPIO=23
|
||||
CONFIG_ETHERNET_MDIO_GPIO=18
|
||||
CONFIG_ETHERNET_PHY_RST_GPIO=5
|
||||
CONFIG_ETHERNET_PHY_ADDR=1
|
||||
CONFIG_EXAMPLE_CONNECT_IPV6=y
|
||||
CONFIG_ETHERNET_RX_TASK_STACK_SIZE=3072
|
||||
@@ -0,0 +1,13 @@
|
||||
CONFIG_IDF_TARGET="esp32c3"
|
||||
|
||||
CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN"
|
||||
CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y
|
||||
CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y
|
||||
CONFIG_EXAMPLE_OTA_RECV_TIMEOUT=3000
|
||||
|
||||
# QEMU-Related configurations
|
||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||
CONFIG_ETHERNET_OPENETH_SUPPORT=y
|
||||
CONFIG_ETHERNET_INTERNAL_SUPPORT=n
|
||||
CONFIG_ETHERNET_SPI_SUPPORT=n
|
||||
@@ -0,0 +1,9 @@
|
||||
# Default sdkconfig parameters to use the OTA
|
||||
# partition table layout, with a 4MB flash size
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_PARTITION_TABLE_TWO_OTA_LARGE=y
|
||||
|
||||
# Certificate bundle configuration
|
||||
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
||||
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
|
||||
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="server_certs/ca_cert.pem"
|
||||
@@ -0,0 +1 @@
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
@@ -0,0 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
|
||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
|
||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
|
||||
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
|
||||
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
|
||||
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
|
||||
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
|
||||
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
|
||||
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
|
||||
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
|
||||
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
|
||||
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
|
||||
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
|
||||
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDWDCCAkACCQCbF4+gVh/MLjANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJJ
|
||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||
b20wHhcNMjEwNzEyMTIzNjI3WhcNNDEwNzA3MTIzNjI3WjBuMQswCQYDVQQGEwJJ
|
||||
TjELMAkGA1UECAwCTUgxDDAKBgNVBAcMA1BVTjEMMAoGA1UECgwDRVNQMQwwCgYD
|
||||
VQQLDANFU1AxDDAKBgNVBAMMA0VTUDEaMBgGCSqGSIb3DQEJARYLZXNwQGVzcC5j
|
||||
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhxF/y7bygndxPwiWL
|
||||
SwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQuc32W
|
||||
ukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2mKRbQ
|
||||
S5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO2fEz
|
||||
YaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnvL6Oz
|
||||
3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdOAoap
|
||||
rFTRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAItw24y565k3C/zENZlxyzto44ud
|
||||
IYPQXN8Fa2pBlLe1zlSIyuaA/rWQ+i1daS8nPotkCbWZyf5N8DYaTE4B0OfvoUPk
|
||||
B5uGDmbuk6akvlB5BGiYLfQjWHRsK9/4xjtIqN1H58yf3QNROuKsPAeywWS3Fn32
|
||||
3//OpbWaClQePx6udRYMqAitKR+QxL7/BKZQsX+UyShuq8hjphvXvk0BW8ONzuw9
|
||||
RcoORxM0FzySYjeQvm4LhzC/P3ZBhEq0xs55aL2a76SJhq5hJy7T/Xz6NFByvlrN
|
||||
lFJJey33KFrAf5vnV9qcyWFIo7PYy2VsaaEjFeefr7q3sTFSMlJeadexW2Y=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDhxF/y7bygndxP
|
||||
wiWLSwS9LY3uBMaJgup0ufNKVhx+FhGQOu44SghuJAaH3KkPUnt6SOM8jC97/yQu
|
||||
c32WukI7eBZoA12kargSnzdv5m5rZZpd+NznSSpoDArOAONKVlzr25A1+aZbix2m
|
||||
KRbQS5w9o1N2BriQuSzd8gL0Y0zEk3VkOWXEL+0yFUT144HnErnD+xnJtHe11yPO
|
||||
2fEzYaGiilh0ddL26PXTugXMZN/8fRVHP50P2OG0SvFpC7vghlLp4VFM1/r3UJnv
|
||||
L6Oz3ALc6dhxZEKQucqlpj8l1UegszQToopemtIj0qXTHw2+uUnkUyWIPjPC+wdO
|
||||
AoaprFTRAgMBAAECggEAE0HCxV/N1Q1h+1OeDDGL5+74yjKSFKyb/vTVcaPCrmaH
|
||||
fPvp0ddOvMZJ4FDMAsiQS6/n4gQ7EKKEnYmwTqj4eUYW8yxGUn3f0YbPHbZT+Mkj
|
||||
z5woi3nMKi/MxCGDQZX4Ow3xUQlITUqibsfWcFHis8c4mTqdh4qj7xJzehD2PVYF
|
||||
gNHZsvVj6MltjBDAVwV1IlGoHjuElm6vuzkfX7phxcA1B4ZqdYY17yCXUnvui46z
|
||||
Xn2kUTOOUCEgfgvGa9E+l4OtdXi5IxjaSraU+dlg2KsE4TpCuN2MEVkeR5Ms3Y7Q
|
||||
jgJl8vlNFJDQpbFukLcYwG7rO5N5dQ6WWfVia/5XgQKBgQD74at/bXAPrh9NxPmz
|
||||
i1oqCHMDoM9sz8xIMZLF9YVu3Jf8ux4xVpRSnNy5RU1gl7ZXbpdgeIQ4v04zy5aw
|
||||
8T4tu9K3XnR3UXOy25AK0q+cnnxZg3kFQm+PhtOCKEFjPHrgo2MUfnj+EDddod7N
|
||||
JQr9q5rEFbqHupFPpWlqCa3QmQKBgQDldWUGokNaEpmgHDMnHxiibXV5LQhzf8Rq
|
||||
gJIQXb7R9EsTSXEvsDyqTBb7PHp2Ko7rZ5YQfyf8OogGGjGElnPoU/a+Jij1gVFv
|
||||
kZ064uXAAISBkwHdcuobqc5EbG3ceyH46F+FBFhqM8KcbxJxx08objmh58+83InN
|
||||
P9Qr25Xw+QKBgEGXMHuMWgQbSZeM1aFFhoMvlBO7yogBTKb4Ecpu9wI5e3Kan3Al
|
||||
pZYltuyf+VhP6XG3IMBEYdoNJyYhu+nzyEdMg8CwXg+8LC7FMis/Ve+o7aS5scgG
|
||||
1to/N9DK/swCsdTRdzmc/ZDbVC+TuVsebFBGYZTyO5KgqLpezqaIQrTxAoGALFCU
|
||||
10glO9MVyl9H3clap5v+MQ3qcOv/EhaMnw6L2N6WVT481tnxjW4ujgzrFcE4YuxZ
|
||||
hgwYu9TOCmeqopGwBvGYWLbj+C4mfSahOAs0FfXDoYazuIIGBpuv03UhbpB1Si4O
|
||||
rJDfRnuCnVWyOTkl54gKJ2OusinhjztBjcrV1XkCgYEA3qNi4uBsPdyz9BZGb/3G
|
||||
rOMSw0CaT4pEMTLZqURmDP/0hxvTk1polP7O/FYwxVuJnBb6mzDa0xpLFPTpIAnJ
|
||||
YXB8xpXU69QVh+EBbemdJWOd+zp5UCfXvb2shAeG3Tn/Dz4cBBMEUutbzP+or0nG
|
||||
vSXnRLaxQhooWm+IuX9SuBQ=
|
||||
-----END PRIVATE KEY-----
|
||||
Reference in New Issue
Block a user