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