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