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