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
ns_net.c
00001 /* 00002 * Copyright (c) 2014-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /** 00018 * \file net.c 00019 * \brief Network API for library model 00020 * 00021 * The network API functions for library model 00022 */ 00023 #include "nsconfig.h" 00024 #include "ns_types.h" 00025 #include "eventOS_scheduler.h" 00026 #include "string.h" 00027 #include "ns_trace.h" 00028 #include "socket_api.h" 00029 #include "nsdynmemLIB.h" 00030 #include "NWK_INTERFACE/Include/protocol.h" 00031 #include "Core/include/ns_socket.h" 00032 #ifdef HAVE_RPL 00033 #include "RPL/rpl_of0.h" 00034 #include "RPL/rpl_mrhof.h" 00035 #include "RPL/rpl_control.h" 00036 #include "RPL/rpl_data.h" 00037 #endif 00038 #include "ccmLIB.h" 00039 #include "6LoWPAN/lowpan_adaptation_interface.h" 00040 #include "6LoWPAN/Bootstraps/network_lib.h" 00041 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00042 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00043 #include "6LoWPAN/ND/nd_router_object.h" 00044 #include "6LoWPAN/MAC/mac_helper.h" 00045 #include "6LoWPAN/MAC/beacon_handler.h" 00046 #ifndef NO_MLE 00047 #include "MLE/mle.h" 00048 #endif 00049 #include "platform/arm_hal_interrupt.h" 00050 #include "common_functions.h" 00051 #include "Service_Libs/whiteboard/whiteboard.h" 00052 #include "net_pana_parameters_api.h" 00053 #ifdef ECC 00054 #include "libX509_V3.h" 00055 #include "ecc.h" 00056 #endif 00057 #include "Security/PANA/pana.h" 00058 #include "Security/PANA/pana_internal_api.h" 00059 #include "nwk_stats_api.h" 00060 #include "NWK_INTERFACE/Include/protocol_stats.h" 00061 #include "Security/Common/sec_lib_definitions.h" 00062 #include "ipv6_stack/protocol_ipv6.h" 00063 #include "ipv6_stack/ipv6_routing_table.h" 00064 #include "net_thread_test.h" 00065 #include "6LoWPAN/Thread/thread_common.h" 00066 #include "6LoWPAN/Thread/thread_routing.h" 00067 #include "6LoWPAN/Thread/thread_bootstrap.h" 00068 #include "6LoWPAN/Thread/thread_management_internal.h" 00069 #include "6LoWPAN/ws/ws_bootstrap.h" 00070 #ifdef HAVE_WS 00071 #include "6LoWPAN/ws/ws_pae_controller.h" 00072 #endif 00073 #include "BorderRouter/border_router.h" 00074 #include "Service_Libs/mle_service/mle_service_api.h" 00075 #include "6LoWPAN/MAC/mac_data_poll.h" 00076 #include "sw_mac.h" 00077 #include "mac_api.h" 00078 #include "ethernet_mac_api.h" 00079 #include <stdarg.h> 00080 00081 00082 #define TRACE_GROUP "lNet" 00083 /** 00084 * \brief A function checks that the channel list is not empty. Channel pages 9 and 10 can have eight 32-bit channel masks. 00085 * \param scan_list is a pointer to the channel list structure given by the application. 00086 * \return 0 on success. 00087 * \return -1 if channel list is empty. 00088 */ 00089 static int arm_channel_list_validation(const channel_list_s *scan_list) 00090 { 00091 uint8_t i = 1; 00092 if (scan_list) { 00093 if (scan_list->channel_page == CHANNEL_PAGE_9 || scan_list->channel_page == CHANNEL_PAGE_10) { 00094 i = 8; 00095 } 00096 while (i--) 00097 if (scan_list->channel_mask[i]) { 00098 return 0; 00099 } 00100 } 00101 return -1; 00102 } 00103 00104 00105 /* Energy & Active Scan API */ 00106 int8_t arm_net_energy_scan(int8_t interface_id, channel_list_s *scan_list, void (*passed_fptr)(int8_t if_id, const mlme_scan_conf_t *conf), uint8_t energy_tresshold) 00107 { 00108 (void)interface_id; 00109 (void)scan_list; 00110 (void)passed_fptr; 00111 (void)energy_tresshold; 00112 int8_t ret_val = -3; 00113 #ifdef HAVE_RF_TUNNEL 00114 (void)interface_id; 00115 (void)scan_list; 00116 (void)passed_fptr; 00117 (void)energy_tresshold; 00118 #else 00119 protocol_interface_info_entry_t *cur = 0; 00120 cur = protocol_stack_interface_info_get_by_id(interface_id); 00121 if (cur) { 00122 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00123 ret_val = -1; 00124 } else { 00125 00126 nwk_scan_params_t *scan_params = 0; 00127 if (cur->mac_parameters) { 00128 scan_params = &cur->mac_parameters->nwk_scan_params; 00129 scan_params->stack_chan_list = *scan_list; 00130 scan_params->energy_treshold = energy_tresshold; 00131 00132 mlme_scan_t req; 00133 mac_create_scan_request(MAC_ED_SCAN_TYPE, &cur->mac_parameters->nwk_scan_params.stack_chan_list, 5, &req); 00134 if (cur->mac_api) { 00135 cur->scan_cb = passed_fptr; 00136 cur->mac_api->mlme_req(cur->mac_api, MLME_SCAN, &req); 00137 ret_val = 0; 00138 } 00139 } 00140 } 00141 } 00142 #endif 00143 return ret_val; 00144 00145 } 00146 00147 int8_t arm_net_nwk_scan(int8_t interface_id, channel_list_s *scan_list, void (*passed_fptr)(int8_t if_id, const mlme_scan_conf_t *conf), uint8_t scan_level) 00148 { 00149 (void)interface_id; 00150 (void)scan_list; 00151 (void)passed_fptr; 00152 (void)scan_level; 00153 int8_t ret_val = -3; 00154 #ifdef HAVE_RF_TUNNEL 00155 (void)interface_id; 00156 (void)scan_list; 00157 (void)passed_fptr; 00158 (void)scan_level; 00159 #else 00160 protocol_interface_info_entry_t *cur = 0; 00161 cur = protocol_stack_interface_info_get_by_id(interface_id); 00162 00163 if (cur) { 00164 cur->scan_cb = passed_fptr; 00165 if (cur->mac_parameters) { 00166 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 00167 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00168 ret_val = -1; 00169 } else if (arm_channel_list_validation(scan_list)) { 00170 tr_debug("Given channel mask is empty!\n"); 00171 ret_val = -2; 00172 } else { 00173 nwk_scan_params_t *scan_params = &cur->mac_parameters->nwk_scan_params; 00174 scan_params->stack_chan_list = *scan_list; 00175 00176 mlme_scan_t req; 00177 mac_create_scan_request(MAC_ACTIVE_SCAN, &scan_params->stack_chan_list, 5, &req); 00178 if (cur->mac_api) { 00179 cur->scan_cb = passed_fptr; 00180 scan_params->active_scan_active = true; 00181 cur->mac_api->mlme_req(cur->mac_api, MLME_SCAN, &req); 00182 } 00183 filter->nwk_active_scan_level = scan_level; 00184 mac_helper_nwk_id_filter_set(0, filter); 00185 mac_helper_mac16_address_set(cur, 0xffff); 00186 protocol_6lowpan_register_handlers(cur); 00187 ret_val = 0; 00188 00189 } 00190 } 00191 } 00192 #endif 00193 return ret_val; 00194 } 00195 00196 nwk_pan_descriptor_t *arm_net_get_scanned_nwk_list(int8_t interface_id) 00197 { 00198 nwk_pan_descriptor_t *ret_val = 0; 00199 protocol_interface_info_entry_t *cur = 0; 00200 cur = protocol_stack_interface_info_get_by_id(interface_id); 00201 if (cur) { 00202 if (cur->mac_parameters) { 00203 ret_val = cur->mac_parameters->nwk_scan_params.nwk_response_info; 00204 } 00205 } 00206 return ret_val; 00207 } 00208 00209 /** 00210 * \brief A function to read pan ID filter. 00211 * \return 16-bit value indicating a pan ID filter. 00212 */ 00213 uint16_t arm_net_get_nwk_pan_id_filter(int8_t interface_id) 00214 { 00215 protocol_interface_info_entry_t *cur = 0; 00216 cur = protocol_stack_interface_info_get_by_id(interface_id); 00217 if (cur) { 00218 if (cur->mac_parameters) { 00219 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 00220 return filter->net_pan_id_filter; 00221 } 00222 } 00223 return 0; 00224 } 00225 00226 /** 00227 * \brief A function to read network layer configurations. 00228 * \param network_params is a pointer to the structure to where the network layer configs are written to. 00229 * \return 0 on success. 00230 * \return Negative value if interface id or PAN coordinator is not known. 00231 */ 00232 int8_t arm_nwk_param_read(int8_t interface_id, link_layer_setups_s *network_params) 00233 { 00234 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00235 addrtype_t addrType = mac_helper_coordinator_address_get(cur, network_params->address); 00236 if (addrType == ADDR_NONE ) { 00237 return -2; 00238 } 00239 network_params->PANId = mac_helper_panid_get(cur); 00240 if (addrType == ADDR_802_15_4_SHORT ) { 00241 network_params->addr_mode = ADDR_MAC_SHORT16; 00242 } else { 00243 network_params->addr_mode = ADDR_MAC_LONG64; 00244 } 00245 00246 network_params->LogicalChannel = cur->mac_parameters->mac_channel; 00247 network_params->sf = 0xff; 00248 return 0; 00249 } 00250 00251 /** 00252 * \brief A function to read MAC PAN-ID, Short address & EUID64 00253 * \param mac_params is a pointer to the structure to where the mac address are written to. 00254 * \return 0 on success. 00255 * \return Negative value if interface id is not known. 00256 */ 00257 int8_t arm_nwk_mac_address_read(int8_t interface_id, link_layer_address_s *mac_params) 00258 { 00259 int8_t ret_val = -2; 00260 protocol_interface_info_entry_t *cur = 0; 00261 cur = protocol_stack_interface_info_get_by_id(interface_id); 00262 if (cur) { 00263 ret_val = 0; 00264 memcpy(mac_params->mac_long, cur->mac, 8); 00265 memcpy(mac_params->iid_eui64, cur->iid_eui64, 8); 00266 if (cur->mac_parameters) { 00267 mac_params->PANId = cur->mac_parameters->pan_id; 00268 mac_params->mac_short = cur->mac_parameters->mac_short_address; 00269 } else { 00270 mac_params->PANId = 0xffff; 00271 mac_params->mac_short = 0xffff; 00272 } 00273 } 00274 return ret_val; 00275 } 00276 00277 /** 00278 * \brief A function to read 6LoWPAN ND border router address and NWK prefix 00279 * \param mac_params is a pointer to the structure to where the mac address are written to. 00280 * \return 0 on success. 00281 * \return -1 . 00282 */ 00283 int8_t arm_nwk_nd_address_read(int8_t interface_id, network_layer_address_s *nd_addr_info) 00284 { 00285 (void)interface_id; 00286 (void)nd_addr_info; 00287 int8_t ret_val = -2; 00288 #ifdef HAVE_6LOWPAN_ND 00289 protocol_interface_info_entry_t *cur = 0; 00290 cur = protocol_stack_interface_info_get_by_id(interface_id); 00291 if (cur) { 00292 if ((cur->lowpan_info & (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) == (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) { 00293 uint8_t *adr_ptr = protocol_6lowpan_nd_border_router_address_get(cur->nwk_id); 00294 if (adr_ptr) { 00295 ret_val = 0; 00296 memcpy(nd_addr_info->border_router, adr_ptr, 16); 00297 memcpy(nd_addr_info->prefix, adr_ptr, 8); 00298 } 00299 } 00300 } 00301 #else 00302 (void)interface_id; 00303 (void)nd_addr_info; 00304 #endif 00305 return ret_val; 00306 } 00307 00308 /** 00309 * \brief Get current used channel. 00310 * 00311 * \return Active channel 00312 * \return -1 if invalid network interface ID is given 00313 */ 00314 int16_t arm_net_get_current_channel(int8_t interface_id) 00315 { 00316 int16_t ret_val = -1; 00317 protocol_interface_info_entry_t *cur = 0; 00318 cur = protocol_stack_interface_info_get_by_id(interface_id); 00319 if (cur) { 00320 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00321 ret_val = cur->mac_parameters->mac_channel; 00322 } 00323 } 00324 00325 return ret_val; 00326 } 00327 00328 /** 00329 * \brief A function to set sleep mode of a host. 00330 * \param state equals to 1 if the sleep mode is to be enabled, 0 if the sleep mode is to be disabled. 00331 */ 00332 void arm_net_host_enter_sleep_state_set(int8_t interface_id, uint8_t state) 00333 { 00334 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00335 if (cur && cur->rfd_poll_info) { 00336 00337 if (state) { 00338 cur->rfd_poll_info->macDeepSleepEnabled = true; 00339 } else { 00340 cur->rfd_poll_info->macDeepSleepEnabled = false; 00341 } 00342 } 00343 } 00344 00345 00346 /** 00347 * \brief A function to read library version information. 00348 * \param ptr is a pointer to an array to where the version information is read to. 00349 */ 00350 void net_get_version_information(uint8_t *ptr) 00351 { 00352 (void)ptr; 00353 } 00354 00355 /** 00356 * \brief Set configured network interface Global address mode (Border router bootstrap mode can't set this). 00357 * 00358 * \param interface_id Network interface ID 00359 * \param mode efine 6LoWPAN Global Address register mode:: 00360 * * NET_6LOWPAN_GP64_ADDRESS, Interface register only GP64 00361 * * NET_6LOWPAN_GP16_ADDRESS, Interface register only GP16 00362 * * NET_6LOWPAN_MULTI_GP_ADDRESS, Interface register GP16 and GP64 addresses. GP16 is primary address and GP64 is secondary. 00363 * 00364 * \param short_address_base Short address base. If application defines value 0-0xfffd 6LoWPAN try to register GP16 address using that address. 0xfffe and 0xffff will generate random 16-bit short address. 00365 * 00366 * \param define_new_short_address_at_DAD This parameter is only checked when mode is not NET_6LOWPAN_GP64_ADDRESS and short_address_base is 0-0xfffd. Recommend value is 1 that will enable automatic new address definition at Duplicate Address Detection(DAD). Value 0 will generate Duplicate Adreress Detection error for interface bootstrap. 00367 Border Router Device will not check that part. 00368 * 00369 * \return >=0 Bootstrap mode set OK. 00370 * \return -1 Unknown network ID. 00371 * \return -2 Illegal for Border Router 00372 * \return -3 Bootsrap not defined yet. 00373 */ 00374 int8_t arm_nwk_6lowpan_gp_address_mode(int8_t interface_id, net_6lowpan_gp_address_mode_e mode, uint16_t short_address_base, uint8_t define_new_short_address_at_DAD) 00375 { 00376 #ifdef HAVE_6LOWPAN_ND 00377 protocol_interface_info_entry_t *cur; 00378 cur = protocol_stack_interface_info_get_by_id(interface_id); 00379 if (!cur) { 00380 return -1; 00381 } 00382 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00383 return -2; 00384 } 00385 if (!(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) { 00386 return -3; 00387 } 00388 00389 if (thread_info(cur)) { 00390 return -2; 00391 } 00392 00393 if (short_address_base < 0xfffe) { 00394 cur->lowpan_desired_short_address = short_address_base; 00395 } else { 00396 protocol_6lowpan_allocate_mac16(cur); //Allocate Random init value 00397 } 00398 cur->reallocate_short_address_if_duplicate = define_new_short_address_at_DAD; 00399 cur->lowpan_address_mode = mode; 00400 00401 return 0; 00402 #else 00403 return -2; 00404 #endif 00405 } 00406 00407 /** 00408 * \brief A function to read networking address informations. 00409 * \param addr_id identifies the address information type to be read. 00410 * \param address is a pointer to a buffer to where the address information is written to. 00411 * \return zero on success, -1 on errors. 00412 */ 00413 int8_t arm_net_address_get(int8_t interface_id, net_address_t addr_id, uint8_t *address) 00414 { 00415 int8_t ret_val = -1; 00416 protocol_interface_info_entry_t *cur; 00417 const uint8_t *addr; 00418 00419 cur = protocol_stack_interface_info_get_by_id(interface_id); 00420 if (!cur) { 00421 return -1; 00422 } 00423 00424 if (!cur->global_address_available) { //Should also check Check Bootstrap state 00425 return -1; 00426 } 00427 00428 switch (addr_id) { 00429 case ADDR_IPV6_LL: 00430 ret_val = addr_interface_get_ll_address(cur, address, 0); 00431 break; 00432 00433 case ADDR_IPV6_GP: 00434 addr = addr_select_with_prefix(cur, NULL, 0, SOCKET_IPV6_PREFER_SRC_PUBLIC | SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT); 00435 if (addr) { 00436 memcpy(address, addr, 16); 00437 ret_val = 0; 00438 } 00439 break; 00440 00441 case ADDR_IPV6_GP_SEC: 00442 addr = addr_select_with_prefix(cur, NULL, 0, SOCKET_IPV6_PREFER_SRC_PUBLIC | SOCKET_IPV6_PREFER_SRC_6LOWPAN_LONG); 00443 /* Return if the "prefer long" gives a different answer to the default "prefer short". Pointer comparison is 00444 * sufficient as addr_select returns a pointer into the address list. */ 00445 if (addr && addr != addr_select_with_prefix(cur, NULL, 0, SOCKET_IPV6_PREFER_SRC_PUBLIC | SOCKET_IPV6_PREFER_SRC_6LOWPAN_SHORT)) { 00446 memcpy(address, addr, 16); 00447 ret_val = 0; 00448 } 00449 break; 00450 } 00451 return ret_val; 00452 } 00453 00454 /** 00455 * \brief A function to read network Interface address count. 00456 * \param interface_id Id to interface. 00457 * \param address_count Pointer where address count will be saved. 00458 * \return zero on success, -1 on errors. 00459 */ 00460 int8_t arm_net_interface_address_list_size(int8_t interface_id, uint16_t *address_count) 00461 { 00462 int8_t ret_val = -1; 00463 protocol_interface_info_entry_t *cur; 00464 *address_count = 0; 00465 cur = protocol_stack_interface_info_get_by_id(interface_id); 00466 if (cur) { 00467 ns_list_foreach(if_address_entry_t, addr, &cur->ip_addresses) { 00468 if (!addr->tentative) { 00469 (*address_count)++; 00470 } 00471 } 00472 00473 ret_val = 0; 00474 } 00475 return ret_val; 00476 } 00477 00478 /** 00479 * \brief A function to set interface metric. 00480 * \param interface_id Network interface ID. 00481 * \param metric Used to rank otherwise-equivalent routes. Lower is preferred and default is 0. The metric value is added to metric provided by the arm_net_route_add() function. 00482 * \return 0 On success, -1 on errors. 00483 */ 00484 int8_t arm_net_interface_set_metric(int8_t interface_id, uint16_t metric) 00485 { 00486 int8_t ret_val = -1; 00487 protocol_interface_info_entry_t *cur; 00488 cur = protocol_stack_interface_info_get_by_id(interface_id); 00489 00490 if (cur) { 00491 cur->ipv6_neighbour_cache.route_if_info.metric = metric; 00492 ret_val = 0; 00493 } 00494 00495 return ret_val; 00496 } 00497 00498 /** 00499 * \brief A function to read the interface metric value on an interface. 00500 * \param interface_id Network interface ID. 00501 * \param metric A pointer to the variable where the interface metric value is saved. 00502 * \return 0 On success, -1 on errors. 00503 */ 00504 int8_t arm_net_interface_get_metric(int8_t interface_id, uint16_t *metric) 00505 { 00506 int8_t ret_val = -1; 00507 protocol_interface_info_entry_t *cur; 00508 cur = protocol_stack_interface_info_get_by_id(interface_id); 00509 00510 if (cur) { 00511 *metric = cur->ipv6_neighbour_cache.route_if_info.metric; 00512 ret_val = 0; 00513 } 00514 00515 return ret_val; 00516 } 00517 00518 /** 00519 * \brief A function to read network Interface. 00520 * \param interface_id Id to interface. 00521 * \param address_buf_size Indicate buffer size in bytes minimal is 16 bytes. 00522 * \param address_buffer pointer where stack save address one by one. 00523 * \param writed_address_count pointer where stack save how many address is writed behind address_buffer. 00524 * 00525 * \return zero on success, -1 on errors. 00526 */ 00527 int8_t arm_net_address_list_get(int8_t interface_id, uint8_t address_buf_size, uint8_t *address_buffer, int *writed_address_count) 00528 { 00529 int8_t ret_val = -1; 00530 protocol_interface_info_entry_t *cur; 00531 int address_count = 0; 00532 00533 00534 cur = protocol_stack_interface_info_get_by_id(interface_id); 00535 if (!cur) { 00536 return -1; 00537 } 00538 00539 if (address_buf_size >= 16) { 00540 int loop_counter = 0; 00541 bool save_address; 00542 while (loop_counter < 2) { 00543 ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) { 00544 if (e->tentative) { 00545 continue; 00546 } 00547 00548 save_address = false; 00549 if (loop_counter) { 00550 if (!addr_is_ipv6_link_local(e->address)) { 00551 save_address = true; 00552 } 00553 } else { 00554 if (addr_is_ipv6_link_local(e->address)) { 00555 save_address = true; 00556 } 00557 } 00558 if (save_address) { 00559 memcpy(address_buffer, e->address, 16); 00560 address_buf_size -= 16; 00561 ret_val = 0; 00562 address_count++; 00563 if (address_buf_size >= 16) { 00564 address_buffer += 16; 00565 } else { 00566 *writed_address_count = address_count; 00567 return ret_val; 00568 } 00569 } 00570 } 00571 loop_counter++; 00572 } 00573 //Save writed address count to Pointer 00574 *writed_address_count = address_count; 00575 } 00576 return ret_val; 00577 } 00578 00579 int8_t arm_net_address_list_get_next(int8_t interface_id, int *n, uint8_t address_buffer[16]) 00580 { 00581 int8_t ret_val = -1; 00582 protocol_interface_info_entry_t *cur; 00583 int address_count = 0; 00584 00585 cur = protocol_stack_interface_info_get_by_id(interface_id); 00586 if (!cur) { 00587 return -1; 00588 } 00589 00590 int loop_counter = 0; 00591 bool save_address; 00592 while (loop_counter < 2) { 00593 ns_list_foreach(if_address_entry_t, e, &cur->ip_addresses) { 00594 if (e->tentative) { 00595 continue; 00596 } 00597 00598 save_address = false; 00599 if (loop_counter) { 00600 if (!addr_is_ipv6_link_local(e->address)) { 00601 save_address = true; 00602 } 00603 } else { 00604 if (addr_is_ipv6_link_local(e->address)) { 00605 save_address = true; 00606 } 00607 } 00608 if (save_address) { 00609 if (*n == address_count) { 00610 memcpy(address_buffer, e->address, 16); 00611 *n = *n + 1; 00612 return 0; 00613 } 00614 address_count++; 00615 } 00616 } 00617 loop_counter++; 00618 } 00619 return ret_val; 00620 } 00621 00622 int8_t arm_net_address_add_to_interface(int8_t interface_id, const uint8_t address[16], uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime) 00623 { 00624 protocol_interface_info_entry_t *cur; 00625 if_address_entry_t *entry; 00626 00627 cur = protocol_stack_interface_info_get_by_id(interface_id); 00628 00629 if (!cur) { 00630 return -1; 00631 } 00632 00633 entry = addr_add(cur, address, prefix_len, ADDR_SOURCE_STATIC, valid_lifetime, preferred_lifetime, false); 00634 00635 if (!entry) { 00636 return -1; 00637 } 00638 00639 return 0; 00640 } 00641 00642 int8_t arm_net_address_delete_from_interface(int8_t interface_id, const uint8_t address[16]) 00643 { 00644 protocol_interface_info_entry_t *cur; 00645 cur = protocol_stack_interface_info_get_by_id(interface_id); 00646 00647 if (!cur) { 00648 return -1; 00649 } 00650 00651 return addr_delete(cur, address); 00652 } 00653 00654 int8_t arm_net_route_add(const uint8_t *prefix, uint8_t prefix_len, const uint8_t *next_hop, uint32_t lifetime, uint8_t metric, int8_t interface_id) 00655 { 00656 ipv6_route_t *entry; 00657 00658 if (prefix_len > 128 || (prefix == NULL && prefix_len != 0)) { 00659 return -2; 00660 } 00661 00662 entry = ipv6_route_add_metric(prefix, prefix_len, interface_id, next_hop, ROUTE_USER, NULL, 0, lifetime, metric); 00663 00664 if (!entry) { 00665 return -1; 00666 } 00667 00668 return 0; 00669 } 00670 00671 int8_t arm_net_route_delete(const uint8_t *prefix, uint8_t prefix_len, const uint8_t *next_hop, int8_t interface_id) 00672 { 00673 if (prefix_len > 128 || (prefix == NULL && prefix_len != 0)) { 00674 return -2; 00675 } 00676 00677 return ipv6_route_delete(prefix, prefix_len, interface_id, next_hop, ROUTE_USER); 00678 } 00679 00680 00681 int8_t arm_nwk_interface_ethernet_init(eth_mac_api_t *api, const char *interface_name_ptr) 00682 { 00683 #ifdef HAVE_ETHERNET 00684 if (!api) { 00685 return -1; 00686 } 00687 00688 protocol_interface_info_entry_t *cur = protocol_stack_interface_generate_ethernet(api); 00689 if (!cur) { 00690 return -3; 00691 } 00692 00693 cur->if_up = ipv6_interface_up; 00694 cur->if_down = ipv6_interface_down; 00695 cur->interface_name = interface_name_ptr; 00696 return cur->id; 00697 #else 00698 (void)api; 00699 (void)interface_name_ptr; 00700 return -2; 00701 #endif 00702 } 00703 00704 extern int8_t arm_nwk_interface_ppp_init(struct eth_mac_api_s *api, const char *interface_name_ptr) 00705 { 00706 #ifdef HAVE_ETHERNET 00707 if (!api) { 00708 return -1; 00709 } 00710 00711 protocol_interface_info_entry_t *cur = protocol_stack_interface_generate_ppp(api); 00712 if (!cur) { 00713 return -3; 00714 } 00715 00716 cur->if_up = ipv6_interface_up; 00717 cur->if_down = ipv6_interface_down; 00718 cur->interface_name = interface_name_ptr; 00719 return cur->id; 00720 #else 00721 (void)api; 00722 (void)interface_name_ptr; 00723 return -2; 00724 #endif 00725 } 00726 00727 int8_t arm_nwk_interface_lowpan_init(mac_api_t *api, char *interface_name_ptr) 00728 { 00729 if (!api) { 00730 return -1; 00731 } 00732 00733 protocol_interface_info_entry_t *cur = protocol_stack_interface_generate_lowpan(api); 00734 if (!cur) { 00735 return -3; 00736 } 00737 protocol_6lowpan_configure_core(cur); 00738 cur->interface_name = interface_name_ptr; 00739 return cur->id; 00740 } 00741 00742 static int arm_net_channel_bit_mask_to_number(const uint32_t *channel_mask) 00743 { 00744 int i, j; 00745 00746 for (j = 0; j < 8; j++) { 00747 for (i = 0; i < 32; i++) { 00748 if (channel_mask[j] & ((uint32_t)1 << i)) { 00749 break; 00750 } 00751 } 00752 if (i < 32) { 00753 break; 00754 } 00755 } 00756 if (j > 7) { 00757 return -1; 00758 } 00759 return i + (j * 32); 00760 } 00761 00762 /** 00763 * \brief Set network interface link layer parameters. 00764 * 00765 * \param interface_id Network interface ID 00766 * \param tun_driver_id Driver id FOR PHY data IN & OUT 00767 * \param channel define network link channel 00768 * \param link_setup Link layer parameters for NET_6LOWPAN_NETWORK_DRIVER defines NetworkID, PAN-ID Short Address 00769 * 00770 00771 * \return >=0 Config set OK. 00772 * \return -1 Unknown network ID or tun driver. 00773 * \return -2 Interface is active, Bootsrap mode not selected or is not NET_6LOWPAN_NETWORK_DRIVER or NET_6LOWPAN_SNIFFER. 00774 * \return -3 No Memory for 6LoWPAN stack. 00775 * \return -4 Null pointer parameter 00776 * \return -5 Channel list empty 00777 */ 00778 int8_t arm_nwk_interface_network_driver_set(int8_t interface_id, const channel_list_s *nwk_channel_list, network_driver_setup_s *link_setup) 00779 { 00780 int8_t ret_val = -1; 00781 protocol_interface_info_entry_t *cur = 0; 00782 00783 if (arm_channel_list_validation(nwk_channel_list)) { 00784 tr_debug("Given channel mask is empty!\n"); 00785 return -5; 00786 } 00787 00788 cur = protocol_stack_interface_info_get_by_id(interface_id); 00789 if (!cur || !cur->mac_api) { 00790 return -1; 00791 } 00792 00793 00794 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00795 ret_val = -2; 00796 } else if ((cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) == 0) { 00797 ret_val = -2; 00798 } else if (link_setup && (link_setup->beacon_payload_tlv_length && link_setup->beacon_payload_tlv_ptr == NULL)) { 00799 ret_val = -4; 00800 } else if (link_setup && (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT || cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER)) { 00801 00802 ret_val = 0; 00803 00804 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_ACCESPOINT) { 00805 //Configure setup 00806 uint8_t *beaon_payload = mac_helper_beacon_payload_reallocate(cur, 18); 00807 if (beaon_payload) { 00808 *beaon_payload++ = link_setup->beacon_protocol_id; 00809 *beaon_payload++ = 7; //Accept Join / Host & Router 00810 memcpy(beaon_payload, link_setup->network_id, 16); 00811 ret_val = mac_helper_beacon_payload_register(cur); 00812 } else { 00813 ret_val = -3; 00814 } 00815 cur->mac_parameters->mac_channel_list = *nwk_channel_list; 00816 } else { 00817 00818 } 00819 00820 if (ret_val == 0) { 00821 if (link_setup->mac_short_adr < 0xfffe) { 00822 cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; 00823 } else { 00824 cur->lowpan_address_mode = NET_6LOWPAN_GP64_ADDRESS; 00825 } 00826 mac_helper_panid_set(cur, link_setup->mac_panid); 00827 mac_helper_mac16_address_set(cur, link_setup->mac_short_adr); 00828 00829 int channel_number = arm_net_channel_bit_mask_to_number(nwk_channel_list->channel_mask); 00830 00831 if (channel_number >= 0) { 00832 // copy the channel list information, which is needed by FHSS 00833 //Set Channel 00834 mac_helper_mac_channel_set(cur, channel_number); 00835 cur->configure_flags |= INTERFACE_NETWORK_DRIVER_SETUP_DEFINED; 00836 } 00837 } else { 00838 mac_helper_beacon_payload_reallocate(cur, 0); 00839 } 00840 } else { 00841 ret_val = -2; 00842 } 00843 return ret_val; 00844 } 00845 00846 int8_t arm_nwk_interface_up(int8_t interface_id) 00847 { 00848 int8_t ret_val = -1; 00849 protocol_interface_info_entry_t *cur = 0; 00850 cur = protocol_stack_interface_info_get_by_id(interface_id); 00851 if (!cur) { 00852 return -1; 00853 } 00854 00855 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) && cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 00856 return -4; 00857 } 00858 00859 if (!cur->if_up || !cur->if_down) { 00860 return -5; 00861 } 00862 00863 cur->net_start_tasklet = eventOS_scheduler_get_active_tasklet(); 00864 ret_val = cur->if_up(cur); 00865 00866 00867 return ret_val; 00868 } 00869 00870 int8_t arm_nwk_interface_down(int8_t interface_id) 00871 { 00872 00873 int8_t ret_val = -1; 00874 protocol_interface_info_entry_t *cur = 0; 00875 cur = protocol_stack_interface_info_get_by_id(interface_id); 00876 if (cur) { 00877 00878 if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 00879 ret_val = -4; 00880 } else if (!cur->if_up || !cur->if_down) { 00881 return -5; 00882 } else { 00883 ret_val = cur->if_down(cur); 00884 } 00885 00886 } 00887 return ret_val; 00888 } 00889 00890 int8_t arm_pana_client_key_pull(int8_t interface_id) 00891 { 00892 #ifndef PANA 00893 (void)interface_id; 00894 #endif 00895 return pana_client_key_pull(interface_id); 00896 } 00897 00898 int8_t arm_nwk_link_layer_security_mode(int8_t interface_id, net_6lowpan_link_layer_sec_mode_e mode, uint8_t sec_level, const net_link_layer_psk_security_info_s *psk_key_info) 00899 { 00900 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00901 if (!cur || thread_info(cur) || !cur->mac_parameters || (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) == 0) { 00902 return -1; 00903 } 00904 00905 #ifndef HAVE_6LOWPAN_ND 00906 return -1; 00907 #else 00908 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00909 return -4; 00910 } 00911 00912 //Verify MLE Service 00913 if (arm_6lowpan_mle_service_ready_for_security_init(cur) != 0) { 00914 return -1; 00915 } 00916 00917 cur->if_lowpan_security_params->nwk_security_mode = mode; 00918 mac_helper_link_frame_counter_set(cur->id, 0); //This is maybe mistake 00919 00920 if (mode == NET_SEC_MODE_NO_LINK_SECURITY) { 00921 cur->mac_parameters->mac_configured_sec_level = 0; 00922 cur->if_lowpan_security_params->security_level = 0; 00923 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00924 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 00925 } else { 00926 if (sec_level == 0 || sec_level > 7) { 00927 return -2; 00928 } 00929 00930 cur->mac_parameters->mac_configured_sec_level = sec_level; 00931 cur->if_lowpan_security_params->security_level = sec_level; 00932 00933 if (mode == NET_SEC_MODE_PSK_LINK_SECURITY) { 00934 if (!psk_key_info) { 00935 return -2; 00936 } 00937 //SET PSK KEY 00938 cur->if_lowpan_security_params->psk_key_info = *psk_key_info; 00939 cur->lowpan_info &= ~INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION; 00940 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00941 } else { 00942 if (!cur->if_lowpan_security_params->pana_params) { 00943 cur->if_lowpan_security_params->pana_params = pana_client_parameter_allocate(); 00944 } 00945 00946 if (!cur->if_lowpan_security_params->pana_params) { 00947 return -2; 00948 } 00949 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 00950 } 00951 } 00952 return 0; 00953 #endif 00954 } 00955 00956 int8_t arm_network_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info) 00957 { 00958 #if !defined(PANA) && !defined(HAVE_WS) 00959 (void)chain_info; 00960 #endif 00961 00962 #ifdef HAVE_WS 00963 ws_pae_controller_certificate_chain_set(chain_info); 00964 #endif 00965 00966 return pana_interface_certificate_chain_set(chain_info); 00967 } 00968 00969 int8_t arm_network_trusted_certificate_add(const arm_certificate_entry_s *cert) 00970 { 00971 #ifdef HAVE_WS 00972 return ws_pae_controller_trusted_certificate_add(cert); 00973 #else 00974 (void) cert; 00975 return -1; 00976 #endif 00977 } 00978 00979 int8_t arm_network_trusted_certificate_remove(const arm_certificate_entry_s *cert) 00980 { 00981 #ifdef HAVE_WS 00982 return ws_pae_controller_trusted_certificate_remove(cert); 00983 #else 00984 (void) cert; 00985 return -1; 00986 #endif 00987 } 00988 00989 int8_t arm_network_trusted_certificates_remove(void) 00990 { 00991 #ifdef HAVE_WS 00992 return ws_pae_controller_trusted_certificates_remove(); 00993 #else 00994 return -1; 00995 #endif 00996 } 00997 00998 int8_t arm_network_own_certificate_add(const arm_certificate_entry_s *cert) 00999 { 01000 #ifdef HAVE_WS 01001 return ws_pae_controller_own_certificate_add(cert); 01002 #else 01003 (void) cert; 01004 return -1; 01005 #endif 01006 } 01007 01008 extern int8_t arm_network_own_certificates_remove(void) 01009 { 01010 #ifdef HAVE_WS 01011 return ws_pae_controller_own_certificates_remove(); 01012 #else 01013 return -1; 01014 #endif 01015 } 01016 01017 int8_t arm_network_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl) 01018 { 01019 #ifdef HAVE_WS 01020 return ws_pae_controller_certificate_revocation_list_add(crl); 01021 #else 01022 (void) crl; 01023 return -1; 01024 #endif 01025 } 01026 01027 int8_t arm_network_certificate_revocation_list_remove(const arm_cert_revocation_list_entry_s *crl) 01028 { 01029 #ifdef HAVE_WS 01030 return ws_pae_controller_certificate_revocation_list_remove(crl); 01031 #else 01032 (void) crl; 01033 return -1; 01034 #endif 01035 } 01036 01037 /** 01038 * \brief Read Pana server security key material 01039 * 01040 * previous_active_network_key is information is only valid when current_active_key_index is bigger than 1. 01041 * 01042 *\param key pointer for store keymaterial information. 01043 * 01044 * \return 0 Key Read OK 01045 * \return -1 Pana server key material not available 01046 */ 01047 int8_t arm_network_key_get(int8_t interface_id, ns_keys_t *key) 01048 { 01049 #ifndef PANA 01050 (void)interface_id; 01051 (void)key; 01052 #endif 01053 return pana_network_key_get(interface_id, key); 01054 } 01055 01056 int8_t arm_pana_server_library_init(int8_t interface_id, net_tls_cipher_e cipher_mode, const uint8_t *key_material, uint32_t time_period_before_activate_key) 01057 { 01058 #ifndef PANA 01059 (void)interface_id; 01060 (void)cipher_mode; 01061 (void)key_material; 01062 (void)time_period_before_activate_key; 01063 #endif 01064 return pana_server_interface_init(interface_id, cipher_mode, key_material, time_period_before_activate_key); 01065 } 01066 01067 int8_t arm_pana_activate_new_key(int8_t interface_id) 01068 { 01069 #ifndef PANA 01070 (void)interface_id; 01071 #endif 01072 return pana_server_trig_new_key(interface_id); 01073 } 01074 01075 int8_t arm_pana_server_key_update(int8_t interface_id, const uint8_t *network_key_material) 01076 { 01077 #ifndef PANA 01078 (void)interface_id; 01079 (void)network_key_material; 01080 #endif 01081 return pana_server_key_update(interface_id, network_key_material); 01082 } 01083 01084 int8_t net_pana_parameter_set(const pana_lib_parameters_s *parameter_ptr) 01085 { 01086 #ifndef PANA 01087 (void)parameter_ptr; 01088 #endif 01089 return pana_set_params(parameter_ptr); 01090 } 01091 01092 01093 /** 01094 * \brief API to read PANA library parameters. 01095 * 01096 * \param parameter_ptr Output pointer for Pana parameters 01097 * 01098 */ 01099 int8_t net_pana_parameter_read(pana_lib_parameters_s *parameter_ptr) 01100 { 01101 #ifndef PANA 01102 (void)parameter_ptr; 01103 #endif 01104 return pana_get_params(parameter_ptr); 01105 } 01106 01107 int8_t arm_pana_client_library_init(int8_t interface_id, net_tls_cipher_e cipher_mode, uint32_t psk_key_id) 01108 { 01109 #ifndef PANA 01110 (void)interface_id; 01111 (void)cipher_mode; 01112 (void)psk_key_id; 01113 #endif 01114 return pana_client_interface_init(interface_id, cipher_mode, psk_key_id); 01115 } 01116 01117 int8_t arm_nwk_interface_configure_ipv6_bootstrap_set(int8_t interface_id, net_ipv6_mode_e bootstrap_mode, const uint8_t *ipv6_prefix_pointer) 01118 { 01119 #ifndef HAVE_ETHERNET 01120 (void)interface_id; 01121 (void)bootstrap_mode; 01122 (void)ipv6_prefix_pointer; 01123 #endif 01124 return ipv6_interface_configure_ipv6_bootstrap_set(interface_id, bootstrap_mode, ipv6_prefix_pointer); 01125 } 01126 01127 int8_t arm_nwk_interface_accept_ipv6_ra(int8_t interface_id, net_ipv6_accept_ra_e accept_ra) 01128 { 01129 #ifndef HAVE_ETHERNET 01130 (void)interface_id; 01131 (void)accept_ra; 01132 #endif 01133 return ipv6_interface_accept_ra(interface_id, accept_ra); 01134 } 01135 01136 int8_t arm_6lowpan_bootsrap_set_for_selected_interface(int8_t interface_id) 01137 { 01138 protocol_interface_info_entry_t *cur; 01139 01140 cur = protocol_stack_interface_info_get_by_id(interface_id); 01141 if (!cur) { 01142 return -1; 01143 } 01144 01145 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE || cur->interface_mode == INTERFACE_UP) { 01146 return -4; 01147 } 01148 01149 if (cur->nwk_id != IF_6LoWPAN) { 01150 return -1; 01151 } 01152 return 0; 01153 } 01154 01155 /** 01156 * \brief Set network interface bootstrap setup. 01157 * 01158 * \param interface_id Network interface ID 01159 * \param bootstrap_mode Selected Bootstrap mode: 01160 * * NET_6LOWPAN_BORDER_ROUTER, Initialise Border router basic setup 01161 * * NET_6LOWPAN_ROUTER, Enable normal 6LoWPAN ND and RPL to bootstrap 01162 * * NET_6LOWPAN_HOST, Enable normal 6LoWPAN ND only to bootstrap 01163 * * NET_6LOWPAN_SLEEPY_HOST, Enable normal 6LoWPAN ND only to bootstrap 01164 * 01165 * \param net_6lowpan_mode_extension Define MLE protocol use and 6LoWPAN mode 01166 * 01167 * \return >=0 Bootstrap mode set OK. 01168 * \return -1 Unknown network ID. 01169 * \return -2 Unsupported bootstrap type or extension in this library. 01170 * \return -3 No Memory for 6LoWPAN stack. 01171 * \return -4 Null pointer parameter 01172 */ 01173 int8_t arm_nwk_interface_configure_6lowpan_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension) 01174 { 01175 int8_t ret_val; 01176 01177 ret_val = arm_6lowpan_bootsrap_set_for_selected_interface(interface_id); 01178 01179 if (ret_val == 0) { 01180 01181 if (net_6lowpan_mode_extension == NET_6LOWPAN_THREAD) { 01182 ret_val = thread_node_bootstrap_init(interface_id, bootstrap_mode); 01183 } else if (net_6lowpan_mode_extension == NET_6LOWPAN_WS) { 01184 ret_val = ws_bootstrap_init(interface_id, bootstrap_mode); 01185 } else { 01186 ret_val = arm_6lowpan_bootstarp_bootstrap_set(interface_id, bootstrap_mode, net_6lowpan_mode_extension); 01187 } 01188 } 01189 01190 return ret_val; 01191 } 01192 01193 int8_t arm_nwk_set_channel_list(int8_t interface_id, const channel_list_s *nwk_channel_list) 01194 { 01195 int8_t ret_val = -1; 01196 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01197 01198 if (!cur || !cur->mac_parameters) { 01199 return -1; 01200 } 01201 01202 if (arm_channel_list_validation(nwk_channel_list)) { 01203 tr_debug("Given channel mask is empty!\n"); 01204 return -2; 01205 } 01206 01207 //CHECK Value 01208 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01209 return -4; 01210 } 01211 01212 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { 01213 if (!cur->border_router_setup) { 01214 return -2; 01215 } 01216 01217 const int channel_number = arm_net_channel_bit_mask_to_number(nwk_channel_list->channel_mask); 01218 if (channel_number < 0) { 01219 return -3; 01220 } 01221 cur->mac_parameters->mac_channel_list = *nwk_channel_list; 01222 cur->mac_parameters->mac_channel = channel_number; 01223 cur->border_router_setup->chanlist = &cur->mac_parameters->mac_channel_list; 01224 ret_val = 0; 01225 } else { 01226 // copy the channel information and store one internal pointer to it 01227 cur->mac_parameters->mac_channel_list = *nwk_channel_list; 01228 ret_val = 0; 01229 } 01230 return ret_val; 01231 } 01232 01233 int8_t arm_nwk_6lowpan_link_scan_parameter_set(int8_t interface_id, uint8_t scan_time) 01234 { 01235 int8_t ret_val = -1; 01236 protocol_interface_info_entry_t *cur = 0; 01237 01238 cur = protocol_stack_interface_info_get_by_id(interface_id); 01239 if (cur) { 01240 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01241 return -4; 01242 } 01243 01244 if (cur->mac_parameters) { 01245 if (scan_time > 14) { 01246 ret_val = -5; 01247 } else { 01248 nwk_scan_params_t *scan_params = 0; 01249 scan_params = &cur->mac_parameters->nwk_scan_params; 01250 scan_params->scan_duration = scan_time; 01251 ret_val = 0; 01252 } 01253 } 01254 } 01255 return ret_val; 01256 } 01257 01258 int8_t arm_nwk_6lowpan_link_panid_filter_for_nwk_scan(int8_t interface_id, uint16_t pan_id_filter) 01259 { 01260 int8_t ret_val = -1; 01261 protocol_interface_info_entry_t *cur = 0; 01262 cur = protocol_stack_interface_info_get_by_id(interface_id); 01263 if (cur) { 01264 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01265 ret_val = -2; 01266 } else if (cur->mac_parameters) { 01267 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01268 filter->net_pan_id_filter = pan_id_filter; 01269 ret_val = 0; 01270 } 01271 } 01272 return ret_val; 01273 } 01274 01275 int8_t arm_nwk_6lowpan_link_nwk_id_filter_for_nwk_scan(int8_t interface_id, const uint8_t *nwk_id_filter) 01276 { 01277 int8_t ret_val = -1; 01278 protocol_interface_info_entry_t *cur = 0; 01279 cur = protocol_stack_interface_info_get_by_id(interface_id); 01280 if (cur) { 01281 01282 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01283 ret_val = -2; 01284 } else if (cur->mac_parameters) { 01285 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01286 ret_val = mac_helper_nwk_id_filter_set(nwk_id_filter, filter); 01287 } 01288 } 01289 return ret_val; 01290 } 01291 01292 int8_t arm_nwk_6lowpan_link_protocol_id_filter_for_nwk_scan(int8_t interface_id, uint8_t protocol_ID) 01293 { 01294 int8_t ret_val = -1; 01295 protocol_interface_info_entry_t *cur = 0; 01296 cur = protocol_stack_interface_info_get_by_id(interface_id); 01297 if (cur) { 01298 01299 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01300 ret_val = -4; 01301 } else if (cur->mac_parameters) { 01302 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01303 filter->beacon_protocol_id_filter = protocol_ID; 01304 ret_val = 0; 01305 } 01306 } 01307 return ret_val; 01308 } 01309 01310 /* Don't have a loopback interface we can optimise for, but we do still need a route so we 01311 * can talk to ourself at all, in case our address isn't in an on-link prefix. 01312 */ 01313 static void net_automatic_loopback_route_update(protocol_interface_info_entry_t *interface, const if_address_entry_t *addr, if_address_callback_t reason) 01314 { 01315 /* Don't care about link-local addresses - we know they're on-link */ 01316 if (addr_is_ipv6_link_local(addr->address)) { 01317 return; 01318 } 01319 01320 /* TODO: When/if we have a real loopback interface, these routes would use it instead of interface->id */ 01321 switch (reason) { 01322 case ADDR_CALLBACK_DAD_COMPLETE: 01323 ipv6_route_add(addr->address, 128, interface->id, NULL, ROUTE_LOOPBACK, 0xFFFFFFFF, 0); 01324 break; 01325 case ADDR_CALLBACK_DELETED: 01326 ipv6_route_delete(addr->address, 128, interface->id, NULL, ROUTE_LOOPBACK); 01327 break; 01328 default: 01329 break; 01330 } 01331 } 01332 01333 int8_t arm_nwk_6lowpan_beacon_join_priority_tx_callback_set(int8_t interface_id, 01334 beacon_join_priority_tx_cb *beacon_join_priority_tx_cb_ptr) 01335 { 01336 return (mac_beacon_link_beacon_join_priority_tx_callback_set(interface_id, beacon_join_priority_tx_cb_ptr)); 01337 } 01338 01339 int8_t arm_nwk_6lowpan_beacon_compare_rx_callback_set(int8_t interface_id, 01340 beacon_compare_rx_cb *beacon_compare_rx_cb_ptr) 01341 { 01342 return (mac_beacon_link_beacon_compare_rx_callback_set(interface_id, beacon_compare_rx_cb_ptr)); 01343 } 01344 01345 /** 01346 * \brief A function to initialize core elements of NanoStack library. 01347 * 01348 * \param core_idle is a function pointer to a function that is called whenever NanoStack is idle. 01349 * \return 0 on success. 01350 * \return -1 if a null pointer is given. 01351 */ 01352 int8_t net_init_core(void) 01353 { 01354 /* Reset Protocol_stats */ 01355 protocol_stats_init(); 01356 protocol_core_init(); 01357 #ifdef HAVE_RPL 01358 rpl_data_init(); 01359 // XXX application should call these! 01360 rpl_of0_init(); 01361 rpl_mrhof_init(); 01362 #endif 01363 network_library_init(); 01364 addr_notification_register(net_automatic_loopback_route_update); 01365 return 0; 01366 } 01367 01368 static int8_t mac_data_poll_host_polling_state_change_check(protocol_interface_info_entry_t *cur) 01369 { 01370 int8_t ret_val = 0; 01371 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01372 tr_warn("Host Control not accepted for Router"); 01373 ret_val = -1; 01374 } else if (nwk_bootsrap_ready(cur) == 0) { 01375 tr_debug("Bootsrap Active"); 01376 ret_val = -2; 01377 } 01378 return ret_val; 01379 } 01380 01381 01382 /** 01383 * \brief Set new Host state. 01384 * 01385 * \param mode new host state 01386 * \param poll_time poll time in seconds only handled when NET_HOST_SLOW_POLL_MODE is enabled 01387 * 01388 * Valid poll time for NET_HOST_SLOW_POLL_MODE is 0 < poll_time poll_time < 864001 (1 Day) 01389 * 01390 * \return 0, State update OK 01391 * \return -1, unknown state 01392 * \return -2, invalid time 01393 * \return -3 MLE handshake trig Fail 01394 * 01395 */ 01396 int8_t arm_nwk_host_mode_set(int8_t interface_id, net_host_mode_t mode, uint32_t poll_time) 01397 { 01398 protocol_interface_info_entry_t *cur; 01399 cur = protocol_stack_interface_info_get_by_id(interface_id); 01400 if (!cur) { 01401 return -1; 01402 } 01403 01404 if (mac_data_poll_host_polling_state_change_check(cur) != 0) { 01405 return -3; 01406 } 01407 01408 net_host_mode_t old_mode; 01409 01410 if (mac_data_poll_host_mode_get(cur, &old_mode) != 0) { 01411 return -1; 01412 } 01413 01414 if (thread_info(cur)) { 01415 //save polltime for later use, polltime is zero for fast poll mode 01416 thread_info(cur)->sleepy_host_poll_time = 0; 01417 if (mode == NET_HOST_SLOW_POLL_MODE) { 01418 thread_info(cur)->sleepy_host_poll_time = poll_time; 01419 } 01420 if (old_mode == NET_HOST_RX_ON_IDLE && mode != old_mode 01421 && thread_info(cur)->thread_device_mode == THREAD_DEVICE_MODE_END_DEVICE) { 01422 tr_debug("End device changing to SED"); 01423 thread_management_device_type_set(cur->id, THREAD_DEVICE_SED); 01424 return 0; 01425 } 01426 } 01427 return mac_data_poll_host_mode_set(cur, mode, poll_time); 01428 } 01429 01430 /** 01431 * \brief Read Current Host State. 01432 * 01433 * \param mode pointer where host state will be saved 01434 01435 * \return 0, State Read update OK 01436 * \return -1, Net Role is Router or stack is idle 01437 * 01438 */ 01439 int8_t arm_nwk_host_mode_get(int8_t interface_id, net_host_mode_t *mode) 01440 { 01441 protocol_interface_info_entry_t *cur; 01442 cur = protocol_stack_interface_info_get_by_id(interface_id); 01443 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 01444 return -1; 01445 } 01446 01447 return mac_data_poll_host_mode_get(cur, mode); 01448 } 01449 01450 01451 int8_t net_nvm_data_clean(int8_t interface_id) 01452 { 01453 int8_t ret_val = -2; // Not ative 01454 protocol_interface_info_entry_t *cur = 0; 01455 cur = protocol_stack_interface_info_get_by_id(interface_id); 01456 if (cur) { 01457 if (cur->mac_parameters) { 01458 nwk_filter_params_s *filter = &(cur->mac_parameters->nwk_filter_params); 01459 01460 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 01461 mac_helper_nwk_id_filter_set(0, filter); 01462 mac_helper_panid_set(cur, 0xffff); 01463 mac_helper_mac16_address_set(cur, 0xffff); 01464 pana_reset_client_session(); 01465 ret_val = 0; 01466 } else { 01467 ret_val = 0; 01468 } 01469 } 01470 } 01471 01472 return ret_val; 01473 } 01474 01475 01476 static void trace_cmd_print(const char *fmt, ...) 01477 { 01478 va_list ap; 01479 va_start(ap, fmt); 01480 vtracef(TRACE_LEVEL_CMD, TRACE_GROUP, fmt, ap); 01481 va_end(ap); 01482 } 01483 void arm_print_routing_table(void) 01484 { 01485 arm_print_routing_table2(trace_cmd_print); 01486 } 01487 01488 void arm_print_routing_table2(void (*print_fn)(const char *fmt, ...)) 01489 { 01490 ipv6_destination_cache_print(print_fn); 01491 ipv6_route_table_print(print_fn); 01492 #ifdef HAVE_RPL 01493 rpl_control_print(print_fn); 01494 #endif 01495 } 01496 01497 void arm_print_neigh_cache(void) 01498 { 01499 arm_print_neigh_cache2(trace_cmd_print); 01500 } 01501 01502 void arm_print_neigh_cache2(void (*print_fn)(const char *fmt, ...)) 01503 { 01504 nwk_interface_print_neigh_cache(print_fn); 01505 } 01506 01507 void arm_print_protocols(void) 01508 { 01509 arm_print_protocols2(trace_cmd_print, ' '); 01510 } 01511 01512 void arm_print_protocols2(void (*print_fn)(const char *fmt, ...), char sep) 01513 { 01514 socket_list_print(print_fn, sep); 01515 } 01516 01517 void arm_ncache_flush(void) 01518 { 01519 nwk_interface_flush_neigh_cache(); 01520 } 01521 01522 int arm_nwk_sleepy_device_parent_buffer_size_set(int8_t interface_id, uint16_t big_packet_threshold, uint16_t small_packets_per_child_count, uint16_t big_packets_total_count) 01523 { 01524 protocol_interface_info_entry_t *cur; 01525 01526 cur = protocol_stack_interface_info_get_by_id(interface_id); 01527 if (cur) { 01528 return lowpan_adaptation_indirect_queue_params_set(cur, big_packet_threshold, 01529 big_packets_total_count, small_packets_per_child_count); 01530 } 01531 return -1; 01532 } 01533 01534 int8_t arm_nwk_set_cca_threshold(int8_t interface_id, uint8_t cca_threshold) 01535 { 01536 protocol_interface_info_entry_t *cur; 01537 cur = protocol_stack_interface_info_get_by_id(interface_id); 01538 if (!cur || !cur->mac_api || (cca_threshold > 100)) { 01539 return -1; 01540 } 01541 mlme_set_t set_req; 01542 set_req.attr = macCCAThreshold; 01543 set_req.attr_index = 0; 01544 set_req.value_pointer = &cca_threshold; 01545 set_req.value_size = sizeof(cca_threshold); 01546 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 01547 return 0; 01548 } 01549 01550 int8_t arm_nwk_set_tx_output_power(int8_t interface_id, uint8_t tx_power) 01551 { 01552 protocol_interface_info_entry_t *cur; 01553 cur = protocol_stack_interface_info_get_by_id(interface_id); 01554 if (!cur || !cur->mac_api || (tx_power > 100)) { 01555 return -1; 01556 } 01557 mlme_set_t set_req; 01558 set_req.attr = macTXPower; 01559 set_req.attr_index = 0; 01560 set_req.value_pointer = &tx_power; 01561 set_req.value_size = sizeof(tx_power); 01562 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 01563 return 0; 01564 }
Generated on Tue Jul 12 2022 13:54:39 by
