Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
protocol_6lowpan_bootstrap.c
00001 /* 00002 * Copyright (c) 2015-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 /* 00019 * \file protocol_6lowpan_bootstrap.c 00020 * 00021 */ 00022 #include "nsconfig.h" 00023 #include "string.h" 00024 #include "ns_types.h" 00025 #include "ns_trace.h" 00026 #include "eventOS_scheduler.h" 00027 #include "nsdynmemLIB.h" 00028 #include "randLIB.h" 00029 #include "NWK_INTERFACE/Include/protocol.h" 00030 #include "NWK_INTERFACE/Include/protocol_timer.h" 00031 #include "Common_Protocols/icmpv6.h" 00032 #include "Common_Protocols/icmpv6_radv.h" 00033 #include "Common_Protocols/udp.h" 00034 #include "6LoWPAN/Bootstraps/network_lib.h" 00035 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00036 #include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h" 00037 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00038 #include "Service_Libs/blacklist/blacklist.h" 00039 #include "6LoWPAN/MAC/mac_helper.h" 00040 #include "mac_api.h" 00041 #include "net_pana_parameters_api.h" 00042 #ifdef HAVE_RPL 00043 #include "RPL/rpl_control.h" 00044 #endif 00045 #ifndef NO_MLE 00046 #include "MLE/mle.h" 00047 #include "MLE/mle_tlv.h" 00048 #endif 00049 #ifdef ECC 00050 #include "libX509_V3.h" 00051 #include "ecc.h" 00052 #endif 00053 00054 #include "ccmLIB.h" 00055 #include "shalib.h" 00056 #include "net_nvm_api.h" 00057 #include "common_functions.h" 00058 #include "net_interface.h" 00059 #include "Security/TLS/tls_lib.h" 00060 #include "Security/Common/sec_lib.h" 00061 #include "Security/PANA/pana.h" 00062 #include "Security/PANA/pana_internal_api.h" 00063 #include "6LoWPAN/ND/nd_router_object.h" 00064 #include "BorderRouter/border_router.h" 00065 #include "6LoWPAN/Thread/thread_common.h" 00066 #include "Service_Libs/mle_service/mle_service_api.h" 00067 #include "Service_Libs/etx/etx.h" 00068 #include "6LoWPAN/MAC/beacon_handler.h" 00069 #include "mac_api.h" 00070 #include "6LoWPAN/MAC/mac_data_poll.h" 00071 #include "libNET/src/net_load_balance_internal.h" 00072 #include "6LoWPAN/NVM/nwk_nvm.h" 00073 00074 00075 /* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315 00076 * says RAND is uniformly distributed between -0.1 and +0.1 00077 */ 00078 #define LOWPAN_RAND_LOW 0x7333 // 1 - 0.1; minimum for "1+RAND" 00079 #define LOWPAN_RAND_HIGH 0x8CCD // 1 + 0.1; maximum for "1+RAND" 00080 00081 #define TRACE_GROUP_LOWPAN_BOOT "6Bo" 00082 #define TRACE_GROUP "6Bo" 00083 00084 #ifdef HAVE_6LOWPAN_ND 00085 #ifdef HAVE_RPL 00086 static int protocol_6lowpan_router_multicast_synch(protocol_interface_info_entry_t *cur); 00087 static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *handle); 00088 #else 00089 #define protocol_6lowpan_router_multicast_synch(cur) (-1) 00090 #endif 00091 00092 static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority); 00093 static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count); 00094 static uint8_t protocol_6lowpan_mle_data_allocate(void); 00095 static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries); 00096 static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status); 00097 00098 static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur); 00099 static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); 00100 static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64); 00101 static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64); 00102 static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface); 00103 00104 static mle_6lowpan_data_t *mle_6lowpan_data; 00105 00106 #define MAX_MC_DIS_COUNT 3 00107 00108 static void lowpan_bootstrap_pan_control(protocol_interface_info_entry_t *cur, bool bootstrap_ready) 00109 { 00110 if (cur->mac_api) { 00111 mlme_start_t start_req; 00112 memset(&start_req, 0, sizeof(mlme_start_t)); 00113 start_req.BeaconOrder = 15; 00114 start_req.SuperframeOrder = 15; 00115 start_req.PANCoordinator = bootstrap_ready; 00116 start_req.LogicalChannel = cur->mac_parameters->mac_channel; 00117 start_req.PANId = cur->mac_parameters->pan_id; 00118 cur->mac_api->mlme_req(cur->mac_api, MLME_START , &start_req); 00119 net_load_balance_internal_state_activate(cur, bootstrap_ready); 00120 } 00121 } 00122 00123 static uint8_t lowpan_mode_get_by_interface_ptr(protocol_interface_info_entry_t *cur) 00124 { 00125 uint8_t mle_mode = 0; 00126 00127 if (!(cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE)) { 00128 mle_mode |= MLE_RX_ON_IDLE; 00129 } 00130 00131 00132 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 00133 mle_mode |= (MLE_FFD_DEV); 00134 } 00135 00136 return mle_mode; 00137 } 00138 00139 uint8_t *mle_general_write_timeout(uint8_t *ptr, protocol_interface_info_entry_t *cur) 00140 { 00141 00142 uint32_t timeout_value = 0; 00143 uint8_t mode = lowpan_mode_get_by_interface_ptr(cur); 00144 00145 if (!mle_6lowpan_data) { 00146 return ptr; 00147 } 00148 00149 if (!(mode & MLE_RX_ON_IDLE)) { 00150 timeout_value = mac_data_poll_host_timeout(cur); 00151 } 00152 if (timeout_value == 0) { 00153 timeout_value = mle_6lowpan_data->host_lifetime; 00154 } 00155 00156 return mle_tlv_write_timeout(ptr, timeout_value); 00157 00158 } 00159 00160 static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur) 00161 { 00162 if (!cur->priorityFlag || 00163 !(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) || 00164 cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00165 return; 00166 } 00167 00168 uint8_t mac64[8]; 00169 00170 if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 00171 // Coordinating parent has been lost during bootstrap 00172 if (!cur_interface->global_address_available) { 00173 tr_debug("bootstrap coordinator down"); 00174 bootsrap_next_state_kick(ER_BOOTSTRAP_CONNECTION_DOWN, cur_interface); 00175 } 00176 } else { 00177 //Call Priority parent loose 00178 if (cur->short_adr != 0xffff) { 00179 memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6); 00180 common_write_16_bit(cur->short_adr, &mac64[6]); 00181 } else { 00182 memcpy(mac64,cur->mac64 , 8); 00183 mac64[0] ^= 2; 00184 } 00185 00186 if (nd_parent_loose_indcate(mac64, cur_interface) != 0) { 00187 //ND Router synch lost 00188 tr_debug("ND Router Synch Loose"); 00189 bootsrap_next_state_kick(ER_PARENT_SYNCH_LOST, cur_interface); 00190 } 00191 } 00192 } 00193 00194 static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur) 00195 { 00196 protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id); 00197 if (!cur_interface) { 00198 return; 00199 } 00200 00201 // Sleepy host 00202 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 00203 mac_data_poll_protocol_poll_mode_decrement(cur_interface); 00204 } 00205 00206 protocol_6lowpan_priority_neighbor_remove(cur_interface, cur); 00207 00208 if (cur->mode & MLE_FFD_DEV) { 00209 protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr); 00210 protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64); 00211 } 00212 mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index); 00213 } 00214 00215 static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries) 00216 { 00217 uint8_t mac64[8]; 00218 uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId); 00219 00220 memcpy(mac64, ll64_ptr + 8, 8); 00221 mac64[0] ^= 2; 00222 00223 mle_neigh_table_entry_t *neig_info = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG ); 00224 00225 if (!neig_info) { 00226 return false;//Why entry is removed before timeout?? 00227 } 00228 00229 00230 if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) { 00231 return false; 00232 } 00233 00234 00235 if (usedAllRetries) { 00236 //GET entry 00237 mle_class_remove_entry(interface_id, neig_info); 00238 return false; 00239 } 00240 00241 return true; 00242 } 00243 00244 static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64) 00245 { 00246 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00247 if (!cur) { 00248 return false; 00249 } 00250 00251 00252 uint16_t bufId; 00253 mle_message_timeout_params_t timeout; 00254 uint8_t ll64[16]; 00255 00256 00257 //Challenge 00258 00259 uint8_t security_level = mle_service_security_level_get(cur->id); 00260 tr_debug("Link REQUEST"); 00261 bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); 00262 if (bufId == 0) { 00263 return -1; 00264 } 00265 00266 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00267 00268 ptr = mle_general_write_source_address(ptr, cur); 00269 ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); 00270 if (security_level) { 00271 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00272 } 00273 if (cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 00274 ptr = mle_general_write_timeout(ptr, cur); 00275 } 00276 00277 memcpy(ll64, ADDR_LINK_LOCAL_PREFIX, 8); 00278 memcpy(&ll64[8], mac64, 8); 00279 ll64[8] ^= 2; 00280 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00281 tr_debug("Buffer overflow at message write"); 00282 } 00283 timeout.retrans_max = 3; 00284 timeout.timeout_init = 2; 00285 timeout.timeout_max = 4; 00286 timeout.delay = MLE_NO_DELAY; 00287 00288 //SET Destination address 00289 mle_service_set_msg_destination_address(bufId, ll64); 00290 //Set Callback 00291 mle_service_set_packet_callback(bufId, protocol_6lowpan_challenge_callback); 00292 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00293 00294 mle_service_send_message(bufId); 00295 return 0; 00296 } 00297 00298 static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64) 00299 { 00300 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00301 if (!cur) { 00302 return false; 00303 } 00304 00305 00306 uint16_t bufId; 00307 mle_message_timeout_params_t timeout; 00308 uint8_t ll64[16]; 00309 00310 00311 //Challenge 00312 00313 uint8_t security_level = mle_service_security_level_get(cur->id); 00314 tr_debug("Link REQUEST"); 00315 bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); 00316 if (bufId == 0) { 00317 return -1; 00318 } 00319 00320 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00321 00322 ptr = mle_general_write_source_address(ptr, cur); 00323 ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); 00324 if (security_level) { 00325 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00326 } 00327 00328 memcpy(ll64, ADDR_LINK_LOCAL_PREFIX, 8); 00329 memcpy(&ll64[8], mac64, 8); 00330 ll64[8] ^= 2; 00331 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00332 tr_debug("Buffer overflow at message write"); 00333 } 00334 timeout.retrans_max = 2; 00335 timeout.timeout_init = 2; 00336 timeout.timeout_max = 4; 00337 timeout.delay = MLE_NO_DELAY; 00338 00339 //SET Destination address 00340 mle_service_set_msg_destination_address(bufId, ll64); 00341 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00342 00343 mle_service_send_message(bufId); 00344 return 0; 00345 } 00346 00347 00348 static uint8_t mle_advert_neigh_cnt(int8_t interface_id, bool short_adr) { 00349 00350 uint8_t advert_neigh_cnt; 00351 uint8_t neighb_max; 00352 00353 uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); 00354 00355 if (short_adr == true) { 00356 neighb_max = 16; 00357 } else { 00358 neighb_max = 5; 00359 } 00360 00361 if (mle_neigh_cnt > neighb_max) { 00362 advert_neigh_cnt = neighb_max; 00363 } else { 00364 advert_neigh_cnt = mle_neigh_cnt; 00365 } 00366 00367 return (advert_neigh_cnt); 00368 } 00369 00370 static uint8_t mle_link_quality_tlv_parse(uint8_t *mac64, uint16_t short_address, uint8_t *ptr, uint16_t data_length, uint8_t *iop_flags_ptr, uint8_t *link_idr_ptr) 00371 { 00372 uint8_t entry_size; 00373 00374 if (data_length) { 00375 entry_size = (*ptr++ & 0x0f) + 3; 00376 data_length--; 00377 00378 // Supports 2 and 8 bytes long MAC addresses 00379 if ((entry_size == 4) || (entry_size == 10)) { 00380 00381 uint8_t own_addr_match = false; 00382 00383 // Searches own address from link quality TLV 00384 while (data_length >= entry_size ) { 00385 00386 if (entry_size == 4){ 00387 if (common_read_16_bit(ptr + 2) == short_address) { 00388 own_addr_match = true; 00389 } 00390 } else { 00391 if (memcmp(ptr + 2, mac64, 8) == 0) { 00392 own_addr_match = true; 00393 } 00394 } 00395 00396 // If own address is found returns success 00397 if (own_addr_match) { 00398 if (iop_flags_ptr) { 00399 *iop_flags_ptr = ptr[0]; 00400 } 00401 if (link_idr_ptr) { 00402 *link_idr_ptr = ptr[1]; 00403 } 00404 return 1; 00405 } 00406 00407 ptr += entry_size; 00408 data_length -= entry_size; 00409 } 00410 } 00411 } 00412 return 0; 00413 } 00414 00415 static uint8_t *mle_table_set_neighbours(int8_t interface_id, uint8_t *ptr) 00416 { 00417 uint8_t *len_ptr = 0; 00418 uint8_t short_temp[2] = {0xff,0xff}; 00419 uint8_t neigh_count = 0; 00420 uint8_t neigh_count_max = 0; 00421 uint8_t *link_flags_ptr; 00422 mle_neigh_table_entry_t *first_entry_ptr = NULL; 00423 bool loop_list = false; 00424 00425 mle_neigh_table_list_t * neigh_list = mle_class_active_list_get(interface_id); 00426 if (!neigh_list) { 00427 return ptr; 00428 } 00429 00430 *ptr++ = MLE_TYPE_LINK_QUALITY; 00431 len_ptr = ptr++; 00432 *len_ptr = 1; 00433 // defaults: complete, 2 bytes long link-layer address 00434 link_flags_ptr = ptr++; 00435 *link_flags_ptr = 0x81; 00436 00437 if (mle_class_get_by_link_address(interface_id, short_temp,ADDR_802_15_4_SHORT )) { 00438 *link_flags_ptr |= 0x07; 00439 neigh_count_max = mle_advert_neigh_cnt(interface_id, false); 00440 } else { 00441 neigh_count_max = mle_advert_neigh_cnt(interface_id, true); 00442 } 00443 00444 do { 00445 ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) 00446 { 00447 00448 loop_list = false; 00449 00450 if ((cur->handshakeReady) && (cur->link_q_adv_sent == false)) { 00451 00452 // If looping list, stops adding entries when at first sent entry again 00453 if (first_entry_ptr == cur) { 00454 break; 00455 } else if (first_entry_ptr == NULL) { 00456 first_entry_ptr = cur; 00457 } 00458 00459 // Limits the number of entries that are sent 00460 if (++neigh_count > neigh_count_max) { 00461 *link_flags_ptr &= 0x7f; 00462 break; 00463 } 00464 00465 if (cur->priorityFlag) { 00466 *ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; 00467 } else { 00468 *ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK; 00469 } 00470 00471 *ptr++ = etx_local_incoming_idr_read(interface_id, cur) >> 3; 00472 00473 if ((*link_flags_ptr & 0x07) == 1) { 00474 ptr = common_write_16_bit(cur->short_adr, ptr); 00475 *len_ptr += 4; 00476 } else { 00477 memcpy(ptr, cur->mac64, 8); 00478 ptr += 8; 00479 *len_ptr += 10; 00480 } 00481 00482 // If end of the neighbor list, start adding entries from start again 00483 if (cur->link.next == 0) { 00484 loop_list = true; 00485 mle_neigh_table_list_t * neigh_temp = mle_class_active_list_get(interface_id); 00486 ns_list_foreach(mle_neigh_table_entry_t, temp, neigh_temp) 00487 { 00488 // Marks entries not sent 00489 temp->link_q_adv_sent = false; 00490 } 00491 } else { 00492 cur->link_q_adv_sent = true; 00493 } 00494 } 00495 } 00496 } while (loop_list); 00497 00498 return ptr; 00499 } 00500 00501 #ifndef NO_MLE 00502 static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t *cur) 00503 { 00504 /* How was this 40 calculated? Seems to be more than enough, at least. 00505 * MODE = 2+1, SRC_ADDR = 2+2, LINK = 2+1+4*neighbours, ROUTE = 2+MLE_ROUTE_MIN_OPTION_LEN+routers 00506 * Total = 10 + neighbours * 4 00507 */ 00508 uint16_t neig_cache_size = 40 + 7; 00509 uint8_t short_temp[2] = {0xff,0xff}; 00510 uint8_t *ptr; 00511 mle_message_timeout_params_t timeout; 00512 00513 if (!cur) { 00514 return 0; 00515 } 00516 00517 if (mle_class_get_by_link_address(cur->id, short_temp,ADDR_802_15_4_SHORT )) { 00518 neig_cache_size += mle_advert_neigh_cnt(cur->id, false) * 10; 00519 } else { 00520 neig_cache_size += mle_advert_neigh_cnt(cur->id, true) << 2; 00521 } 00522 00523 uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT); 00524 00525 if (bufId == 0) { 00526 return -1; 00527 } 00528 00529 timeout.retrans_max = 0; 00530 timeout.timeout_init = 0; 00531 timeout.timeout_max = 0; 00532 timeout.delay = MLE_NO_DELAY; 00533 00534 tr_debug("Send MLE Advertisement"); 00535 mle_service_set_msg_destination_address(bufId,ADDR_LINK_LOCAL_ALL_ROUTERS); 00536 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00537 00538 ptr = mle_service_get_data_pointer(bufId); 00539 ptr = mle_general_write_source_address(ptr, cur); 00540 ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); 00541 ptr = mle_table_set_neighbours(cur->id, ptr); 00542 00543 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00544 tr_debug("Buffer overflow at message write"); 00545 } 00546 00547 return mle_service_send_message(bufId); 00548 } 00549 #endif 00550 00551 static uint8_t compute_link_margin(int8_t rssi) 00552 { 00553 if (rssi < -94) { 00554 return 0; 00555 } 00556 00557 return (rssi + 94); 00558 } 00559 00560 static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info) 00561 { 00562 /** 00563 * MLE Request need to include always challenge 00564 * - MLE_TYPE_CHALLENGE 00565 */ 00566 if (mle_tlv_option_discover(ptr, data_len, MLE_TYPE_CHALLENGE, tlv_info) < 4) { 00567 // TLV not found or length is smaller than 4 00568 return -1; 00569 } 00570 return 0; 00571 } 00572 00573 static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length) 00574 { 00575 mle_tlv_info_t mle_tlv_info; 00576 uint32_t timeout_tlv; 00577 00578 if (!mle_6lowpan_data) { 00579 return; 00580 } 00581 00582 if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) { 00583 uint8_t *t_ptr = mle_tlv_info.dataPtr; 00584 entry_temp->mode = *t_ptr; 00585 } 00586 00587 if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { 00588 timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); 00589 } else { 00590 if (entry_temp->mode & MLE_FFD_DEV) { 00591 timeout_tlv = mle_6lowpan_data->router_lifetime; 00592 } else { 00593 timeout_tlv = mle_6lowpan_data->host_lifetime; 00594 } 00595 } 00596 mle_entry_timeout_update(entry_temp, timeout_tlv); 00597 } 00598 00599 static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address) 00600 { 00601 mle_tlv_info_t mle_tlv_info; 00602 00603 if (tlv_length) { 00604 if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) { 00605 entry_temp->short_adr = common_read_16_bit(mle_tlv_info.dataPtr); 00606 } 00607 00608 if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) { 00609 uint8_t link_idr; 00610 uint8_t iop_flags; 00611 if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) { 00612 etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp); 00613 00614 if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) { 00615 entry_temp->priority_child_flag = true; 00616 } else { 00617 entry_temp->priority_child_flag = false; 00618 } 00619 } 00620 } 00621 } 00622 00623 } 00624 00625 //Generate link request 00626 static uint16_t mle_router_synch(protocol_interface_info_entry_t *cur, const uint8_t *destAddress, uint8_t delay, uint8_t incoming_idr, bool retrans, bool register_short) 00627 { 00628 mle_message_timeout_params_t timeout; 00629 uint16_t bufId = mle_service_msg_allocate(cur->id, 64, true, MLE_COMMAND_REQUEST); 00630 if (bufId == 0) { 00631 return 0; 00632 } 00633 00634 uint8_t security_level = mle_service_security_level_get(cur->id); 00635 00636 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00637 if (register_short) { 00638 ptr = mle_tlv_write_source_address(ptr, cur->lowpan_desired_short_address); 00639 } else { 00640 ptr = mle_general_write_source_address(ptr, cur); 00641 } 00642 ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); 00643 if (security_level) { 00644 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00645 } 00646 if (cur->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 00647 ptr = mle_general_write_timeout(ptr, cur); 00648 } 00649 00650 if (destAddress && incoming_idr != 0){ 00651 uint8_t mac64[8]; 00652 memcpy(mac64, &destAddress[8], 8); 00653 mac64[0] ^= 2; 00654 ptr = mle_tlv_write_link_quality(ptr, incoming_idr, mac64, 0, false); 00655 } 00656 00657 if (destAddress) { 00658 mle_service_set_msg_destination_address(bufId,destAddress); 00659 } else { 00660 mle_service_set_msg_destination_address(bufId,ADDR_LINK_LOCAL_ALL_ROUTERS); 00661 } 00662 00663 if (retrans) { 00664 if (destAddress) { 00665 timeout.retrans_max = 3; 00666 timeout.timeout_init = 1; 00667 timeout.timeout_max = 3; 00668 } else { 00669 timeout.retrans_max = 2; 00670 timeout.timeout_init = 2; 00671 timeout.timeout_max = 4; 00672 } 00673 } else { 00674 timeout.retrans_max = 1; 00675 timeout.timeout_init = 1; 00676 timeout.timeout_max = 3; 00677 } 00678 00679 timeout.delay = delay; 00680 00681 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00682 tr_debug("Buffer overflow at message write"); 00683 } 00684 00685 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00686 mle_service_send_message(bufId); 00687 return bufId; 00688 } 00689 00690 static int mle_router_accept_request_build(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, uint8_t *challenge, uint8_t chalLen, uint8_t type, uint8_t incoming_idr, uint8_t priority_flag) 00691 { 00692 uint16_t bufId; 00693 uint8_t mac64[8]; 00694 mle_message_timeout_params_t timeout; 00695 00696 uint8_t security_level = mle_service_security_level_get(cur->id); 00697 00698 00699 00700 if (type == MLE_COMMAND_ACCEPT) { 00701 bufId = mle_service_msg_allocate(cur->id, 64, false,type); 00702 timeout.retrans_max = 0; 00703 timeout.timeout_init = 0; 00704 timeout.timeout_max = 0; 00705 } else { 00706 bufId = mle_service_msg_allocate(cur->id, 64, true,type); 00707 timeout.retrans_max = 2; 00708 timeout.timeout_init = 2; 00709 timeout.timeout_max = 2; 00710 } 00711 00712 if (bufId == 0) { 00713 return -1; 00714 } 00715 00716 if (addr_is_ipv6_multicast(mle_msg->packet_dst_address)) { 00717 timeout.delay = MLE_STANDARD_RESPONSE_DELAY; 00718 } else { 00719 timeout.delay = MLE_NO_DELAY; 00720 } 00721 00722 tr_debug("MLE Router Link Request response"); 00723 00724 mle_service_set_msg_destination_address(bufId,mle_msg->packet_src_address); 00725 00726 uint8_t *ptr = mle_service_get_data_pointer(bufId); 00727 ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); 00728 00729 if (security_level) { 00730 ptr = mle_general_write_link_layer_framecounter(ptr, cur); 00731 } 00732 00733 if (challenge && chalLen) { 00734 00735 ptr = mle_tlv_write_response(ptr, challenge, chalLen); 00736 } 00737 00738 memcpy(mac64, &mle_msg->packet_src_address[8], 8); 00739 mac64[0] ^= 2; 00740 ptr = mle_tlv_write_link_quality(ptr, incoming_idr, mac64, 0, priority_flag); 00741 00742 ptr = mle_general_write_source_address(ptr, cur); 00743 if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { 00744 tr_debug("Buffer overflow at message write"); 00745 } 00746 mle_service_set_msg_timeout_parameters(bufId, &timeout); 00747 00748 if (type == MLE_COMMAND_ACCEPT) { 00749 mle_service_set_msg_token_bucket_priority(bufId); 00750 } else { 00751 mle_service_set_packet_callback(bufId, mle_accept_request_cb); 00752 } 00753 00754 mle_service_send_message(bufId); 00755 return 0; 00756 } 00757 00758 static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64) 00759 { 00760 mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false); 00761 tr_debug("MLE link reject"); 00762 if (entry_temp) { 00763 mle_class_remove_entry(cur->id, entry_temp); 00764 } 00765 } 00766 00767 static bool mle_child_update_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries) 00768 { 00769 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00770 if (!cur) { 00771 return false; 00772 } 00773 00774 if (mle_service_check_msg_response(msgId)) { 00775 return false; 00776 } 00777 00778 if (usedAllRetries) { 00779 tr_debug("Link Update fail-->Reset bootstrap"); 00780 mac_data_poll_protocol_poll_mode_decrement(cur); 00781 bootsrap_next_state_kick(ER_BOOTSTRAP_CONNECTION_DOWN, cur); 00782 00783 return false; 00784 } 00785 mac_data_poll_protocol_poll_mode_decrement(cur); 00786 return true; 00787 } 00788 00789 int protocol_6lowpan_child_update(protocol_interface_info_entry_t *cur) 00790 { 00791 uint16_t bufId; 00792 uint8_t cordAddress[16]; 00793 if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, cordAddress) != 0) { 00794 return -1; 00795 } 00796 00797 bufId = mle_router_synch(cur, cordAddress, MLE_NO_DELAY, 0, true, false); 00798 if (bufId == 0) { 00799 return -1; 00800 } 00801 00802 return mle_service_set_packet_callback(bufId, mle_child_update_cb); 00803 00804 } 00805 00806 static bool mle_parent_link_req_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries) 00807 { 00808 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00809 if (!cur) { 00810 return false; 00811 } 00812 00813 if (mle_service_check_msg_response(msgId)) { 00814 if (cur->nwk_bootstrap_state == ER_MLE_LINK_REQ) { 00815 //Enter ND scan 00816 bootsrap_next_state_kick(ER_SCAN, cur); 00817 } 00818 #ifdef HAVE_RPL 00819 else if (cur->nwk_bootstrap_state == ER_ROUTER_SYNCH) { 00820 //Trig RPL multicast dis 00821 cur->nwk_bootstrap_state = ER_RPL_MC; 00822 cur->bootsrap_state_machine_cnt = 55; 00823 } 00824 #endif 00825 else if (cur->nwk_bootstrap_state == ER_MLE_LINK_ADDRESS_SYNCH) { 00826 mac_data_poll_protocol_poll_mode_disable(cur); 00827 bootsrap_next_state_kick(ER_BOOTSRAP_DONE, cur); 00828 00829 } else if (cur->nwk_bootstrap_state == ER_MLE_LINK_SHORT_SYNCH) { 00830 tr_debug("MAC16 address synch ready"); 00831 //SET Here 16-bit 00832 //SET MAC16 Address & LL16 00833 mac_helper_mac16_address_set(cur, cur->lowpan_desired_short_address); 00834 protocol_6lowpan_set_ll16(cur, cur->lowpan_desired_short_address); 00835 protocol_6lowpan_address_reg_ready(cur); 00836 } 00837 return false; 00838 } 00839 00840 if (usedAllRetries) { 00841 switch (cur->nwk_bootstrap_state) { 00842 case ER_MLE_LINK_REQ: 00843 case ER_ROUTER_SYNCH: 00844 case ER_MLE_LINK_ADDRESS_SYNCH: 00845 case ER_MLE_LINK_SHORT_SYNCH: 00846 tr_debug("Link synch fail %u", cur->nwk_bootstrap_state); 00847 bootsrap_next_state_kick(ER_BOOTSTRAP_CONNECTION_DOWN, cur); 00848 break; 00849 default: 00850 break; 00851 } 00852 return false; 00853 } 00854 return true; 00855 } 00856 00857 static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries) 00858 { 00859 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00860 if (!cur) { 00861 return false; 00862 } 00863 00864 if (mle_service_check_msg_response(msgId)) { 00865 return false; 00866 } 00867 00868 if (usedAllRetries) { 00869 //If message has been sent by MLE service sends MLE reject to clear link 00870 if (mle_service_check_msg_sent(msgId)) { 00871 uint8_t *address_ptr = mle_service_get_msg_destination_address_pointer(msgId); 00872 mle_service_reject_message_build(cur->id, address_ptr, false); 00873 } 00874 return false; 00875 } 00876 return true; 00877 } 00878 00879 int protocol_6lowpan_parent_link_req(protocol_interface_info_entry_t *cur) 00880 { 00881 uint16_t bufId; 00882 uint8_t cordAddress[16]; 00883 if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, cordAddress) != 0) { 00884 return -1; 00885 } 00886 00887 bufId = mle_router_synch(cur, cordAddress, MLE_NO_DELAY, 0, true, false); 00888 if (bufId == 0) { 00889 tr_debug("No Buf"); 00890 return -1; 00891 } 00892 cur->nwk_bootstrap_state = ER_MLE_LINK_REQ; 00893 00894 return mle_service_set_packet_callback(bufId, mle_parent_link_req_cb); 00895 00896 } 00897 #ifdef HAVE_RPL 00898 static int protocol_6lowpan_router_multicast_synch(protocol_interface_info_entry_t *cur) 00899 { 00900 uint16_t bufId; 00901 00902 bufId = mle_router_synch(cur, NULL, MLE_NO_DELAY, 0, true, false); 00903 00904 if (bufId == 0) { 00905 return -1; 00906 } 00907 cur->nwk_bootstrap_state = ER_ROUTER_SYNCH; 00908 00909 return mle_service_set_packet_callback(bufId, mle_parent_link_req_cb); 00910 } 00911 #endif 00912 00913 static int protocol_6lowpan_parent_address_synch(protocol_interface_info_entry_t *cur, bool register_short) 00914 { 00915 uint16_t bufId; 00916 00917 uint8_t cordAddress[16]; 00918 if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, cordAddress) != 0) { 00919 return -1; 00920 } 00921 00922 bufId = mle_router_synch(cur, cordAddress, MLE_NO_DELAY, 0, true, register_short); 00923 if (bufId == 0) { 00924 return -1; 00925 } 00926 if (register_short) { 00927 cur->nwk_bootstrap_state = ER_MLE_LINK_SHORT_SYNCH; 00928 00929 } else { 00930 cur->nwk_bootstrap_state = ER_MLE_LINK_ADDRESS_SYNCH; 00931 } 00932 00933 return mle_service_set_packet_callback(bufId, mle_parent_link_req_cb); 00934 } 00935 00936 static bool mle_new_link_req_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries) 00937 { 00938 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00939 if (!cur) { 00940 return false; 00941 } 00942 00943 uint8_t *address_ptr = mle_service_get_msg_destination_address_pointer(msgId); 00944 00945 if (mle_service_check_msg_response(msgId)) { 00946 if (address_ptr && !addr_is_ipv6_multicast(address_ptr)) { 00947 // Remove from blacklist 00948 blacklist_update(address_ptr, true); 00949 } 00950 return false; 00951 } 00952 00953 if (usedAllRetries) { 00954 if (address_ptr && !addr_is_ipv6_multicast(address_ptr)) { 00955 tr_warn("Sync fail to new router"); 00956 // Add to blacklist or update current entry 00957 blacklist_update(address_ptr, false); 00958 } 00959 return false; 00960 } 00961 return true; 00962 } 00963 00964 int protocol_6lowpan_router_synch_to_new_router(protocol_interface_info_entry_t *cur, uint8_t *ll64, uint8_t incoming_idr, bool retrans) 00965 { 00966 uint16_t bufId; 00967 00968 bufId = mle_router_synch(cur, ll64, MLE_STANDARD_RESPONSE_DELAY, incoming_idr, retrans, false); 00969 if (bufId == 0) { 00970 return -1; 00971 } 00972 00973 return mle_service_set_packet_callback(bufId, mle_new_link_req_cb); 00974 } 00975 00976 00977 static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mle_neigh_table_entry_t *entry_temp) 00978 { 00979 00980 return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp) >> 3; 00981 00982 } 00983 00984 static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t *mle_msg, uint8_t only_max_limit_chk) 00985 { 00986 uint16_t mle_neigh_cnt; 00987 bool link_quality = false; 00988 00989 if (!mle_6lowpan_data || mle_6lowpan_data->nbr_of_neigh_max == 0) { 00990 return true; 00991 } 00992 00993 mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); 00994 00995 // Neighbor max limit 00996 if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) { 00997 tr_debug("Number of neighbor max limit"); 00998 return false; 00999 } 01000 01001 if (only_max_limit_chk) { 01002 return true; 01003 } 01004 01005 if (mle_msg->message_type == MLE_COMMAND_REQUEST) { 01006 mle_tlv_info_t mle_tlv_info; 01007 if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) { 01008 link_quality = true; 01009 } 01010 } 01011 01012 // Lower threshold reached, start to limit answering to multicast messages 01013 if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_lower_threshold) { 01014 // If multicast link request or link request was triggered from advertisement 01015 if (addr_is_ipv6_multicast(mle_msg->packet_dst_address) || link_quality == true) { 01016 01017 // Upper threshold reached, no responses to multicasts anymore 01018 if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_upper_threshold) { 01019 return false; 01020 } 01021 01022 uint16_t ignore_prob = randLIB_get_random_in_range(1, 01023 mle_6lowpan_data->nbr_of_neigh_upper_threshold - mle_6lowpan_data->nbr_of_neigh_lower_threshold); 01024 01025 if (ignore_prob < (mle_neigh_cnt - mle_6lowpan_data->nbr_of_neigh_lower_threshold)) { 01026 return false; 01027 } 01028 } 01029 } 01030 01031 return true; 01032 } 01033 01034 void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) 01035 { 01036 uint8_t *t_ptr; 01037 uint8_t response_type; 01038 uint8_t mode = 0x0a; 01039 mle_tlv_info_t mle_tlv_info; 01040 mle_tlv_info_t mle_challenge; 01041 mle_neigh_table_entry_t *entry_temp; 01042 uint8_t linkMargin; 01043 uint8_t incoming_idr; 01044 uint16_t responseId, own_mac16; 01045 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01046 if (!cur) { 01047 return; 01048 } 01049 01050 //Calculate link margin 01051 linkMargin = compute_link_margin(mle_msg->dbm); 01052 01053 own_mac16 = mac_helper_mac16_address_get(cur); 01054 01055 switch (mle_msg->message_type) { 01056 case MLE_COMMAND_REQUEST: 01057 tr_debug("Link REQ"); 01058 if (!cur->global_address_available) { 01059 return; 01060 } else if (mle_validate_6lowpan_link_request_message(mle_msg->data_ptr, mle_msg->data_length,&mle_challenge) !=0 ) { 01061 return; 01062 } 01063 01064 entry_temp = NULL; 01065 //If link request frame counter is invalid do not update neighbor entry and use three way handshake 01066 if (security_headers->invalid_frame_counter) { 01067 //Limit rate for triggering link requests 01068 if (!mle_6lowpan_data->link_req_token_bucket) { 01069 return; 01070 } 01071 mle_6lowpan_data->link_req_token_bucket--; 01072 } else { 01073 //Update only old information based on link request 01074 entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); 01075 if (entry_temp) { 01076 mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); 01077 mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); 01078 mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); 01079 } else { 01080 if (!mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { 01081 return; 01082 } 01083 } 01084 } 01085 01086 incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp); 01087 01088 if (entry_temp && entry_temp->handshakeReady) { 01089 response_type = MLE_COMMAND_ACCEPT; 01090 } else { 01091 response_type = MLE_COMMAND_ACCEPT_AND_REQUEST; 01092 } 01093 mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, response_type, incoming_idr, false); 01094 break; 01095 01096 case MLE_COMMAND_ACCEPT_AND_REQUEST: 01097 case MLE_COMMAND_ACCEPT: 01098 if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) { 01099 if (mle_validate_6lowpan_link_request_message(mle_msg->data_ptr, mle_msg->data_length, &mle_challenge) != 0) { 01100 return; 01101 } 01102 } 01103 //Validate Response First 01104 responseId = mle_tlv_validate_response(mle_msg->data_ptr, mle_msg->data_length); 01105 if (responseId == 0) { 01106 return; 01107 } 01108 01109 tr_debug("Accept & Request"); 01110 01111 entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); 01112 01113 if (!entry_temp) { 01114 // If there is space for neighbors try to allocate new entry 01115 if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, true)) { 01116 entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true); 01117 } 01118 } 01119 01120 if (!entry_temp) { 01121 tr_debug("Reject by no space"); 01122 mle_service_reject_message_build(cur->id, mle_msg->packet_src_address, false); 01123 return; 01124 } 01125 01126 //Init mle security counters 01127 01128 //Response state set now timeout know positive state 01129 mle_service_set_msg_response_true(responseId); 01130 01131 entry_temp->threadNeighbor = false; 01132 entry_temp->handshakeReady = 1; 01133 01134 mac_data_poll_protocol_poll_mode_decrement(cur); 01135 01136 //Read Source address and Challenge 01137 mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); 01138 if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) { 01139 // If no global address set priority (bootstrap ongoing) 01140 if (!cur->global_address_available) { 01141 entry_temp->priorityFlag = true; 01142 } 01143 01144 mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); 01145 incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); 01146 mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, entry_temp->priorityFlag); 01147 } else { 01148 mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); 01149 incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); 01150 } 01151 mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); 01152 // If MLE frame counter was invalid update its value since three way handshake is complete 01153 if (security_headers->invalid_frame_counter) { 01154 entry_temp->mle_frame_counter = security_headers->frameCounter; 01155 } 01156 break; 01157 01158 case MLE_COMMAND_REJECT: 01159 if (security_headers->invalid_frame_counter) { 01160 return; 01161 } 01162 protocol_6lowpan_link_reject_handler(cur, mle_msg->packet_src_address); 01163 break; 01164 01165 case MLE_COMMAND_ADVERTISEMENT: 01166 tr_info("Received MLE Advertisement from %s", trace_ipv6(mle_msg->packet_src_address)); 01167 if (!cur->global_address_available || security_headers->invalid_frame_counter) { 01168 tr_error("MLE adv: Invalid frame counter: %s", security_headers->invalid_frame_counter ? "true" : "false"); 01169 return; 01170 } else { 01171 uint8_t drop_advertisment = 0; 01172 01173 if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) { 01174 t_ptr = mle_tlv_info.dataPtr; 01175 mode = *t_ptr; 01176 } 01177 01178 entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false); 01179 if (!entry_temp) { 01180 if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) { 01181 // If there is space for neighbors synchronizes to new router 01182 if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { 01183 // Checks blacklist 01184 if (blacklist_reject(mle_msg->packet_src_address)) { 01185 return; 01186 } 01187 incoming_idr = mle_calculate_idr(interface_id, mle_msg, NULL); 01188 protocol_6lowpan_router_synch_to_new_router(cur, mle_msg->packet_src_address, 0, false); 01189 } 01190 } 01191 tr_error("MLE adv: No MLE entry"); 01192 return; 01193 } 01194 01195 //Verify Own Address 01196 drop_advertisment = 1; 01197 //Disvover own address only when we are aloocated address 01198 if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) { 01199 uint8_t link_flags; 01200 if (mle_tlv_info.tlvLen > 0) { 01201 link_flags = *(mle_tlv_info.dataPtr); 01202 if (mle_link_quality_tlv_parse(cur->mac,mac_helper_mac16_address_get(cur) , mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, NULL, NULL)) 01203 { 01204 drop_advertisment = 0; 01205 } 01206 01207 if (drop_advertisment) { 01208 if (link_flags & 0x80) { 01209 //Total Entry at messgae 01210 //Possible remove 01211 if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) { 01212 //Remove Entry 01213 mle_class_remove_entry(cur->id, entry_temp); 01214 tr_error("MLE adv: Own address not found"); 01215 return; 01216 } 01217 } 01218 } 01219 } 01220 } 01221 01222 //UPDATE 01223 mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); 01224 mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); 01225 if (entry_temp->handshakeReady) { 01226 mle_entry_timeout_refresh(entry_temp); 01227 } 01228 } 01229 break; 01230 01231 default: 01232 break; 01233 } 01234 } 01235 01236 int8_t arm_6lowpan_mle_service_ready_for_security_init(protocol_interface_info_entry_t *cur) 01237 { 01238 //Verify MLE Service 01239 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01240 //validate MLE service 01241 if (!mle_service_interface_registeration_validate(cur->id)) { 01242 //Register 01243 if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { 01244 tr_error("Mle Service init Fail"); 01245 return -1; 01246 } 01247 if (mle_6lowpan_data) { 01248 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01249 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01250 return -1; 01251 } 01252 mle_service_set_frame_counter_check(true); 01253 mle_service_set_accept_invalid_frame_counter(true); 01254 } 01255 } 01256 } 01257 return 0; 01258 } 01259 01260 static uint8_t protocol_6lowpan_mle_data_allocate(void) 01261 { 01262 if (mle_6lowpan_data) { 01263 return 0; 01264 } 01265 01266 mle_6lowpan_data = ns_dyn_mem_alloc(sizeof(mle_6lowpan_data_t)); 01267 01268 if (!mle_6lowpan_data) { 01269 return 0; 01270 } 01271 01272 mle_6lowpan_data->router_lifetime = MLE_ROUTER_DEFAULT_LIFETIME; 01273 mle_6lowpan_data->host_lifetime = MLE_ROUTER_HOST_LIFETIME; 01274 mle_6lowpan_data->nbr_of_neigh_lower_threshold = MLE_NBR_OF_NEIGHBOR_MAX_LIMIT; 01275 mle_6lowpan_data->nbr_of_neigh_upper_threshold = MLE_NBR_OF_NEIGHBOR_LOWER_THRESHOLD; 01276 mle_6lowpan_data->nbr_of_neigh_max = MLE_NBR_OF_NEIGHBOR_UPPER_THRESHOLD; 01277 01278 mle_6lowpan_data->token_bucket_size = MLE_TOKEN_BUCKET_SIZE; 01279 mle_6lowpan_data->token_bucket_rate = MLE_TOKEN_BUCKET_RATE; 01280 mle_6lowpan_data->token_bucket_count = MLE_TOKEN_BUCKET_COUNT; 01281 01282 mle_6lowpan_data->link_req_token_bucket = MLE_LINK_REQ_TOKEN_BUCKET_SIZE; 01283 01284 return 0; 01285 } 01286 01287 mle_6lowpan_data_t *protocol_6lowpan_mle_data_get(void) 01288 { 01289 return mle_6lowpan_data; 01290 } 01291 01292 static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority) 01293 { 01294 mle_neigh_table_list_t *mle_neigh_table; 01295 uint8_t count = 0; 01296 uint8_t ll64[16]; 01297 01298 if (!cur_interface) { 01299 return; 01300 } 01301 01302 mle_neigh_table = mle_class_active_list_get(cur_interface->id); 01303 01304 if (!mle_neigh_table) { 01305 return; 01306 } 01307 01308 entry_count = protocol_6lowpan_mle_order_last_entries(mle_neigh_table, entry_count); 01309 01310 ns_list_foreach_reverse_safe(mle_neigh_table_entry_t, entry, mle_neigh_table) { 01311 if (++count > entry_count) { 01312 break; 01313 } 01314 01315 if (!force_priority) { 01316 if (entry->priorityFlag || entry->priority_child_flag) { 01317 break; 01318 } 01319 } 01320 01321 memcpy(ll64, ADDR_LINK_LOCAL_PREFIX, 8); 01322 memcpy(&ll64[8], entry->mac64, 8); 01323 ll64[8] ^= 2; 01324 01325 tr_debug("MLE purge"); 01326 01327 // Sends REJECT 01328 mle_service_reject_message_build(cur_interface->id, ll64, false); 01329 mle_class_remove_entry(cur_interface->id, entry); 01330 01331 // Adds purged neighbor to blacklist so that it is not added right away back from advertisement 01332 blacklist_update(ll64, false); 01333 } 01334 } 01335 01336 static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count) 01337 { 01338 mle_neigh_table_entry_t *last; 01339 mle_neigh_table_entry_t *first_ordered = NULL; 01340 uint8_t count = 0; 01341 01342 do { 01343 last = NULL; 01344 01345 ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { 01346 01347 if (entry == first_ordered) { 01348 break; 01349 } 01350 01351 if (last == NULL) { 01352 last = entry; 01353 continue; 01354 } 01355 01356 // Primary parent (parent selected for bootstrap or RPL primary parent) 01357 if (entry->priorityFlag && !last->priorityFlag) { 01358 continue; 01359 } 01360 01361 // Secondary parent (RPL secondary parent) 01362 if (entry->second_priority_flag && !last->second_priority_flag) { 01363 continue; 01364 } 01365 01366 // Uses this node as parent 01367 if (entry->priority_child_flag && !last->priority_child_flag) { 01368 continue; 01369 } 01370 01371 // Better ETX 01372 if (entry->etx <= last->etx) { 01373 continue; 01374 } 01375 01376 last = entry; 01377 } 01378 01379 // Sets last to end of list 01380 if (last) { 01381 ns_list_remove(mle_neigh_table, last); 01382 01383 if (first_ordered) { 01384 ns_list_add_before(mle_neigh_table, first_ordered, last); 01385 } else { 01386 ns_list_add_to_end(mle_neigh_table, last); 01387 } 01388 01389 first_ordered = last; 01390 01391 count++; 01392 01393 if (count == entry_count) { 01394 break; 01395 } 01396 // If no lasts anymore then exits 01397 } else { 01398 break; 01399 } 01400 01401 } while (true); 01402 01403 return count; 01404 } 01405 01406 static int8_t arm_6lowpan_bootstrap_down(protocol_interface_info_entry_t *cur) 01407 { 01408 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 01409 return -1; 01410 } 01411 mac_data_poll_disable(cur); 01412 /* Save security counter values to RAM and NVM */ 01413 if (cur->nwk_wpan_nvm_api) { 01414 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01415 } 01416 cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id); 01417 mle_service_interface_receiver_handler_update(cur->id, mle_6lowpan_message_handler); 01418 return nwk_6lowpan_down(cur); 01419 } 01420 #ifdef HAVE_6LOWPAN_ND 01421 01422 static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg) 01423 { 01424 #ifdef PANA 01425 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 01426 //Accept Only Link Reject 01427 if (interface && mle_msg->message_type == MLE_COMMAND_REJECT) { 01428 01429 if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) { 01430 return; 01431 } 01432 01433 if (protocol_6lowpan_interface_compare_cordinator_netid(interface, mle_msg->packet_src_address + 8) != 0) { 01434 return; 01435 } 01436 01437 if (interface->nwk_bootstrap_state != ER_PANA_AUTH) { 01438 return; 01439 } 01440 01441 //Stop Pana and call ECC 01442 tr_debug("MLE Link reject from cordinator"); 01443 pana_reset_client_session(); 01444 bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, interface); 01445 } 01446 #endif 01447 } 01448 01449 void arm_6lowpan_security_init_ifup(protocol_interface_info_entry_t *cur) 01450 { 01451 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01452 01453 mle_service_security_init(cur->id, cur->if_lowpan_security_params->security_level,cur->if_lowpan_security_params->mle_security_frame_counter, NULL, protocol_6lowpan_mle_service_security_notify_cb); 01454 switch (cur->if_lowpan_security_params->nwk_security_mode) { 01455 01456 case NET_SEC_MODE_PSK_LINK_SECURITY: 01457 01458 mle_service_security_set_security_key(cur->id, cur->if_lowpan_security_params->psk_key_info.security_key, cur->if_lowpan_security_params->psk_key_info.key_id, true); 01459 mle_service_security_set_frame_counter(cur->id, cur->if_lowpan_security_params->mle_security_frame_counter); 01460 break; 01461 case NET_SEC_MODE_PANA_LINK_SECURITY: 01462 mle_service_interface_receiver_bypass_handler_update(cur->id, lowpan_mle_receive_security_bypass_cb); 01463 break; 01464 default: 01465 break; 01466 } 01467 } 01468 01469 cur->mac_parameters->mac_key_id_mode = MAC_KEY_ID_MODE_IDX; 01470 cur->mac_parameters->mac_configured_sec_level = cur->if_lowpan_security_params->security_level; 01471 switch (cur->if_lowpan_security_params->nwk_security_mode) { 01472 01473 case NET_SEC_MODE_PANA_LINK_SECURITY: 01474 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01475 break; 01476 01477 case NET_SEC_MODE_PSK_LINK_SECURITY: 01478 mac_helper_security_default_key_set(cur, cur->if_lowpan_security_params->psk_key_info.security_key, cur->if_lowpan_security_params->psk_key_info.key_id, MAC_KEY_ID_MODE_IDX); 01479 /* fall through */ 01480 default: 01481 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 01482 break; 01483 } 01484 } 01485 #endif 01486 01487 static int8_t arm_6lowpan_bootstrap_up(protocol_interface_info_entry_t *cur) 01488 { 01489 int8_t ret_val = -1; 01490 if ((cur->configure_flags & INTERFACE_SETUP_MASK) != INTERFACE_SETUP_READY) { 01491 tr_debug("Interface not yet fully configured"); 01492 ret_val = -5; 01493 } else { 01494 01495 //Verify MLE Service 01496 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01497 //validate MLE service 01498 if (!mle_service_interface_registeration_validate(cur->id)) { 01499 //Register 01500 01501 if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { 01502 tr_error("Mle Service init Fail"); 01503 return -1; 01504 } 01505 } 01506 01507 if (mle_6lowpan_data) { 01508 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01509 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01510 tr_error("Mle Service tokens set Fail"); 01511 return -1; 01512 } 01513 mle_service_set_frame_counter_check(true); 01514 mle_service_set_accept_invalid_frame_counter(true); 01515 } 01516 } 01517 01518 arm_6lowpan_security_init_ifup(cur); 01519 01520 //SET 6lowpan default here 01521 mac_helper_mac_mlme_max_retry_set(cur->id, LOWPAN_MAX_FRAME_RETRIES); 01522 01523 addr_interface_set_ll64(cur, NULL); 01524 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER) { 01525 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 01526 //rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 01527 icmpv6_radv_enable(cur); 01528 } 01529 ret_val = nwk_6lowpan_up(cur); 01530 } 01531 return ret_val; 01532 } 01533 #endif 01534 01535 void arm_6lowpan_bootstrap_init(protocol_interface_info_entry_t *cur) 01536 { 01537 //Init 6lowpan Bootsrap 01538 icmp_nd_routers_init(); 01539 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ACTIVE; 01540 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY; 01541 bootsrap_next_state_kick(ER_SCAN, cur); 01542 mac_helper_mac16_address_set(cur, 0xffff); 01543 } 01544 01545 #ifdef HAVE_6LOWPAN_ND 01546 static void arm_6lowpan_bootstrap_functions_set(protocol_interface_info_entry_t *cur) 01547 { 01548 cur->if_up = arm_6lowpan_bootstrap_up; 01549 cur->if_down = arm_6lowpan_bootstrap_down; 01550 } 01551 01552 static uint8_t protocol_6lowpan_analyze_beacon_payload(uint8_t *ptr, uint8_t len, protocol_interface_info_entry_t *cur) 01553 { 01554 (void)len; 01555 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01556 01557 if (*ptr == filter->beacon_protocol_id_filter || filter->beacon_protocol_id_filter == 0xff) { 01558 ptr++; 01559 if (filter->nwk_active_scan_level == 2) { 01560 if ((*ptr & 1)) { 01561 if (filter->beacon_nwk_id_filter) { 01562 ptr++; 01563 if (memcmp(filter->beacon_nwk_id_filter, ptr, 16)) { 01564 tr_debug("NWK ID filter"); 01565 return 0; 01566 } 01567 } 01568 return 1; 01569 } 01570 } else { 01571 return 1; 01572 } 01573 } 01574 01575 return 0; 01576 } 01577 01578 int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur) 01579 { 01580 int8_t ret_val = -1; 01581 if ((cur->configure_flags & INTERFACE_SETUP_NETWORK_DRIVER_MASK) != INTERFACE_SETUP_NETWORK_DRIVER_READY) { 01582 tr_debug("Interface not yet fully configured\n"); 01583 ret_val = -5; 01584 } else { 01585 protocol_6lowpan_register_handlers(cur); 01586 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 01587 mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); 01588 mac_helper_default_security_level_set(cur, SEC_NONE); 01589 01590 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) { 01591 mac_helper_pib_boolean_set(cur, macAssociationPermit, false); 01592 mac_helper_pib_boolean_set(cur, macPromiscuousMode, true); 01593 lowpan_bootstrap_pan_control(cur, false); 01594 01595 } else if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT) { 01596 // Updates beacon 01597 beacon_join_priority_update(cur->id); 01598 mac_helper_pib_boolean_set(cur, macAssociationPermit, true); 01599 net_load_balance_internal_state_activate(cur, true); 01600 } 01601 01602 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 01603 cur->interface_mode = INTERFACE_UP; 01604 cur->nwk_mode = ARM_NWK_RAW_PHY_MODE; 01605 cur->lowpan_info |= (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY); 01606 cur->bootsrap_state_machine_cnt = 0; 01607 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 01608 01609 ret_val = 0; 01610 } 01611 return ret_val; 01612 } 01613 01614 static bool lowpan_interface_is_active(int8_t interface_id) { 01615 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01616 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 01617 return false; 01618 } 01619 01620 return true; 01621 } 01622 01623 static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) 01624 { 01625 if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) { 01626 tr_debug("Trig Next Key"); 01627 mac_helper_security_key_swap_next_to_default(cur); 01628 mle_service_security_key_trig(cur->id, security_params->KeyIndex); 01629 if (cur->nwk_wpan_nvm_api) { 01630 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01631 } 01632 } 01633 } 01634 int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension) 01635 { 01636 int8_t ret_val = -1; 01637 bool enable_mle_protocol = true; 01638 protocol_interface_info_entry_t *cur; 01639 01640 cur = protocol_stack_interface_info_get_by_id(interface_id); 01641 if (!cur) { 01642 return -1; 01643 } 01644 01645 arm_6lowpan_bootstrap_functions_set(cur); 01646 cur->mac_parameters->beacon_ind = protocol_6lowpan_analyze_beacon_payload; 01647 01648 mac_beacon_link_beacon_join_priority_tx_callback_set(cur->id, protocol_6lowpan_beacon_join_priority_tx); 01649 mac_beacon_link_beacon_compare_rx_callback_set(cur->id, protocol_6lowpan_beacon_compare_rx); 01650 01651 if (net_6lowpan_mode_extension == NET_6LOWPAN_ND_WITHOUT_MLE) { 01652 enable_mle_protocol = false; 01653 } 01654 01655 cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb; 01656 //Allocate MLE class here 01657 //Deallocate old here 01658 01659 mle_class_deallocate(interface_id); 01660 01661 if (enable_mle_protocol) { 01662 01663 mac_description_storage_size_t buffer; 01664 //Read MAC device table sizes 01665 if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { 01666 return -1; 01667 } 01668 if (mle_class_init(interface_id, buffer.device_decription_table_size, &protocol_6lowpan_neighbor_information_remove, &protocol_6lowpan_host_challenge, &lowpan_interface_is_active) != 0) { 01669 return -1; 01670 } 01671 mle_class_router_challenge(interface_id, protocol_6lowpan_router_challenge); 01672 } 01673 01674 mle_service_interface_unregister(cur->id); 01675 01676 if (bootstrap_mode == NET_6LOWPAN_NETWORK_DRIVER || bootstrap_mode == NET_6LOWPAN_SNIFFER) { 01677 enable_mle_protocol = false; 01678 cur->if_up = arm_network_processor_up; 01679 if (bootstrap_mode == NET_6LOWPAN_NETWORK_DRIVER) { 01680 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT; 01681 cur->mac_parameters->beacon_ind = NULL; //Drop beacons 01682 } else { 01683 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER; 01684 } 01685 cur->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE; 01686 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 01687 arm_nwk_6lowpan_borderrouter_data_free(cur); 01688 01689 ret_val = 0; 01690 goto bootstrap_finish_check; 01691 } else { 01692 if (enable_mle_protocol) { 01693 #ifdef NO_MLE 01694 return -2; 01695 #else 01696 cur->comm_status_ind_cb = lowpan_comm_status_indication_cb; 01697 if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { 01698 tr_error("Mle Service init Fail"); 01699 return -1; 01700 } 01701 01702 if (protocol_6lowpan_mle_data_allocate() != 0) { 01703 tr_error("MLE data allocate Fail"); 01704 return -1; 01705 } 01706 01707 if (blacklist_init() != 0) { 01708 tr_error("Blacklist init Fail"); 01709 return -1; 01710 } 01711 01712 if (mle_6lowpan_data) { 01713 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01714 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01715 tr_error("Mle Service tokens set Fail"); 01716 return -1; 01717 } 01718 mle_service_set_frame_counter_check(true); 01719 mle_service_set_accept_invalid_frame_counter(true); 01720 } 01721 #endif 01722 } 01723 01724 arm_6lowpan_bootstrap_functions_set(cur); 01725 cur->configure_flags &= ~INTERFACE_BOOTSTRAP_DEFINED; 01726 switch (bootstrap_mode) { 01727 case NET_6LOWPAN_HOST: 01728 protocol_6lowpan_host_init(cur, false); 01729 ret_val = 0; 01730 break; 01731 case NET_6LOWPAN_SLEEPY_HOST: 01732 protocol_6lowpan_host_init(cur, true); 01733 ret_val = 0; 01734 break; 01735 01736 case NET_6LOWPAN_ROUTER: 01737 protocol_6lowpan_router_init(cur); 01738 ret_val = 0; 01739 break; 01740 01741 case NET_6LOWPAN_BORDER_ROUTER: 01742 ret_val = arm_nwk_6lowpan_borderrouter_init(cur); 01743 cur->mac_parameters->beacon_ind = NULL; //Drop beacons 01744 break; 01745 default: 01746 break; 01747 01748 } 01749 } 01750 01751 bootstrap_finish_check: 01752 if (ret_val == 0) { 01753 /** 01754 * Do Thread dealloc 01755 */ 01756 thread_info_deallocate(cur); 01757 //ADD RPL Support if supported and device is router 01758 #ifdef HAVE_RPL 01759 /** 01760 * ADD RPL Flag If device is router 01761 */ 01762 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01763 //rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 01764 //rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur); 01765 } 01766 #endif 01767 cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED; 01768 if (enable_mle_protocol) { 01769 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_MLE; 01770 } else { 01771 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_MLE; 01772 } 01773 } 01774 01775 return ret_val; 01776 } 01777 01778 01779 static void protocol_6lowpan_bootstrap_icmp_rs_msg_tx(protocol_interface_info_entry_t *cur) 01780 { 01781 buffer_t *buf = icmpv6_build_rs(cur, NULL); 01782 01783 protocol_push(buf); 01784 } 01785 01786 void nwk_6lowpan_router_scan_state(protocol_interface_info_entry_t *cur) 01787 { 01788 cur->nwk_rpl_scan_counter = 0; 01789 if (cur->nwk_nd_re_scan_count == 0) { 01790 if (cur->border_router_setup) { 01791 //Activate RS 01792 arm_border_router_ready(cur); 01793 } else { 01794 tr_warn("No ND Router"); 01795 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 01796 } 01797 01798 } else { 01799 //Verify is ND Object allocated already 01800 if (!cur->border_router_setup && nd_object_active()) { 01801 tr_debug("Wait response from ND"); 01802 } else { 01803 tr_debug("RS*"); 01804 protocol_6lowpan_bootstrap_icmp_rs_msg_tx(cur); 01805 cur->nwk_nd_re_scan_count--; 01806 if (cur->border_router_setup) { 01807 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(25, 50); 01808 } else { 01809 if ((cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) == 0) { 01810 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(25, 40); 01811 } else { 01812 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(60, 70); 01813 } 01814 } 01815 } 01816 } 01817 } 01818 01819 void nwk_6lowpan_bootstrap_ready(protocol_interface_info_entry_t *cur) 01820 { 01821 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) { 01822 uint8_t bootsrap_ready = 0; 01823 01824 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 01825 01826 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01827 if (pana_ping_notify_msg_tx(cur->mac_parameters->pan_id) == 0) { 01828 tr_warn("PING TX fail"); 01829 } else { 01830 bootsrap_ready = 1; 01831 } 01832 01833 } else { 01834 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01835 #ifndef NO_MLE 01836 tr_debug("MLE Parent Advertisment"); 01837 if (protocol_6lowpan_mle_neigh_advertise(cur) == 0) { 01838 bootsrap_ready = 1; 01839 } else { 01840 tr_warn("MLE Host Parent Advert TX fail"); 01841 } 01842 #endif 01843 } else { 01844 bootsrap_ready = 1; 01845 } 01846 } 01847 } else { 01848 bootsrap_ready = 1; 01849 01850 } 01851 if (bootsrap_ready) { 01852 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01853 // Updates beacon 01854 beacon_join_priority_update(cur->id); 01855 lowpan_bootstrap_pan_control(cur, true); 01856 } 01857 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 01858 } else { 01859 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 01860 cur->bootsrap_state_machine_cnt = 2; 01861 } 01862 } 01863 } 01864 01865 void protocol_6lowpan_link_advertise_handle(nd_router_t *cur, protocol_interface_info_entry_t *cur_interface, uint16_t tick) 01866 { 01867 if ((cur_interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_MLE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) == (INTERFACE_NWK_BOOTSRAP_MLE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) { 01868 #ifndef NO_MLE 01869 if (cur->mle_advert_timer) { 01870 if (cur->mle_advert_timer > tick) { 01871 cur->mle_advert_timer -= tick; 01872 01873 } else { 01874 if (protocol_6lowpan_mle_neigh_advertise(cur_interface) == 0) { 01875 01876 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 01877 cur->mle_advert_timer = 0; 01878 } else { 01879 cur->mle_advert_timer = 155; 01880 01881 if (mle_6lowpan_data) { 01882 uint16_t period = mle_6lowpan_data->router_lifetime / 4; 01883 if (period > 640) { 01884 period = 640; 01885 } 01886 period *= 10; //seconds ticks --> 100ms ticks 01887 //set 0.9 - 1.1 * period 01888 cur->mle_advert_timer = randLIB_randomise_base(period, LOWPAN_RAND_LOW, LOWPAN_RAND_HIGH); 01889 } 01890 } 01891 } else { 01892 cur->mle_advert_timer = 2; 01893 } 01894 01895 if (cur->mle_purge_timer) { 01896 cur->mle_purge_timer -= 1; 01897 } else { 01898 if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { 01899 uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface->id); 01900 if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) { 01901 protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true); 01902 } 01903 01904 if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_upper_threshold - MLE_NEIGHBOR_PURGE_NBR)) { 01905 protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, false); 01906 } 01907 01908 uint16_t mle_purge_timer; 01909 /* From 1.0 to 1.5 * MLE_NEIGHBOR_PURGE_TIMER */ 01910 mle_purge_timer = randLIB_randomise_base(MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT, 0x8000, 0xC000); 01911 cur->mle_purge_timer = mle_purge_timer; 01912 } 01913 } 01914 // Updates blacklist timer 01915 blacklist_ttl_update(1); 01916 } 01917 } 01918 #endif 01919 } else { 01920 cur->mle_advert_timer = 0; 01921 } 01922 } 01923 01924 static void protocol_6lowpan_nd_ready(protocol_interface_info_entry_t *cur) 01925 { 01926 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 01927 tr_debug("ND BS ready"); 01928 bootsrap_next_state_kick(ER_BIND_COMP, cur); 01929 clear_power_state(ICMP_ACTIVE); 01930 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY; 01931 } else { 01932 tr_debug("RE ND ready"); 01933 clear_power_state(ICMP_ACTIVE); 01934 mac_data_poll_protocol_poll_mode_disable(cur); 01935 //TRIG MLE Challenge for Normal Host 01936 if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) { 01937 //TRIG Only Normal Host 01938 #ifndef NO_MLE 01939 //GET Cordinaotor MLE Entry 01940 addrtype_t addrType; 01941 uint8_t tempAddr[8]; 01942 addrType = mac_helper_coordinator_address_get(cur, tempAddr); 01943 01944 mle_neigh_table_entry_t *entry_t = mle_class_get_by_link_address(cur->id, tempAddr, addrType); 01945 if (entry_t) { 01946 if (entry_t->ttl > MLE_TABLE_CHALLENGE_TIMER) { 01947 entry_t->ttl = (MLE_TABLE_CHALLENGE_TIMER + 1); 01948 } 01949 } 01950 #endif 01951 } 01952 } 01953 } 01954 01955 static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface) 01956 { 01957 nd_router_t *cur; 01958 cur = nd_get_object_by_nwk_id(cur_interface->nwk_id); 01959 01960 if(!cur) { 01961 return; 01962 } 01963 01964 cur->nd_timer = 10; 01965 cur->ns_forward_timer = 0; 01966 01967 uint16_t mle_timer = 0; 01968 protocol_6lowpan_nd_ready(cur_interface); 01969 if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01970 addr_add_router_groups(cur_interface); 01971 addr_add_group(cur_interface, ADDR_REALM_LOCAL_ALL_ROUTERS); 01972 icmpv6_radv_enable(cur_interface); 01973 icmpv6_restart_router_advertisements(cur_interface, cur->border_router); 01974 /* Stop the ND revalidate timer - this means we don't do RS again */ 01975 cur->nd_re_validate = 0; 01976 mle_timer = 300; 01977 } else { 01978 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 01979 mac_data_poll_protocol_poll_mode_decrement(cur_interface); 01980 mle_timer = 20; 01981 } else { 01982 mle_timer = 155; 01983 } 01984 } 01985 if (cur_interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01986 if (cur->mle_advert_timer == 0) { 01987 cur->mle_advert_timer = mle_timer; 01988 cur->mle_purge_timer = MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT; 01989 } 01990 } else { 01991 cur->mle_advert_timer = 0; 01992 } 01993 } 01994 01995 void protocol_6lowpan_bootstrap_nd_ready(protocol_interface_info_entry_t *cur_interface) 01996 { 01997 01998 tr_debug("ND Ready"); 01999 02000 02001 02002 if (cur_interface->lowpan_address_mode == NET_6LOWPAN_GP64_ADDRESS) { 02003 protocol_6lowpan_address_reg_ready(cur_interface); 02004 } else { 02005 //Here we need to verify address mode 02006 tr_debug("Synch MAC16 with parent"); 02007 if (protocol_6lowpan_parent_address_synch(cur_interface, true) != 0 ) { 02008 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur_interface); 02009 } 02010 } 02011 02012 02013 } 02014 02015 #ifdef HAVE_RPL 02016 02017 static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *handle) 02018 { 02019 02020 protocol_interface_info_entry_t *cur = handle; 02021 if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) { 02022 return; 02023 } 02024 switch (event) { 02025 case RPL_EVENT_DAO_DONE: 02026 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 02027 bootsrap_next_state_kick(ER_BOOTSRAP_DONE, cur); 02028 clear_power_state(ICMP_ACTIVE); 02029 } else if (cur->nwk_bootstrap_state == ER_RPL_LOCAL_REPAIR) { 02030 // Updates beacon 02031 cur->bootsrap_state_machine_cnt = 0; 02032 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02033 beacon_join_priority_update(cur->id); 02034 lowpan_bootstrap_pan_control(cur, true); 02035 } 02036 break; 02037 02038 case RPL_EVENT_LOCAL_REPAIR_START: 02039 if (!(cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 02040 tr_error("RPL Local repair started"); 02041 lowpan_bootstrap_pan_control(cur, false); 02042 cur->bootsrap_state_machine_cnt = 0; 02043 cur->nwk_bootstrap_state = ER_RPL_LOCAL_REPAIR; 02044 } 02045 break; 02046 02047 case RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS: 02048 tr_error("RPL Local repair fail-->interface to idle"); 02049 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02050 break; 02051 } 02052 } 02053 02054 /** 02055 * \brief Send ICMP RPL DIS message. 02056 * 02057 * \return 0 , buffer_allocation fail & 1 message sent 02058 */ 02059 uint8_t nwk_bootstrap_icmp_rpl_dis_msg_tx(protocol_interface_info_entry_t *cur) 02060 { 02061 if (cur->rpl_domain) { 02062 rpl_control_transmit_dis(cur->rpl_domain, cur, 0, 0, NULL, 0, NULL); 02063 return 1; 02064 } 02065 02066 return 0; 02067 } 02068 02069 /** 02070 * \brief Send ICMP RPL DIS message to bootstrap coordinator 02071 * 02072 * \return 0 , buffer_allocation fail & 1 message sent 02073 */ 02074 static uint8_t nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(protocol_interface_info_entry_t *cur) 02075 { 02076 if (!cur->rpl_domain) { 02077 return 0; 02078 } 02079 02080 uint8_t coord_address[16]; 02081 if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, coord_address) != 0) { 02082 tr_debug("Unicast DIS no coord"); 02083 return 0; 02084 } 02085 02086 rpl_control_transmit_dis(cur->rpl_domain, cur, 0, 0, NULL, 0, coord_address); 02087 return 1; 02088 } 02089 02090 static void nwk_rpl_dio_scan(protocol_interface_info_entry_t *cur) 02091 { 02092 if (cur->nwk_rpl_scan_counter < MAX_MC_DIS_COUNT) { 02093 if (nwk_bootstrap_icmp_rpl_dis_msg_tx(cur)) { 02094 cur->bootsrap_state_machine_cnt = 45 << cur->nwk_rpl_scan_counter; 02095 cur->nwk_rpl_scan_counter++; 02096 tr_debug("MC_DIS\n"); 02097 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02098 } else { 02099 cur->bootsrap_state_machine_cnt = 3; 02100 } 02101 } else { 02102 //GivE Up Bootsrap 02103 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 02104 } 02105 } 02106 02107 02108 void nwk_6lowpan_rpl_router_discover(protocol_interface_info_entry_t *cur) 02109 { 02110 if (cur->rpl_domain) { 02111 tr_debug("MC DIS Force"); 02112 if (nwk_bootstrap_icmp_rpl_dis_msg_tx(cur)) { 02113 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02114 cur->bootsrap_state_machine_cnt = 55; 02115 } else { 02116 cur->nwk_bootstrap_state = ER_RPL_MC; 02117 cur->bootsrap_state_machine_cnt = 15; 02118 } 02119 } else { 02120 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02121 nwk_6lowpan_bootstrap_ready(cur); 02122 } 02123 } 02124 02125 void nwk_6lowpan_rpl_router_result_check(protocol_interface_info_entry_t *cur) 02126 { 02127 if (cur->rpl_domain) { 02128 if (rpl_control_have_dodag(cur->rpl_domain)) { 02129 tr_debug("UNI DIS"); 02130 cur->bootsrap_state_machine_cnt = 0; 02131 } else { 02132 nwk_rpl_dio_scan(cur); 02133 } 02134 } else { 02135 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02136 nwk_6lowpan_bootstrap_ready(cur); 02137 } 02138 } 02139 #endif 02140 02141 void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *cur) 02142 { 02143 tr_debug("ND Ready!!"); 02144 cur->nwk_rpl_scan_counter = 0; 02145 02146 #ifndef NO_MLE 02147 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 02148 if (protocol_6lowpan_router_multicast_synch(cur) != 0) { 02149 tr_debug("Router link request start fail"); 02150 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02151 } 02152 #ifdef HAVE_RPL 02153 if (protocol_6lowpan_rpl_domain) { 02154 // arm_nwk_6lowpan_rpl_dodag_poison from a previous connection may have left force_leaf set 02155 rpl_control_force_leaf(protocol_6lowpan_rpl_domain, false); 02156 rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 02157 rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur); 02158 } 02159 // Send unicast DIS to coordinator 02160 nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur); 02161 #endif /* HAVE_RPL */ 02162 } else { 02163 //No point to update link 02164 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST || cur->lowpan_address_mode != NET_6LOWPAN_GP64_ADDRESS) { 02165 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) { 02166 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 02167 tr_debug("Enable Poll state"); 02168 mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE); 02169 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); 02170 mac_data_poll_init(cur); 02171 mac_data_poll_init_protocol_poll(cur); 02172 } 02173 if (protocol_6lowpan_parent_address_synch(cur, false) != 0) { 02174 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02175 } 02176 } else { 02177 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02178 nwk_6lowpan_bootstrap_ready(cur); 02179 } 02180 } 02181 #else 02182 #ifdef HAVE_RPL 02183 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02184 nwk_6lowpan_rpl_router_result_check(cur); 02185 #else 02186 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02187 nwk_6lowpan_bootstrap_ready(cur); 02188 #endif 02189 #endif 02190 } 02191 #ifdef PANA 02192 void nwk_6lowpan_pana_key_pull(protocol_interface_info_entry_t *cur) 02193 { 02194 //REG GP16 address 02195 if (pana_ping_notify_msg_tx(cur->mac_parameters->pan_id) == 0) { 02196 tr_warn("PING TX fail"); 02197 cur->nwk_bootstrap_state = ER_PANA_PING; 02198 cur->bootsrap_state_machine_cnt = 2; 02199 } 02200 } 02201 #endif 02202 02203 #ifndef NO_MLE 02204 02205 #ifdef PANA 02206 void nwk_6lowpan_bootsrap_pana_authentication_cb(bool processSuccesfully, protocol_interface_info_entry_t *cur) 02207 { 02208 if (processSuccesfully) { 02209 bootsrap_next_state_kick(ER_PANA_AUTH_DONE, cur); 02210 } else { 02211 bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, cur); 02212 02213 } 02214 } 02215 02216 static void nwk_6lowpan_bootsrap_pana_authentication_start(protocol_interface_info_entry_t *cur) 02217 { 02218 uint8_t temp_coordinator_address[16]; 02219 pana_tls_setup_s setup; 02220 sec_suite_t *suite = 0; 02221 tr_debug("Wake Pana by Bootsrap"); 02222 protocol_6lowpan_interface_get_link_local_cordinator_address(cur, temp_coordinator_address); 02223 //Release old before copy new 02224 if (cur->pana_sec_info_temp == 0) { 02225 tr_debug("Allocate Pana auth Info"); 02226 cur->pana_sec_info_temp = ns_dyn_mem_alloc(sizeof(auth_info_t)); 02227 } 02228 if (cur->if_lowpan_security_params->pana_params) { 02229 setup.psk_key_id = cur->if_lowpan_security_params->pana_params->psk_key_id; 02230 02231 switch (cur->if_lowpan_security_params->pana_params->nwk_chipher_mode) { 02232 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 02233 setup.security_support = SEC_CIPHERSUITE_PSK; 02234 break; 02235 02236 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 02237 setup.security_support = SEC_CIPHERSUITE_ECC; 02238 break; 02239 case NET_TLS_PSK_AND_ECC_CIPHER: 02240 setup.security_support = SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC; 02241 break; 02242 } 02243 02244 setup.pan_id = cur->mac_parameters->pan_id; 02245 suite = pana_client_init(cur->pana_sec_info_temp, temp_coordinator_address, &setup); 02246 02247 } 02248 if (suite) { 02249 //SET address 02250 //SET CORD Address 02251 nd_router_t *object = nd_get_pana_address(); 02252 cur->nwk_bootstrap_state = ER_PANA_AUTH; 02253 cur->bootsrap_state_machine_cnt = 0; 02254 if (object) { 02255 icmp_nd_set_nd_def_router_address(suite->session_address, object); 02256 02257 tr_debug("ND Router adr: %s", trace_ipv6(suite->session_address)); 02258 02259 //SET CORD ADDRESS 02260 if (memcmp(&suite->session_address[8], ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 02261 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT , &(suite->session_address[14])); 02262 } else { 02263 suite->session_address[8] ^= 2; 02264 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG , &(suite->session_address[8])); 02265 suite->session_address[8] ^= 2; 02266 } 02267 } else { 02268 tr_debug("Use Mac Coordinator"); 02269 } 02270 suite->session_port = UDP_PORT_PANA; 02271 suite->interface = cur; 02272 } else { 02273 cur->nwk_bootstrap_state = ER_PANA_AUTH_ERROR; 02274 cur->bootsrap_state_machine_cnt = 1; 02275 } 02276 } 02277 #endif 02278 02279 #endif 02280 02281 static void nwk_6lowpan_network_authentication_fail(protocol_interface_info_entry_t *cur) 02282 { 02283 nwk_scan_params_t *scan_params = 02284 &cur->mac_parameters->nwk_scan_params; 02285 02286 tr_warn("Pana Auhth er"); 02287 02288 scan_params->nwk_cur_active = mac_helper_free_pan_descriptions(scan_params->nwk_cur_active); 02289 //Black List coordinator 02290 uint8_t coord_pan_address[10]; 02291 addrtype_t cord_adr_type = mac_helper_coordinator_address_get(cur, coord_pan_address +2); 02292 02293 if (cord_adr_type != ADDR_NONE ) { 02294 uint16_t pana_id = mac_helper_panid_get(cur); 02295 common_write_16_bit(pana_id, coord_pan_address); 02296 if (cord_adr_type == ADDR_802_15_4_SHORT ) { 02297 memset(coord_pan_address + 4, 0, 6); 02298 } 02299 02300 pan_cordinator_blacklist_pan_set(&cur->pan_cordinator_black_list, coord_pan_address, 300); 02301 } 02302 02303 nwk_bootsrap_state_update(ARM_NWK_AUHTENTICATION_FAIL, cur); 02304 } 02305 02306 02307 static void nwk_protocol_network_key_set_from_pana(protocol_interface_info_entry_t *cur) 02308 { 02309 uint8_t *key_ptr = pana_key_get(cur->pana_sec_info_temp->network_key); 02310 02311 if (key_ptr) { 02312 mac_helper_security_default_key_set(cur, (key_ptr + 16), cur->pana_sec_info_temp->key_id, MAC_KEY_ID_MODE_IDX); 02313 mle_service_security_set_security_key(cur->id, key_ptr, cur->pana_sec_info_temp->key_id, true); 02314 if (cur->nwk_wpan_nvm_api) { 02315 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 02316 } 02317 } 02318 } 02319 02320 uint8_t *protocol_6lowpan_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId) 02321 { 02322 (void)keyId; 02323 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 02324 if (!interface) { 02325 return NULL; 02326 } 02327 switch (event) { 02328 case MLE_SEC_MAX_FRAME_COUNTER_REACHED : 02329 02330 break; 02331 02332 case MLE_SEC_KEY_UPDATE_NOTIFY : 02333 //Call MAC update 02334 mac_helper_security_key_swap_next_to_default(interface); 02335 02336 break; 02337 02338 case MLE_SEC_UNKNOWN_KEY : 02339 break; 02340 } 02341 return NULL; 02342 } 02343 02344 static void nwk_protocol_network_key_init_from_pana(protocol_interface_info_entry_t *cur) 02345 { 02346 uint8_t *key_ptr = pana_key_get(cur->pana_sec_info_temp->network_key); 02347 02348 if (key_ptr) { 02349 mac_helper_security_default_key_set(cur, (key_ptr + 16), cur->pana_sec_info_temp->key_id, MAC_KEY_ID_MODE_IDX); 02350 //mac_security_interface_link_frame_counter_reset(cur->id); 02351 mac_helper_default_security_level_set(cur, SEC_ENC_MIC32); 02352 mac_helper_default_security_key_id_mode_set(cur,MAC_KEY_ID_MODE_IDX); 02353 //Init MLE Frame counter and key's and security 02354 mle_service_security_init(cur->id, SEC_ENC_MIC32,cur->if_lowpan_security_params->mle_security_frame_counter, NULL, protocol_6lowpan_mle_service_security_notify_cb); 02355 mle_service_security_set_security_key(cur->id, key_ptr, cur->pana_sec_info_temp->key_id, true); 02356 mle_service_security_set_frame_counter(cur->id, cur->if_lowpan_security_params->mle_security_frame_counter); 02357 } 02358 } 02359 02360 static void nwk_6lowpan_network_authentication_done(protocol_interface_info_entry_t *cur) 02361 { 02362 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) { 02363 mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params); 02364 02365 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 02366 nwk_protocol_network_key_init_from_pana(cur); 02367 } else { 02368 tr_debug("SET NO security"); 02369 mac_helper_default_security_level_set(cur, SEC_NONE); 02370 } 02371 02372 #ifndef NO_MLE 02373 if (protocol_6lowpan_parent_link_req(cur) != 0) { 02374 tr_debug("Link request start fail"); 02375 } 02376 #else 02377 cur->nwk_bootstrap_state = ER_SCAN; 02378 nwk_6lowpan_router_scan_state(cur); 02379 #endif 02380 } else { 02381 mac_data_poll_protocol_poll_mode_disable(cur); 02382 if ((cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) == 0) { 02383 tr_debug("PULL kEY Done by Host"); 02384 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02385 nwk_6lowpan_bootstrap_ready(cur); 02386 } else { 02387 tr_debug("PULL kEY Done by Router"); 02388 #ifdef PANA 02389 cur->nwk_bootstrap_state = ER_PANA_PING; 02390 nwk_6lowpan_pana_key_pull(cur); 02391 #endif 02392 } 02393 02394 nwk_protocol_network_key_set_from_pana(cur); 02395 #ifndef NO_TLS 02396 #endif 02397 02398 } 02399 } 02400 02401 02402 bool protocol_6lowpan_bootsrap_link_set(protocol_interface_info_entry_t *interface, mlme_pan_descriptor_t *pan_descriptor, const uint8_t *beacon_payload, uint8_t beacon_length) 02403 { 02404 mlme_start_t start_req; 02405 memset(&start_req, 0, sizeof(mlme_start_t)); 02406 mac_helper_coordinator_address_set(interface, (addrtype_t)pan_descriptor->CoordAddrMode, pan_descriptor->CoordAddress); 02407 02408 interface->mac_parameters->mac_channel = pan_descriptor->LogicalChannel; 02409 interface->mac_parameters->pan_id = pan_descriptor->CoordPANId; 02410 if (interface->nwk_wpan_nvm_api) { 02411 wpan_nvm_params_t *params = interface->nwk_wpan_nvm_api->nvm_params_get_cb(interface->nwk_wpan_nvm_api, pan_descriptor->CoordPANId); 02412 interface->if_lowpan_security_params->mle_security_frame_counter = params->mle_securit_counter; 02413 //SET MAC and MLE security frame counters 02414 mle_service_security_set_frame_counter(interface->id, params->mle_securit_counter); 02415 mac_helper_link_frame_counter_set(interface->id, params->mac_security_frame_counter); 02416 } 02417 02418 start_req.PANId = pan_descriptor->CoordPANId; 02419 start_req.LogicalChannel = pan_descriptor->LogicalChannel; 02420 start_req.ChannelPage = 0; 02421 start_req.BeaconOrder = pan_descriptor->SuperframeSpec[0] >> 4; 02422 start_req.SuperframeOrder = pan_descriptor->SuperframeSpec[0] & 0x0f; 02423 //SET Beacon Payload 02424 uint8_t *b_ptr = mac_helper_beacon_payload_reallocate(interface, beacon_length); 02425 if (!b_ptr) { 02426 tr_error("Beacon Payload allocate Fail"); 02427 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02428 return false; 02429 } 02430 memcpy(b_ptr, beacon_payload, beacon_length); 02431 mac_helper_beacon_payload_register(interface); 02432 //Start and set pan-id 02433 interface->mac_api->mlme_req(interface->mac_api, MLME_START, &start_req); 02434 mac_helper_panid_set(interface, pan_descriptor->CoordPANId); 02435 02436 return true; 02437 } 02438 02439 bool protocol_6lowpan_bootsrap_start(protocol_interface_info_entry_t *interface) 02440 { 02441 net_load_balance_internal_state_activate(interface, false); 02442 02443 //SET allways RX ON Idle device by default 02444 mac_helper_pib_boolean_set(interface, macRxOnWhenIdle, true); 02445 interface->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 02446 02447 mac_data_poll_init(interface); 02448 mac_helper_mac16_address_set(interface, 0xffff); 02449 tr_debug("Mac Ready"); 02450 interface->nwk_nd_re_scan_count = 2; 02451 02452 if (interface->if_lowpan_security_params->nwk_security_mode == NET_SEC_MODE_PSK_LINK_SECURITY) { 02453 tr_debug("SET Security Mode"); 02454 mac_helper_default_security_level_set(interface, interface->mac_parameters->mac_configured_sec_level); 02455 mac_helper_default_security_key_id_mode_set(interface,MAC_KEY_ID_MODE_IDX); 02456 } 02457 02458 //Check first pana and then MLE and else start RS scan pahse 02459 if (interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 02460 #ifdef PANA 02461 nwk_6lowpan_bootsrap_pana_authentication_start(interface); 02462 tr_debug("Pana auth"); 02463 #else 02464 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02465 return false; 02466 #endif 02467 } else if (interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 02468 if (protocol_6lowpan_parent_link_req(interface) != 0) { 02469 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02470 return false; 02471 } 02472 } else { 02473 bootsrap_next_state_kick(ER_SCAN, interface); 02474 } 02475 return true; 02476 } 02477 02478 02479 void protocol_6lowpan_mac_scan_confirm(int8_t if_id, const mlme_scan_conf_t* conf) 02480 { 02481 nwk_pan_descriptor_t *result; 02482 nwk_pan_descriptor_t *best; 02483 protocol_interface_info_entry_t *interface = NULL; 02484 02485 if (conf->ScanType != MAC_ACTIVE_SCAN) { 02486 return; 02487 } 02488 02489 interface = protocol_stack_interface_info_get_by_id(if_id); 02490 if (!interface) { 02491 tr_debug("Mac scan confirm:Unknow Interface"); 02492 return; 02493 } 02494 bool is_border_router = false; 02495 if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 02496 is_border_router = true; 02497 } 02498 02499 interface->mac_parameters->nwk_scan_params.active_scan_active = false; 02500 02501 result = arm_net_get_scanned_nwk_list(if_id); 02502 if (!result || !conf->ResultListSize) { 02503 tr_debug("Mac scan confirm:No Beacons"); 02504 if (is_border_router == false) { 02505 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02506 return; 02507 } 02508 } 02509 02510 //Analyze Best Result 02511 best = mac_helper_select_best_lqi(result); 02512 mac_helper_drop_selected_from_the_scanresult(&interface->mac_parameters->nwk_scan_params, best); 02513 02514 bool link_start_ok = false; 02515 if (is_border_router == false) { 02516 link_start_ok = protocol_6lowpan_bootsrap_link_set(interface, best->pan_descriptor, best->beacon_payload, best->beacon_length); 02517 } 02518 02519 mac_helper_free_scan_confirm(&interface->mac_parameters->nwk_scan_params); 02520 02521 best = mac_helper_free_pan_descriptions(best); 02522 02523 if (link_start_ok) { 02524 protocol_6lowpan_bootsrap_start(interface); 02525 } 02526 02527 if (is_border_router == true) { 02528 if (interface->nwk_bootstrap_state == ER_WARM_ACTIVE_SCAN) { 02529 border_router_start(interface, true); 02530 interface->bootsrap_state_machine_cnt = 0; 02531 interface->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02532 } else { 02533 border_router_start(interface, false); 02534 } 02535 02536 } 02537 } 02538 02539 void bootstrap_timer_handle(uint16_t ticks) 02540 { 02541 ticks; 02542 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 02543 if (cur->nwk_id == IF_6LoWPAN) { 02544 if (cur->nwk_bootstrap_state == ER_ACTIVE_SCAN || cur->nwk_bootstrap_state == ER_WARM_ACTIVE_SCAN) { 02545 // Retransmit Scan request 02546 bootsrap_next_state_kick(cur->nwk_bootstrap_state, cur); 02547 tr_error("Restart active scan"); 02548 } else { 02549 // Retransmit Start request 02550 mlme_start_t start_req; 02551 memset(&start_req, 0, sizeof(mlme_start_t)); 02552 start_req.PANId = cur->border_router_setup->mac_panid; 02553 start_req.LogicalChannel = cur->mac_parameters->mac_channel; 02554 start_req.ChannelPage = 0; 02555 start_req.BeaconOrder = 0x0f; 02556 start_req.SuperframeOrder = 0x0f; 02557 start_req.PANCoordinator = 1; 02558 if( cur->mac_api ){ 02559 cur->mac_api->mlme_req(cur->mac_api, MLME_START, (void*)&start_req); 02560 tr_error("Restart MAC"); 02561 } 02562 } 02563 } 02564 } 02565 } 02566 02567 void protocol_6lowpan_bootstrap(protocol_interface_info_entry_t *cur) 02568 { 02569 switch (cur->nwk_bootstrap_state) { 02570 case ER_ACTIVE_SCAN: 02571 case ER_WARM_ACTIVE_SCAN: 02572 tr_debug("Start Active Scan"); 02573 cur->mac_parameters->nwk_scan_params.stack_chan_list = cur->mac_parameters->mac_channel_list; 02574 02575 mlme_scan_t req; 02576 mac_create_scan_request(MAC_ACTIVE_SCAN, &cur->mac_parameters->mac_channel_list, cur->mac_parameters->nwk_scan_params.scan_duration, &req); 02577 if( cur->mac_api ){ 02578 cur->scan_cb = protocol_6lowpan_mac_scan_confirm; 02579 cur->mac_parameters->nwk_scan_params.active_scan_active = true; 02580 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 02581 protocol_timer_start(PROTOCOL_TIMER_BOOTSTRAP_TIM, bootstrap_timer_handle, BOOTSTRAP_SCAN_TIMEOUT); 02582 } 02583 cur->mac_api->mlme_req(cur->mac_api, MLME_SCAN, &req); 02584 } 02585 break; 02586 02587 case ER_SCAN: 02588 //LED1_TOGGLE(); 02589 nwk_6lowpan_router_scan_state(cur); 02590 break; 02591 02592 case ER_PANA_AUTH_ERROR: 02593 nwk_6lowpan_network_authentication_fail(cur); 02594 break; 02595 02596 case ER_PANA_AUTH_DONE: 02597 nwk_6lowpan_network_authentication_done(cur); 02598 break; 02599 02600 case ER_BIND_COMP: 02601 nwk_6lowpan_nd_address_registartion_ready(cur); 02602 break; 02603 02604 #ifdef HAVE_RPL 02605 02606 case ER_RPL_MC: 02607 nwk_6lowpan_rpl_router_discover(cur); 02608 break; 02609 02610 case ER_RPL_SCAN: 02611 nwk_6lowpan_rpl_router_result_check(cur); 02612 break; 02613 #endif 02614 case ER_BOOTSRAP_DONE: 02615 nwk_6lowpan_bootstrap_ready(cur); 02616 break; 02617 02618 case ER_PARENT_SYNCH_LOST: 02619 tr_debug("-->Parent synch Lose"); 02620 nwk_bootsrap_state_update(ARM_NWK_NWK_PARENT_POLL_FAIL, cur); 02621 break; 02622 02623 case ER_BOOTSTRAP_CONNECTION_DOWN: 02624 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02625 break; 02626 02627 case ER_BOOTSTRAP_IP_ADDRESS_ALLOC_FAIL: 02628 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 02629 tr_info("-->idle"); 02630 break; 02631 02632 case ER_BOOTSTRAP_DAD_FAIL: 02633 nwk_bootsrap_state_update(ARM_NWK_DUPLICATE_ADDRESS_DETECTED, cur); 02634 break; 02635 02636 case ER_BOOTSTRAP_SCAN_FAIL: 02637 tr_debug("Network Bootsrap Start Fail"); 02638 nwk_bootsrap_state_update(ARM_NWK_NWK_SCAN_FAIL, cur); 02639 break; 02640 #ifdef PANA 02641 case ER_PANA_PING: 02642 nwk_6lowpan_pana_key_pull(cur); 02643 break; 02644 #endif 02645 case ER_MLE_LINK_REQ: 02646 //No need to do anything in this case 02647 break; 02648 default: 02649 tr_error("Unknow state %d", cur->nwk_bootstrap_state); 02650 02651 } 02652 } 02653 02654 void protocol_6lowpan_nd_borderrouter_connection_down(protocol_interface_info_entry_t *interface) 02655 { 02656 /*if (rpl_object_poisons() == 0) ??? */ { 02657 mac_helper_mac16_address_set(interface, 0xffff); 02658 02659 //TRIG Event for ND connection Down 02660 bootsrap_next_state_kick(ER_BOOTSTRAP_IP_ADDRESS_ALLOC_FAIL, interface); 02661 } 02662 } 02663 02664 void protocol_6lowpan_bootstrap_re_start(protocol_interface_info_entry_t *interface) 02665 { 02666 mac_helper_mac16_address_set(interface, 0xffff); 02667 arm_6lowpan_bootstrap_init(interface); 02668 tr_info("-->Bootsrap"); 02669 } 02670 02671 uint8_t *protocol_6lowpan_nd_border_router_address_get(nwk_interface_id nwk_id) 02672 { 02673 nd_router_t *object = nd_get_object_by_nwk_id(nwk_id); 02674 if (object) { 02675 return object->border_router; 02676 } 02677 return 0; 02678 } 02679 02680 uint8_t protocol_6lowpan_rf_link_scalability_from_lqi(uint8_t lqi) 02681 { 02682 uint8_t i = 16; 02683 if (lqi >= 240) { 02684 i = 1; 02685 } else { 02686 lqi /= 16; 02687 if (lqi) { 02688 i = (16 - lqi); 02689 } 02690 } 02691 return i; 02692 } 02693 02694 int protocol_6lowpan_del_ll16(protocol_interface_info_entry_t *cur, uint16_t mac_short_address) 02695 { 02696 uint8_t address[16]; 02697 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02698 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC, 6); 02699 common_write_16_bit(mac_short_address, &address[14]); 02700 02701 return addr_delete(cur, address); 02702 } 02703 02704 int protocol_6lowpan_set_ll16(protocol_interface_info_entry_t *cur, uint16_t mac_short_address) 02705 { 02706 if_address_entry_t *address_entry; 02707 uint8_t address[16]; 02708 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02709 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC , 6); 02710 common_write_16_bit(mac_short_address, &address[14]); 02711 02712 address_entry = addr_add(cur, address, 64, ADDR_SOURCE_UNKNOWN, 0xffffffff, 0xffffffff, false); 02713 if (address_entry) { 02714 return 0; 02715 } 02716 return -1; 02717 } 02718 02719 static void protocol_6lowpan_generate_link_reject(protocol_interface_info_entry_t *cur, const mlme_comm_status_t *status) 02720 { 02721 uint8_t address[16]; 02722 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02723 if (status->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { 02724 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC , 6); 02725 memcpy(address + 14,status->SrcAddr, 2); 02726 } else { 02727 memcpy(address + 8,status->SrcAddr, 8); 02728 address[8] ^= 2; 02729 } 02730 if (mac_helper_default_security_level_get(cur)) { 02731 mle_service_reject_message_build(cur->id, address, false); 02732 return; 02733 } 02734 02735 } 02736 02737 static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) 02738 { 02739 #ifndef NO_MLE 02740 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); 02741 if (!cur) { 02742 return; 02743 } 02744 02745 switch (status->status) { 02746 case MLME_UNSUPPORTED_SECURITY: 02747 case MLME_UNAVAILABLE_KEY: 02748 /* Generate MLE Link Reject to destination */ 02749 if (status->DstAddrMode == MAC_ADDR_MODE_16_BIT && status->DstAddr[0] == 0xff && status->DstAddr[1] == 0xff) { 02750 return; //Drop brodcast security failure 02751 } 02752 02753 if (!cur->mle_link_reject_tokens) { 02754 return; 02755 } 02756 cur->mle_link_reject_tokens--; 02757 protocol_6lowpan_generate_link_reject(cur, status); 02758 02759 break; 02760 case MLME_DATA_POLL_NOTIFICATION: 02761 mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false); 02762 break; 02763 default: 02764 break; 02765 } 02766 #endif 02767 } 02768 02769 bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address) 02770 { 02771 bool return_value = false; 02772 #ifndef NO_MLE 02773 mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false); 02774 if (neigh_entry) { 02775 //Remove entry 02776 if (neigh_entry->priorityFlag) { 02777 return_value = true; 02778 } else if (neigh_entry->second_priority_flag) { 02779 return_value = true; 02780 } 02781 mle_class_remove_entry(interface_id, neigh_entry); 02782 } 02783 #endif 02784 return return_value; 02785 } 02786 02787 void protocol_6lowpan_mle_timer(uint16_t ticks_update) 02788 { 02789 #ifndef NO_MLE 02790 if (mle_6lowpan_data) { 02791 /* Three request in burst and after that one link request per second */ 02792 mle_6lowpan_data->link_req_token_bucket += ticks_update; 02793 if (mle_6lowpan_data->link_req_token_bucket > MLE_LINK_REQ_TOKEN_BUCKET_SIZE) { 02794 mle_6lowpan_data->link_req_token_bucket = MLE_LINK_REQ_TOKEN_BUCKET_SIZE; 02795 } 02796 } 02797 #endif 02798 } 02799 02800 #endif
Generated on Tue Jul 12 2022 13:03:11 by
