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