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