EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_net.c Source File

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 }