1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stddef.h>
8 #include <string.h>
9
10 #include <zephyr/kernel.h>
11
12 #include <zephyr/logging/log.h>
13
14 #include "babblekit/testcase.h"
15
16 LOG_MODULE_REGISTER(bt_settings_hook, LOG_LEVEL_DBG);
17
18 struct settings_list_node {
19 sys_snode_t node;
20 char *key;
21 };
22
23 static K_MUTEX_DEFINE(settings_list_mutex);
24 static atomic_t settings_record_enabled = ATOMIC_INIT(0);
25
26 static sys_slist_t settings_list = SYS_SLIST_STATIC_INIT(settings_list);
27
add_key(const char * key)28 static void add_key(const char *key)
29 {
30 struct settings_list_node *new_node;
31 size_t key_size = strlen(key);
32 bool key_already_in = false;
33
34 struct settings_list_node *loop_node;
35
36 if (settings_record_enabled == 1) {
37 k_mutex_lock(&settings_list_mutex, K_FOREVER);
38
39 SYS_SLIST_FOR_EACH_CONTAINER(&settings_list, loop_node, node) {
40 if (strcmp(loop_node->key, key) == 0) {
41 key_already_in = true;
42 }
43 }
44
45 if (!key_already_in) {
46 new_node = k_malloc(sizeof(struct settings_list_node));
47 TEST_ASSERT(new_node != NULL, "Failed to malloc new_node");
48
49 new_node->key = k_malloc(sizeof(char) * key_size);
50 TEST_ASSERT(new_node->key != NULL, "Failed to malloc new_node->key");
51
52 memcpy(new_node->key, key, sizeof(char) * key_size);
53
54 sys_slist_append(&settings_list, &new_node->node);
55 }
56
57 k_mutex_unlock(&settings_list_mutex);
58 }
59 }
60
remove_key(const char * key)61 static void remove_key(const char *key)
62 {
63 struct settings_list_node *loop_node, *prev_loop_node;
64
65 prev_loop_node = NULL;
66
67 if (settings_record_enabled == 1) {
68 k_mutex_lock(&settings_list_mutex, K_FOREVER);
69
70 SYS_SLIST_FOR_EACH_CONTAINER(&settings_list, loop_node, node) {
71 if (strcmp(loop_node->key, key) == 0) {
72 break;
73 }
74
75 prev_loop_node = loop_node;
76 }
77
78 if (loop_node != NULL) {
79 sys_slist_remove(&settings_list, &prev_loop_node->node, &loop_node->node);
80
81 k_free(loop_node->key);
82 k_free(loop_node);
83 }
84
85 k_mutex_unlock(&settings_list_mutex);
86 }
87 }
88
start_settings_record(void)89 void start_settings_record(void)
90 {
91 atomic_set(&settings_record_enabled, 1);
92 }
93
stop_settings_record(void)94 void stop_settings_record(void)
95 {
96 atomic_set(&settings_record_enabled, 0);
97 }
98
settings_list_cleanup(void)99 void settings_list_cleanup(void)
100 {
101 struct settings_list_node *loop_node, *next_loop_node, *prev_loop_node;
102
103 prev_loop_node = NULL;
104
105 k_mutex_lock(&settings_list_mutex, K_FOREVER);
106
107 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&settings_list, loop_node, next_loop_node, node) {
108 sys_slist_remove(&settings_list, &prev_loop_node->node, &loop_node->node);
109
110 k_free(loop_node->key);
111 k_free(loop_node);
112 }
113
114 k_mutex_unlock(&settings_list_mutex);
115 }
116
get_settings_list_size(void)117 int get_settings_list_size(void)
118 {
119 struct settings_list_node *loop_node;
120 int number_of_settings = 0;
121
122 SYS_SLIST_FOR_EACH_CONTAINER(&settings_list, loop_node, node) {
123 LOG_ERR("Setting registered: %s", loop_node->key);
124 number_of_settings += 1;
125 }
126
127 return number_of_settings;
128 }
129
bt_testing_settings_store_hook(const char * key,const void * value,size_t val_len)130 void bt_testing_settings_store_hook(const char *key, const void *value, size_t val_len)
131 {
132 LOG_DBG("Store: %s", key);
133 LOG_HEXDUMP_DBG(value, val_len, "Data:");
134
135 add_key(key);
136 }
137
bt_testing_settings_delete_hook(const char * key)138 void bt_testing_settings_delete_hook(const char *key)
139 {
140 LOG_DBG("Delete: %s", key);
141
142 remove_key(key);
143 }
144