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.
protocol_core.c
00001 /* 00002 * Copyright (c) 2014-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 #include "nsconfig.h" 00019 #include "string.h" 00020 #include "ns_types.h" 00021 #include "eventOS_event.h" 00022 #include "eventOS_scheduler.h" 00023 #include "eventOS_callback_timer.h" 00024 #include "ns_trace.h" 00025 #include "nsdynmemLIB.h" 00026 #include "Core/include/socket.h" 00027 #include "NWK_INTERFACE/Include/protocol.h" 00028 #include "NWK_INTERFACE/Include/protocol_timer.h" 00029 #include "platform/arm_hal_interrupt.h" 00030 #ifndef NO_MLE 00031 #include "MLE/mle.h" 00032 #endif 00033 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00034 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00035 #include "6LoWPAN/Bootstraps/network_lib.h" 00036 #include "NWK_INTERFACE/Include/protocol_stats.h" 00037 #include "NWK_INTERFACE/Include/protocol_timer.h" 00038 #include "common_functions.h" 00039 #include "randLIB.h" 00040 #include "platform/arm_hal_phy.h" 00041 #include "platform/arm_hal_interrupt.h" 00042 #ifdef ECC 00043 #include "libX509_V3.h" 00044 #include "ecc.h" 00045 #endif 00046 #include "shalib.h" 00047 #include "Security/TLS/tls_lib.h" 00048 #include "Security/Common/sec_lib.h" 00049 #include "net_nvm_api.h" 00050 #include "net_pana_parameters_api.h" 00051 #include "Security/PANA/pana.h" 00052 #include "Security/PANA/pana_internal_api.h" 00053 #include "Common_Protocols/ipv6.h" 00054 #include "Common_Protocols/ipv6_fragmentation.h" 00055 #include "Common_Protocols/icmpv6_radv.h" 00056 #include "Common_Protocols/icmpv6.h" 00057 #include "Common_Protocols/mld.h" 00058 #include "Common_Protocols/udp.h" 00059 #include "6LoWPAN/ND/nd_router_object.h" 00060 #include "MPL/mpl.h" 00061 #include "RPL/rpl_control.h" 00062 #include "libDHCPv6/libDHCPv6.h" 00063 #include "6LoWPAN/Thread/thread_common.h" 00064 #include "6LoWPAN/Thread/thread_bootstrap.h" 00065 #include "6LoWPAN/Thread/thread_routing.h" 00066 #include "6LoWPAN/Thread/thread_management_internal.h" 00067 #include "6LoWPAN/ws/ws_bootstrap.h" 00068 #include "6LoWPAN/ws/ws_common.h" 00069 #include "ipv6_stack/protocol_ipv6.h" 00070 #include "Service_Libs/whiteboard/whiteboard.h" 00071 00072 #include "6LoWPAN/MAC/beacon_handler.h" 00073 #include "6LoWPAN/MAC/mac_helper.h" 00074 #include "6LoWPAN/MAC/mac_response_handler.h" 00075 #include "6LoWPAN/MAC/mac_data_poll.h" 00076 #include "6LoWPAN/NVM/nwk_nvm.h" 00077 #include "6LoWPAN/lowpan_adaptation_interface.h" 00078 #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" 00079 #include "Service_Libs/load_balance/load_balance_api.h" 00080 #include "Service_Libs/pan_blacklist/pan_blacklist_api.h" 00081 00082 #include "mac_api.h" 00083 #include "ethernet_mac_api.h" 00084 00085 #define TRACE_GROUP_CORE "core" 00086 00087 #define TRACE_GROUP "core" 00088 00089 #ifndef SEC_LIB_X_100MS_COUNTER 00090 #define SEC_LIB_X_100MS_COUNTER 1 //Default scaller is 100ms tick 00091 #endif 00092 00093 // RFC 4861 says we only have to reroll ReachableTime every couple of hours, but 00094 // to make sure the code is regularly exercised, let's make it 10 minutes. 00095 #define REACHABLE_TIME_UPDATE_SECONDS 600 00096 00097 /** Quick monotonic time for simple timestamp comparisons; 100ms ticks. 00098 * This can of course wrap, so to handle this correctly comparisons must be 00099 * expressed like: 00100 * 00101 * "if (time_now - time_then < 200)" 00102 * NOT 00103 * "if (time_now < time_then + 200)" 00104 */ 00105 uint32_t protocol_core_monotonic_time; 00106 static int8_t protocol_root_tasklet_ID = -1; 00107 00108 int protocol_core_buffers_in_event_queue; 00109 00110 protocol_interface_info_entry_t *protocol_core_multicast_upstream; 00111 00112 typedef struct { 00113 uint8_t core_timer_ticks; 00114 bool core_timer_event; 00115 uint16_t core_security_ticks_counter; 00116 } lowpan_core_timer_structures_s; 00117 00118 protocol_interface_list_t NS_LIST_NAME_INIT(protocol_interface_info_list); 00119 00120 static lowpan_core_timer_structures_s protocol_core_timer_info; 00121 00122 /** Cores Power Save Varibale whic indicate States */ 00123 volatile uint8_t power_save_state = 0; 00124 00125 void core_timer_event_handle(uint16_t ticksUpdate); 00126 static void protocol_buffer_poll(buffer_t *b); 00127 00128 static int8_t net_interface_get_free_id(void); 00129 00130 static void nwk_net_event_post(arm_nwk_interface_status_type_e posted_event, int8_t net_tasklet, int8_t nwk_id); 00131 00132 static uint16_t protocol_core_seconds_timer = 10; 00133 00134 int8_t protocol_read_tasklet_id(void) 00135 { 00136 return protocol_root_tasklet_ID; 00137 } 00138 00139 uint8_t check_power_state(uint8_t mode) 00140 { 00141 uint8_t ret_val = power_save_state & mode; 00142 return ret_val; 00143 } 00144 00145 00146 void set_power_state(uint8_t mode) 00147 { 00148 power_save_state |= mode; 00149 } 00150 00151 void clear_power_state(uint8_t mode) 00152 { 00153 power_save_state &= ~mode; 00154 } 00155 00156 void arm_net_protocol_packet_handler(buffer_t *buf, protocol_interface_info_entry_t *cur_interface) 00157 { 00158 if (cur_interface->if_stack_buffer_handler) { 00159 cur_interface->if_stack_buffer_handler(buf); 00160 //buf = 0; 00161 } else { 00162 buffer_free(buf); 00163 } 00164 } 00165 00166 void protocol_root_tasklet(arm_event_t *event) 00167 { 00168 arm_internal_event_type_e event_type; 00169 event_type = (arm_internal_event_type_e)event->event_type; 00170 00171 switch (event_type) { 00172 case ARM_LIB_TASKLET_INIT_EVENT: 00173 tr_debug("NS Root task Init"); 00174 break; 00175 00176 case ARM_IN_PROTOCOL_TIMER_EVENT: { 00177 uint16_t tick_update = (uint16_t)event->event_data; 00178 /* This event is delivered as "user-allocated", so finish reading 00179 * before "freeing" */ 00180 protocol_timer_event_lock_free(); 00181 protocol_timer_cb(tick_update); 00182 break; 00183 } 00184 case ARM_IN_INTERFACE_BOOTSTRAP_CB: 00185 net_bootsrap_cb_run(event->event_id); 00186 break; 00187 case ARM_IN_INTERFACE_CORE_TIMER_CB: 00188 /* This event is delivered as "user-allocated", so finish reading 00189 * before "freeing" */ 00190 core_timer_event_handle((uint16_t)event->event_data); 00191 break; 00192 case ARM_IN_INTERFACE_PROTOCOL_HANDLE: { 00193 buffer_t *buf = event->data_ptr; 00194 protocol_buffer_poll(buf); 00195 break; 00196 } 00197 case ARM_IN_SECURITY_ECC_CALLER: 00198 sec_ecc_sceduler(); 00199 break; 00200 default: 00201 break; 00202 } 00203 } 00204 void protocol_core_security_tick_update(uint16_t tick_update) 00205 { 00206 if (protocol_core_timer_info.core_security_ticks_counter <= tick_update) { 00207 sec_timer_handle(); 00208 protocol_core_timer_info.core_security_ticks_counter = SEC_LIB_X_100MS_COUNTER; 00209 } 00210 } 00211 00212 static void nwk_bootsrap_timer(protocol_interface_info_entry_t *cur) 00213 { 00214 if (cur->bootsrap_state_machine_cnt) { 00215 if (cur->bootsrap_state_machine_cnt-- == 1) { 00216 arm_event_s event = { 00217 .receiver = protocol_root_tasklet_ID, 00218 .sender = 0, 00219 .event_id = (uint8_t)cur->id, 00220 .event_type = ARM_IN_INTERFACE_BOOTSTRAP_CB, 00221 .data_ptr = NULL, 00222 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00223 }; 00224 if (eventOS_event_send(&event) != 0) { 00225 cur->bootsrap_state_machine_cnt = 1; // Try again next tick 00226 tr_error("nwk_bootsrap_timer(): event send failed"); 00227 } 00228 } 00229 } 00230 } 00231 00232 void core_timer_event_handle(uint16_t ticksUpdate) 00233 { 00234 protocol_core_monotonic_time += ticksUpdate; 00235 00236 if (protocol_core_seconds_timer <= ticksUpdate) { 00237 uint16_t extra_ticks = ticksUpdate - protocol_core_seconds_timer; 00238 uint16_t seconds = 1 + extra_ticks / 10; 00239 protocol_core_seconds_timer = (10 - extra_ticks % 10); 00240 // TODO: make this lot use "seconds", not 1 00241 00242 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00243 if (cur->nwk_id == IF_6LoWPAN) { 00244 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00245 if (thread_info(cur)) { 00246 thread_seconds_timer(cur, seconds); 00247 } else if (ws_info(cur)) { 00248 ws_common_seconds_timer(cur, seconds); 00249 } else if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 00250 beacon_join_priority_update(cur->id); 00251 } 00252 00253 if (cur->mac_parameters) { 00254 mac_neighbor_table_neighbor_timeout_update(mac_neighbor_info(cur), seconds); 00255 } 00256 00257 if (cur->nwk_wpan_nvm_api) { 00258 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, false); 00259 } 00260 } 00261 } else if (cur->nwk_id == IF_IPV6) { 00262 //Slow Pointer Update 00263 ipv6_core_slow_timer_event_handle(cur); 00264 } 00265 00266 if (cur->lb_api) { 00267 cur->lb_api->lb_seconds_tick_update(cur->lb_api); 00268 } 00269 00270 00271 00272 addr_slow_timer(cur, seconds); 00273 mld_slow_timer(cur, seconds); 00274 ipv6_neighbour_cache_slow_timer(&cur->ipv6_neighbour_cache, seconds); 00275 pan_blacklist_time_update(&cur->pan_blaclist_cache, seconds); 00276 pan_coordinator_blacklist_time_update(&cur->pan_cordinator_black_list, seconds); 00277 if (cur->reachable_time_ttl > seconds) { 00278 cur->reachable_time_ttl -= seconds; 00279 } else { 00280 protocol_stack_interface_set_reachable_time(cur, cur->base_reachable_time); 00281 } 00282 00283 cur->icmp_ra_tokens += seconds; 00284 if (cur->icmp_ra_tokens > 3) { 00285 cur->icmp_ra_tokens = 3; 00286 } 00287 00288 cur->mle_link_reject_tokens += seconds; 00289 if (cur->mle_link_reject_tokens > 2) { 00290 cur->mle_link_reject_tokens = 2; 00291 } 00292 } 00293 00294 mpl_slow_timer(seconds); 00295 rpl_control_slow_timer(seconds); 00296 ipv6_route_table_ttl_update(seconds); 00297 ipv6_destination_cache_timer(seconds); 00298 ipv6_frag_timer(seconds); 00299 cipv6_frag_timer(seconds); 00300 protocol_6lowpan_mle_timer(seconds); 00301 /* This limit bad behaviour device's MLE link reject generation */ 00302 00303 } else { 00304 protocol_core_seconds_timer -= ticksUpdate; 00305 } 00306 00307 //Fast Timer 00308 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00309 if (cur->nwk_id == IF_6LoWPAN) { 00310 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00311 nwk_bootsrap_timer(cur); 00312 nd_object_timer(cur,ticksUpdate); 00313 if (thread_info(cur)) { 00314 thread_timer(cur, ticksUpdate); 00315 } else if (ws_info(cur)) { 00316 ws_common_fast_timer(cur, ticksUpdate); 00317 } 00318 lowpan_context_timer(&cur->lowpan_contexts, ticksUpdate); 00319 } 00320 } else if (cur->nwk_id == IF_IPV6) { 00321 ipv6_core_timer_event_handle(cur, ticksUpdate); 00322 } 00323 00324 ipv6_neighbour_cache_fast_timer(&cur->ipv6_neighbour_cache, ticksUpdate); 00325 addr_fast_timer(cur, ticksUpdate); 00326 mld_fast_timer(cur, ticksUpdate); 00327 00328 /* This gives us the RFC 4443 default (10 tokens/s, bucket size 10) */ 00329 cur->icmp_tokens += ticksUpdate; 00330 if (cur->icmp_tokens > 10) { 00331 cur->icmp_tokens = 10; 00332 } 00333 } 00334 00335 rpl_control_fast_timer(ticksUpdate); 00336 icmpv6_radv_timer(ticksUpdate); 00337 protocol_core_security_tick_update(ticksUpdate); 00338 platform_enter_critical(); 00339 protocol_core_timer_info.core_timer_event = false; 00340 platform_exit_critical(); 00341 } 00342 00343 void protocol_core_cb(uint16_t ticksUpdate) 00344 { 00345 protocol_timer_start(PROTOCOL_TIMER_STACK_TIM, protocol_core_cb, 100); 00346 protocol_core_timer_info.core_timer_ticks += ticksUpdate; 00347 if (!protocol_core_timer_info.core_timer_event) { 00348 protocol_core_timer_info.core_timer_event = true; 00349 /* Static initialised, constant values */ 00350 static arm_event_storage_t event = { 00351 .data = { 00352 .sender = 0, 00353 .data_ptr = NULL, 00354 .event_type = ARM_IN_INTERFACE_CORE_TIMER_CB, 00355 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00356 } 00357 }; 00358 event.data.receiver = protocol_root_tasklet_ID; 00359 event.data.event_data = protocol_core_timer_info.core_timer_ticks; 00360 eventOS_event_send_user_allocated(&event); 00361 protocol_core_timer_info.core_timer_ticks = 0; 00362 } 00363 } 00364 00365 00366 void protocol_core_init(void) 00367 { 00368 protocol_root_tasklet_ID = eventOS_event_handler_create(&protocol_root_tasklet, ARM_LIB_TASKLET_INIT_EVENT); 00369 tr_debug("Allocate Root Tasklet"); 00370 if (protocol_timer_init() == -1) { 00371 tr_error("Protocol timer init failed"); 00372 } 00373 protocol_core_monotonic_time = 0; 00374 protocol_core_timer_info.core_timer_event = false; 00375 protocol_core_timer_info.core_timer_ticks = 0; 00376 protocol_core_timer_info.core_security_ticks_counter = SEC_LIB_X_100MS_COUNTER; 00377 00378 protocol_timer_start(PROTOCOL_TIMER_STACK_TIM, protocol_core_cb, 100); 00379 00380 } 00381 00382 void protocol_core_interface_info_reset(protocol_interface_info_entry_t *entry) 00383 { 00384 if (entry) { 00385 entry->global_address_available = false; 00386 icmpv6_radv_disable(entry); 00387 icmpv6_stop_router_advertisements(entry, NULL); 00388 lowpan_context_list_free(&entry->lowpan_contexts); 00389 ipv6_neighbour_cache_flush(&entry->ipv6_neighbour_cache); 00390 entry->if_stack_buffer_handler = 0; 00391 entry->if_6lowpan_dad_process.active = false; 00392 //Clean 00393 ns_list_foreach_safe(if_address_entry_t, addr, &entry->ip_addresses) { 00394 addr_delete_entry(entry, addr); 00395 } 00396 #ifdef MULTICAST_FORWARDING 00397 ns_list_foreach_safe(if_group_fwd_entry_t, group, &entry->ip_groups_fwd) { 00398 addr_multicast_fwd_remove(entry, group->group); 00399 } 00400 #endif 00401 #ifdef HAVE_RPL 00402 /* This is done after address deletion, so RPL can act on them */ 00403 rpl_control_remove_domain_from_interface(entry); 00404 #endif 00405 } 00406 } 00407 00408 void bootsrap_next_state_kick(icmp_state_t new_state, protocol_interface_info_entry_t *cur) 00409 { 00410 cur->bootsrap_state_machine_cnt = 0; 00411 cur->nwk_bootstrap_state = new_state; 00412 arm_event_s event = { 00413 .receiver = protocol_root_tasklet_ID, 00414 .sender = 0, 00415 .event_id = (uint8_t)cur->id, 00416 .event_type = ARM_IN_INTERFACE_BOOTSTRAP_CB, 00417 .data_ptr = NULL, 00418 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00419 }; 00420 if (eventOS_event_send(&event) != 0) { 00421 tr_error("bootsrap_next_state_kick(): event send failed"); 00422 } 00423 } 00424 00425 uint32_t protocol_stack_interface_set_reachable_time(protocol_interface_info_entry_t *cur, uint32_t base_reachable_time) 00426 { 00427 cur->base_reachable_time = base_reachable_time; 00428 cur->reachable_time_ttl = REACHABLE_TIME_UPDATE_SECONDS; 00429 00430 return cur->ipv6_neighbour_cache.reachable_time = randLIB_randomise_base(base_reachable_time, 0x4000, 0xBFFF); 00431 } 00432 00433 00434 static void protocol_core_base_init(protocol_interface_info_entry_t *entry,nwk_interface_id nwk_id) 00435 { 00436 entry->nwk_id = nwk_id; 00437 switch (nwk_id) { 00438 case IF_IPV6: 00439 entry->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_ETHERNET_ROUTER; 00440 break; 00441 default: 00442 entry->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER; 00443 break; 00444 } 00445 entry->bootStrapId = -1; 00446 entry->lowpan_address_mode = NET_6LOWPAN_GP64_ADDRESS; 00447 entry->ipv6_configure = NULL; 00448 entry->if_lowpan_security_params = NULL; 00449 entry->if_ns_transmit = NULL; 00450 entry->if_special_forwarding = NULL; 00451 entry->if_snoop = NULL; 00452 entry->if_icmp_handler = NULL; 00453 entry->if_map_ip_to_link_addr = NULL; 00454 entry->if_map_link_addr_to_ip = NULL; 00455 entry->if_6lowpan_dad_process.active = false; 00456 entry->lowpan_desired_short_address = 0xfffe; 00457 entry->lowpan_info = 0; 00458 entry->rpl_domain = NULL; 00459 entry->if_down = NULL; 00460 entry->if_up = NULL; 00461 } 00462 00463 static void protocol_core_base_finish_init(protocol_interface_info_entry_t *entry) 00464 { 00465 entry->configure_flags = 0; 00466 entry->bootsrap_state_machine_cnt = 0; 00467 entry->pana_sec_info_temp = NULL; 00468 entry->lb_api = NULL; 00469 entry->global_address_available = false; 00470 entry->reallocate_short_address_if_duplicate = true; 00471 entry->iids_map_to_mac = false; 00472 entry->opaque_slaac_iids = true; 00473 entry->ip_multicast_as_mac_unicast_to_parent = false; 00474 entry->dad_failures = 0; 00475 entry->icmp_tokens = 10; 00476 entry->mle_link_reject_tokens = 2; 00477 entry->ip_forwarding = true; /* Default to on for now... */ 00478 entry->ip_multicast_forwarding = true; /* Default to on for now... */ 00479 #ifdef HAVE_IPV6_ND 00480 entry->recv_ra_routes = true; 00481 entry->recv_ra_prefixes = true; 00482 #endif 00483 entry->send_mld = true; 00484 #ifdef HAVE_MPL 00485 entry->mpl_seed = false; 00486 entry->mpl_control_trickle_params = rfc7731_default_control_message_trickle_params; 00487 entry->mpl_data_trickle_params = rfc7731_default_data_message_trickle_params; 00488 entry->mpl_seed_set_entry_lifetime = RFC7731_DEFAULT_SEED_SET_ENTRY_LIFETIME; 00489 entry->mpl_proactive_forwarding = true; 00490 entry->mpl_seed_id_mode = MULTICAST_MPL_SEED_ID_IPV6_SRC_FOR_DOMAIN; 00491 #endif 00492 entry->cur_hop_limit = UNICAST_HOP_LIMIT_DEFAULT; 00493 protocol_stack_interface_set_reachable_time(entry, 30000); 00494 entry->dup_addr_detect_transmits = 1; 00495 entry->ipv6_neighbour_cache.link_mtu = IPV6_MIN_LINK_MTU; 00496 entry->max_link_mtu = IPV6_MIN_LINK_MTU; 00497 entry->pmtu_lifetime = 10 * 60; // RFC 1981 default - 10 minutes 00498 icmpv6_radv_init(entry); 00499 ns_list_link_init(entry, link); 00500 entry->if_stack_buffer_handler = NULL; 00501 entry->interface_name = 0; 00502 entry->border_router_setup = NULL; 00503 #ifdef HAVE_THREAD 00504 entry->thread_info = NULL; 00505 #endif 00506 entry->mesh_callbacks = NULL; 00507 entry->ip_addresses_max_slaac_entries = 0; 00508 ns_list_init(&entry->lowpan_contexts); 00509 ns_list_init(&entry->ip_addresses); 00510 ns_list_init(&entry->ip_groups); 00511 #ifdef MULTICAST_FORWARDING 00512 ns_list_init(&entry->ip_groups_fwd); 00513 entry->ip_mcast_fwd_for_scope = IPV6_SCOPE_SITE_LOCAL; // Default for backwards compatibility 00514 #endif 00515 ns_list_init(&entry->ipv6_neighbour_cache.list); 00516 } 00517 00518 00519 00520 static int lowpan_security_parameters_allocate(protocol_interface_info_entry_t *entry) 00521 { 00522 entry->if_lowpan_security_params = ns_dyn_mem_alloc(sizeof(if_6lowpan_security_info_t)); 00523 if (!entry->if_lowpan_security_params) { 00524 return -1; 00525 } 00526 00527 entry->if_lowpan_security_params->security_level = 0; 00528 entry->if_lowpan_security_params->mle_security_frame_counter = 0; 00529 entry->if_lowpan_security_params->pana_params = NULL; 00530 entry->if_lowpan_security_params->nwk_security_mode = NET_SEC_MODE_NO_LINK_SECURITY; 00531 return 0; 00532 } 00533 00534 static void lowpan_security_parameters_deallocate(protocol_interface_info_entry_t *entry) 00535 { 00536 ns_dyn_mem_free(entry->if_lowpan_security_params); 00537 entry->if_lowpan_security_params = NULL; 00538 00539 } 00540 00541 static protocol_interface_info_entry_t * protocol_interface_class_allocate(nwk_interface_id nwk_id) 00542 { 00543 protocol_interface_info_entry_t *entry = ns_dyn_mem_alloc(sizeof(protocol_interface_info_entry_t)); 00544 if (entry) { 00545 memset(entry, 0, sizeof(protocol_interface_info_entry_t)); 00546 /* We assume for now zone indexes for interface, link and realm all equal interface id */ 00547 int8_t id = net_interface_get_free_id(); 00548 entry->id = id; 00549 entry->zone_index[IPV6_SCOPE_INTERFACE_LOCAL] = id; 00550 entry->zone_index[IPV6_SCOPE_LINK_LOCAL] = id; 00551 entry->zone_index[IPV6_SCOPE_REALM_LOCAL] = id; 00552 protocol_core_base_init(entry,nwk_id); 00553 } 00554 return entry; 00555 } 00556 00557 static protocol_interface_info_entry_t *protocol_core_interface_6lowpan_entry_get_with_mac(mac_api_t *api) 00558 { 00559 if( !api ){ 00560 return NULL; 00561 } 00562 protocol_interface_info_entry_t *entry = protocol_interface_class_allocate(IF_6LoWPAN); 00563 if (!entry) { 00564 return NULL; 00565 } 00566 00567 if (lowpan_adaptation_interface_init(entry->id, api->phyMTU) != 0) { 00568 goto interface_failure; 00569 } 00570 00571 if (reassembly_interface_init(entry->id, 8, 5) != 0) { 00572 goto interface_failure; 00573 } 00574 00575 if (lowpan_security_parameters_allocate(entry) != 0) { 00576 goto interface_failure; 00577 } 00578 00579 entry->mac_parameters = ns_dyn_mem_alloc(sizeof(arm_15_4_mac_parameters_t)); 00580 if (!entry->mac_parameters) { 00581 goto interface_failure; 00582 } 00583 memset(entry->mac_parameters, 0, sizeof(arm_15_4_mac_parameters_t)); 00584 entry->mac_parameters->MacUnsusecured_2003_cab = mac_unsecured_2003_compatibility; 00585 entry->mac_parameters->mac_short_address = 0xffff; 00586 entry->mac_parameters->pan_id = 0xffff; 00587 entry->mac_parameters->nwk_filter_params.beacon_protocol_id_filter = 0xff; 00588 entry->mac_parameters->nwk_filter_params.net_pan_id_filter = 0xffff; 00589 entry->mac_parameters->mac_in_direct_entry_timeout = 7000; //default timeout 00590 00591 entry->mac_parameters->mac_prev_key_attribute_id = 0; 00592 entry->mac_parameters->mac_default_key_attribute_id = 1; 00593 entry->mac_parameters->mac_next_key_attribute_id = 2; 00594 00595 entry->beacon_cb = beacon_received; 00596 00597 entry->mac_api = api; 00598 int8_t err = entry->mac_api->mac_initialize( entry->mac_api, &mcps_data_confirm_handler, &mcps_data_indication_handler, 00599 &mcps_purge_confirm_handler, &mlme_confirm_handler, &mlme_indication_handler, 00600 entry->id ); 00601 if( err < 0 ){ 00602 goto interface_failure; 00603 } 00604 00605 //Set default key source 00606 mac_helper_set_default_key_source(entry); 00607 00608 protocol_core_base_finish_init(entry); 00609 return entry; 00610 00611 interface_failure: 00612 lowpan_adaptation_interface_free(entry->id); 00613 reassembly_interface_free(entry->id); 00614 ns_dyn_mem_free(entry->mac_parameters); 00615 lowpan_security_parameters_deallocate(entry); 00616 ns_dyn_mem_free(entry); 00617 entry = NULL; 00618 return NULL; 00619 } 00620 00621 static void protocol_6lowpan_mac_set(protocol_interface_info_entry_t *cur, const uint8_t *mac) 00622 { 00623 memcpy(cur->iid_eui64, mac, 8); 00624 /* Invert U/L Bit */ 00625 cur->iid_eui64[0] ^= 2; 00626 00627 mac_helper_mac64_set(cur, mac); 00628 } 00629 00630 #ifdef HAVE_ETHERNET 00631 static bool protocol_ipv6_setup_allocate(protocol_interface_info_entry_t *entry) 00632 { 00633 entry->ipv6_configure = ns_dyn_mem_alloc(sizeof(ipv6_interface_info_t)); 00634 if (entry->ipv6_configure) { 00635 entry->lowpan_info = INTERFACE_NWK_ROUTER_DEVICE; 00636 memset(entry->ipv6_configure, 0, sizeof(ipv6_interface_info_t)); 00637 entry->ipv6_configure->temporaryUlaAddressState = false; 00638 return true; 00639 } 00640 return false; 00641 } 00642 00643 static protocol_interface_info_entry_t *protocol_core_interface_ethernet_entry_get(eth_mac_api_t *api) 00644 { 00645 protocol_interface_info_entry_t *entry = protocol_interface_class_allocate(IF_IPV6); 00646 if (!entry) { 00647 return NULL; 00648 } 00649 if (!protocol_ipv6_setup_allocate(entry)) { 00650 ns_dyn_mem_free(entry); 00651 entry = NULL; 00652 } else { 00653 entry->eth_mac_api = api; 00654 ipv6_interface_phy_sap_register(entry); 00655 protocol_core_base_finish_init(entry); 00656 } 00657 00658 return entry; 00659 } 00660 00661 static void protocol_ethernet_mac_set(protocol_interface_info_entry_t *cur, const uint8_t *mac) 00662 { 00663 if( !cur || !cur->eth_mac_api ) { 00664 return; 00665 } 00666 00667 memcpy(cur->mac, mac, 6); 00668 cur->mac[6] = 0; 00669 cur->mac[7] = 0; 00670 cur->iid_eui64[0] = mac[0] ^ 2; 00671 cur->iid_eui64[1] = mac[1]; 00672 cur->iid_eui64[2] = mac[2]; 00673 cur->iid_eui64[3] = 0xff; 00674 cur->iid_eui64[4] = 0xfe; 00675 cur->iid_eui64[5] = mac[3]; 00676 cur->iid_eui64[6] = mac[4]; 00677 cur->iid_eui64[7] = mac[5]; 00678 00679 cur->eth_mac_api->mac48_set(cur->eth_mac_api, cur->mac); 00680 } 00681 00682 #else 00683 protocol_interface_info_entry_t *protocol_core_interface_ethernet_entry_get(eth_mac_api_t *api) 00684 { 00685 (void)api; 00686 return NULL; 00687 } 00688 00689 static void protocol_ethernet_mac_set(protocol_interface_info_entry_t *cur, const uint8_t *mac) 00690 { 00691 (void)cur; 00692 (void)mac; 00693 } 00694 #endif 00695 00696 static void protocol_stack_interface_iid_eui64_generate(protocol_interface_info_entry_t *cur , const uint8_t *mac) 00697 { 00698 if (cur->nwk_id == IF_6LoWPAN) { 00699 protocol_6lowpan_mac_set(cur, mac); 00700 } else { 00701 protocol_ethernet_mac_set(cur, mac); 00702 } 00703 //By default use this EUI-64-based IID for SLAAC 00704 memcpy(cur->iid_slaac, cur->iid_eui64, 8); 00705 //And why not feed it into the random seed too? 00706 randLIB_add_seed(common_read_64_bit(cur->mac)); 00707 } 00708 00709 protocol_interface_info_entry_t *nwk_interface_get_ipv6_ptr(void) 00710 { 00711 #ifdef HAVE_ETHERNET 00712 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00713 if (cur->nwk_id == IF_IPV6) { 00714 return cur; 00715 } 00716 } 00717 #endif 00718 00719 return NULL; 00720 } 00721 00722 void nwk_interface_print_neigh_cache(route_print_fn_t *print_fn) 00723 { 00724 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00725 ipv6_neighbour_cache_print(&cur->ipv6_neighbour_cache, print_fn); 00726 } 00727 } 00728 00729 void nwk_interface_flush_neigh_cache(void) 00730 { 00731 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00732 ipv6_neighbour_cache_flush(&cur->ipv6_neighbour_cache); 00733 } 00734 } 00735 00736 protocol_interface_info_entry_t *protocol_stack_interface_info_get(nwk_interface_id nwk_id) 00737 { 00738 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) 00739 if (cur->nwk_id == nwk_id) { 00740 return cur; 00741 } 00742 00743 return NULL; 00744 } 00745 00746 protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_id(int8_t nwk_id) 00747 { 00748 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) 00749 if (cur->id == nwk_id) { 00750 return cur; 00751 } 00752 00753 return NULL; 00754 } 00755 00756 protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_bootstrap_id(int8_t id) 00757 { 00758 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) 00759 if (cur->bootStrapId == id) { 00760 return cur; 00761 } 00762 00763 return NULL; 00764 } 00765 00766 protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_rpl_domain(const struct rpl_domain *domain, int8_t last_id) 00767 { 00768 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00769 if (cur->id > last_id && cur->rpl_domain == domain) { 00770 return cur; 00771 } 00772 } 00773 00774 return NULL; 00775 } 00776 00777 protocol_interface_info_entry_t *protocol_stack_interface_info_get_by_fhss_api(const struct fhss_api *fhss_api) 00778 { 00779 #ifdef HAVE_WS 00780 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00781 if (cur->ws_info->fhss_api == fhss_api) { 00782 return cur; 00783 } 00784 } 00785 #else 00786 (void)fhss_api; 00787 #endif //HAVE_WS 00788 return NULL; 00789 } 00790 00791 protocol_interface_info_entry_t *protocol_stack_interface_sleep_possibility(void) 00792 { 00793 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00794 if (!cur->if_stack_buffer_handler) { 00795 continue; 00796 } 00797 00798 if (cur->nwk_id == IF_IPV6) { 00799 return NULL; 00800 } 00801 00802 /* Note that rf_mac_setup == NULL is okay */ 00803 if (cur->mac_parameters && cur->rfd_poll_info == NULL) { 00804 return NULL; 00805 } 00806 } 00807 00808 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00809 if (cur->mac_parameters && cur->rfd_poll_info) { 00810 if (!cur->rfd_poll_info->pollActive && lowpan_adaptation_tx_active(cur->id)) { 00811 return cur; 00812 } 00813 } 00814 } 00815 00816 return NULL; 00817 } 00818 00819 uint8_t nwk_bootsrap_ready(protocol_interface_info_entry_t *cur) 00820 { 00821 int8_t ret_val = 0; 00822 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) == 0) { 00823 if (cur->nwk_bootstrap_state == ER_BOOTSRAP_DONE) { 00824 ret_val = 1; 00825 } 00826 } 00827 return ret_val; 00828 } 00829 00830 static int8_t net_interface_get_free_id(void) 00831 { 00832 uint_fast8_t id; // Must be unsigned for loop test to work... 00833 00834 for (id = 1; id <= INT8_MAX; id++) { 00835 bool in_use = false; 00836 /* interface index == default zone index for link, interface and realm, so 00837 * ensure selected ID is not in use for any of those scopes */ 00838 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00839 if (cur->id == (int8_t) id || 00840 cur->zone_index[IPV6_SCOPE_INTERFACE_LOCAL] == id || 00841 cur->zone_index[IPV6_SCOPE_LINK_LOCAL] == id || 00842 cur->zone_index[IPV6_SCOPE_REALM_LOCAL] == id) { 00843 in_use = true; 00844 break; 00845 } 00846 } 00847 if (!in_use) { 00848 return id; 00849 } 00850 } 00851 00852 return -1; 00853 } 00854 00855 protocol_interface_info_entry_t *protocol_stack_interface_generate_ethernet(eth_mac_api_t *api) 00856 { 00857 if( !api ){ 00858 return NULL; 00859 } 00860 protocol_interface_info_entry_t *new_entry = NULL; 00861 00862 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00863 if (cur->eth_mac_api == api) { 00864 return cur; 00865 } 00866 } 00867 00868 if (api) { 00869 new_entry = protocol_core_interface_ethernet_entry_get(api); 00870 00871 if (new_entry) { 00872 neighbor_cache_init(&(new_entry->neigh_cache)); 00873 pan_blacklist_cache_init(&(new_entry->pan_blaclist_cache)); 00874 pan_coordinator_blacklist_cache_init(&(new_entry->pan_cordinator_black_list)); 00875 ipv6_neighbour_cache_init(&new_entry->ipv6_neighbour_cache, new_entry->id); 00876 addr_max_slaac_entries_set(new_entry, 16); 00877 uint8_t mac[6]; 00878 int8_t error = api->mac48_get( api, mac ); 00879 if(error){ 00880 tr_error("mac_ext_mac64_address_get failed: %d", error); 00881 ns_dyn_mem_free(new_entry); 00882 return NULL; 00883 } 00884 00885 protocol_stack_interface_iid_eui64_generate(new_entry, mac); 00886 ns_list_add_to_start(&protocol_interface_info_list, new_entry); 00887 00888 (void) ipv6_route_table_set_max_entries(new_entry->id, ROUTE_RADV, 16); 00889 00890 return new_entry; 00891 } 00892 } 00893 return NULL; 00894 } 00895 00896 protocol_interface_info_entry_t *protocol_stack_interface_generate_lowpan(mac_api_t *api) 00897 { 00898 if( !api ){ 00899 return NULL; 00900 } 00901 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 00902 if (cur->mac_api == api) { 00903 return cur; 00904 } 00905 } 00906 00907 protocol_interface_info_entry_t *new_entry = protocol_core_interface_6lowpan_entry_get_with_mac(api); 00908 00909 if (new_entry) { 00910 neighbor_cache_init(&(new_entry->neigh_cache)); 00911 pan_blacklist_cache_init(&(new_entry->pan_blaclist_cache)); 00912 pan_coordinator_blacklist_cache_init(&(new_entry->pan_cordinator_black_list)); 00913 ipv6_neighbour_cache_init(&new_entry->ipv6_neighbour_cache, new_entry->id); 00914 00915 uint8_t mac[8]; 00916 int8_t error = api->mac64_get( api, MAC_EXTENDED_READ_ONLY, mac ); 00917 if(error){ 00918 tr_error("mac_ext_mac64_address_get failed: %d", error); 00919 ns_dyn_mem_free(new_entry); 00920 return NULL; 00921 } 00922 protocol_stack_interface_iid_eui64_generate(new_entry, mac); 00923 ns_list_add_to_start(&protocol_interface_info_list, new_entry); 00924 return new_entry; 00925 } 00926 return NULL; 00927 } 00928 00929 bool nwk_interface_compare_mac_address(protocol_interface_info_entry_t *cur, uint_fast8_t addrlen, const uint8_t addr[/*addrlen*/]) 00930 { 00931 if (!cur) { 00932 return false; 00933 } 00934 00935 switch (addrlen) { 00936 case 2: 00937 return cur->mac_parameters && cur->mac_parameters->mac_short_address == common_read_16_bit(addr); 00938 case 8: 00939 return memcmp(addr, cur->mac, 8) == 0; 00940 default: 00941 return false; 00942 } 00943 } 00944 00945 /** 00946 * \brief Push Buffer to Protocol Core. 00947 * 00948 * \param buf pointer to buffer. NULL is accepted and ignored. 00949 */ 00950 void protocol_push(buffer_t *buf) 00951 { 00952 /* Ignore NULL */ 00953 if (!buf) { 00954 return; 00955 } 00956 00957 arm_event_s event = { 00958 .receiver = protocol_root_tasklet_ID, 00959 .sender = 0, 00960 .event_type = ARM_IN_INTERFACE_PROTOCOL_HANDLE, 00961 .data_ptr = buf, 00962 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00963 }; 00964 00965 if (eventOS_event_send(&event) == 0) { 00966 protocol_core_buffers_in_event_queue++; 00967 } else { 00968 if ((buf->info & B_DIR_MASK) == B_DIR_DOWN) { 00969 buf = socket_tx_buffer_event(buf, SOCKET_NO_RAM); 00970 } 00971 if (buf) { 00972 buffer_free(buf); 00973 } else { 00974 tr_debug("TCP Allocated"); 00975 } 00976 } 00977 } 00978 00979 /* 00980 * A protocol poll function to be typically called from 'Event Core'. This function is registered to the call queue by using event_cb_send() from 'Event Core'. 00981 */ 00982 static void protocol_buffer_poll(buffer_t *b) 00983 { 00984 protocol_core_buffers_in_event_queue--; 00985 00986 // Avoid the danger of with route data becoming stale (including 00987 // dead info pointers) while the packet is in the queue. 00988 if (b->route && ipv6_route_table_source_was_invalidated(b->route->route_info.source)) { 00989 buffer_free_route(b); 00990 // Attempt re-route immediately - some layers assume routing already 00991 // performed by higher layers. 00992 if (!ipv6_buffer_route(b)) { 00993 goto error; 00994 } 00995 } 00996 00997 // Once buffer queue is empty, clear the invalidation flags for above test 00998 if (protocol_core_buffers_in_event_queue == 0) { 00999 ipv6_route_table_source_invalidated_reset(); 01000 } else if (protocol_core_buffers_in_event_queue < 0) { 01001 tr_err("protocol_core_buffers_in_event_queue negative"); 01002 } 01003 01004 // Call the actual handler 01005 protocol_interface_info_entry_t *cur = b->interface ; 01006 if (cur && cur->if_stack_buffer_handler) { 01007 cur->if_stack_buffer_handler(b); 01008 return; 01009 } 01010 01011 error: 01012 socket_tx_buffer_event_and_free(b, SOCKET_TX_FAIL); 01013 } 01014 01015 static void nwk_net_event_post(arm_nwk_interface_status_type_e posted_event, int8_t net_tasklet, int8_t nwk_id) 01016 { 01017 arm_event_s event = { 01018 .receiver = net_tasklet, 01019 .sender = protocol_read_tasklet_id(), /**< Event sender Tasklet ID */ 01020 .event_type = ARM_LIB_NWK_INTERFACE_EVENT, 01021 .event_data = posted_event, 01022 .event_id = (int8_t) nwk_id, 01023 .data_ptr = NULL, 01024 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 01025 }; 01026 if (eventOS_event_send(&event) != 0) { 01027 tr_error("nwk_net_event_post(): event send failed"); 01028 } 01029 } 01030 01031 void nwk_bootsrap_state_update(arm_nwk_interface_status_type_e posted_event, protocol_interface_info_entry_t *cur) 01032 { 01033 //Clear Bootsrap Active Bit allways 01034 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_ACTIVE; 01035 cur->bootsrap_state_machine_cnt = 0; 01036 nwk_net_event_post(posted_event, cur->net_start_tasklet, cur->id); 01037 01038 if (posted_event == ARM_NWK_BOOTSTRAP_READY) { 01039 01040 switch (cur->bootsrap_mode) { 01041 01042 case ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT: 01043 case ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER: 01044 case ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER: 01045 case ARM_NWK_BOOTSRAP_MODE_ETHERNET_HOST: 01046 case ARM_NWK_BOOTSRAP_MODE_ETHERNET_ROUTER: 01047 #ifdef HAVE_ETHERNET 01048 if (cur->ipv6_configure) { 01049 cur->ipv6_configure->IPv6_ND_state = IPV6_READY; 01050 if (cur->ipv6_configure->ipv6_stack_mode == NET_IPV6_BOOTSTRAP_STATIC) { 01051 addr_add_router_groups(cur); 01052 icmpv6_radv_enable(cur);//Activate RA send only with static enviroment 01053 icmpv6_restart_router_advertisements(cur, ADDR_UNSPECIFIED); 01054 if (cur->ipv6_configure->accept_ra != NET_IPV6_RA_ACCEPT_ALWAYS) { 01055 icmpv6_recv_ra_routes(cur, false); // removes all existing RADV routes 01056 icmpv6_recv_ra_prefixes(cur, false); 01057 } 01058 } 01059 } 01060 #endif 01061 break; 01062 01063 default: 01064 mac_data_poll_protocol_poll_mode_disable(cur); 01065 if (!cur->rpl_domain) { 01066 tr_debug("NON RPL Ready"); 01067 //nwk_protocol_poll_mode_disable(cur->nwk_id, 0); 01068 } else { 01069 tr_debug("RPL Ready"); 01070 } 01071 } 01072 } else { 01073 if (cur->if_down) { 01074 cur->if_down(cur); 01075 } else { 01076 tr_debug("if_down() NULL"); 01077 } 01078 } 01079 } 01080 01081 void net_bootsrap_cb_run(uint8_t event) 01082 { 01083 int8_t nwk_id = (int8_t) event; 01084 protocol_interface_info_entry_t *cur = 0; 01085 cur = protocol_stack_interface_info_get_by_id(nwk_id); 01086 if (cur) { 01087 if (cur->nwk_id == IF_6LoWPAN) { 01088 //eventOS_scheduler_set_active_tasklet(protocol_read_tasklet_id()); 01089 if (thread_info(cur)) { 01090 thread_bootstrap_state_machine(cur); 01091 } else if (ws_info(cur)) { 01092 ws_bootstrap_state_machine(cur); 01093 } else { 01094 protocol_6lowpan_bootstrap(cur); 01095 } 01096 } else if (cur->nwk_id == IF_IPV6) { 01097 //IPV6 Bootsrap Run 01098 } 01099 } 01100 } 01101 01102 void protocol_core_dhcpv6_allocated_address_remove(protocol_interface_info_entry_t *cur, uint8_t *guaPrefix) 01103 { 01104 ipv6_stack_route_advert_remove(guaPrefix, 64); 01105 //Delete Address & Routes 01106 ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) { 01107 if (e->source == ADDR_SOURCE_DHCP && (e->prefix_len == 64) && bitsequal(e->address, guaPrefix, 64)) { 01108 01109 ipv6_stack_route_advert_remove(e->address, 128); 01110 01111 ns_list_remove(&cur->ip_addresses, e); 01112 ns_dyn_mem_free(e); 01113 tr_debug("Delete DHCPv6 Allocated Address"); 01114 break; 01115 } 01116 } 01117 } 01118 01119 /* XXX note that this does not perform any scope checks, so will for example match 01120 * link local addresses on any interface - you may want addr_interface_address_compare */ 01121 int8_t protocol_interface_address_compare(const uint8_t *addr) 01122 { 01123 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 01124 if (addr_is_assigned_to_interface(cur, addr)) { 01125 return 0; 01126 } 01127 } 01128 01129 return -1; 01130 } 01131
Generated on Tue Aug 9 2022 00:37:18 by
