BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
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 Tue Jul 12 2022 12:22:18 by
