Skip to content

Commit fc4c97b

Browse files
Juha Heiskanenjuhhei01
authored andcommitted
Generic mesh neighbor table class.
This class will remove MLE protocol based neighbor table.
1 parent 4b81978 commit fc4c97b

File tree

3 files changed

+422
-0
lines changed

3 files changed

+422
-0
lines changed
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
* Copyright (c) 2018, Arm Limited and affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
19+
#include "nsconfig.h"
20+
#include "string.h"
21+
#include "ns_types.h"
22+
#include "ns_trace.h"
23+
#include "common_functions.h"
24+
#include "nsdynmemLIB.h"
25+
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
26+
27+
mac_neighbor_table_t *mac_neighbor_table_create(uint8_t table_size, neighbor_entry_remove_notify *remove_cb, neighbor_entry_nud_notify *nud_cb, void *user_indentifier, uint32_t nud_threshold)
28+
{
29+
mac_neighbor_table_t *table_class = ns_dyn_mem_alloc(sizeof(mac_neighbor_table_t) + sizeof(mac_neighbor_table_entry_t) * table_size);
30+
if (!table_class) {
31+
return NULL;
32+
}
33+
memset(table_class, 0, sizeof(mac_neighbor_table_t));
34+
35+
mac_neighbor_table_entry_t *cur_ptr = &table_class->neighbor_entry_buffer[0];
36+
table_class->list_total_size = table_size;
37+
table_class->nud_threshold = nud_threshold;
38+
table_class->table_user_identifier = user_indentifier;
39+
table_class->user_nud_notify_cb = nud_cb;
40+
table_class->user_remove_notify_cb = remove_cb;
41+
ns_list_init(&table_class->neighbour_list);
42+
ns_list_init(&table_class->free_list);
43+
for (uint8_t i = 0; i< table_size; i++) {
44+
memset(cur_ptr, 0, sizeof(mac_neighbor_table_entry_t));
45+
cur_ptr->index = i;
46+
//Add to list
47+
ns_list_add_to_end(&table_class->free_list,cur_ptr);
48+
cur_ptr++;
49+
}
50+
51+
return table_class;
52+
53+
}
54+
55+
void mac_neighbor_table_delete(mac_neighbor_table_t *table_class)
56+
{
57+
ns_dyn_mem_free(table_class);
58+
}
59+
60+
static void neighbor_table_class_remove_entry(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *entry)
61+
{
62+
ns_list_remove(&table_class->neighbour_list, entry);
63+
table_class->neighbour_list_size--;
64+
if (entry->nud_active) {
65+
entry->nud_active = false;
66+
table_class->active_nud_process--;
67+
}
68+
69+
if (table_class->user_remove_notify_cb) {
70+
table_class->user_remove_notify_cb(entry, table_class->table_user_identifier);
71+
}
72+
73+
74+
uint8_t index = entry->index;
75+
memset(entry, 0, sizeof(mac_neighbor_table_entry_t));
76+
entry->index = index;
77+
ns_list_add_to_end(&table_class->free_list,entry);
78+
}
79+
80+
void mac_neighbor_table_neighbor_list_clean(mac_neighbor_table_t *table_class)
81+
{
82+
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) {
83+
neighbor_table_class_remove_entry(table_class, cur);
84+
}
85+
}
86+
87+
88+
void mac_neighbor_table_neighbor_timeout_update(mac_neighbor_table_t *table_class, uint32_t time_update)
89+
{
90+
bool nud_is_enabled = false;
91+
if (table_class->nud_threshold && table_class->user_nud_notify_cb) {
92+
nud_is_enabled = true;
93+
}
94+
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) {
95+
96+
if (cur->lifetime > time_update) {
97+
cur->lifetime -= time_update;
98+
if (!nud_is_enabled || cur->nud_active || !cur->rx_on_idle) {
99+
continue;
100+
}
101+
102+
uint32_t time_from_start = cur->link_lifetime - cur->lifetime;
103+
bool activate_nud = false;
104+
if ((table_class->nud_threshold > cur->link_lifetime) && (time_from_start > cur->link_lifetime / 2)) {
105+
//Trig allways at middle way
106+
activate_nud = true;
107+
} else if (time_from_start > table_class->nud_threshold) {
108+
activate_nud = true;
109+
}
110+
111+
if (activate_nud) {
112+
if (table_class->user_nud_notify_cb(cur, table_class->table_user_identifier)) {
113+
table_class->active_nud_process++;
114+
cur->nud_active = true;
115+
}
116+
}
117+
118+
} else {
119+
neighbor_table_class_remove_entry(table_class, cur);
120+
}
121+
}
122+
}
123+
124+
125+
mac_neighbor_table_entry_t *mac_neighbor_table_entry_allocate(mac_neighbor_table_t *table_class, const uint8_t *mac64)
126+
{
127+
mac_neighbor_table_entry_t *entry = ns_list_get_first(&table_class->free_list);
128+
if (!entry) {
129+
return NULL;
130+
}
131+
//Remove from the list
132+
ns_list_remove(&table_class->free_list, entry);
133+
//Add to list
134+
ns_list_add_to_end(&table_class->neighbour_list,entry);
135+
table_class->neighbour_list_size++;
136+
memcpy(entry->mac64, mac64, 8);
137+
entry->mac16 = 0xffff;
138+
entry->rx_on_idle = true;
139+
entry->ffd_device = true;
140+
entry->lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME;
141+
entry->link_lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME;
142+
return entry;
143+
}
144+
145+
static mac_neighbor_table_entry_t *neighbor_table_class_entry_validate(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry)
146+
{
147+
ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) {
148+
if (cur == neighbor_entry) {
149+
return cur;
150+
}
151+
}
152+
return NULL;
153+
154+
}
155+
156+
void mac_neighbor_table_neighbor_remove(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry)
157+
{
158+
mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry);
159+
if (entry) {
160+
neighbor_table_class_remove_entry(table_class, entry);
161+
}
162+
}
163+
164+
165+
void mac_neighbor_table_neighbor_refresh(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, uint32_t life_time)
166+
{
167+
mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry);
168+
if (entry) {
169+
entry->lifetime = life_time;
170+
entry->link_lifetime = life_time;
171+
if (entry->nud_active) {
172+
entry->nud_active = false;
173+
table_class->active_nud_process--;
174+
}
175+
}
176+
}
177+
178+
void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry)
179+
{
180+
mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry);
181+
if (entry) {
182+
entry->connected_device = true;
183+
}
184+
}
185+
186+
void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device)
187+
{
188+
mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry);
189+
if (entry) {
190+
entry->trusted_device = trusted_device;
191+
}
192+
}
193+
194+
195+
mac_neighbor_table_entry_t *mac_neighbor_table_address_discover(mac_neighbor_table_t *table_class, const uint8_t *address, uint8_t address_type)
196+
{
197+
uint16_t short_address;
198+
if (address_type == 2) {
199+
short_address = common_read_16_bit(address);
200+
} else if (address_type == 3) {
201+
202+
} else {
203+
return NULL;
204+
}
205+
206+
ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) {
207+
if (address_type == 2) {
208+
if (cur->mac16 != 0xffff && cur->mac16 == short_address) {
209+
return cur;
210+
}
211+
} else {
212+
if (memcmp(cur->mac64, address, 8) == 0) {
213+
return cur;
214+
}
215+
}
216+
}
217+
218+
return NULL;
219+
}
220+
221+
mac_neighbor_table_entry_t *mac_neighbor_table_attribute_discover(mac_neighbor_table_t *table_class, uint8_t index)
222+
{
223+
ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list) {
224+
225+
if (cur->index == index) {
226+
return cur;
227+
}
228+
}
229+
return NULL;
230+
}

0 commit comments

Comments
 (0)