Files
esp-idf/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c
lly 5ef656af35 ble_mesh: Miscellaneous fixes
1. Add buf ref debug in adv_send
2. Use different locks for different items
3. Remove useless CONFIG_BLE_MESH_NODE
4. Modify lock used during provisioning
5. Add lock for message transport
6. Fix memory leak when node is reset
7. Remove static flag in provisioner init
8. Fix Provisioner lock and init issues
9. Rename some Provisioner related functions
10. Add an API to set Provisioner static oob value
2020-04-20 18:26:14 +08:00

270 lines
6.4 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 "sdkconfig.h"
#include "osi/hash_map.h"
#include "osi/alarm.h"
#include "osi/hash_functions.h"
#include "esp_timer.h"
#include "mesh_kernel.h"
#include "mesh_trace.h"
#include "provisioner_prov.h"
static osi_mutex_t bm_alarm_lock;
static osi_mutex_t bm_list_lock;
static osi_mutex_t bm_buf_lock;
static osi_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) {
osi_mutex_new(&bm_alarm_lock);
__ASSERT(bm_alarm_lock, "%s, fail", __func__);
}
}
static void bt_mesh_alarm_lock(void)
{
if (bm_alarm_lock) {
osi_mutex_lock(&bm_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
}
}
static void bt_mesh_alarm_unlock(void)
{
if (bm_alarm_lock) {
osi_mutex_unlock(&bm_alarm_lock);
}
}
static void bt_mesh_list_mutex_new(void)
{
if (!bm_list_lock) {
osi_mutex_new(&bm_list_lock);
__ASSERT(bm_list_lock, "%s, fail", __func__);
}
}
void bt_mesh_list_lock(void)
{
if (bm_list_lock) {
osi_mutex_lock(&bm_list_lock, OSI_MUTEX_MAX_TIMEOUT);
}
}
void bt_mesh_list_unlock(void)
{
if (bm_list_lock) {
osi_mutex_unlock(&bm_list_lock);
}
}
static void bt_mesh_buf_mutex_new(void)
{
if (!bm_buf_lock) {
osi_mutex_new(&bm_buf_lock);
__ASSERT(bm_buf_lock, "%s, fail", __func__);
}
}
void bt_mesh_buf_lock(void)
{
if (bm_buf_lock) {
osi_mutex_lock(&bm_buf_lock, OSI_MUTEX_MAX_TIMEOUT);
}
}
void bt_mesh_buf_unlock(void)
{
if (bm_buf_lock) {
osi_mutex_unlock(&bm_buf_lock);
}
}
static void bt_mesh_atomic_mutex_new(void)
{
if (!bm_atomic_lock) {
osi_mutex_new(&bm_atomic_lock);
__ASSERT(bm_atomic_lock, "%s, fail", __func__);
}
}
void bt_mesh_atomic_lock(void)
{
if (bm_atomic_lock) {
osi_mutex_lock(&bm_atomic_lock, OSI_MUTEX_MAX_TIMEOUT);
}
}
void bt_mesh_atomic_unlock(void)
{
if (bm_atomic_lock) {
osi_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 != NULL);
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
{
osi_alarm_t *alarm = NULL;
assert(work != NULL && bm_alarm_hash_map != NULL);
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)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
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)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
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)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
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)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
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)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
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);
}