41 #include "net/nbr-table.h"
44 typedef struct nbr_table_key {
45 struct nbr_table_key *next;
51 static uint8_t used_map[NBR_TABLE_MAX_NEIGHBORS];
53 static uint8_t locked_map[NBR_TABLE_MAX_NEIGHBORS];
55 #define MAX_NUM_TABLES 8
57 static struct nbr_table *all_tables[MAX_NUM_TABLES];
59 static unsigned num_tables;
62 MEMB(neighbor_addr_mem, nbr_table_key_t, NBR_TABLE_MAX_NEIGHBORS);
67 static nbr_table_key_t *
68 key_from_index(
int index)
70 return index != -1 ? &((nbr_table_key_t *)neighbor_addr_mem.mem)[index] :
NULL;
74 static nbr_table_item_t *
75 item_from_index(nbr_table_t *table,
int index)
77 return table !=
NULL && index != -1 ? (
char *)table->data + index * table->item_size :
NULL;
82 index_from_key(nbr_table_key_t *key)
84 return key !=
NULL ? key - (nbr_table_key_t *)neighbor_addr_mem.mem : -1;
89 index_from_item(nbr_table_t *table,
const nbr_table_item_t *item)
91 return table !=
NULL && item !=
NULL ? ((int)((
char *)item - (
char *)table->data)) / table->item_size : -1;
95 static nbr_table_item_t *
96 item_from_key(nbr_table_t *table, nbr_table_key_t *key)
98 return item_from_index(table, index_from_key(key));
102 static nbr_table_key_t *
103 key_from_item(nbr_table_t *table,
const nbr_table_item_t *item)
105 return key_from_index(index_from_item(table, item));
110 index_from_lladdr(
const linkaddr_t *lladdr)
112 nbr_table_key_t *key;
121 return index_from_key(key);
130 nbr_get_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item)
132 int item_index = index_from_item(table, item);
133 if(table !=
NULL && item_index != -1) {
134 return (bitmap[item_index] & (1 << table->index)) != 0;
143 nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item,
int value)
145 int item_index = index_from_item(table, item);
146 if(table !=
NULL && item_index != -1) {
148 bitmap[item_index] |= 1 << table->index;
150 bitmap[item_index] &= ~(1 << table->index);
159 static nbr_table_key_t *
160 nbr_table_allocate(
void)
162 nbr_table_key_t *key;
163 int least_used_count = 0;
164 nbr_table_key_t *least_used_key =
NULL;
178 int item_index = index_from_key(key);
179 int locked = locked_map[item_index];
182 int used = used_map[item_index];
186 if((used & 1) == 1) {
192 if(least_used_key ==
NULL || used_count < least_used_count) {
193 least_used_key = key;
194 least_used_count = used_count;
195 if(used_count == 0) {
202 if(least_used_key ==
NULL) {
208 for(i = 0; i<MAX_NUM_TABLES; i++) {
209 if(all_tables[i] !=
NULL && all_tables[i]->callback !=
NULL) {
211 nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
212 if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
213 all_tables[i]->callback(removed_item);
218 used_map[index_from_key(least_used_key)] = 0;
222 return least_used_key;
230 nbr_table_register(nbr_table_t *table, nbr_table_callback *callback)
232 if(num_tables < MAX_NUM_TABLES) {
233 table->index = num_tables++;
234 table->callback = callback;
235 all_tables[table->index] = table;
245 nbr_table_head(nbr_table_t *table)
248 nbr_table_item_t *item = item_from_key(table,
list_head(nbr_table_keys));
250 if(nbr_get_bit(used_map, table, item)) {
253 return nbr_table_next(table, item);
259 nbr_table_next(nbr_table_t *table, nbr_table_item_t *item)
262 void *key = key_from_item(table, item);
265 item = item_from_key(table, key);
266 }
while(item && !nbr_get_bit(used_map, table, item));
272 nbr_table_add_lladdr(nbr_table_t *table,
const linkaddr_t *lladdr)
275 nbr_table_item_t *item;
276 nbr_table_key_t *key;
284 if((index = index_from_lladdr(lladdr)) == -1) {
286 key = nbr_table_allocate();
297 index = index_from_key(key);
304 item = item_from_index(table, index);
307 memset(item, 0, table->item_size);
308 nbr_set_bit(used_map, table, item, 1);
315 nbr_table_get_from_lladdr(nbr_table_t *table,
const linkaddr_t *lladdr)
317 void *item = item_from_index(table, index_from_lladdr(lladdr));
318 return nbr_get_bit(used_map, table, item) ? item :
NULL;
323 nbr_table_remove(nbr_table_t *table,
void *item)
325 int ret = nbr_set_bit(used_map, table, item, 0);
326 nbr_set_bit(locked_map, table, item, 0);
332 nbr_table_lock(nbr_table_t *table,
void *item)
334 return nbr_set_bit(locked_map, table, item, 1);
339 nbr_table_unlock(nbr_table_t *table,
void *item)
341 return nbr_set_bit(locked_map, table, item, 0);
346 nbr_table_get_lladdr(nbr_table_t *table,
const void *item)
348 nbr_table_key_t *key = key_from_item(table, item);
349 return key !=
NULL ? &key->lladdr :
NULL;