esp-idf/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c
lly 7cd08b5824 ble_mesh: Miscellaneous modifications
1. Add an API to set Provisioner static oob value
2. Add an API to deinit BLE Mesh stack
3. Add an API to set Provisioner unicast address
4. Add an API to provision devices with fixed address
5. Add an API to store node composition data
6. Add an API to get node with device uuid
7. Add an API to get node with unicast address
8. Add an API to delete node with device uuid
9. Add an API to delete node with unicast address
10. Add an API for Provisioner to update local AppKey
11. Add an API for Provisioner to update local NetKey
12. Support Provisioner persistent functionality
13. Fix Provisioner entering IV Update procedure
14. Fix an issue which may cause client failing to send msg
15. Use bt_mesh.flags to indicate device role
16. Remove several useless macros
17. Callback RSSI of received mesh provisioning packets
18. Modify the Provisioner disable function
19. Change some log level from debug to info
20. Add parameters to Provisioner bind AppKey completion event
21. Fix node ignoring relay messages issue
22. Support using a specific partition for BLE Mesh
23. Fix compile warning when proxy related macros are disabled
24. Clean up BLE Mesh stack included header files
25. NULL can be input if client message needs no parameters
26. Fix compile warning when BT log is disabled
27. Initilize BLE Mesh stack local variables
28. Support using PSRAM for BLE Mesh mutex, queue and task
29. Add a menuconfig option to enable using memory from PSRAM
30. Clean up sdkconfig.defaults of BLE Mesh examples
2020-02-26 17:37:44 +08:00

294 lines
6.9 KiB
C

/*
* 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);
}