1 /*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "btstack_link_key_db_memory.c"
39
40 #include <string.h>
41 #include <stdlib.h>
42
43 #include "classic/btstack_link_key_db_memory.h"
44
45 #include "btstack_debug.h"
46 #include "btstack_linked_list.h"
47 #include "btstack_memory.h"
48 #include "btstack_util.h"
49 #include "classic/core.h"
50
51 // This list should be directly accessed only by tests
52 btstack_linked_list_t db_mem_link_keys = NULL;
53
54 // Device info
db_open(void)55 static void db_open(void){
56 }
57
db_set_local_bd_addr(bd_addr_t bd_addr)58 static void db_set_local_bd_addr(bd_addr_t bd_addr){
59 (void)bd_addr;
60 }
61
db_close(void)62 static void db_close(void){
63 }
64
get_item(btstack_linked_list_t list,bd_addr_t bd_addr)65 static btstack_link_key_db_memory_entry_t * get_item(btstack_linked_list_t list, bd_addr_t bd_addr) {
66 btstack_linked_item_t *it;
67 for (it = (btstack_linked_item_t *) list; it ; it = it->next){
68 btstack_link_key_db_memory_entry_t * item = (btstack_link_key_db_memory_entry_t *) it;
69 if (bd_addr_cmp(item->bd_addr, bd_addr) == 0) {
70 return item;
71 }
72 }
73 return NULL;
74 }
75
get_link_key(bd_addr_t bd_addr,link_key_t link_key,link_key_type_t * link_key_type)76 static int get_link_key(bd_addr_t bd_addr, link_key_t link_key, link_key_type_t * link_key_type) {
77 btstack_link_key_db_memory_entry_t * item = get_item(db_mem_link_keys, bd_addr);
78
79 if (!item) return 0;
80
81 (void)memcpy(link_key, item->link_key, LINK_KEY_LEN);
82 if (link_key_type) {
83 *link_key_type = item->link_key_type;
84 }
85 btstack_linked_list_remove(&db_mem_link_keys, (btstack_linked_item_t *) item);
86 btstack_linked_list_add(&db_mem_link_keys, (btstack_linked_item_t *) item);
87
88 return 1;
89 }
90
delete_link_key(bd_addr_t bd_addr)91 static void delete_link_key(bd_addr_t bd_addr){
92 btstack_link_key_db_memory_entry_t * item = get_item(db_mem_link_keys, bd_addr);
93
94 if (!item) return;
95
96 btstack_linked_list_remove(&db_mem_link_keys, (btstack_linked_item_t *) item);
97 btstack_memory_btstack_link_key_db_memory_entry_free((btstack_link_key_db_memory_entry_t*)item);
98 }
99
100
put_link_key(bd_addr_t bd_addr,link_key_t link_key,link_key_type_t link_key_type)101 static void put_link_key(bd_addr_t bd_addr, link_key_t link_key, link_key_type_t link_key_type){
102
103 // check for existing record and remove if found
104 btstack_link_key_db_memory_entry_t * record = get_item(db_mem_link_keys, bd_addr);
105 if (record){
106 btstack_linked_list_remove(&db_mem_link_keys, (btstack_linked_item_t*) record);
107 }
108
109 // record not found, get new one from memory pool
110 if (!record) {
111 record = btstack_memory_btstack_link_key_db_memory_entry_get();
112 }
113
114 // if none left, re-use last item and remove from list
115 if (!record){
116 record = (btstack_link_key_db_memory_entry_t*) btstack_linked_list_get_last_item(&db_mem_link_keys);
117 if (record) {
118 btstack_linked_list_remove(&db_mem_link_keys, (btstack_linked_item_t*) record);
119 }
120 }
121
122 if (!record) return;
123
124 (void)memcpy(record->bd_addr, bd_addr, sizeof(bd_addr_t));
125 (void)memcpy(record->link_key, link_key, LINK_KEY_LEN);
126 record->link_key_type = link_key_type;
127 btstack_linked_list_add(&db_mem_link_keys, (btstack_linked_item_t *) record);
128 }
129
iterator_init(btstack_link_key_iterator_t * it)130 static int iterator_init(btstack_link_key_iterator_t * it){
131 it->context = (void*) db_mem_link_keys;
132 return 1;
133 }
134
iterator_get_next(btstack_link_key_iterator_t * it,bd_addr_t bd_addr,link_key_t link_key,link_key_type_t * link_key_type)135 static int iterator_get_next(btstack_link_key_iterator_t * it, bd_addr_t bd_addr, link_key_t link_key, link_key_type_t * link_key_type){
136 btstack_link_key_db_memory_entry_t *item = (btstack_link_key_db_memory_entry_t *) it->context;
137 if (item == NULL) return 0;
138
139 // fetch values
140 (void)memcpy(bd_addr, item->bd_addr, 6);
141 (void)memcpy(link_key, item->link_key, 16);
142 *link_key_type = item->link_key_type;
143
144 // next
145 it->context = (void *) item->item.next;
146
147 return 1;
148 }
149
iterator_done(btstack_link_key_iterator_t * it)150 static void iterator_done(btstack_link_key_iterator_t * it){
151 UNUSED(it);
152 }
153
154 const btstack_link_key_db_t btstack_link_key_db_memory = {
155 db_open,
156 db_set_local_bd_addr,
157 db_close,
158 get_link_key,
159 put_link_key,
160 delete_link_key,
161 iterator_init,
162 iterator_get_next,
163 iterator_done,
164 };
165
btstack_link_key_db_memory_instance(void)166 const btstack_link_key_db_t * btstack_link_key_db_memory_instance(void){
167 return &btstack_link_key_db_memory;
168 }
169
170
171