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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
mac_neighbor_table.c
00001 /* 00002 * Copyright (c) 2018-2019, 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/ns_address_internal.h" 00027 #include "platform/topo_trace.h" 00028 00029 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) 00030 { 00031 mac_neighbor_table_t *table_class = ns_dyn_mem_alloc(sizeof(mac_neighbor_table_t) + sizeof(mac_neighbor_table_entry_t) * table_size); 00032 if (!table_class) { 00033 return NULL; 00034 } 00035 memset(table_class, 0, sizeof(mac_neighbor_table_t)); 00036 00037 mac_neighbor_table_entry_t *cur_ptr = &table_class->neighbor_entry_buffer [0]; 00038 table_class->list_total_size = table_size; 00039 table_class->table_user_identifier = user_indentifier; 00040 table_class->user_nud_notify_cb = nud_cb; 00041 table_class->user_remove_notify_cb = remove_cb; 00042 ns_list_init(&table_class->neighbour_list ); 00043 ns_list_init(&table_class->free_list ); 00044 for (uint8_t i = 0; i < table_size; i++) { 00045 memset(cur_ptr, 0, sizeof(mac_neighbor_table_entry_t)); 00046 cur_ptr->index = i; 00047 //Add to list 00048 ns_list_add_to_end(&table_class->free_list , cur_ptr); 00049 cur_ptr++; 00050 } 00051 00052 return table_class; 00053 00054 } 00055 00056 void mac_neighbor_table_delete(mac_neighbor_table_t *table_class) 00057 { 00058 mac_neighbor_table_neighbor_list_clean(table_class); 00059 ns_dyn_mem_free(table_class); 00060 } 00061 00062 static void neighbor_table_class_remove_entry(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *entry) 00063 { 00064 ns_list_remove(&table_class->neighbour_list , entry); 00065 table_class->neighbour_list_size --; 00066 if (entry->nud_active ) { 00067 entry->nud_active = false; 00068 table_class->active_nud_process --; 00069 } 00070 00071 if (table_class->user_remove_notify_cb ) { 00072 table_class->user_remove_notify_cb (entry, table_class->table_user_identifier ); 00073 } 00074 topo_trace(TOPOLOGY_MLE, entry->mac64 , TOPO_REMOVE); 00075 00076 00077 uint8_t index = entry->index ; 00078 memset(entry, 0, sizeof(mac_neighbor_table_entry_t)); 00079 entry->index = index; 00080 ns_list_add_to_end(&table_class->free_list , entry); 00081 } 00082 00083 void mac_neighbor_table_neighbor_list_clean(mac_neighbor_table_t *table_class) 00084 { 00085 if (!table_class) { 00086 return; 00087 } 00088 ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00089 neighbor_table_class_remove_entry(table_class, cur); 00090 } 00091 topo_trace(TOPOLOGY_MLE, NULL, TOPO_CLEAR); 00092 } 00093 00094 00095 void mac_neighbor_table_neighbor_timeout_update(mac_neighbor_table_t *table_class, uint32_t time_update) 00096 { 00097 if (!table_class) { 00098 return; 00099 } 00100 00101 ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00102 00103 if (cur->lifetime > time_update) { 00104 cur->lifetime -= time_update; 00105 if (!table_class->user_nud_notify_cb || table_class->active_nud_process > ACTIVE_NUD_PROCESS_MAX || cur->nud_active || !cur->rx_on_idle) { 00106 continue; 00107 } 00108 00109 if (table_class->user_nud_notify_cb (cur, table_class->table_user_identifier )) { 00110 table_class->active_nud_process ++; 00111 cur->nud_active = true; 00112 } 00113 00114 } else { 00115 neighbor_table_class_remove_entry(table_class, cur); 00116 } 00117 } 00118 } 00119 00120 00121 mac_neighbor_table_entry_t *mac_neighbor_table_entry_allocate(mac_neighbor_table_t *table_class, const uint8_t *mac64) 00122 { 00123 if (!table_class) { 00124 return NULL; 00125 } 00126 mac_neighbor_table_entry_t *entry = ns_list_get_first(&table_class->free_list ); 00127 if (!entry) { 00128 return NULL; 00129 } 00130 //Remove from the list 00131 ns_list_remove(&table_class->free_list , entry); 00132 //Add to list 00133 ns_list_add_to_end(&table_class->neighbour_list , entry); 00134 table_class->neighbour_list_size ++; 00135 memcpy(entry->mac64 , mac64, 8); 00136 entry->mac16 = 0xffff; 00137 entry->rx_on_idle = true; 00138 entry->ffd_device = true; 00139 entry->nud_active = false; 00140 entry->advertisment = false; 00141 entry->connected_device = false; 00142 entry->trusted_device = false; 00143 entry->lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; 00144 entry->link_lifetime = NEIGHBOR_CLASS_LINK_DEFAULT_LIFETIME; 00145 entry->link_role = NORMAL_NEIGHBOUR; 00146 topo_trace(TOPOLOGY_MLE, mac64, TOPO_ADD); 00147 return entry; 00148 } 00149 00150 static mac_neighbor_table_entry_t *neighbor_table_class_entry_validate(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00151 { 00152 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00153 if (cur == neighbor_entry) { 00154 return cur; 00155 } 00156 } 00157 return NULL; 00158 00159 } 00160 00161 void mac_neighbor_table_neighbor_remove(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00162 { 00163 mac_neighbor_table_entry_t *entry = neighbor_table_class_entry_validate(table_class, neighbor_entry); 00164 if (entry) { 00165 neighbor_table_class_remove_entry(table_class, entry); 00166 } 00167 } 00168 00169 00170 void mac_neighbor_table_neighbor_refresh(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, uint32_t life_time) 00171 { 00172 neighbor_entry->lifetime = life_time; 00173 neighbor_entry->link_lifetime = life_time; 00174 if (neighbor_entry->nud_active ) { 00175 neighbor_entry->nud_active = false; 00176 table_class->active_nud_process --; 00177 } 00178 00179 } 00180 00181 void mac_neighbor_table_neighbor_connected(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry) 00182 { 00183 (void)table_class; 00184 neighbor_entry->connected_device = true; 00185 } 00186 00187 void mac_neighbor_table_trusted_neighbor(mac_neighbor_table_t *table_class, mac_neighbor_table_entry_t *neighbor_entry, bool trusted_device) 00188 { 00189 (void)table_class; 00190 if (!neighbor_entry->trusted_device && trusted_device) { 00191 neighbor_entry->lifetime = neighbor_entry->link_lifetime ; 00192 } 00193 neighbor_entry->trusted_device = trusted_device; 00194 } 00195 00196 mac_neighbor_table_entry_t *mac_neighbor_table_address_discover(mac_neighbor_table_t *table_class, const uint8_t *address, uint8_t address_type) 00197 { 00198 if (!table_class) { 00199 return NULL; 00200 } 00201 uint16_t short_address; 00202 if (address_type == ADDR_802_15_4_SHORT ) { 00203 short_address = common_read_16_bit(address); 00204 } else if (address_type == ADDR_802_15_4_LONG ) { 00205 00206 } else { 00207 return NULL; 00208 } 00209 00210 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00211 if (address_type == ADDR_802_15_4_SHORT ) { 00212 if (cur->mac16 != 0xffff && cur->mac16 == short_address) { 00213 return cur; 00214 } 00215 } else { 00216 if (memcmp(cur->mac64, address, 8) == 0) { 00217 return cur; 00218 } 00219 } 00220 } 00221 00222 return NULL; 00223 } 00224 00225 mac_neighbor_table_entry_t *mac_neighbor_table_attribute_discover(mac_neighbor_table_t *table_class, uint8_t index) 00226 { 00227 ns_list_foreach(mac_neighbor_table_entry_t, cur, &table_class->neighbour_list ) { 00228 00229 if (cur->index == index) { 00230 return cur; 00231 } 00232 } 00233 return NULL; 00234 } 00235 00236 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) 00237 { 00238 // Check it really is LL64 (not LL16) 00239 if (memcmp(ipv6Address, ADDR_LINK_LOCAL_PREFIX, 8) != 0) { 00240 return NULL; //Mot Link Local Address 00241 } 00242 00243 if (memcmp((ipv6Address + 8), ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 00244 return NULL; 00245 } 00246 // map 00247 uint8_t temporary_mac64[8]; 00248 memcpy(temporary_mac64, (ipv6Address + 8), 8); 00249 temporary_mac64[0] ^= 2; 00250 00251 return mac_neighbor_entry_get_by_mac64(table_class, temporary_mac64, allocateNew, new_entry_allocated); 00252 00253 } 00254 00255 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) 00256 { 00257 mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(table_class, mac64, ADDR_802_15_4_LONG ); 00258 if (entry || !allocateNew) { 00259 if (new_entry_allocated) { 00260 *new_entry_allocated = false; 00261 } 00262 return entry; 00263 } 00264 00265 if (new_entry_allocated) { 00266 *new_entry_allocated = true; 00267 } 00268 00269 return mac_neighbor_table_entry_allocate(table_class, mac64); 00270 } 00271 00272 mac_neighbor_table_entry_t *mac_neighbor_entry_get_priority(mac_neighbor_table_t *table_class) 00273 { 00274 00275 ns_list_foreach(mac_neighbor_table_entry_t, entry, &table_class->neighbour_list ) { 00276 if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR) { 00277 return entry; 00278 } 00279 } 00280 return NULL; 00281 }
Generated on Tue Jul 12 2022 13:54:31 by
