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