BA / Mbed OS BaBoRo1
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/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