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.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:53:45 by
 1.7.2
 1.7.2 
    