mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-04 02:50:58 +02:00
ble_mesh: Add ESP BLE Mesh implementation
1. BLE Mesh Core * Provisioning: Node Role * PB-ADV and PB-GATT * Authentication OOB * Provisioning: Provisioner Role * PB-ADV and PB-GATT * Authentication OOB * Networking * Relay * Segmentation and Reassembly * Key Refresh * IV Update * Proxy Support * Multiple Client Models Run Simultaneously * Support multiple client models send packets to different nodes simultaneously * No blocking between client model and server * NVS Storage * Store BLE Mesh node related information in flash * Store BLE Mesh Provisioner related information in flash 2. BLE Mesh Models * Foundation Models * Configuration Server Model * Configuration Client Model * Health Server Model * Health Client Model * Generic * Generic OnOff Server * Generic OnOff Client * Generic Level Server * Generic Level Client * Generic Default Transition Time Server * Generic Default Transition Time Client * Generic Power OnOff Server * Generic Power OnOff Setup Server * Generic Power OnOff Client * Generic Power Level Server * Generic Power Level Setup Server * Generic Power Level Client * Generic Battery Server * Generic Battery Client * Generic Location Server * Generic Location Setup Server * Generic Location Client * Generic Admin Property Server * Generic Manufacturer Property Server * Generic User Property Server * Generic Client Property Server * Generic Property Client * Sensor Server Model * Sensor Server * Sensor Setup Server * Sensor Client * Time and Scenes * Time Server * Time Setup Server * Time Client * Scene Server * Scene Setup Server * Scene Client * Scheduler Server * Scheduler Setup Server * Scheduler Client * Lighting * Light Lightness Server * Light Lightness Setup Server * Light Lightness Client * Light CTL Server * Light CTL Setup Server * Light CTL Client * Light CTL Temperature Server * Light HSL Server * Light HSL Setup Server * Light HSL Client * Light HSL Hue Server * Light HSL Saturation Server * Light xyL Server * Light xyL Setup Server * Light xyL Client * Light LC Server * Light LC Setup Server * Light LC Client 3. BLE Mesh Applications * BLE Mesh Node * OnOff Client Example * OnOff Server Example * BLE Mesh Provisioner * Example * Fast Provisioning * Vendor Fast Prov Server Model * Vendor Fast Prov Client Model * Examples * Wi-Fi & BLE Mesh Coexistence * Example * BLE Mesh Console Commands * Examples
This commit is contained in:
293
components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c
Normal file
293
components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
* Copyright (c) 2016 Wind River Systems, Inc.
|
||||
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "osi/hash_map.h"
|
||||
#include "osi/alarm.h"
|
||||
#include "osi/hash_functions.h"
|
||||
|
||||
#include "mesh_common.h"
|
||||
#include "provisioner_prov.h"
|
||||
|
||||
static bt_mesh_mutex_t bm_alarm_lock;
|
||||
static bt_mesh_mutex_t bm_list_lock;
|
||||
static bt_mesh_mutex_t bm_buf_lock;
|
||||
static bt_mesh_mutex_t bm_atomic_lock;
|
||||
static hash_map_t *bm_alarm_hash_map;
|
||||
static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + \
|
||||
CONFIG_BLE_MESH_PBG_SAME_TIME;
|
||||
|
||||
typedef struct alarm_t {
|
||||
/* timer id point to here */
|
||||
esp_timer_handle_t alarm_hdl;
|
||||
osi_alarm_callback_t cb;
|
||||
void *cb_data;
|
||||
int64_t deadline_us;
|
||||
} osi_alarm_t;
|
||||
|
||||
static void bt_mesh_alarm_mutex_new(void)
|
||||
{
|
||||
if (!bm_alarm_lock.mutex) {
|
||||
bt_mesh_mutex_create(&bm_alarm_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_alarm_mutex_free(void)
|
||||
{
|
||||
bt_mesh_mutex_free(&bm_alarm_lock);
|
||||
}
|
||||
|
||||
static void bt_mesh_alarm_lock(void)
|
||||
{
|
||||
bt_mesh_mutex_lock(&bm_alarm_lock);
|
||||
}
|
||||
|
||||
static void bt_mesh_alarm_unlock(void)
|
||||
{
|
||||
bt_mesh_mutex_unlock(&bm_alarm_lock);
|
||||
}
|
||||
|
||||
static void bt_mesh_list_mutex_new(void)
|
||||
{
|
||||
if (!bm_list_lock.mutex) {
|
||||
bt_mesh_mutex_create(&bm_list_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_list_mutex_free(void)
|
||||
{
|
||||
bt_mesh_mutex_free(&bm_list_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_list_lock(void)
|
||||
{
|
||||
bt_mesh_mutex_lock(&bm_list_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_list_unlock(void)
|
||||
{
|
||||
bt_mesh_mutex_unlock(&bm_list_lock);
|
||||
}
|
||||
|
||||
static void bt_mesh_buf_mutex_new(void)
|
||||
{
|
||||
if (!bm_buf_lock.mutex) {
|
||||
bt_mesh_mutex_create(&bm_buf_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_buf_mutex_free(void)
|
||||
{
|
||||
bt_mesh_mutex_free(&bm_buf_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_buf_lock(void)
|
||||
{
|
||||
bt_mesh_mutex_lock(&bm_buf_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_buf_unlock(void)
|
||||
{
|
||||
bt_mesh_mutex_unlock(&bm_buf_lock);
|
||||
}
|
||||
|
||||
static void bt_mesh_atomic_mutex_new(void)
|
||||
{
|
||||
if (!bm_atomic_lock.mutex) {
|
||||
bt_mesh_mutex_create(&bm_atomic_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void bt_mesh_atomic_mutex_free(void)
|
||||
{
|
||||
bt_mesh_mutex_free(&bm_atomic_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_atomic_lock(void)
|
||||
{
|
||||
bt_mesh_mutex_lock(&bm_atomic_lock);
|
||||
}
|
||||
|
||||
void bt_mesh_atomic_unlock(void)
|
||||
{
|
||||
bt_mesh_mutex_unlock(&bm_atomic_lock);
|
||||
}
|
||||
|
||||
s64_t k_uptime_get(void)
|
||||
{
|
||||
/** k_uptime_get_32 is in in milliseconds,
|
||||
* but esp_timer_get_time is in microseconds
|
||||
*/
|
||||
return (esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
u32_t k_uptime_get_32(void)
|
||||
{
|
||||
/** k_uptime_get_32 is in in milliseconds,
|
||||
* but esp_timer_get_time is in microseconds
|
||||
*/
|
||||
return (u32_t)(esp_timer_get_time() / 1000);
|
||||
}
|
||||
|
||||
void k_sleep(s32_t duration)
|
||||
{
|
||||
vTaskDelay(duration / portTICK_PERIOD_MS);
|
||||
return;
|
||||
}
|
||||
|
||||
void bt_mesh_k_init(void)
|
||||
{
|
||||
bt_mesh_alarm_mutex_new();
|
||||
bt_mesh_list_mutex_new();
|
||||
bt_mesh_buf_mutex_new();
|
||||
bt_mesh_atomic_mutex_new();
|
||||
bm_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE,
|
||||
hash_function_pointer, NULL,
|
||||
(data_free_fn)osi_alarm_free, NULL);
|
||||
__ASSERT(bm_alarm_hash_map, "%s, Failed to create hash map", __func__);
|
||||
}
|
||||
|
||||
void bt_mesh_k_deinit(void)
|
||||
{
|
||||
bt_mesh_alarm_mutex_free();
|
||||
bt_mesh_list_mutex_free();
|
||||
bt_mesh_buf_mutex_free();
|
||||
bt_mesh_atomic_mutex_free();
|
||||
if (bm_alarm_hash_map) {
|
||||
hash_map_free(bm_alarm_hash_map);
|
||||
bm_alarm_hash_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
|
||||
{
|
||||
osi_alarm_t *alarm = NULL;
|
||||
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
k_work_init(&work->work, handler);
|
||||
|
||||
bt_mesh_alarm_lock();
|
||||
if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) {
|
||||
alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0);
|
||||
if (alarm == NULL) {
|
||||
BT_ERR("%s, Unable to create alarm", __func__);
|
||||
bt_mesh_alarm_unlock();
|
||||
return;
|
||||
}
|
||||
if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
|
||||
BT_ERR("%s Unable to add the timer to hash map.", __func__);
|
||||
}
|
||||
}
|
||||
bt_mesh_alarm_unlock();
|
||||
|
||||
alarm = hash_map_get(bm_alarm_hash_map, work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Just init the work timer only, don't start it.
|
||||
osi_alarm_cancel(alarm);
|
||||
return;
|
||||
}
|
||||
|
||||
int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay)
|
||||
{
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// Cancel the alarm first, before start the alarm.
|
||||
osi_alarm_cancel(alarm);
|
||||
osi_alarm_set(alarm, delay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period)
|
||||
{
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Cancel the alarm first before starting it. */
|
||||
osi_alarm_cancel(alarm);
|
||||
osi_alarm_set_periodic(alarm, period);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int k_delayed_work_cancel(struct k_delayed_work *work)
|
||||
{
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s, Unable to find expected alarm in hash map", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_cancel(alarm);
|
||||
alarm->deadline_us = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int k_delayed_work_free(struct k_delayed_work *work)
|
||||
{
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s Unable to find expected alarm in hash map", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osi_alarm_cancel(alarm);
|
||||
hash_map_erase(bm_alarm_hash_map, work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
|
||||
{
|
||||
if (!work || !bm_alarm_hash_map) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
|
||||
if (alarm == NULL) {
|
||||
BT_WARN("%s Unable to find expected alarm in hash map", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return osi_alarm_get_remaining_ms(alarm);
|
||||
}
|
Reference in New Issue
Block a user