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