Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers protocol_core.c Source File

protocol_core.c

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