Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
border_router.c
00001 /* 00002 * Copyright (c) 2012-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 #include "nsconfig.h" 00019 #include "ns_types.h" 00020 #include "string.h" 00021 #include "ns_trace.h" 00022 #include "nsdynmemLIB.h" 00023 #include "NWK_INTERFACE/Include/protocol.h" 00024 #include "NWK_INTERFACE/Include/protocol_timer.h" 00025 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00026 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00027 #ifndef NO_MLE 00028 #include "MLE/mle.h" 00029 #endif 00030 #include "mac_api.h" 00031 00032 #include "RPL/rpl_control.h" 00033 #include "6LoWPAN/ND/nd_router_object.h" 00034 #include "Service_Libs/whiteboard/whiteboard.h" 00035 #include "Service_Libs/blacklist/blacklist.h" 00036 #include "Service_Libs/nd_proxy/nd_proxy.h" 00037 #include "shalib.h" 00038 00039 #ifdef ECC 00040 #include "libX509_V3.h" 00041 #include "ecc.h" 00042 #endif 00043 #include "Security/TLS/tls_lib.h" 00044 #include "Security/Common/sec_lib.h" 00045 #include "net_nvm_api.h" 00046 #include "Security/PANA/pana.h" 00047 #include "Security/PANA/pana_internal_api.h" 00048 #include "Common_Protocols/ipv6.h" 00049 #include "Common_Protocols/icmpv6.h" 00050 #include "Common_Protocols/icmpv6_prefix.h" 00051 #include "Common_Protocols/icmpv6_radv.h" 00052 #include "ipv6_stack/protocol_ipv6.h" 00053 #include "common_functions.h" 00054 #include "net_thread_test.h" 00055 #include "6LoWPAN/Thread/thread_common.h" 00056 #include "6LoWPAN/Thread/thread_bootstrap.h" 00057 #include "6LoWPAN/Thread/thread_routing.h" 00058 #include "BorderRouter/border_router.h" 00059 #include "6LoWPAN/MAC/mac_helper.h" 00060 #include "6LoWPAN/MAC/beacon_handler.h" 00061 #include "6LoWPAN/NVM/nwk_nvm.h" 00062 #include "libNET/src/net_load_balance_internal.h" 00063 #include "6LoWPAN/lowpan_adaptation_interface.h" 00064 #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" 00065 00066 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00067 00068 #define TRACE_GROUP_BORDER_ROUTER "br" 00069 00070 #define TRACE_GROUP "br" 00071 00072 00073 static int8_t border_router_nd_abro_periodically_update_by_stack(nd_router_setup_t *nd_router_configuration); 00074 static void border_router_free(protocol_interface_info_entry_t *cur); 00075 00076 void arm_nwk_6lowpan_borderrouter_data_free(protocol_interface_info_entry_t *cur) 00077 { 00078 if (cur->border_router_setup) { 00079 if (cur->border_router_setup->nd_nwk) { 00080 icmp_nd_border_router_release(cur->border_router_setup->nd_nwk); 00081 ns_dyn_mem_free(cur->border_router_setup->nd_nwk); 00082 } 00083 if (cur->border_router_setup->nd_border_router_configure) { 00084 ns_dyn_mem_free(cur->border_router_setup->nd_border_router_configure); 00085 } 00086 ns_dyn_mem_free(cur->border_router_setup); 00087 cur->border_router_setup = 0; 00088 } 00089 } 00090 00091 void nd_border_router_setup_refresh(nwk_interface_id id, bool fresh_abro) 00092 { 00093 uint8_t *ptr = 0; 00094 nd_router_t *nd_router_object; 00095 nd_router_setup_t *nd_configure; 00096 protocol_interface_info_entry_t *cur_interface; 00097 uint8_t nd_options[30]; 00098 00099 cur_interface = protocol_stack_interface_info_get(id); 00100 if (!cur_interface) { 00101 return; 00102 } else if (cur_interface->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00103 return; 00104 } else if (cur_interface->border_router_setup == 0) { 00105 return; 00106 } else if (!cur_interface->border_router_setup->nd_nwk) { 00107 return; 00108 } else if (!cur_interface->border_router_setup->nd_border_router_configure) { 00109 return; 00110 } 00111 00112 nd_router_object = cur_interface->border_router_setup->nd_nwk; 00113 nd_configure = cur_interface->border_router_setup->nd_border_router_configure; 00114 nd_router_object->life_time = nd_configure->life_time; 00115 00116 if (!ns_list_is_empty(&nd_router_object->prefix_list)) { 00117 tr_debug("Release Prefix\n"); 00118 icmpv6_prefix_list_free(&nd_router_object->prefix_list); 00119 } 00120 00121 if (!ns_list_is_empty(&nd_router_object->context_list)) { 00122 tr_info("Release Context"); 00123 lowpan_context_list_free(&nd_router_object->context_list); 00124 } 00125 00126 if (!ns_list_is_empty(&nd_configure->context_list)) { 00127 tr_info("Refresh Contexts"); 00128 ns_list_foreach(lowpan_context_t, cur, &nd_configure->context_list) { 00129 uint8_t cid_flags = cur->cid | (cur->compression ? LOWPAN_CONTEXT_C : 0); 00130 uint16_t lifetime_mins = (cur->lifetime + 599) / 600; 00131 /* Update contexts in our ABRO advertising storage */ 00132 lowpan_context_update(&nd_router_object->context_list, cid_flags, lifetime_mins, cur->prefix, cur->length, true); 00133 /* And contexts used by the interface itself (we don't hear our own adverts) */ 00134 lowpan_context_update(&cur_interface->lowpan_contexts, cid_flags, lifetime_mins, cur->prefix, cur->length, true); 00135 } 00136 } 00137 /* Set Prefixs */ 00138 if (!ns_list_is_empty(&nd_configure->prefix_list)) { 00139 tr_info("Refresh Prefixs"); 00140 ns_list_foreach(prefix_entry_t, cur, &nd_configure->prefix_list) { 00141 ptr = nd_options; 00142 *ptr++ = cur->prefix_len; //Prefix Len 00143 *ptr++ = cur->options; //Autonomous address enabled 00144 ptr = common_write_32_bit(cur->lifetime, ptr); 00145 ptr = common_write_32_bit(cur->preftime, ptr); 00146 ptr = common_write_32_bit(0, ptr); //Reserved 00147 00148 memcpy(ptr, cur->prefix, 16); 00149 icmp_nd_router_prefix_update(nd_options, nd_router_object, cur_interface); 00150 } 00151 } 00152 00153 //Update version num 00154 00155 if (fresh_abro) { 00156 if (border_router_nd_abro_periodically_update_by_stack(nd_configure) == 0) { 00157 tr_info("ABRO Update and NVM operation OK"); 00158 } 00159 } 00160 00161 nd_router_object->abro_version_num = nd_configure->abro_version_num; 00162 } 00163 00164 int8_t arm_nwk_6lowpan_border_route_nd_default_prefix_timeout_set(int8_t interface_id, uint32_t time) 00165 { 00166 int8_t ret_val = -1; 00167 protocol_interface_info_entry_t *cur = 0; 00168 cur = protocol_stack_interface_info_get_by_id(interface_id); 00169 if (cur) { 00170 uint8_t *nd_options = ns_dyn_mem_temporary_alloc(30); 00171 if (nd_options) { 00172 uint8_t *ptr; 00173 ptr = nd_options; 00174 00175 ptr = common_write_16_bit(0x4040, ptr); //Prefix Len + Autonomous address enabled 00176 ptr = common_write_32_bit(time, ptr); 00177 ptr = common_write_32_bit(time, ptr); 00178 memcpy(ptr, cur->border_router_setup->border_router_gp_adr, 8); 00179 ptr += 8; 00180 memset(ptr, 0, 8); 00181 ret_val = icmp_nd_router_prefix_proxy_update(nd_options, cur->border_router_setup->nd_border_router_configure); 00182 ns_dyn_mem_free(nd_options); 00183 } 00184 } 00185 return ret_val; 00186 } 00187 00188 int8_t arm_nwk_6lowpan_border_router_context_update(int8_t interface_id, uint8_t c_id_flags, uint8_t context_len, uint16_t ttl, const uint8_t *context_ptr) 00189 { 00190 int8_t ret_val = -2; 00191 protocol_interface_info_entry_t *cur = 0; 00192 cur = protocol_stack_interface_info_get_by_id(interface_id); 00193 if (cur) { 00194 ret_val = 0; 00195 if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00196 ret_val = -4; 00197 } else if (cur->border_router_setup == 0) { 00198 ret_val = -3; 00199 } else { 00200 if (c_id_flags < 0x20 && context_len >= 64) { 00201 if (cur->border_router_setup->nd_nwk) { 00202 nd_router_setup_t *routerSetup = cur->border_router_setup->nd_border_router_configure; 00203 00204 if (!lowpan_contex_get_by_id(&routerSetup->context_list, (c_id_flags & LOWPAN_CONTEXT_CID_MASK))) { 00205 if (ns_list_count(&routerSetup->context_list) >= ND_MAX_PROXY_CONTEXT_COUNT) { 00206 return -1; 00207 } 00208 } 00209 00210 if (lowpan_context_update(&routerSetup->context_list, c_id_flags, ttl, context_ptr, context_len, true) != 0) { 00211 ret_val = -2; 00212 } else { 00213 ret_val = 0; 00214 } 00215 } 00216 } else { 00217 ret_val = -3; 00218 } 00219 } 00220 } 00221 return ret_val; 00222 } 00223 00224 int8_t arm_nwk_6lowpan_border_router_nd_context_load(int8_t interface_id, uint8_t *contex_data) 00225 { 00226 int8_t ret_val = -2; 00227 protocol_interface_info_entry_t *cur = 0; 00228 cur = protocol_stack_interface_info_get_by_id(interface_id); 00229 if (cur) { 00230 ret_val = 0; 00231 if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00232 ret_val = -4; 00233 } else if (cur->border_router_setup == 0) { 00234 ret_val = -3; 00235 } else { 00236 uint8_t c_id; 00237 uint16_t lifetime; 00238 nd_router_setup_t *nd_router_setup; 00239 uint8_t con_len = *contex_data++; 00240 00241 nd_router_setup = cur->border_router_setup->nd_border_router_configure; 00242 00243 c_id = *contex_data++ & 0x1f; // ignore reserved fields 00244 lifetime = common_read_16_bit(contex_data); 00245 contex_data += 2; 00246 //Now Pointer Indicate to prefix 00247 //Check first is current ID at list 00248 if (!lowpan_contex_get_by_id(&nd_router_setup->context_list, (c_id & LOWPAN_CONTEXT_CID_MASK))) { 00249 if (ns_list_count(&nd_router_setup->context_list) >= ND_MAX_PROXY_CONTEXT_COUNT) { 00250 tr_debug("All Contexts are allocated"); 00251 return -1; 00252 } 00253 } 00254 return lowpan_context_update(&nd_router_setup->context_list, c_id, lifetime, contex_data, con_len, true); 00255 00256 } 00257 } 00258 return ret_val; 00259 } 00260 00261 00262 //int8_t border_router_nd_configure_update(void) 00263 int8_t arm_nwk_6lowpan_border_router_configure_push(int8_t interface_id) 00264 { 00265 int8_t ret_val = -1; 00266 protocol_interface_info_entry_t *cur_interface; 00267 cur_interface = protocol_stack_interface_info_get_by_id(interface_id); 00268 if (cur_interface) { 00269 ret_val = 0; 00270 if (cur_interface->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00271 ret_val = -4; 00272 } else if (cur_interface->border_router_setup == 0) { 00273 ret_val = -3; 00274 } else if ((cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 00275 ret_val = -2; 00276 } else { 00277 if (thread_info(cur_interface) == NULL) { 00278 cur_interface->border_router_setup->nd_nwk->nd_timer = 1; 00279 cur_interface->border_router_setup->nd_nwk->nd_re_validate = 1; 00280 cur_interface->border_router_setup->nd_nwk->abro_version_num++; 00281 ret_val = 0; 00282 } 00283 } 00284 } 00285 return ret_val; 00286 } 00287 00288 int8_t arm_nwk_6lowpan_border_router_context_remove_by_id(int8_t interface_id, uint8_t c_id) 00289 { 00290 lowpan_context_t *entry; 00291 protocol_interface_info_entry_t *cur_interface = 0; 00292 nd_router_setup_t *nd_router_configuration = 0; 00293 cur_interface = protocol_stack_interface_info_get_by_id(interface_id); 00294 if (!cur_interface) { 00295 return -1; 00296 } 00297 00298 if (cur_interface->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00299 return -4; 00300 } 00301 00302 if (cur_interface->border_router_setup == 0) { 00303 return -3; 00304 } 00305 00306 nd_router_configuration = cur_interface->border_router_setup->nd_border_router_configure; 00307 00308 entry = lowpan_contex_get_by_id(&nd_router_configuration->context_list, c_id); 00309 if (entry) { 00310 ns_list_remove(&nd_router_configuration->context_list, entry); 00311 ns_dyn_mem_free(entry); 00312 } 00313 return 0; 00314 } 00315 00316 int8_t arm_nwk_6lowpan_border_router_context_parameter_update(int8_t interface_id, uint8_t c_id, uint8_t compress_mode, uint16_t ttl) 00317 { 00318 protocol_interface_info_entry_t *cur_interface; 00319 nd_router_setup_t *nd_router_configuration; 00320 lowpan_context_t *entry; 00321 cur_interface = protocol_stack_interface_info_get_by_id(interface_id); 00322 if (!cur_interface) { 00323 return -1; 00324 } 00325 00326 if (cur_interface->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00327 return -4; 00328 } 00329 00330 if (cur_interface->border_router_setup == 0) { 00331 return -3; 00332 } 00333 00334 nd_router_configuration = cur_interface->border_router_setup->nd_border_router_configure; 00335 00336 entry = lowpan_contex_get_by_id(&nd_router_configuration->context_list, c_id); 00337 if (entry) { 00338 uint8_t cid_flag = entry->cid; 00339 entry->compression = compress_mode; 00340 entry->lifetime = ttl; 00341 cid_flag |= (entry->compression ? LOWPAN_CONTEXT_C : 0); 00342 return 0; 00343 } 00344 return -1; 00345 } 00346 00347 int8_t arm_nwk_6lowpan_border_router_init(int8_t interface_id, const border_router_setup_s *border_router_setup_ptr) 00348 { 00349 int8_t ret_val = -3; 00350 protocol_interface_info_entry_t *cur = 0; 00351 nd_router_setup_t *nd_router_configuration = 0; 00352 cur = protocol_stack_interface_info_get_by_id(interface_id); 00353 if (cur) { 00354 ret_val = 0; 00355 if (cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00356 ret_val = -4; 00357 } else if (cur->border_router_setup == 0) { 00358 ret_val = -3; 00359 } else if (thread_info(cur)) { 00360 ret_val = -5; 00361 } else if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 00362 uint8_t *ptr = cur->border_router_setup->border_router_gp_adr; 00363 memcpy(ptr, border_router_setup_ptr->lowpan_nd_prefix, 8); 00364 ptr += 8; 00365 cur->border_router_setup->mac_short_adr = border_router_setup_ptr->mac_short_adr; 00366 if (border_router_setup_ptr->mac_short_adr < 0xfffe) { 00367 cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; 00368 mac_helper_mac16_address_set(cur, border_router_setup_ptr->mac_short_adr); 00369 memcpy(ptr, ADDR_SHORT_ADR_SUFFIC, 6); 00370 ptr += 6; 00371 ptr = common_write_16_bit(cur->border_router_setup->mac_short_adr, ptr); 00372 } else { 00373 memcpy(ptr, cur->iid_eui64, 8); 00374 cur->lowpan_address_mode = NET_6LOWPAN_GP64_ADDRESS; 00375 } 00376 00377 nd_router_configuration = cur->border_router_setup->nd_border_router_configure; 00378 00379 nd_router_configuration->life_time = border_router_setup_ptr->ra_life_time; 00380 nd_router_configuration->abro_version_num = border_router_setup_ptr->abro_version_num; 00381 cur->configure_flags |= INTERFACE_ND_BORDER_ROUTER_DEFINED; 00382 } else { 00383 ret_val = -1; 00384 } 00385 00386 if (ret_val == 0) { 00387 uint8_t *nd_options = 0; 00388 uint8_t *beaon_payload = 0; 00389 00390 //Check here FHSS Pointer Hox Hoxs 00391 beaon_payload = mac_helper_beacon_payload_reallocate(cur, 18); 00392 00393 cur->border_router_setup->mac_panid = border_router_setup_ptr->mac_panid; 00394 00395 if (beaon_payload == NULL) { 00396 ret_val = -2; 00397 } else { 00398 *beaon_payload++ = border_router_setup_ptr->beacon_protocol_id; 00399 *beaon_payload++ = 7; //Accept Join / Host & Router 00400 memcpy(beaon_payload, border_router_setup_ptr->network_id, 16); 00401 00402 if (mac_helper_beacon_payload_register(cur) != 0) { 00403 tr_error("Beacon payload register Fail"); 00404 } 00405 00406 nd_options = ns_dyn_mem_temporary_alloc(30); 00407 if (nd_options) { 00408 uint8_t *ptr = cur->border_router_setup->nd_nwk->border_router; 00409 nd_router_base_init(cur->border_router_setup->nd_nwk); 00410 00411 00412 cur->border_router_setup->nd_nwk->nd_state = ND_BR_READY; 00413 cur->border_router_setup->nd_nwk->nwk_id = IF_6LoWPAN; 00414 cur->border_router_setup->nd_nwk->life_time = border_router_setup_ptr->ra_life_time; 00415 memcpy(cur->border_router_setup->nd_nwk->border_router, cur->border_router_setup->border_router_gp_adr, 16); 00416 if (border_router_setup_ptr->mac_short_adr < 0xfffe) { 00417 cur->border_router_setup->mac_short_adr = border_router_setup_ptr->mac_short_adr; 00418 } else { 00419 cur->border_router_setup->mac_short_adr = 0xffff; 00420 } 00421 00422 //Create GP64 00423 if (ret_val == 0) { 00424 ptr = nd_options; 00425 *ptr++ = 64;//Prefix Len 00426 *ptr++ = PIO_A; //Autonomous address enabled 00427 memset(ptr, 0xff, 8);/* Valid Life time & Valid Preferred Life time 0xffffff */ 00428 ptr += 8; 00429 memcpy(ptr, border_router_setup_ptr->lowpan_nd_prefix, 8); 00430 ptr += 8; 00431 memset(ptr, 0, 8); 00432 ret_val = icmp_nd_router_prefix_proxy_update(nd_options, nd_router_configuration); 00433 00434 //Default Prefix TO ND 00435 } 00436 if (ret_val == 0) { 00437 //Context 00438 if (lowpan_context_update(&nd_router_configuration->context_list, (LOWPAN_CONTEXT_C | 0), (24 * 60), border_router_setup_ptr->lowpan_nd_prefix, 64, true) != 0) { 00439 ret_val = -2; 00440 } 00441 } 00442 00443 ns_dyn_mem_free(nd_options); 00444 if (ret_val == 0) { 00445 tr_info("BR nwk base ready for start"); 00446 } 00447 } else { 00448 ret_val = -2; 00449 } 00450 } 00451 00452 if (ret_val == -2) { 00453 if (cur) { 00454 border_router_free(cur); 00455 } 00456 } 00457 } 00458 } 00459 return ret_val; 00460 } 00461 00462 static void border_router_free(protocol_interface_info_entry_t *cur) 00463 { 00464 if (cur->border_router_setup) { 00465 if (cur->border_router_setup->nd_nwk) { 00466 icmp_nd_router_object_reset(cur->border_router_setup->nd_nwk); 00467 ns_dyn_mem_free(cur->border_router_setup->nd_nwk); 00468 } 00469 00470 00471 if (cur->border_router_setup->nd_border_router_configure) { 00472 icmpv6_prefix_list_free(&cur->border_router_setup->nd_border_router_configure->prefix_list); 00473 lowpan_context_list_free(&cur->border_router_setup->nd_border_router_configure->context_list); 00474 } 00475 ns_dyn_mem_free(cur->border_router_setup); 00476 cur->border_router_setup = 0; 00477 } 00478 } 00479 00480 static int8_t border_router_nd_abro_periodically_update_by_stack(nd_router_setup_t *nd_router_configuration) 00481 { 00482 int8_t ret_val = -1; 00483 if (nd_router_configuration) { 00484 nd_router_configuration->abro_version_num++; 00485 ret_val = 0; 00486 } 00487 return ret_val; 00488 } 00489 00490 void border_router_start(protocol_interface_info_entry_t *cur, bool warm_link_restart) 00491 { 00492 nd_router_t *nd_nwk = cur->border_router_setup->nd_nwk; 00493 mlme_start_t start_req; 00494 memset(&start_req, 0, sizeof(mlme_start_t)); 00495 start_req.PANId = cur->border_router_setup->mac_panid; 00496 start_req.LogicalChannel = cur->mac_parameters->mac_channel; 00497 start_req.ChannelPage = 0; 00498 start_req.BeaconOrder = 0x0f; 00499 start_req.SuperframeOrder = 0x0f; 00500 start_req.PANCoordinator = 1; 00501 if (cur->mac_api) { 00502 protocol_timer_start(PROTOCOL_TIMER_BOOTSTRAP_TIM, bootstrap_timer_handle, BOOTSTRAP_START_TIMEOUT); 00503 cur->mac_api->mlme_req(cur->mac_api, MLME_START, (void *)&start_req); 00504 } 00505 if (warm_link_restart) { 00506 return; 00507 } 00508 mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); 00509 #ifndef NO_MLE 00510 blacklist_clear(); 00511 #endif 00512 00513 cur->border_router_setup->initActive = true; 00514 00515 cur->lowpan_info |= INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY; 00516 addr_interface_set_ll64(cur, NULL); 00517 cur->interface_mode = INTERFACE_UP; 00518 cur->nwk_mode = ARM_NWK_GP_IP_MODE; 00519 if (nd_nwk) { 00520 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 00521 protocol_6lowpan_router_synch_to_new_router(cur, NULL, 0, true); 00522 cur->bootsrap_state_machine_cnt = 30; 00523 } else { 00524 nd_nwk->mle_advert_timer = 0; 00525 cur->bootsrap_state_machine_cnt = 1; 00526 } 00527 cur->nwk_bootstrap_state = ER_SCAN; 00528 whiteboard_interface_register(nd_nwk->border_router, cur->id); 00529 cur->nwk_nd_re_scan_count = 2; 00530 00531 } else { 00532 thread_interface_up(cur); 00533 rpl_control_remove_domain_from_interface(cur); 00534 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 00535 } 00536 } 00537 00538 static int arm_mac_channel_list_analyze(protocol_interface_info_entry_t *cur) 00539 { 00540 int number_of_channels = 0; 00541 for (int i = 0; i < 8; i++) { 00542 for (int j = 0; j < 4; j++) { 00543 number_of_channels += common_count_bits((uint8_t)(cur->mac_parameters->mac_channel_list.channel_mask[i] >> (j * 8))); 00544 } 00545 } 00546 return number_of_channels; 00547 } 00548 00549 static int8_t arm_border_router_interface_up(protocol_interface_info_entry_t *cur) 00550 { 00551 bool warm_restart = false; 00552 if (cur->interface_mode == INTERFACE_UP || cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00553 //Disable interface like starting normal scan request 00554 if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE) { 00555 return -4; 00556 } 00557 warm_restart = true; 00558 tr_debug("Do warm link start"); 00559 } else { 00560 nd_router_t *nd_nwk = cur->border_router_setup->nd_nwk; 00561 //SET SHort Address 00562 if (cur->border_router_setup->mac_short_adr < 0xfffe) { 00563 mac_helper_mac16_address_set(cur, cur->border_router_setup->mac_short_adr); 00564 cur->lowpan_desired_short_address = cur->border_router_setup->mac_short_adr; 00565 protocol_6lowpan_set_ll16(cur, cur->border_router_setup->mac_short_adr); 00566 } 00567 mac_helper_panid_set(cur, cur->border_router_setup->mac_panid); 00568 00569 if (cur->nwk_wpan_nvm_api) { 00570 wpan_nvm_params_t *params = cur->nwk_wpan_nvm_api->nvm_params_get_cb(cur->nwk_wpan_nvm_api, cur->border_router_setup->mac_panid); 00571 cur->if_lowpan_security_params->mle_security_frame_counter = params->mle_securit_counter; 00572 //SET MAC and MLE security frame counters 00573 mle_service_security_set_frame_counter(cur->id, params->mle_securit_counter); 00574 mac_helper_link_frame_counter_set(cur->id, params->mac_security_frame_counter); 00575 } 00576 00577 // cur->mac_channel = cur->border_router_setup->channel; 00578 if (nd_nwk) { 00579 nd_border_router_setup_refresh(nd_nwk->nwk_id, false); 00580 } 00581 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER; 00582 icmpv6_recv_ra_routes(cur, false); 00583 protocol_6lowpan_interface_common_init(cur); 00584 00585 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 00586 mac_helper_pib_boolean_set(cur, macAssociationPermit, true); 00587 00588 arm_6lowpan_security_init_ifup(cur); 00589 00590 mac_helper_default_security_level_set(cur, cur->mac_parameters->mac_configured_sec_level); 00591 00592 //set 6lowpan default 00593 mac_helper_mac_mlme_max_retry_set(cur->id, LOWPAN_MAX_FRAME_RETRIES); 00594 00595 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { 00596 if (pana_server_key_material_load(cur->id) != 0) { 00597 tr_warn("Border router security load fail"); 00598 return -3; 00599 } 00600 } 00601 } 00602 00603 int number_of_channels = arm_mac_channel_list_analyze(cur); 00604 cur->lowpan_info |= INTERFACE_NWK_ACTIVE; 00605 00606 /* Start network scan when at least 2 of 256 channels are enabled, 00607 * otherwise MAC is started immediately. 00608 */ 00609 if (number_of_channels > 1) { 00610 if (warm_restart) { 00611 bootsrap_next_state_kick(ER_WARM_ACTIVE_SCAN, cur); 00612 } else { 00613 bootsrap_next_state_kick(ER_ACTIVE_SCAN, cur); 00614 } 00615 } else { 00616 border_router_start(cur, warm_restart); 00617 } 00618 return 0; 00619 } 00620 00621 static int arm_border_router_proxy_validate(int8_t interface_id, uint8_t *address) 00622 { 00623 00624 /* Could also check route type, but I don't think it really matters */ 00625 ipv6_route_t *route; 00626 route = ipv6_route_choose_next_hop(address, interface_id, NULL); 00627 if (!route || route->prefix_len < 128) { 00628 return -1; 00629 } 00630 00631 return 0; 00632 } 00633 00634 int arm_border_router_proxy_state_update(int8_t caller_interface_id, int8_t handler_interface_id, bool status) 00635 { 00636 (void)caller_interface_id; 00637 00638 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(handler_interface_id); 00639 if (!cur) { 00640 tr_error("No Interface"); 00641 return -1; 00642 } 00643 00644 if (status) { 00645 tr_debug("Border router Backhaul link ready"); 00646 } else { 00647 tr_debug("Border router Backhaul link down"); 00648 } 00649 return 0; 00650 } 00651 00652 void arm_border_router_ready(protocol_interface_info_entry_t *cur) 00653 { 00654 if (cur->border_router_setup) { 00655 nd_router_t *nd_nwk = cur->border_router_setup->nd_nwk; 00656 if (nd_nwk) { 00657 addr_add_router_groups(cur); 00658 addr_add_group(cur, ADDR_REALM_LOCAL_ALL_ROUTERS); 00659 icmpv6_radv_enable(cur); 00660 00661 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 00662 nd_nwk->mle_advert_timer = 50; 00663 } 00664 00665 nd_nwk->nd_re_validate = nd_nwk->life_time; 00666 nd_nwk->nd_re_validate /= 4; 00667 nd_nwk->nd_re_validate *= 3; 00668 nd_nwk->nd_timer = 10; 00669 nd_set_br(nd_nwk); 00670 icmpv6_restart_router_advertisements(cur, nd_nwk->border_router); 00671 rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true); 00672 cur->border_router_setup->initActive = false; 00673 00674 //SET Interface Default address 00675 cur->global_address_available = true; 00676 ipv6_prefix_on_link_update(nd_nwk->border_router); 00677 00678 } 00679 //Updates beacon contents 00680 beacon_join_priority_update(cur->id); 00681 00682 cur->bootsrap_state_machine_cnt = 0; 00683 cur->nwk_bootstrap_state = ER_BOOTSRAP_DONE; 00684 net_load_balance_internal_state_activate(cur, true); 00685 nwk_bootsrap_state_update(ARM_NWK_BOOTSTRAP_READY, cur); 00686 nd_proxy_downstream_interface_register(cur->id, arm_border_router_proxy_validate, arm_border_router_proxy_state_update); 00687 } 00688 } 00689 00690 static int8_t arm_border_router_interface_down(protocol_interface_info_entry_t *cur) 00691 { 00692 int8_t ret_val = 0; 00693 nd_router_t *nd_nwk = cur->border_router_setup->nd_nwk; 00694 /* Change Active -> Idle */ 00695 /* Disable Protocols Timers */ 00696 tr_info("BR-->IDLE"); 00697 neighbor_cache_flush(&cur->neigh_cache); 00698 00699 mlme_reset_t reset; 00700 reset.SetDefaultPIB = true; 00701 cur->mac_api->mlme_req(cur->mac_api, MLME_RESET, &reset); 00702 00703 net_load_balance_internal_state_activate(cur, false); 00704 whiteboard_interface_unregister_all_address(cur->id); 00705 if (cur->nwk_wpan_nvm_api) { 00706 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 00707 } 00708 cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id); 00709 mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur)); 00710 #ifndef NO_MLE 00711 blacklist_clear(); 00712 #endif 00713 if (nd_nwk) { 00714 ipv6_prefix_on_link_remove(nd_nwk->border_router); 00715 icmp_nd_border_router_release(nd_nwk); 00716 } 00717 00718 //MAC 00719 mac_helper_link_frame_counter_set(cur->id, 0); 00720 mac_helper_panid_set(cur, 0xffff); 00721 mac_helper_mac16_address_set(cur, 0xffff); 00722 /* Init RPL Timers */ 00723 00724 cur->lowpan_info &= ~INTERFACE_NWK_ACTIVE; 00725 mac_helper_default_security_level_set(cur, SEC_NONE); 00726 //Reset WhiteBoard 00727 whiteboard_init(cur->id); 00728 lowpan_adaptation_interface_reset(cur->id); 00729 reassembly_interface_reset(cur->id); 00730 protocol_core_interface_info_reset(cur); 00731 cur->bootsrap_state_machine_cnt = 0; 00732 cur->interface_mode = INTERFACE_IDLE; 00733 nd_proxy_downstream_interface_unregister(cur->id); 00734 return ret_val; 00735 } 00736 00737 int8_t arm_nwk_6lowpan_borderrouter_init(protocol_interface_info_entry_t *cur) 00738 { 00739 /* Border Router Allocate entry */ 00740 if (cur->border_router_setup == 0) { 00741 cur->border_router_setup = ns_dyn_mem_alloc(sizeof(br_info_t)); 00742 if (!cur->border_router_setup) { 00743 return -1; 00744 00745 } 00746 cur->border_router_setup->nd_nwk = ns_dyn_mem_alloc(sizeof(nd_router_t)); 00747 cur->border_router_setup->nd_border_router_configure = ns_dyn_mem_alloc(sizeof(nd_router_setup_t)); 00748 00749 if (cur->border_router_setup->nd_nwk == 0 || cur->border_router_setup->nd_border_router_configure == 0) { 00750 arm_nwk_6lowpan_borderrouter_data_free(cur); 00751 } 00752 if (cur->border_router_setup) { 00753 cur->border_router_setup->mac_short_adr = 0xffff; 00754 cur->border_router_setup->mac_panid = 0xffff; 00755 if (cur->border_router_setup->nd_border_router_configure) { 00756 ns_list_init(&cur->border_router_setup->nd_border_router_configure->prefix_list); 00757 ns_list_init(&cur->border_router_setup->nd_border_router_configure->context_list); 00758 } 00759 } 00760 00761 } else { 00762 if (cur->border_router_setup->nd_nwk) { 00763 //Clear Setup 00764 nd_router_t *router_object = cur->border_router_setup->nd_nwk; 00765 /** 00766 * Reset Current ND Setup 00767 */ 00768 icmp_nd_router_object_reset(router_object); 00769 } 00770 } 00771 whiteboard_init(cur->id); 00772 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER; 00773 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 00774 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00775 cur->if_up = arm_border_router_interface_up; 00776 cur->if_down = arm_border_router_interface_down; 00777 return 0; 00778 } 00779 00780 #else 00781 00782 int8_t arm_nwk_6lowpan_border_router_init(int8_t interface_id, const border_router_setup_s *border_router_setup_ptr) 00783 { 00784 (void) interface_id; 00785 (void) border_router_setup_ptr; 00786 return -3; 00787 } 00788 00789 int8_t arm_nwk_6lowpan_border_router_context_parameter_update(int8_t interface_id, uint8_t c_id, 00790 uint8_t compress_mode, uint16_t ttl) 00791 { 00792 (void) interface_id; 00793 (void) c_id; 00794 (void) compress_mode; 00795 (void) ttl; 00796 return -1; 00797 } 00798 00799 int8_t arm_nwk_6lowpan_border_router_context_remove_by_id(int8_t interface_id, uint8_t c_id) 00800 { 00801 (void) interface_id; 00802 (void) c_id; 00803 return -1; 00804 } 00805 00806 int8_t arm_nwk_6lowpan_border_router_configure_push(int8_t interface_id) 00807 { 00808 (void) interface_id; 00809 return -1; 00810 } 00811 00812 int8_t arm_nwk_6lowpan_border_router_nd_context_load(int8_t interface_id, uint8_t *contex_data) 00813 { 00814 (void) interface_id; 00815 (void) contex_data; 00816 return -1; 00817 } 00818 00819 int8_t arm_nwk_6lowpan_border_router_context_update(int8_t interface_id, uint8_t c_id_flags, uint8_t context_len, uint16_t ttl, const uint8_t *context_ptr) 00820 { 00821 (void) interface_id; 00822 (void) c_id_flags; 00823 (void) context_len; 00824 (void) ttl; 00825 (void) context_ptr; 00826 return -1; 00827 } 00828 00829 int8_t arm_nwk_6lowpan_border_route_nd_default_prefix_timeout_set(int8_t interface_id, uint32_t time) 00830 { 00831 (void) interface_id; 00832 (void) time; 00833 return -1; 00834 } 00835 00836 #endif
Generated on Tue Jul 12 2022 13:54:03 by
