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