Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mac_neighbor_table.c
00001 /* 00002 * Copyright (c) 2018, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 00019 #include "nsconfig.h" 00020 #include "string.h" 00021 #include "ns_types.h" 00022 #include "ns_trace.h" 00023 #include "common_functions.h" 00024 #include "nsdynmemLIB.h" 00025 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00026 #include "Core/include/address.h" 00027 #include "platform/topo_trace.h" 00028 00029 #define TRACE_GROUP "mnei" 00030 00031 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) 00032 { 00033 mac_neighbor_table_t *table_class = ns_dyn_mem_alloc(sizeof(mac_neighbor_table_t) + sizeof(mac_neighbor_table_entry_t) * table_size); 00034 if (!table_class) { 00035 return NULL; 00036 } 00037 memset(table_class, 0, sizeof(mac_neighbor_table_t)); 00038 00039 mac_neighbor_table_entry_t *cur_ptr = &table_class->neighbor_entry_buffer [0]; 00040 table_class->list_total_size = table_size; 00041 table_class->table_user_identifier = user_indentifier; 00042 table_class->user_nud_notify_cb = nud_cb; 00043 table_class->user_remove_notify_cb = remove_cb; 00044 ns_list_init(&table_class->neighbour_list ); 00045 ns_list_init(&table_class->free_list ); 00046 for (uint8_t i = 0; i< table_size; i++) { 00047 memset(cur_ptr, 0, sizeof(mac_neighbor_table_entry_t)); 00048 cur_ptr->index = i; 00049 //Add to list 00050 ns_list_add_to_end(&table_class->free_list ,cur_ptr); 00051 cur_ptr++; 00052 } 00053 00054 return table_class; 00055 00056 } 00057 00058 void mac_neighbor_table_delete(mac_neighbor_table_t *table_class) 00059 { 00060 mac_neighbor_table_neighbor_list_clean(table_class); 00061 ns_dyn_mem_free(table_class); 00062 } 00063 00064 static void neighbor_table_class_remove_entry(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *entry) 00065 { 00066 ns_list_remove(&table_class->neighbour_list , entry); 00067 table_class->neighbour_list_size --; 00068 if (entry->nud_active ) { 00069 entry->nud_active = false; 00070 table_class->active_nud_process --; 00071 } 00072 00073 if (table_class->user_remove_notify_cb ) { 00074 table_class->user_remove_notify_cb (entry, table_class->table_user_identifier ); 00075 } 00076 topo_trace(TOPOLOGY_MLE, entry->mac64 , TOPO_REMOVE); 00077 00078 00079 uint8_t index = entry->index ; 00080 memset(entry, 0, sizeof(mac_neighbor_table_entry_t)); 00081 entry->index = index; 00082 ns_list_add_to_end(&table_class->free_list ,entry); 00083 } 00084 00085 void mac_neighbor_table_neighbor_list_clean(mac_neighbor_table_t *table_class) 00086 { 00087 if (!table_class) { 00088 return; 00089 } 00090 ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00091 neighbor_table_class_remove_entry(table_class, cur); 00092 } 00093 topo_trace(TOPOLOGY_MLE, NULL, TOPO_CLEAR); 00094 } 00095 00096 00097 void mac_neighbor_table_neighbor_timeout_update(mac_neighbor_table_t *table_class, uint32_t time_update) 00098 { 00099 if (!table_class) { 00100 return; 00101 } 00102 00103 ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00104 00105 if (cur->lifetime > time_update) { 00106 cur->lifetime -= time_update; 00107 if (!table_class->user_nud_notify_cb || table_class->active_nud_process > ACTIVE_NUD_PROCESS_MAX || cur->nud_active || !cur->rx_on_idle) { 00108 continue; 00109 } 00110 00111 if (table_class->user_nud_notify_cb (cur, table_class->table_user_identifier )) { 00112 table_class->active_nud_process ++; 00113 cur->nud_active = true; 00114 tr_debug("Nud started index %u : %"PRIu32" time ", cur->index, cur->lifetime); 00115 } 00116 00117 } else { 00118 tr_debug("Node index %u time out ", cur->index); 00119 neighbor_table_class_remove_entry(table_class, cur); 00120 } 00121 } 00122 } 00123 00124 00125 mac_neighbor_table_entry_t *mac_neighbor_table_entry_allocate(mac_neighbor_table_t *table_class, const uint8_t *mac64) 00126 { 00127 if (!table_class) { 00128 return NULL; 00129 } 00130 mac_neighbor_table_entry_t *entry = ns_list_get_first(&table_class->free_list ); 00131 if (!entry) { 00132 return NULL; 00133 } 00134 //Remove from the list 00135 ns_list_remove(&table_class->free_list , entry); 00136 //Add to list 00137 ns_list_add_to_end(&table_class->neighbour_list ,entry); 00138 table_class->neighbour_list_size ++; 00139 memcpy(entry->mac64 , mac64, 8); 00140 entry->mac16 = 0xffff; 00141 entry->rx_on_idle = true; 00142 entry->ffd_device = true; 00143 entry->nud_active = false; 00144 entry->advertisment = false; 00145 entry->connected_device = false; 00146 entry->trusted_device = false; 00147 entry->lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; 00148 entry->link_lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; 00149 entry->link_role = NORMAL_NEIGHBOUR; 00150 topo_trace(TOPOLOGY_MLE, mac64, TOPO_ADD); 00151 return entry; 00152 } 00153 00154 static mac_neighbor_table_entry_t *neighbor_table_class_entry_validate(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00155 { 00156 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00157 if (cur == neighbor_entry) { 00158 return cur; 00159 } 00160 } 00161 return NULL; 00162 00163 } 00164 00165 void mac_neighbor_table_neighbor_remove(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00166 { 00167 mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry); 00168 if (entry) { 00169 neighbor_table_class_remove_entry(table_class, entry); 00170 } 00171 } 00172 00173 00174 void mac_neighbor_table_neighbor_refresh(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, uint32_t life_time) 00175 { 00176 neighbor_entry->lifetime = life_time; 00177 neighbor_entry->link_lifetime = life_time; 00178 if (neighbor_entry->nud_active ) { 00179 tr_debug("Node index NUD response %u : %"PRIu32" time ", neighbor_entry->index , neighbor_entry->lifetime ); 00180 neighbor_entry->nud_active = false; 00181 table_class->active_nud_process --; 00182 } 00183 00184 } 00185 00186 void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00187 { 00188 (void)table_class; 00189 neighbor_entry->connected_device = true; 00190 } 00191 00192 void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device) 00193 { 00194 (void)table_class; 00195 neighbor_entry->trusted_device = trusted_device; 00196 } 00197 00198 mac_neighbor_table_entry_t *mac_neighbor_table_address_discover(mac_neighbor_table_t *table_class, const uint8_t *address, uint8_t address_type) 00199 { 00200 if (!table_class) { 00201 return NULL; 00202 } 00203 uint16_t short_address; 00204 if (address_type == ADDR_802_15_4_SHORT ) { 00205 short_address = common_read_16_bit(address); 00206 } else if (address_type == ADDR_802_15_4_LONG ) { 00207 00208 } else { 00209 return NULL; 00210 } 00211 00212 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00213 if (address_type == ADDR_802_15_4_SHORT ) { 00214 if (cur->mac16 != 0xffff && cur->mac16 == short_address) { 00215 return cur; 00216 } 00217 } else { 00218 if (memcmp(cur->mac64, address, 8) == 0) { 00219 return cur; 00220 } 00221 } 00222 } 00223 00224 return NULL; 00225 } 00226 00227 mac_neighbor_table_entry_t *mac_neighbor_table_attribute_discover(mac_neighbor_table_t *table_class, uint8_t index) 00228 { 00229 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00230 00231 if (cur->index == index) { 00232 return cur; 00233 } 00234 } 00235 return NULL; 00236 } 00237 00238 mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_ll64(mac_neighbor_table_t *table_class, const uint8_t *ipv6Address, bool allocateNew, bool *new_entry_allocated) 00239 { 00240 // Check it really is LL64 (not LL16) 00241 if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX , 8) != 0) { 00242 return NULL; //Mot Link Local Address 00243 } 00244 00245 if (memcmp((ipv6Address + 8), ADDR_SHORT_ADR_SUFFIC , 6) == 0) { 00246 return NULL; 00247 } 00248 // map 00249 uint8_t temporary_mac64[8]; 00250 memcpy(temporary_mac64, (ipv6Address + 8), 8); 00251 temporary_mac64[0] ^= 2; 00252 00253 return mac_neighbor_entry_get_by_mac64(table_class, temporary_mac64, allocateNew, new_entry_allocated); 00254 00255 } 00256 00257 mac_neighbor_table_entry_t *mac_neighbor_entry_get_by_mac64(mac_neighbor_table_t *table_class, const uint8_t *mac64, bool allocateNew, bool *new_entry_allocated) 00258 { 00259 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(table_class, mac64, ADDR_802_15_4_LONG ); 00260 if (entry || !allocateNew) { 00261 if (new_entry_allocated) { 00262 *new_entry_allocated = false; 00263 } 00264 return entry; 00265 } 00266 00267 if (new_entry_allocated) { 00268 *new_entry_allocated = true; 00269 } 00270 00271 return mac_neighbor_table_entry_allocate(table_class, mac64); 00272 } 00273 00274
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2