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