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.
protocol_6lowpan_bootstrap.c
00001 /* 00002 * Copyright (c) 2015-2018, 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 uint8_t advert_neigh_cnt; 00328 uint8_t neighb_max; 00329 00330 uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface); 00331 00332 if (short_adr == true) { 00333 neighb_max = 16; 00334 } else { 00335 neighb_max = 5; 00336 } 00337 00338 if (mle_neigh_cnt > neighb_max) { 00339 advert_neigh_cnt = neighb_max; 00340 } else { 00341 advert_neigh_cnt = mle_neigh_cnt; 00342 } 00343 00344 return (advert_neigh_cnt); 00345 } 00346 00347 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) 00348 { 00349 uint8_t entry_size; 00350 00351 if (data_length) { 00352 entry_size = (*ptr++ & 0x0f) + 3; 00353 data_length--; 00354 00355 // Supports 2 and 8 bytes long MAC addresses 00356 if ((entry_size == 4) || (entry_size == 10)) { 00357 00358 uint8_t own_addr_match = false; 00359 00360 // Searches own address from link quality TLV 00361 while (data_length >= entry_size ) { 00362 00363 if (entry_size == 4){ 00364 if (common_read_16_bit(ptr + 2) == short_address) { 00365 own_addr_match = true; 00366 } 00367 } else { 00368 if (memcmp(ptr + 2, mac64, 8) == 0) { 00369 own_addr_match = true; 00370 } 00371 } 00372 00373 // If own address is found returns success 00374 if (own_addr_match) { 00375 if (iop_flags_ptr) { 00376 *iop_flags_ptr = ptr[0]; 00377 } 00378 if (link_idr_ptr) { 00379 *link_idr_ptr = ptr[1]; 00380 } 00381 return 1; 00382 } 00383 00384 ptr += entry_size; 00385 data_length -= entry_size; 00386 } 00387 } 00388 } 00389 return 0; 00390 } 00391 00392 static bool neighbor_list_short_address_available(mac_neighbor_table_t *table_class) 00393 { 00394 ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, &table_class->neighbour_list ) { 00395 if (cur_entry->connected_device && cur_entry->mac16 == 0xffff) { 00396 return false; 00397 } 00398 } 00399 return true; 00400 } 00401 00402 00403 static uint8_t *mle_table_set_neighbours(protocol_interface_info_entry_t *cur, uint8_t *ptr) 00404 { 00405 uint8_t *len_ptr = 0; 00406 uint8_t neigh_count = 0; 00407 uint8_t neigh_count_max = 0; 00408 uint8_t *link_flags_ptr; 00409 mac_neighbor_table_entry_t *first_entry_ptr = NULL; 00410 00411 mac_neighbor_table_list_t * neigh_list = &cur->mac_parameters->mac_neighbor_table->neighbour_list; 00412 00413 *ptr++ = MLE_TYPE_LINK_QUALITY; 00414 len_ptr = ptr++; 00415 *len_ptr = 1; 00416 00417 link_flags_ptr = ptr++; 00418 //*link_flags_ptr = 0x81; 00419 bool use_short_address_compression = neighbor_list_short_address_available(mac_neighbor_info(cur)); 00420 if (use_short_address_compression) { 00421 //complete, 2 bytes long link-layer address 00422 *link_flags_ptr = 0x81; 00423 } else { 00424 //complete, 8 bytes long link-layer address 00425 *link_flags_ptr = 0x87; 00426 00427 } 00428 neigh_count_max = mle_advert_neigh_cnt(cur, use_short_address_compression); 00429 00430 bool clean_entries = false; 00431 ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list) 00432 { 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 { 01184 drop_advertisment = 0; 01185 } 01186 01187 if (drop_advertisment) { 01188 if (link_flags & 0x80) { 01189 //Total Entry at messgae 01190 //Possible remove 01191 if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) { 01192 //Remove Entry 01193 mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp); 01194 tr_error("MLE adv: Own address not found"); 01195 return; 01196 } 01197 } 01198 } 01199 } 01200 } 01201 01202 //UPDATE 01203 mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); 01204 mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); 01205 if (entry_temp->connected_device ) { 01206 mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime ); 01207 } 01208 } 01209 break; 01210 01211 default: 01212 break; 01213 } 01214 } 01215 01216 int8_t arm_6lowpan_mle_service_ready_for_security_init(protocol_interface_info_entry_t *cur) 01217 { 01218 //Verify MLE Service 01219 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01220 //validate MLE service 01221 if (!mle_service_interface_registeration_validate(cur->id)) { 01222 //Register 01223 if (mle_service_interface_register(cur->id,cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { 01224 tr_error("Mle Service init Fail"); 01225 return -1; 01226 } 01227 if (mle_6lowpan_data) { 01228 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01229 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01230 return -1; 01231 } 01232 mle_service_set_frame_counter_check(true); 01233 mle_service_set_accept_invalid_frame_counter(true); 01234 } 01235 } 01236 } 01237 return 0; 01238 } 01239 01240 static uint8_t protocol_6lowpan_mle_data_allocate(void) 01241 { 01242 if (mle_6lowpan_data) { 01243 return 0; 01244 } 01245 01246 mle_6lowpan_data = ns_dyn_mem_alloc(sizeof(mle_6lowpan_data_t)); 01247 01248 if (!mle_6lowpan_data) { 01249 return 0; 01250 } 01251 01252 mle_6lowpan_data->router_lifetime = MLE_ROUTER_DEFAULT_LIFETIME; 01253 mle_6lowpan_data->host_lifetime = MLE_ROUTER_HOST_LIFETIME; 01254 mle_6lowpan_data->nbr_of_neigh_lower_threshold = MLE_NBR_OF_NEIGHBOR_MAX_LIMIT; 01255 mle_6lowpan_data->nbr_of_neigh_upper_threshold = MLE_NBR_OF_NEIGHBOR_LOWER_THRESHOLD; 01256 mle_6lowpan_data->nbr_of_neigh_max = MLE_NBR_OF_NEIGHBOR_UPPER_THRESHOLD; 01257 01258 mle_6lowpan_data->token_bucket_size = MLE_TOKEN_BUCKET_SIZE; 01259 mle_6lowpan_data->token_bucket_rate = MLE_TOKEN_BUCKET_RATE; 01260 mle_6lowpan_data->token_bucket_count = MLE_TOKEN_BUCKET_COUNT; 01261 01262 mle_6lowpan_data->link_req_token_bucket = MLE_LINK_REQ_TOKEN_BUCKET_SIZE; 01263 01264 return 0; 01265 } 01266 01267 mle_6lowpan_data_t *protocol_6lowpan_mle_data_get(void) 01268 { 01269 return mle_6lowpan_data; 01270 } 01271 01272 static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority) 01273 { 01274 01275 uint8_t count = 0; 01276 uint8_t ll64[16]; 01277 01278 if (!cur_interface) { 01279 return; 01280 } 01281 mac_neighbor_table_list_t *mac_table_list = &cur_interface->mac_parameters->mac_neighbor_table->neighbour_list; 01282 01283 entry_count = protocol_6lowpan_mle_order_last_entries(cur_interface->id, mac_table_list, entry_count); 01284 01285 ns_list_foreach_reverse_safe(mac_neighbor_table_entry_t, entry, mac_table_list) { 01286 if (++count > entry_count) { 01287 break; 01288 } 01289 01290 if (!force_priority) { 01291 if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR || entry->link_role == CHILD_NEIGHBOUR) { 01292 break; 01293 } 01294 } 01295 01296 memcpy(ll64, ADDR_LINK_LOCAL_PREFIX, 8); 01297 memcpy(&ll64[8], entry->mac64, 8); 01298 ll64[8] ^= 2; 01299 01300 tr_debug("MLE purge"); 01301 01302 // Sends REJECT 01303 mle_service_reject_message_build(cur_interface->id, ll64, false); 01304 mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), entry); 01305 01306 // Adds purged neighbor to blacklist so that it is not added right away back from advertisement 01307 blacklist_update(ll64, false); 01308 } 01309 } 01310 01311 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) 01312 { 01313 mac_neighbor_table_entry_t *last; 01314 mac_neighbor_table_entry_t *first_ordered = NULL; 01315 etx_storage_t * etx_last, *etx_cur; 01316 uint8_t count = 0; 01317 do { 01318 last = NULL; 01319 01320 ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_neigh_table) { 01321 01322 if (entry == first_ordered) { 01323 break; 01324 } 01325 01326 if (last == NULL) { 01327 last = entry; 01328 continue; 01329 } 01330 01331 if (entry->link_role > last->link_role ) { //Bigger link role is allways better 01332 continue; 01333 } else if (entry->link_role == last->link_role ) { 01334 // Compare ETX when Link role is same 01335 etx_cur = etx_storage_entry_get(interface_id, entry->index); 01336 etx_last = etx_storage_entry_get(interface_id, last->index ); 01337 if (etx_cur && etx_last && etx_cur->etx <= etx_last->etx) { 01338 continue; 01339 } 01340 } 01341 last = entry; 01342 } 01343 01344 // Sets last to end of list 01345 if (last) { 01346 ns_list_remove(mac_neigh_table, last); 01347 01348 if (first_ordered) { 01349 ns_list_add_before(mac_neigh_table, first_ordered, last); 01350 } else { 01351 ns_list_add_to_end(mac_neigh_table, last); 01352 } 01353 01354 first_ordered = last; 01355 01356 count++; 01357 01358 if (count == entry_count) { 01359 break; 01360 } 01361 // If no lasts anymore then exits 01362 } else { 01363 break; 01364 } 01365 01366 } while (true); 01367 01368 return count; 01369 } 01370 01371 static int8_t arm_6lowpan_bootstrap_down(protocol_interface_info_entry_t *cur) 01372 { 01373 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 01374 return -1; 01375 } 01376 mac_data_poll_disable(cur); 01377 /* Save security counter values to RAM and NVM */ 01378 if (cur->nwk_wpan_nvm_api) { 01379 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01380 } 01381 cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id); 01382 mle_service_interface_receiver_handler_update(cur->id, mle_6lowpan_message_handler); 01383 return nwk_6lowpan_down(cur); 01384 } 01385 #ifdef HAVE_6LOWPAN_ND 01386 01387 static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg) 01388 { 01389 (void) interface_id; 01390 #ifdef PANA 01391 protocol_interface_info_entry_t *interface = mle_msg->interface_ptr; 01392 //Accept Only Link Reject 01393 if (mle_msg->message_type == MLE_COMMAND_REJECT) { 01394 01395 if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) { 01396 return; 01397 } 01398 01399 if (protocol_6lowpan_interface_compare_cordinator_netid(interface, mle_msg->packet_src_address + 8) != 0) { 01400 return; 01401 } 01402 01403 if (interface->nwk_bootstrap_state != ER_PANA_AUTH) { 01404 return; 01405 } 01406 01407 //Stop Pana and call ECC 01408 tr_debug("MLE Link reject from cordinator"); 01409 pana_reset_client_session(); 01410 bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, interface); 01411 } 01412 #endif 01413 } 01414 01415 void arm_6lowpan_security_init_ifup(protocol_interface_info_entry_t *cur) 01416 { 01417 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01418 01419 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); 01420 switch (cur->if_lowpan_security_params->nwk_security_mode) { 01421 01422 case NET_SEC_MODE_PSK_LINK_SECURITY: 01423 01424 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); 01425 mle_service_security_set_frame_counter(cur->id, cur->if_lowpan_security_params->mle_security_frame_counter); 01426 break; 01427 case NET_SEC_MODE_PANA_LINK_SECURITY: 01428 mle_service_interface_receiver_bypass_handler_update(cur->id, lowpan_mle_receive_security_bypass_cb); 01429 break; 01430 default: 01431 break; 01432 } 01433 } 01434 01435 cur->mac_parameters->mac_key_id_mode = MAC_KEY_ID_MODE_IDX; 01436 cur->mac_parameters->mac_configured_sec_level = cur->if_lowpan_security_params->security_level; 01437 switch (cur->if_lowpan_security_params->nwk_security_mode) { 01438 01439 case NET_SEC_MODE_PANA_LINK_SECURITY: 01440 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01441 break; 01442 01443 case NET_SEC_MODE_PSK_LINK_SECURITY: 01444 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); 01445 /* fall through */ 01446 default: 01447 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 01448 break; 01449 } 01450 } 01451 #endif 01452 01453 static int8_t arm_6lowpan_bootstrap_up(protocol_interface_info_entry_t *cur) 01454 { 01455 int8_t ret_val = -1; 01456 if ((cur->configure_flags & INTERFACE_SETUP_MASK) != INTERFACE_SETUP_READY) { 01457 tr_debug("Interface not yet fully configured"); 01458 ret_val = -5; 01459 } else { 01460 01461 //Verify MLE Service 01462 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01463 //validate MLE service 01464 if (!mle_service_interface_registeration_validate(cur->id)) { 01465 //Register 01466 01467 if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { 01468 tr_error("Mle Service init Fail"); 01469 return -1; 01470 } 01471 } 01472 01473 if (mle_6lowpan_data) { 01474 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01475 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01476 tr_error("Mle Service tokens set Fail"); 01477 return -1; 01478 } 01479 mle_service_set_frame_counter_check(true); 01480 mle_service_set_accept_invalid_frame_counter(true); 01481 } 01482 } 01483 01484 arm_6lowpan_security_init_ifup(cur); 01485 01486 //SET 6lowpan default here 01487 mac_helper_mac_mlme_max_retry_set(cur->id, LOWPAN_MAX_FRAME_RETRIES); 01488 01489 addr_interface_set_ll64(cur, NULL); 01490 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER) { 01491 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 01492 //rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 01493 icmpv6_radv_enable(cur); 01494 } 01495 ret_val = nwk_6lowpan_up(cur); 01496 } 01497 return ret_val; 01498 } 01499 #endif 01500 01501 void arm_6lowpan_bootstrap_init(protocol_interface_info_entry_t *cur) 01502 { 01503 //Init 6lowpan Bootsrap 01504 icmp_nd_routers_init(); 01505 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ACTIVE; 01506 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY; 01507 bootsrap_next_state_kick(ER_SCAN, cur); 01508 mac_helper_mac16_address_set(cur, 0xffff); 01509 } 01510 01511 #ifdef HAVE_6LOWPAN_ND 01512 static void arm_6lowpan_bootstrap_functions_set(protocol_interface_info_entry_t *cur) 01513 { 01514 cur->if_up = arm_6lowpan_bootstrap_up; 01515 cur->if_down = arm_6lowpan_bootstrap_down; 01516 } 01517 01518 static uint8_t protocol_6lowpan_analyze_beacon_payload(uint8_t *ptr, uint8_t len, protocol_interface_info_entry_t *cur) 01519 { 01520 (void)len; 01521 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01522 01523 if (*ptr == filter->beacon_protocol_id_filter || filter->beacon_protocol_id_filter == 0xff) { 01524 ptr++; 01525 if (filter->nwk_active_scan_level == 2) { 01526 if ((*ptr & 1)) { 01527 if (filter->beacon_nwk_id_filter) { 01528 ptr++; 01529 if (memcmp(filter->beacon_nwk_id_filter, ptr, 16)) { 01530 tr_debug("NWK ID filter"); 01531 return 0; 01532 } 01533 } 01534 return 1; 01535 } 01536 } else { 01537 return 1; 01538 } 01539 } 01540 01541 return 0; 01542 } 01543 01544 int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur) 01545 { 01546 int8_t ret_val = -1; 01547 if ((cur->configure_flags & INTERFACE_SETUP_NETWORK_DRIVER_MASK) != INTERFACE_SETUP_NETWORK_DRIVER_READY) { 01548 tr_debug("Interface not yet fully configured\n"); 01549 ret_val = -5; 01550 } else { 01551 protocol_6lowpan_register_handlers(cur); 01552 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 01553 mac_helper_default_security_level_set(cur, SEC_NONE); 01554 01555 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) { 01556 mac_helper_pib_boolean_set(cur, macAssociationPermit, false); 01557 mac_helper_pib_boolean_set(cur, macPromiscuousMode, true); 01558 lowpan_bootstrap_pan_control(cur, false); 01559 01560 } else if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT) { 01561 // Updates beacon 01562 beacon_join_priority_update(cur->id); 01563 mac_helper_pib_boolean_set(cur, macAssociationPermit, true); 01564 net_load_balance_internal_state_activate(cur, true); 01565 } 01566 01567 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 01568 cur->interface_mode = INTERFACE_UP; 01569 cur->nwk_mode = ARM_NWK_RAW_PHY_MODE; 01570 cur->lowpan_info |= (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY); 01571 cur->bootsrap_state_machine_cnt = 0; 01572 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 01573 01574 ret_val = 0; 01575 } 01576 return ret_val; 01577 } 01578 01579 static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) 01580 { 01581 if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) { 01582 tr_debug("Trig Next Key"); 01583 mac_helper_security_key_swap_next_to_default(cur); 01584 mle_service_security_key_trig(cur->id, security_params->KeyIndex); 01585 if (cur->nwk_wpan_nvm_api) { 01586 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01587 } 01588 } 01589 } 01590 01591 static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) 01592 { 01593 01594 protocol_interface_info_entry_t *cur_interface = user_data; 01595 lowpan_adaptation_remove_free_indirect_table(cur_interface, entry_ptr); 01596 // Sleepy host 01597 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 01598 mac_data_poll_protocol_poll_mode_decrement(cur_interface); 01599 } 01600 01601 protocol_6lowpan_priority_neighbor_remove(cur_interface, entry_ptr); 01602 01603 if (entry_ptr->ffd_device ) { 01604 protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, entry_ptr->mac16 ); 01605 protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, entry_ptr->mac64 ); 01606 } 01607 mac_helper_devicetable_remove(cur_interface->mac_api, entry_ptr->index ); 01608 //Removes ETX neighbor 01609 etx_neighbor_remove(cur_interface->id, entry_ptr->index ); 01610 //Remove MLE frame counter info 01611 mle_service_frame_counter_entry_delete(cur_interface->id, entry_ptr->index ); 01612 01613 } 01614 01615 01616 static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data) 01617 { 01618 01619 // Sleepy host 01620 protocol_interface_info_entry_t *cur_interface = user_data; 01621 01622 if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01623 //Trig middle way challenge if Broadcast message have been missed 01624 if (!entry_ptr->ffd_device ) { 01625 return false; //End device must do this 01626 } 01627 01628 if (entry_ptr->lifetime > (entry_ptr->link_lifetime / 2)) { 01629 return false; //Trig only when midway is overed 01630 } 01631 return protocol_6lowpan_router_challenge(cur_interface, entry_ptr->mac64 ); 01632 } 01633 01634 if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) { 01635 return false; //Do not never challenge than priority parent 01636 } 01637 01638 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 01639 return false; //Sleepy end device should not never challenge 01640 } 01641 01642 if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) { 01643 return false; 01644 } 01645 01646 return protocol_6lowpan_host_challenge(cur_interface, entry_ptr->mac64 ); 01647 } 01648 01649 01650 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) 01651 { 01652 int8_t ret_val = -1; 01653 bool enable_mle_protocol = true; 01654 protocol_interface_info_entry_t *cur; 01655 01656 cur = protocol_stack_interface_info_get_by_id(interface_id); 01657 if (!cur) { 01658 return -1; 01659 } 01660 01661 arm_6lowpan_bootstrap_functions_set(cur); 01662 cur->mac_parameters->beacon_ind = protocol_6lowpan_analyze_beacon_payload; 01663 01664 mac_beacon_link_beacon_join_priority_tx_callback_set(cur->id, protocol_6lowpan_beacon_join_priority_tx); 01665 mac_beacon_link_beacon_compare_rx_callback_set(cur->id, protocol_6lowpan_beacon_compare_rx); 01666 01667 if (net_6lowpan_mode_extension == NET_6LOWPAN_ND_WITHOUT_MLE) { 01668 enable_mle_protocol = false; 01669 } 01670 01671 cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb; 01672 //Allocate MLE class here 01673 //Deallocate old here 01674 mac_neighbor_table_delete(mac_neighbor_info(cur)); 01675 mac_description_storage_size_t buffer; 01676 //Read MAC device table sizes 01677 if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) { 01678 return -1; 01679 } 01680 01681 mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size, lowpan_neighbor_entry_remove_notify 01682 , lowpan_neighbor_entry_nud_notify, cur); 01683 if (!mac_neighbor_info(cur)) { 01684 return -1; 01685 } 01686 01687 if (enable_mle_protocol) { 01688 if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size)) { 01689 return -1; 01690 } 01691 01692 if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) { 01693 return -1; 01694 } 01695 01696 lowpan_adaptation_interface_etx_update_enable(cur->id); 01697 } 01698 01699 mle_service_interface_unregister(cur->id); 01700 01701 if (bootstrap_mode == NET_6LOWPAN_NETWORK_DRIVER || bootstrap_mode == NET_6LOWPAN_SNIFFER) { 01702 enable_mle_protocol = false; 01703 cur->if_up = arm_network_processor_up; 01704 if (bootstrap_mode == NET_6LOWPAN_NETWORK_DRIVER) { 01705 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT; 01706 cur->mac_parameters->beacon_ind = NULL; //Drop beacons 01707 } else { 01708 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER; 01709 } 01710 cur->lowpan_info &= ~INTERFACE_NWK_ROUTER_DEVICE; 01711 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 01712 arm_nwk_6lowpan_borderrouter_data_free(cur); 01713 01714 ret_val = 0; 01715 goto bootstrap_finish_check; 01716 } else { 01717 if (enable_mle_protocol) { 01718 #ifdef NO_MLE 01719 return -2; 01720 #else 01721 cur->comm_status_ind_cb = lowpan_comm_status_indication_cb; 01722 if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) { 01723 tr_error("Mle Service init Fail"); 01724 return -1; 01725 } 01726 01727 if (protocol_6lowpan_mle_data_allocate() != 0) { 01728 tr_error("MLE data allocate Fail"); 01729 return -1; 01730 } 01731 01732 if (blacklist_init() != 0) { 01733 tr_error("Blacklist init Fail"); 01734 return -1; 01735 } 01736 01737 if (mle_6lowpan_data) { 01738 if (mle_service_interface_token_bucket_settings_set(cur->id, mle_6lowpan_data->token_bucket_size, 01739 mle_6lowpan_data->token_bucket_rate, mle_6lowpan_data->token_bucket_count) < 0) { 01740 tr_error("Mle Service tokens set Fail"); 01741 return -1; 01742 } 01743 mle_service_set_frame_counter_check(true); 01744 mle_service_set_accept_invalid_frame_counter(true); 01745 } 01746 #endif 01747 } 01748 01749 arm_6lowpan_bootstrap_functions_set(cur); 01750 cur->configure_flags &= ~INTERFACE_BOOTSTRAP_DEFINED; 01751 switch (bootstrap_mode) { 01752 case NET_6LOWPAN_HOST: 01753 protocol_6lowpan_host_init(cur, false); 01754 ret_val = 0; 01755 break; 01756 case NET_6LOWPAN_SLEEPY_HOST: 01757 protocol_6lowpan_host_init(cur, true); 01758 ret_val = 0; 01759 break; 01760 01761 case NET_6LOWPAN_ROUTER: 01762 protocol_6lowpan_router_init(cur); 01763 ret_val = 0; 01764 break; 01765 01766 case NET_6LOWPAN_BORDER_ROUTER: 01767 ret_val = arm_nwk_6lowpan_borderrouter_init(cur); 01768 cur->mac_parameters->beacon_ind = NULL; //Drop beacons 01769 break; 01770 default: 01771 break; 01772 01773 } 01774 } 01775 01776 bootstrap_finish_check: 01777 if (ret_val == 0) { 01778 /** 01779 * Do Thread dealloc 01780 */ 01781 thread_info_deallocate(cur); 01782 //ADD RPL Support if supported and device is router 01783 #ifdef HAVE_RPL 01784 /** 01785 * ADD RPL Flag If device is router 01786 */ 01787 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01788 //rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 01789 //rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur); 01790 } 01791 #endif 01792 cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED; 01793 if (enable_mle_protocol) { 01794 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_MLE; 01795 } else { 01796 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_MLE; 01797 } 01798 } 01799 01800 return ret_val; 01801 } 01802 01803 01804 static void protocol_6lowpan_bootstrap_icmp_rs_msg_tx(protocol_interface_info_entry_t *cur) 01805 { 01806 buffer_t *buf = icmpv6_build_rs(cur, NULL); 01807 01808 protocol_push(buf); 01809 } 01810 01811 void nwk_6lowpan_router_scan_state(protocol_interface_info_entry_t *cur) 01812 { 01813 cur->nwk_rpl_scan_counter = 0; 01814 if (cur->nwk_nd_re_scan_count == 0) { 01815 if (cur->border_router_setup) { 01816 //Activate RS 01817 arm_border_router_ready(cur); 01818 } else { 01819 tr_warn("No ND Router"); 01820 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 01821 } 01822 01823 } else { 01824 //Verify is ND Object allocated already 01825 if (!cur->border_router_setup && nd_object_active()) { 01826 tr_debug("Wait response from ND"); 01827 } else { 01828 tr_debug("RS*"); 01829 protocol_6lowpan_bootstrap_icmp_rs_msg_tx(cur); 01830 cur->nwk_nd_re_scan_count--; 01831 if (cur->border_router_setup) { 01832 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(25, 50); 01833 } else { 01834 if ((cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) == 0) { 01835 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(25, 40); 01836 } else { 01837 cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(60, 70); 01838 } 01839 } 01840 } 01841 } 01842 } 01843 01844 void nwk_6lowpan_bootstrap_ready(protocol_interface_info_entry_t *cur) 01845 { 01846 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) { 01847 uint8_t bootsrap_ready = 0; 01848 01849 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 01850 01851 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01852 if (pana_ping_notify_msg_tx(cur->mac_parameters->pan_id) == 0) { 01853 tr_warn("PING TX fail"); 01854 } else { 01855 bootsrap_ready = 1; 01856 } 01857 01858 } else { 01859 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 01860 #ifndef NO_MLE 01861 tr_debug("MLE Parent Advertisment"); 01862 if (protocol_6lowpan_mle_neigh_advertise(cur) == 0) { 01863 bootsrap_ready = 1; 01864 } else { 01865 tr_warn("MLE Host Parent Advert TX fail"); 01866 } 01867 #endif 01868 } else { 01869 bootsrap_ready = 1; 01870 } 01871 } 01872 } else { 01873 bootsrap_ready = 1; 01874 01875 } 01876 if (bootsrap_ready) { 01877 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01878 // Updates beacon 01879 beacon_join_priority_update(cur->id); 01880 lowpan_bootstrap_pan_control(cur, true); 01881 } 01882 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 01883 } else { 01884 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 01885 cur->bootsrap_state_machine_cnt = 2; 01886 } 01887 } 01888 } 01889 01890 void protocol_6lowpan_link_advertise_handle(nd_router_t *cur, protocol_interface_info_entry_t *cur_interface, uint16_t tick) 01891 { 01892 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)) { 01893 #ifndef NO_MLE 01894 if (cur->mle_advert_timer) { 01895 if (cur->mle_advert_timer > tick) { 01896 cur->mle_advert_timer -= tick; 01897 01898 } else { 01899 if (protocol_6lowpan_mle_neigh_advertise(cur_interface) == 0) { 01900 01901 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 01902 cur->mle_advert_timer = 0; 01903 } else { 01904 cur->mle_advert_timer = 155; 01905 01906 if (mle_6lowpan_data) { 01907 uint16_t period = mle_6lowpan_data->router_lifetime / 4; 01908 if (period > 640) { 01909 period = 640; 01910 } 01911 period *= 10; //seconds ticks --> 100ms ticks 01912 //set 0.9 - 1.1 * period 01913 cur->mle_advert_timer = randLIB_randomise_base(period, LOWPAN_RAND_LOW, LOWPAN_RAND_HIGH); 01914 } 01915 } 01916 } else { 01917 cur->mle_advert_timer = 2; 01918 } 01919 01920 if (cur->mle_purge_timer) { 01921 cur->mle_purge_timer -= 1; 01922 } else { 01923 if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { 01924 uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface); 01925 if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) { 01926 protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true); 01927 } 01928 01929 if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_upper_threshold - MLE_NEIGHBOR_PURGE_NBR)) { 01930 protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, false); 01931 } 01932 01933 uint16_t mle_purge_timer; 01934 /* From 1.0 to 1.5 * MLE_NEIGHBOR_PURGE_TIMER */ 01935 mle_purge_timer = randLIB_randomise_base(MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT, 0x8000, 0xC000); 01936 cur->mle_purge_timer = mle_purge_timer; 01937 } 01938 } 01939 // Updates blacklist timer 01940 blacklist_ttl_update(1); 01941 } 01942 } 01943 #endif 01944 } else { 01945 cur->mle_advert_timer = 0; 01946 } 01947 } 01948 01949 static void protocol_6lowpan_nd_ready(protocol_interface_info_entry_t *cur) 01950 { 01951 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 01952 tr_debug("ND BS ready"); 01953 bootsrap_next_state_kick(ER_BIND_COMP, cur); 01954 clear_power_state(ICMP_ACTIVE); 01955 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY; 01956 } else { 01957 tr_debug("RE ND ready"); 01958 clear_power_state(ICMP_ACTIVE); 01959 mac_data_poll_protocol_poll_mode_disable(cur); 01960 //TRIG MLE Challenge for Normal Host 01961 if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) { 01962 //TRIG Only Normal Host 01963 #ifndef NO_MLE 01964 //GET Cordinator MLE Entry 01965 addrtype_t addrType; 01966 uint8_t tempAddr[8]; 01967 addrType = mac_helper_coordinator_address_get(cur, tempAddr); 01968 mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tempAddr, addrType); 01969 01970 if (neig_info) { 01971 if (neig_info->lifetime > MLE_TABLE_CHALLENGE_TIMER) { 01972 neig_info->lifetime = (MLE_TABLE_CHALLENGE_TIMER + 1); 01973 } 01974 } 01975 #endif 01976 } 01977 } 01978 } 01979 01980 static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface) 01981 { 01982 nd_router_t *cur; 01983 cur = nd_get_object_by_nwk_id(cur_interface->nwk_id); 01984 01985 if(!cur) { 01986 return; 01987 } 01988 01989 cur->nd_timer = 10; 01990 cur->ns_forward_timer = 0; 01991 01992 uint16_t mle_timer = 0; 01993 protocol_6lowpan_nd_ready(cur_interface); 01994 if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01995 addr_add_router_groups(cur_interface); 01996 addr_add_group(cur_interface, ADDR_REALM_LOCAL_ALL_ROUTERS); 01997 icmpv6_radv_enable(cur_interface); 01998 icmpv6_restart_router_advertisements(cur_interface, cur->border_router); 01999 /* Stop the ND revalidate timer - this means we don't do RS again */ 02000 cur->nd_re_validate = 0; 02001 mle_timer = 300; 02002 } else { 02003 if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) { 02004 mac_data_poll_protocol_poll_mode_decrement(cur_interface); 02005 mle_timer = 20; 02006 } else { 02007 mle_timer = 155; 02008 } 02009 } 02010 if (cur_interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 02011 if (cur->mle_advert_timer == 0) { 02012 cur->mle_advert_timer = mle_timer; 02013 cur->mle_purge_timer = MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT; 02014 } 02015 } else { 02016 cur->mle_advert_timer = 0; 02017 } 02018 } 02019 02020 void protocol_6lowpan_bootstrap_nd_ready(protocol_interface_info_entry_t *cur_interface) 02021 { 02022 02023 tr_debug("ND Ready"); 02024 02025 02026 02027 if (cur_interface->lowpan_address_mode == NET_6LOWPAN_GP64_ADDRESS) { 02028 protocol_6lowpan_address_reg_ready(cur_interface); 02029 } else { 02030 //Here we need to verify address mode 02031 tr_debug("Synch MAC16 with parent"); 02032 if (protocol_6lowpan_parent_address_synch(cur_interface, true) != 0 ) { 02033 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur_interface); 02034 } 02035 } 02036 02037 02038 } 02039 02040 #ifdef HAVE_RPL 02041 02042 static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *handle) 02043 { 02044 02045 protocol_interface_info_entry_t *cur = handle; 02046 if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) { 02047 return; 02048 } 02049 switch (event) { 02050 case RPL_EVENT_DAO_DONE: 02051 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 02052 bootsrap_next_state_kick(ER_BOOTSRAP_DONE, cur); 02053 clear_power_state(ICMP_ACTIVE); 02054 } else if (cur->nwk_bootstrap_state == ER_RPL_LOCAL_REPAIR) { 02055 // Updates beacon 02056 cur->bootsrap_state_machine_cnt = 0; 02057 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02058 beacon_join_priority_update(cur->id); 02059 lowpan_bootstrap_pan_control(cur, true); 02060 } 02061 break; 02062 02063 case RPL_EVENT_LOCAL_REPAIR_START: 02064 if (!(cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE)) { 02065 tr_error("RPL Local repair started"); 02066 lowpan_bootstrap_pan_control(cur, false); 02067 cur->bootsrap_state_machine_cnt = 0; 02068 cur->nwk_bootstrap_state = ER_RPL_LOCAL_REPAIR; 02069 } 02070 break; 02071 02072 case RPL_EVENT_LOCAL_REPAIR_NO_MORE_DIS: 02073 tr_error("RPL Local repair fail-->interface to idle"); 02074 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02075 break; 02076 } 02077 } 02078 02079 /** 02080 * \brief Send ICMP RPL DIS message. 02081 * 02082 * \return 0 , buffer_allocation fail & 1 message sent 02083 */ 02084 uint8_t nwk_bootstrap_icmp_rpl_dis_msg_tx(protocol_interface_info_entry_t *cur) 02085 { 02086 if (cur->rpl_domain) { 02087 rpl_control_transmit_dis(cur->rpl_domain, cur, 0, 0, NULL, 0, NULL); 02088 return 1; 02089 } 02090 02091 return 0; 02092 } 02093 02094 /** 02095 * \brief Send ICMP RPL DIS message to bootstrap coordinator 02096 * 02097 * \return 0 , buffer_allocation fail & 1 message sent 02098 */ 02099 static uint8_t nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(protocol_interface_info_entry_t *cur) 02100 { 02101 if (!cur->rpl_domain) { 02102 return 0; 02103 } 02104 02105 uint8_t coord_address[16]; 02106 if (protocol_6lowpan_interface_get_link_local_cordinator_address(cur, coord_address) != 0) { 02107 tr_debug("Unicast DIS no coord"); 02108 return 0; 02109 } 02110 02111 rpl_control_transmit_dis(cur->rpl_domain, cur, 0, 0, NULL, 0, coord_address); 02112 return 1; 02113 } 02114 02115 static void nwk_rpl_dio_scan(protocol_interface_info_entry_t *cur) 02116 { 02117 if (cur->nwk_rpl_scan_counter < MAX_MC_DIS_COUNT) { 02118 if (nwk_bootstrap_icmp_rpl_dis_msg_tx(cur)) { 02119 cur->bootsrap_state_machine_cnt = 45 << cur->nwk_rpl_scan_counter; 02120 cur->nwk_rpl_scan_counter++; 02121 tr_debug("MC_DIS\n"); 02122 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02123 } else { 02124 cur->bootsrap_state_machine_cnt = 3; 02125 } 02126 } else { 02127 //GivE Up Bootsrap 02128 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 02129 } 02130 } 02131 02132 02133 void nwk_6lowpan_rpl_router_discover(protocol_interface_info_entry_t *cur) 02134 { 02135 if (cur->rpl_domain) { 02136 tr_debug("MC DIS Force"); 02137 if (nwk_bootstrap_icmp_rpl_dis_msg_tx(cur)) { 02138 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02139 cur->bootsrap_state_machine_cnt = 55; 02140 } else { 02141 cur->nwk_bootstrap_state = ER_RPL_MC; 02142 cur->bootsrap_state_machine_cnt = 15; 02143 } 02144 } else { 02145 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02146 nwk_6lowpan_bootstrap_ready(cur); 02147 } 02148 } 02149 02150 void nwk_6lowpan_rpl_router_result_check(protocol_interface_info_entry_t *cur) 02151 { 02152 if (cur->rpl_domain) { 02153 if (rpl_control_have_dodag(cur->rpl_domain)) { 02154 tr_debug("UNI DIS"); 02155 cur->bootsrap_state_machine_cnt = 0; 02156 } else { 02157 nwk_rpl_dio_scan(cur); 02158 } 02159 } else { 02160 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02161 nwk_6lowpan_bootstrap_ready(cur); 02162 } 02163 } 02164 #endif 02165 02166 void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *cur) 02167 { 02168 tr_debug("ND Ready!!"); 02169 cur->nwk_rpl_scan_counter = 0; 02170 02171 #ifndef NO_MLE 02172 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 02173 if (protocol_6lowpan_router_multicast_synch(cur) != 0) { 02174 tr_debug("Router link request start fail"); 02175 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02176 } 02177 #ifdef HAVE_RPL 02178 if (protocol_6lowpan_rpl_domain) { 02179 // arm_nwk_6lowpan_rpl_dodag_poison from a previous connection may have left force_leaf set 02180 rpl_control_force_leaf(protocol_6lowpan_rpl_domain, false); 02181 rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 02182 rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, cur); 02183 } 02184 // Send unicast DIS to coordinator 02185 nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur); 02186 #endif /* HAVE_RPL */ 02187 } else { 02188 //No point to update link 02189 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST || cur->lowpan_address_mode != NET_6LOWPAN_GP64_ADDRESS) { 02190 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) { 02191 cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 02192 tr_debug("Enable Poll state"); 02193 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); 02194 mac_data_poll_init(cur); 02195 mac_data_poll_init_protocol_poll(cur); 02196 } 02197 if (protocol_6lowpan_parent_address_synch(cur, false) != 0) { 02198 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02199 } 02200 } else { 02201 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02202 nwk_6lowpan_bootstrap_ready(cur); 02203 } 02204 } 02205 #else 02206 #ifdef HAVE_RPL 02207 cur->nwk_bootstrap_state = ER_RPL_SCAN; 02208 nwk_6lowpan_rpl_router_result_check(cur); 02209 #else 02210 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02211 nwk_6lowpan_bootstrap_ready(cur); 02212 #endif 02213 #endif 02214 } 02215 #ifdef PANA 02216 void nwk_6lowpan_pana_key_pull(protocol_interface_info_entry_t *cur) 02217 { 02218 //REG GP16 address 02219 if (pana_ping_notify_msg_tx(cur->mac_parameters->pan_id) == 0) { 02220 tr_warn("PING TX fail"); 02221 cur->nwk_bootstrap_state = ER_PANA_PING; 02222 cur->bootsrap_state_machine_cnt = 2; 02223 } 02224 } 02225 #endif 02226 02227 #ifndef NO_MLE 02228 02229 #ifdef PANA 02230 void nwk_6lowpan_bootsrap_pana_authentication_cb(bool processSuccesfully, protocol_interface_info_entry_t *cur) 02231 { 02232 if (processSuccesfully) { 02233 bootsrap_next_state_kick(ER_PANA_AUTH_DONE, cur); 02234 } else { 02235 bootsrap_next_state_kick(ER_PANA_AUTH_ERROR, cur); 02236 02237 } 02238 } 02239 02240 static void nwk_6lowpan_bootsrap_pana_authentication_start(protocol_interface_info_entry_t *cur) 02241 { 02242 uint8_t temp_coordinator_address[16]; 02243 pana_tls_setup_s setup; 02244 sec_suite_t *suite = 0; 02245 tr_debug("Wake Pana by Bootsrap"); 02246 protocol_6lowpan_interface_get_link_local_cordinator_address(cur, temp_coordinator_address); 02247 //Release old before copy new 02248 if (cur->pana_sec_info_temp == 0) { 02249 tr_debug("Allocate Pana auth Info"); 02250 cur->pana_sec_info_temp = ns_dyn_mem_alloc(sizeof(auth_info_t)); 02251 } 02252 if (cur->if_lowpan_security_params->pana_params) { 02253 setup.psk_key_id = cur->if_lowpan_security_params->pana_params->psk_key_id; 02254 02255 switch (cur->if_lowpan_security_params->pana_params->nwk_chipher_mode) { 02256 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 02257 setup.security_support = SEC_CIPHERSUITE_PSK; 02258 break; 02259 02260 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 02261 setup.security_support = SEC_CIPHERSUITE_ECC; 02262 break; 02263 case NET_TLS_PSK_AND_ECC_CIPHER: 02264 setup.security_support = SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC; 02265 break; 02266 } 02267 02268 setup.pan_id = cur->mac_parameters->pan_id; 02269 suite = pana_client_init(cur->pana_sec_info_temp, temp_coordinator_address, &setup); 02270 02271 } 02272 if (suite) { 02273 //SET address 02274 //SET CORD Address 02275 nd_router_t *object = nd_get_pana_address(); 02276 cur->nwk_bootstrap_state = ER_PANA_AUTH; 02277 cur->bootsrap_state_machine_cnt = 0; 02278 if (object) { 02279 icmp_nd_set_nd_def_router_address(suite->session_address, object); 02280 02281 tr_debug("ND Router adr: %s", trace_ipv6(suite->session_address)); 02282 02283 //SET CORD ADDRESS 02284 if (memcmp(&suite->session_address[8], ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 02285 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT , &(suite->session_address[14])); 02286 } else { 02287 suite->session_address[8] ^= 2; 02288 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG , &(suite->session_address[8])); 02289 suite->session_address[8] ^= 2; 02290 } 02291 } else { 02292 tr_debug("Use Mac Coordinator"); 02293 } 02294 suite->session_port = UDP_PORT_PANA; 02295 suite->interface = cur; 02296 } else { 02297 cur->nwk_bootstrap_state = ER_PANA_AUTH_ERROR; 02298 cur->bootsrap_state_machine_cnt = 1; 02299 } 02300 } 02301 #endif 02302 02303 #endif 02304 02305 static void coordinator_black_list(protocol_interface_info_entry_t *cur) 02306 { 02307 uint8_t coord_pan_address[10]; 02308 addrtype_t cord_adr_type = mac_helper_coordinator_address_get(cur, coord_pan_address +2); 02309 02310 if (cord_adr_type != ADDR_NONE ) { 02311 uint16_t pana_id = mac_helper_panid_get(cur); 02312 common_write_16_bit(pana_id, coord_pan_address); 02313 if (cord_adr_type == ADDR_802_15_4_SHORT ) { 02314 memset(coord_pan_address + 4, 0, 6); 02315 } 02316 02317 pan_cordinator_blacklist_pan_set(&cur->pan_cordinator_black_list, coord_pan_address, 300); 02318 } 02319 } 02320 02321 static void nwk_6lowpan_network_authentication_fail(protocol_interface_info_entry_t *cur) 02322 { 02323 nwk_scan_params_t *scan_params = 02324 &cur->mac_parameters->nwk_scan_params; 02325 02326 tr_warn("Pana Auhth er"); 02327 02328 scan_params->nwk_cur_active = mac_helper_free_pan_descriptions(scan_params->nwk_cur_active); 02329 //Black List coordinator 02330 coordinator_black_list(cur); 02331 02332 nwk_bootsrap_state_update(ARM_NWK_AUHTENTICATION_FAIL, cur); 02333 } 02334 02335 02336 static void nwk_protocol_network_key_set_from_pana(protocol_interface_info_entry_t *cur) 02337 { 02338 uint8_t *key_ptr = pana_key_get(cur->pana_sec_info_temp->network_key); 02339 02340 if (key_ptr) { 02341 mac_helper_security_default_key_set(cur, (key_ptr + 16), cur->pana_sec_info_temp->key_id, MAC_KEY_ID_MODE_IDX); 02342 mle_service_security_set_security_key(cur->id, key_ptr, cur->pana_sec_info_temp->key_id, true); 02343 if (cur->nwk_wpan_nvm_api) { 02344 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 02345 } 02346 } 02347 } 02348 02349 uint8_t *protocol_6lowpan_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId) 02350 { 02351 (void)keyId; 02352 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 02353 if (!interface) { 02354 return NULL; 02355 } 02356 switch (event) { 02357 case MLE_SEC_MAX_FRAME_COUNTER_REACHED : 02358 02359 break; 02360 02361 case MLE_SEC_KEY_UPDATE_NOTIFY : 02362 //Call MAC update 02363 mac_helper_security_key_swap_next_to_default(interface); 02364 02365 break; 02366 02367 case MLE_SEC_UNKNOWN_KEY : 02368 break; 02369 } 02370 return NULL; 02371 } 02372 02373 static void nwk_protocol_network_key_init_from_pana(protocol_interface_info_entry_t *cur) 02374 { 02375 uint8_t *key_ptr = pana_key_get(cur->pana_sec_info_temp->network_key); 02376 02377 if (key_ptr) { 02378 mac_helper_security_default_key_set(cur, (key_ptr + 16), cur->pana_sec_info_temp->key_id, MAC_KEY_ID_MODE_IDX); 02379 //mac_security_interface_link_frame_counter_reset(cur->id); 02380 mac_helper_default_security_level_set(cur, SEC_ENC_MIC32); 02381 mac_helper_default_security_key_id_mode_set(cur,MAC_KEY_ID_MODE_IDX); 02382 //Init MLE Frame counter and key's and security 02383 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); 02384 mle_service_security_set_security_key(cur->id, key_ptr, cur->pana_sec_info_temp->key_id, true); 02385 mle_service_security_set_frame_counter(cur->id, cur->if_lowpan_security_params->mle_security_frame_counter); 02386 } 02387 } 02388 02389 static void nwk_6lowpan_network_authentication_done(protocol_interface_info_entry_t *cur) 02390 { 02391 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ACTIVE) { 02392 mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params); 02393 02394 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 02395 nwk_protocol_network_key_init_from_pana(cur); 02396 } else { 02397 tr_debug("SET NO security"); 02398 mac_helper_default_security_level_set(cur, SEC_NONE); 02399 } 02400 02401 #ifndef NO_MLE 02402 if (protocol_6lowpan_parent_link_req(cur) != 0) { 02403 tr_debug("Link request start fail"); 02404 } 02405 #else 02406 pan_coordinator_blacklist_free(&cur->pan_cordinator_black_list); 02407 cur->nwk_bootstrap_state = ER_SCAN; 02408 nwk_6lowpan_router_scan_state(cur); 02409 #endif 02410 } else { 02411 mac_data_poll_protocol_poll_mode_disable(cur); 02412 if ((cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) == 0) { 02413 tr_debug("PULL kEY Done by Host"); 02414 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02415 nwk_6lowpan_bootstrap_ready(cur); 02416 } else { 02417 tr_debug("PULL kEY Done by Router"); 02418 #ifdef PANA 02419 cur->nwk_bootstrap_state = ER_PANA_PING; 02420 nwk_6lowpan_pana_key_pull(cur); 02421 #endif 02422 } 02423 02424 nwk_protocol_network_key_set_from_pana(cur); 02425 #ifndef NO_TLS 02426 #endif 02427 02428 } 02429 } 02430 02431 02432 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) 02433 { 02434 mlme_start_t start_req; 02435 memset(&start_req, 0, sizeof(mlme_start_t)); 02436 mac_helper_coordinator_address_set(interface, (addrtype_t)pan_descriptor->CoordAddrMode, pan_descriptor->CoordAddress); 02437 02438 interface->mac_parameters->mac_channel = pan_descriptor->LogicalChannel; 02439 interface->mac_parameters->pan_id = pan_descriptor->CoordPANId; 02440 if (interface->nwk_wpan_nvm_api) { 02441 wpan_nvm_params_t *params = interface->nwk_wpan_nvm_api->nvm_params_get_cb(interface->nwk_wpan_nvm_api, pan_descriptor->CoordPANId); 02442 interface->if_lowpan_security_params->mle_security_frame_counter = params->mle_securit_counter; 02443 //SET MAC and MLE security frame counters 02444 mle_service_security_set_frame_counter(interface->id, params->mle_securit_counter); 02445 mac_helper_link_frame_counter_set(interface->id, params->mac_security_frame_counter); 02446 } 02447 02448 start_req.PANId = pan_descriptor->CoordPANId; 02449 start_req.LogicalChannel = pan_descriptor->LogicalChannel; 02450 start_req.ChannelPage = 0; 02451 start_req.BeaconOrder = pan_descriptor->SuperframeSpec[0] >> 4; 02452 start_req.SuperframeOrder = pan_descriptor->SuperframeSpec[0] & 0x0f; 02453 //SET Beacon Payload 02454 uint8_t *b_ptr = mac_helper_beacon_payload_reallocate(interface, beacon_length); 02455 if (!b_ptr) { 02456 tr_error("Beacon Payload allocate Fail"); 02457 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02458 return false; 02459 } 02460 memcpy(b_ptr, beacon_payload, beacon_length); 02461 mac_helper_beacon_payload_register(interface); 02462 //Start and set pan-id 02463 interface->mac_api->mlme_req(interface->mac_api, MLME_START, &start_req); 02464 mac_helper_panid_set(interface, pan_descriptor->CoordPANId); 02465 02466 return true; 02467 } 02468 02469 bool protocol_6lowpan_bootsrap_start(protocol_interface_info_entry_t *interface) 02470 { 02471 net_load_balance_internal_state_activate(interface, false); 02472 02473 //SET allways RX ON Idle device by default 02474 mac_helper_pib_boolean_set(interface, macRxOnWhenIdle, true); 02475 interface->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 02476 02477 mac_data_poll_init(interface); 02478 mac_helper_mac16_address_set(interface, 0xffff); 02479 tr_debug("Mac Ready"); 02480 interface->nwk_nd_re_scan_count = 2; 02481 02482 if (interface->if_lowpan_security_params->nwk_security_mode == NET_SEC_MODE_PSK_LINK_SECURITY) { 02483 tr_debug("SET Security Mode"); 02484 mac_helper_default_security_level_set(interface, interface->mac_parameters->mac_configured_sec_level); 02485 mac_helper_default_security_key_id_mode_set(interface,MAC_KEY_ID_MODE_IDX); 02486 } 02487 02488 //Check first pana and then MLE and else start RS scan pahse 02489 if (interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 02490 #ifdef PANA 02491 nwk_6lowpan_bootsrap_pana_authentication_start(interface); 02492 tr_debug("Pana auth"); 02493 #else 02494 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02495 return false; 02496 #endif 02497 } else if (interface->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 02498 if (protocol_6lowpan_parent_link_req(interface) != 0) { 02499 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02500 return false; 02501 } 02502 } else { 02503 bootsrap_next_state_kick(ER_SCAN, interface); 02504 } 02505 return true; 02506 } 02507 02508 02509 void protocol_6lowpan_mac_scan_confirm(int8_t if_id, const mlme_scan_conf_t* conf) 02510 { 02511 nwk_pan_descriptor_t *result; 02512 nwk_pan_descriptor_t *best; 02513 protocol_interface_info_entry_t *interface = NULL; 02514 02515 if (conf->ScanType != MAC_ACTIVE_SCAN) { 02516 return; 02517 } 02518 02519 interface = protocol_stack_interface_info_get_by_id(if_id); 02520 if (!interface) { 02521 tr_debug("Mac scan confirm:Unknow Interface"); 02522 return; 02523 } 02524 bool is_border_router = false; 02525 if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 02526 is_border_router = true; 02527 } 02528 02529 interface->mac_parameters->nwk_scan_params.active_scan_active = false; 02530 02531 result = arm_net_get_scanned_nwk_list(if_id); 02532 if (!result || !conf->ResultListSize) { 02533 tr_debug("Mac scan confirm:No Beacons"); 02534 if (is_border_router == false) { 02535 bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, interface); 02536 return; 02537 } 02538 } 02539 02540 //Analyze Best Result 02541 best = mac_helper_select_best_lqi(result); 02542 mac_helper_drop_selected_from_the_scanresult(&interface->mac_parameters->nwk_scan_params, best); 02543 02544 bool link_start_ok = false; 02545 if (is_border_router == false) { 02546 link_start_ok = protocol_6lowpan_bootsrap_link_set(interface, best->pan_descriptor, best->beacon_payload, best->beacon_length); 02547 } 02548 02549 mac_helper_free_scan_confirm(&interface->mac_parameters->nwk_scan_params); 02550 02551 best = mac_helper_free_pan_descriptions(best); 02552 02553 if (link_start_ok) { 02554 protocol_6lowpan_bootsrap_start(interface); 02555 } 02556 02557 if (is_border_router == true) { 02558 if (interface->nwk_bootstrap_state == ER_WARM_ACTIVE_SCAN) { 02559 border_router_start(interface, true); 02560 interface->bootsrap_state_machine_cnt = 0; 02561 interface->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 02562 } else { 02563 border_router_start(interface, false); 02564 } 02565 02566 } 02567 } 02568 02569 void bootstrap_timer_handle(uint16_t ticks) 02570 { 02571 (void)ticks; 02572 ns_list_foreach(protocol_interface_info_entry_t, cur, &protocol_interface_info_list) { 02573 if (cur->nwk_id == IF_6LoWPAN) { 02574 if (cur->nwk_bootstrap_state == ER_ACTIVE_SCAN || cur->nwk_bootstrap_state == ER_WARM_ACTIVE_SCAN) { 02575 // Retransmit Scan request 02576 bootsrap_next_state_kick(cur->nwk_bootstrap_state, cur); 02577 tr_error("Restart active scan"); 02578 } else { 02579 // Retransmit Start request 02580 mlme_start_t start_req; 02581 memset(&start_req, 0, sizeof(mlme_start_t)); 02582 start_req.PANId = cur->border_router_setup->mac_panid; 02583 start_req.LogicalChannel = cur->mac_parameters->mac_channel; 02584 start_req.ChannelPage = 0; 02585 start_req.BeaconOrder = 0x0f; 02586 start_req.SuperframeOrder = 0x0f; 02587 start_req.PANCoordinator = 1; 02588 if( cur->mac_api ){ 02589 cur->mac_api->mlme_req(cur->mac_api, MLME_START, (void*)&start_req); 02590 tr_error("Restart MAC"); 02591 } 02592 } 02593 } 02594 } 02595 } 02596 02597 void protocol_6lowpan_bootstrap(protocol_interface_info_entry_t *cur) 02598 { 02599 switch (cur->nwk_bootstrap_state) { 02600 case ER_ACTIVE_SCAN: 02601 case ER_WARM_ACTIVE_SCAN: 02602 tr_debug("Start Active Scan"); 02603 cur->mac_parameters->nwk_scan_params.stack_chan_list = cur->mac_parameters->mac_channel_list; 02604 02605 mlme_scan_t req; 02606 mac_create_scan_request(MAC_ACTIVE_SCAN, &cur->mac_parameters->mac_channel_list, cur->mac_parameters->nwk_scan_params.scan_duration, &req); 02607 if( cur->mac_api ){ 02608 cur->scan_cb = protocol_6lowpan_mac_scan_confirm; 02609 cur->mac_parameters->nwk_scan_params.active_scan_active = true; 02610 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 02611 protocol_timer_start(PROTOCOL_TIMER_BOOTSTRAP_TIM, bootstrap_timer_handle, BOOTSTRAP_SCAN_TIMEOUT); 02612 } 02613 cur->mac_api->mlme_req(cur->mac_api, MLME_SCAN, &req); 02614 } 02615 break; 02616 02617 case ER_SCAN: 02618 //LED1_TOGGLE(); 02619 nwk_6lowpan_router_scan_state(cur); 02620 break; 02621 02622 case ER_PANA_AUTH_ERROR: 02623 nwk_6lowpan_network_authentication_fail(cur); 02624 break; 02625 02626 case ER_PANA_AUTH_DONE: 02627 nwk_6lowpan_network_authentication_done(cur); 02628 break; 02629 02630 case ER_BIND_COMP: 02631 nwk_6lowpan_nd_address_registartion_ready(cur); 02632 break; 02633 02634 #ifdef HAVE_RPL 02635 02636 case ER_RPL_MC: 02637 nwk_6lowpan_rpl_router_discover(cur); 02638 break; 02639 02640 case ER_RPL_SCAN: 02641 nwk_6lowpan_rpl_router_result_check(cur); 02642 break; 02643 #endif 02644 case ER_BOOTSRAP_DONE: 02645 nwk_6lowpan_bootstrap_ready(cur); 02646 break; 02647 02648 case ER_PARENT_SYNCH_LOST: 02649 tr_debug("-->Parent synch Lose"); 02650 nwk_bootsrap_state_update(ARM_NWK_NWK_PARENT_POLL_FAIL, cur); 02651 break; 02652 02653 case ER_BOOTSTRAP_CONNECTION_DOWN: 02654 nwk_bootsrap_state_update(ARM_NWK_NWK_CONNECTION_DOWN, cur); 02655 break; 02656 02657 case ER_BOOTSTRAP_IP_ADDRESS_ALLOC_FAIL: 02658 nwk_bootsrap_state_update(ARM_NWK_IP_ADDRESS_ALLOCATION_FAIL, cur); 02659 tr_info("-->idle"); 02660 break; 02661 02662 case ER_BOOTSTRAP_DAD_FAIL: 02663 nwk_bootsrap_state_update(ARM_NWK_DUPLICATE_ADDRESS_DETECTED, cur); 02664 break; 02665 02666 case ER_BOOTSTRAP_SCAN_FAIL: 02667 tr_debug("Network Bootsrap Start Fail"); 02668 nwk_bootsrap_state_update(ARM_NWK_NWK_SCAN_FAIL, cur); 02669 break; 02670 #ifdef PANA 02671 case ER_PANA_PING: 02672 nwk_6lowpan_pana_key_pull(cur); 02673 break; 02674 #endif 02675 case ER_MLE_LINK_REQ: 02676 //No need to do anything in this case 02677 break; 02678 default: 02679 tr_error("Unknow state %d", cur->nwk_bootstrap_state); 02680 02681 } 02682 } 02683 02684 void protocol_6lowpan_nd_borderrouter_connection_down(protocol_interface_info_entry_t *interface) 02685 { 02686 /*if (rpl_object_poisons() == 0) ??? */ { 02687 mac_helper_mac16_address_set(interface, 0xffff); 02688 02689 //TRIG Event for ND connection Down 02690 bootsrap_next_state_kick(ER_BOOTSTRAP_IP_ADDRESS_ALLOC_FAIL, interface); 02691 } 02692 } 02693 02694 void protocol_6lowpan_bootstrap_re_start(protocol_interface_info_entry_t *interface) 02695 { 02696 mac_helper_mac16_address_set(interface, 0xffff); 02697 arm_6lowpan_bootstrap_init(interface); 02698 tr_info("-->Bootsrap"); 02699 } 02700 02701 uint8_t *protocol_6lowpan_nd_border_router_address_get(nwk_interface_id nwk_id) 02702 { 02703 nd_router_t *object = nd_get_object_by_nwk_id(nwk_id); 02704 if (object) { 02705 return object->border_router; 02706 } 02707 return 0; 02708 } 02709 02710 uint8_t protocol_6lowpan_rf_link_scalability_from_lqi(uint8_t lqi) 02711 { 02712 uint8_t i = 16; 02713 if (lqi >= 240) { 02714 i = 1; 02715 } else { 02716 lqi /= 16; 02717 if (lqi) { 02718 i = (16 - lqi); 02719 } 02720 } 02721 return i; 02722 } 02723 02724 int protocol_6lowpan_del_ll16(protocol_interface_info_entry_t *cur, uint16_t mac_short_address) 02725 { 02726 uint8_t address[16]; 02727 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02728 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC, 6); 02729 common_write_16_bit(mac_short_address, &address[14]); 02730 02731 return addr_delete(cur, address); 02732 } 02733 02734 int protocol_6lowpan_set_ll16(protocol_interface_info_entry_t *cur, uint16_t mac_short_address) 02735 { 02736 if_address_entry_t *address_entry; 02737 uint8_t address[16]; 02738 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02739 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC , 6); 02740 common_write_16_bit(mac_short_address, &address[14]); 02741 02742 address_entry = addr_add(cur, address, 64, ADDR_SOURCE_UNKNOWN, 0xffffffff, 0xffffffff, false); 02743 if (address_entry) { 02744 return 0; 02745 } 02746 return -1; 02747 } 02748 02749 static void protocol_6lowpan_generate_link_reject(protocol_interface_info_entry_t *cur, const mlme_comm_status_t *status) 02750 { 02751 uint8_t address[16]; 02752 memcpy(address, ADDR_LINK_LOCAL_PREFIX, 8); 02753 if (status->SrcAddrMode == MAC_ADDR_MODE_16_BIT) { 02754 memcpy(address + 8, ADDR_SHORT_ADR_SUFFIC , 6); 02755 memcpy(address + 14,status->SrcAddr, 2); 02756 } else { 02757 memcpy(address + 8,status->SrcAddr, 8); 02758 address[8] ^= 2; 02759 } 02760 if (mac_helper_default_security_level_get(cur)) { 02761 tr_debug("Drop link by asymmetric security"); 02762 mle_service_reject_message_build(cur->id, address, false); 02763 return; 02764 } 02765 02766 } 02767 02768 static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) 02769 { 02770 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); 02771 if (!cur) { 02772 return; 02773 } 02774 02775 mac_neighbor_table_entry_t * entry_ptr; 02776 02777 switch (status->status) { 02778 case MLME_UNSUPPORTED_SECURITY: 02779 case MLME_UNAVAILABLE_KEY: 02780 /* Generate MLE Link Reject to destination */ 02781 if (status->DstAddrMode == MAC_ADDR_MODE_16_BIT && status->DstAddr[0] == 0xff && status->DstAddr[1] == 0xff) { 02782 return; //Drop brodcast security failure 02783 } 02784 02785 if (!cur->mle_link_reject_tokens) { 02786 return; 02787 } 02788 cur->mle_link_reject_tokens--; 02789 protocol_6lowpan_generate_link_reject(cur, status); 02790 02791 break; 02792 case MLME_DATA_POLL_NOTIFICATION: 02793 entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), status->SrcAddr, status->SrcAddrMode); 02794 if (entry_ptr) { 02795 // Refresh Timeout 02796 mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_ptr, entry_ptr->link_lifetime ); 02797 } 02798 break; 02799 default: 02800 break; 02801 } 02802 } 02803 02804 bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address) 02805 { 02806 02807 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 02808 if (!cur) { 02809 return false; 02810 } 02811 bool return_value = false; 02812 mac_neighbor_table_entry_t *neigh_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), link_local_address, false, NULL); 02813 if (neigh_entry) { 02814 //Remove entry 02815 if (neigh_entry->link_role == PRIORITY_PARENT_NEIGHBOUR || neigh_entry->link_role == SECONDARY_PARENT_NEIGHBOUR) { 02816 return_value = true; 02817 } 02818 mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neigh_entry); 02819 } 02820 return return_value; 02821 } 02822 02823 void protocol_6lowpan_mle_timer(uint16_t ticks_update) 02824 { 02825 #ifndef NO_MLE 02826 if (mle_6lowpan_data) { 02827 /* Three request in burst and after that one link request per second */ 02828 mle_6lowpan_data->link_req_token_bucket += ticks_update; 02829 if (mle_6lowpan_data->link_req_token_bucket > MLE_LINK_REQ_TOKEN_BUCKET_SIZE) { 02830 mle_6lowpan_data->link_req_token_bucket = MLE_LINK_REQ_TOKEN_BUCKET_SIZE; 02831 } 02832 } 02833 #endif 02834 } 02835 02836 #endif
Generated on Tue Aug 9 2022 00:37:18 by
1.7.2