Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
net_load_balance.c
00001 /* 00002 * Copyright (c) 2016-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 #include "nsconfig.h" 00019 #include "ns_types.h" 00020 #include "ns_trace.h" 00021 #include <string.h> 00022 #include "net_load_balance_api.h" 00023 #include "net_interface.h" 00024 #include "NWK_INTERFACE/Include/protocol.h" 00025 #ifdef HAVE_6LOWPAN_ND 00026 #include "net_rpl.h" 00027 #include "Service_Libs/load_balance/load_balance_api.h" 00028 #include "Service_Libs/mle_service/mle_service_api.h" 00029 #include "nsdynmemLIB.h" 00030 #include "ns_list.h" 00031 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00032 #include "mlme.h" 00033 #include "mac_api.h" 00034 #include "sw_mac.h" 00035 #include "6LoWPAN/MAC/mac_helper.h" 00036 #include "6LoWPAN/MAC/mac_data_poll.h" 00037 #include "libNET/src/net_load_balance_internal.h" 00038 #ifdef ECC 00039 #include "libX509_V3.h" 00040 #include "ecc.h" 00041 #endif 00042 #ifdef PANA 00043 #include "Security/PANA/pana.h" 00044 #include "Security/PANA/pana_internal_api.h" 00045 #endif 00046 #include "6LoWPAN/ND/nd_router_object.h" 00047 #ifdef HAVE_RPL 00048 #include "RPL/rpl_control.h" 00049 #endif 00050 00051 #define TRACE_GROUP "6lb" 00052 00053 static uint8_t net_load_balance_priority_get(const void * load_balance_user) 00054 { 00055 const protocol_interface_info_entry_t *cur = load_balance_user; 00056 if (!cur->rpl_domain) { 00057 return 0; 00058 } 00059 int16_t priority = protocol_6lowpan_rpl_global_priority_get(); 00060 if (priority < 0) { 00061 priority = 0; 00062 } else if (priority > 255) { 00063 priority = 255; 00064 } 00065 00066 return priority; 00067 } 00068 00069 static void net_load_balance_beacon_tx(const void *load_balance_user) 00070 { 00071 const protocol_interface_info_entry_t *cur = load_balance_user; 00072 mlme_set_t set_req; 00073 set_req.attr = macLoadBalancingBeaconTx; 00074 set_req.attr_index = 0; 00075 set_req.value_pointer = NULL; 00076 set_req.value_size = 0; 00077 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00078 00079 } 00080 00081 static bool net_load_balance_network_switch_req(void * load_balance_user, struct mlme_pan_descriptor_s *PANDescriptor, const uint8_t *beacon_payload, uint16_t beacon_payload_length) 00082 { 00083 protocol_interface_info_entry_t *interface = load_balance_user; 00084 //Run down current interface setup and do start 00085 if (interface->if_down(interface) != 0) { 00086 return false; 00087 } 00088 #ifdef PANA 00089 pana_reset_client_session(); 00090 #endif 00091 if (interface->if_up(interface) != 0) { 00092 return false; 00093 } 00094 00095 if (!protocol_6lowpan_bootsrap_link_set(interface, PANDescriptor, beacon_payload, beacon_payload_length)) { 00096 return false; 00097 } 00098 00099 //Start configured bootstrap 00100 return protocol_6lowpan_bootsrap_start(interface); 00101 } 00102 00103 static void net_load_balance_link_reject(const protocol_interface_info_entry_t *cur) 00104 { 00105 uint8_t ll_all_nodes[16]; 00106 memcpy(ll_all_nodes, ADDR_LINK_LOCAL_ALL_NODES, 16); 00107 mle_service_interface_receiver_handler_update(cur->id, NULL); 00108 mle_service_reject_message_build(cur->id, ll_all_nodes, false); 00109 00110 nd_router_t *nd_router = nd_get_object_by_nwk_id(cur->nwk_id); 00111 if(nd_router) { 00112 nd_router->nd_timer = 0; 00113 nd_router->ns_forward_timer = 0; 00114 nd_router->mle_advert_timer = 0; 00115 } 00116 } 00117 00118 static bool net_load_balance_network_switch_notify_cb(const void *load_balance_user, load_balance_nwk_switch_operation operation, uint16_t *timeout) 00119 { 00120 const protocol_interface_info_entry_t *cur = load_balance_user; 00121 switch (operation) { 00122 case LB_ROUTER_LEAVE: 00123 if (arm_nwk_6lowpan_rpl_dodag_poison(cur->id) == 0) { 00124 *timeout = 8; 00125 } else { 00126 *timeout = 0; 00127 } 00128 break; 00129 00130 case LB_NEIGHBOUR_LEAVE: 00131 net_load_balance_link_reject(cur); 00132 *timeout = 4; 00133 break; 00134 } 00135 return true; 00136 } 00137 #endif 00138 00139 int8_t net_load_balance_network_switch_cb_set(int8_t interface_id, net_load_balance_network_switch_notify *network_switch_notify) 00140 { 00141 #ifdef HAVE_6LOWPAN_ND 00142 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00143 if (!interface_ptr) { 00144 return -1; 00145 } 00146 00147 return load_balance_network_switch_cb_set(interface_ptr->lb_api, network_switch_notify); 00148 #else 00149 return -1; 00150 #endif 00151 } 00152 00153 00154 int8_t net_load_balance_create(int8_t interface_id, bool enable_periodic_beacon_interval) 00155 { 00156 #ifdef HAVE_6LOWPAN_ND 00157 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00158 if (!interface_ptr || !interface_ptr->mac_api) { 00159 return -1; 00160 } else if(interface_ptr->lb_api) { 00161 return -3; 00162 } 00163 //Allocate load balance user class 00164 load_balance_api_t *lb_api = load_balance_create(net_load_balance_network_switch_notify_cb, enable_periodic_beacon_interval); 00165 if (!lb_api) { 00166 return -2; 00167 } 00168 //Here initialize load balance based on current mac max beacon data size 00169 uint16_t beacon_payload_size; 00170 if (interface_ptr->mac_api->phyMTU > MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) { 00171 beacon_payload_size = MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD; 00172 } else { 00173 beacon_payload_size = interface_ptr->mac_api->phyMTU - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD; 00174 } 00175 00176 if (lb_api->lb_initialize(lb_api, net_load_balance_beacon_tx, net_load_balance_priority_get, net_load_balance_network_switch_req, beacon_payload_size, interface_ptr) != 0) { 00177 load_balance_delete(lb_api); 00178 return -2; 00179 } 00180 00181 //Store here load balance class pointer pointer 00182 interface_ptr->lb_api = lb_api; 00183 00184 //Enable if 00185 if ((interface_ptr->lowpan_info & (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) == (INTERFACE_NWK_ACTIVE | INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) { 00186 net_load_balance_internal_state_activate(interface_ptr, true); 00187 } 00188 00189 return 0; 00190 #else 00191 return -1; 00192 #endif 00193 } 00194 00195 00196 int8_t net_load_balance_delete(int8_t interface_id) 00197 { 00198 #ifdef HAVE_6LOWPAN_ND 00199 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00200 if (!interface_ptr) { 00201 return -1; 00202 } 00203 load_balance_api_t *lb_api = interface_ptr->lb_api; 00204 interface_ptr->lb_api = NULL; 00205 00206 return load_balance_delete(lb_api); 00207 #else 00208 return -1; 00209 #endif 00210 } 00211 00212 int8_t net_load_balance_threshold_set(int8_t interface_id, uint8_t threshold_min, uint8_t threshold_max) 00213 { 00214 #ifdef HAVE_6LOWPAN_ND 00215 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00216 if (!interface_ptr) { 00217 return -1; 00218 } 00219 00220 if (threshold_min > threshold_max) { 00221 return -1; 00222 } 00223 00224 return load_balance_network_threshold_set(interface_ptr->lb_api, threshold_min, threshold_max); 00225 #else 00226 return -1; 00227 #endif 00228 } 00229 00230 void net_load_balance_internal_state_activate(protocol_interface_info_entry_t *interface_ptr, bool state) 00231 { 00232 #ifdef HAVE_6LOWPAN_ND 00233 if (!interface_ptr || !interface_ptr->lb_api || !interface_ptr->mac_api) { 00234 return; 00235 } 00236 uint32_t trigle_period = 3600; 00237 uint32_t route_lifetime_period = 3600; 00238 //Enable Load Balance 00239 #ifdef HAVE_RPL 00240 if (state && interface_ptr->rpl_domain) { 00241 struct rpl_instance *instance = rpl_control_lookup_instance(interface_ptr->rpl_domain, 1, NULL); 00242 if (instance) { 00243 const rpl_dodag_conf_t *dodag_config = rpl_control_get_dodag_config(instance); 00244 if (dodag_config) { 00245 //dio max Period caluclate in seconds 00246 uint32_t Imax_ms = (dodag_config->dio_interval_min + dodag_config->dio_interval_doublings) < 32 ? 00247 (1ul << (dodag_config->dio_interval_min + dodag_config->dio_interval_doublings)) : 0xfffffffful; 00248 trigle_period = Imax_ms / 1000; 00249 route_lifetime_period = (uint32_t)dodag_config->default_lifetime * dodag_config->lifetime_unit; 00250 00251 } 00252 } 00253 } 00254 #endif 00255 interface_ptr->lb_api->lb_enable(interface_ptr->lb_api, state, trigle_period, route_lifetime_period); 00256 mlme_set_t set_req; 00257 set_req.attr = macLoadBalancingAcceptAnyBeacon; 00258 set_req.attr_index = 0; 00259 set_req.value_pointer = &state; 00260 set_req.value_size = sizeof(bool); 00261 interface_ptr->mac_api->mlme_req(interface_ptr->mac_api, MLME_SET, &set_req); 00262 #endif 00263 00264 } 00265 00266 #ifdef HAVE_RPL 00267 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00268 static int8_t net_load_balance_api_get_node_count_cb(void *lb_user, uint16_t *node_count) 00269 { 00270 protocol_interface_info_entry_t *interface_ptr = lb_user; 00271 if (rpl_control_get_instance_dao_target_count(interface_ptr->rpl_domain, 1, NULL, node_count) ) { 00272 return 0; 00273 } 00274 00275 return -1; 00276 } 00277 #endif 00278 #endif 00279 00280 #ifdef HAVE_RPL 00281 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00282 static int8_t net_load_balance_api_get_set_load_level_cb(void *lb_user, uint8_t load_level) 00283 { 00284 //Call DODAG preference 00285 protocol_interface_info_entry_t *interface_ptr = lb_user; 00286 if (!interface_ptr->rpl_domain || interface_ptr->rpl_domain != protocol_6lowpan_rpl_domain || !protocol_6lowpan_rpl_root_dodag) { 00287 return -1; 00288 } 00289 00290 if (load_level > RPL_DODAG_PREF_MASK) { 00291 load_level = RPL_DODAG_PREF_MASK; 00292 } 00293 00294 rpl_control_set_dodag_pref(protocol_6lowpan_rpl_root_dodag, RPL_DODAG_PREF_MASK - load_level); 00295 return 0; 00296 } 00297 #endif 00298 #endif 00299 00300 int8_t net_load_balance_load_level_update_enable(int8_t interface_id, uint16_t expected_device_count) 00301 { 00302 #ifdef HAVE_RPL 00303 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00304 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00305 if (!interface_ptr) { 00306 return -1; 00307 } 00308 00309 uint16_t temp16 = expected_device_count % 8; 00310 if (temp16) { 00311 expected_device_count += (8 - temp16); 00312 } 00313 00314 return load_balance_network_load_monitor_enable(interface_ptr->lb_api, expected_device_count, RPL_DODAG_PREF_MASK + 1, net_load_balance_api_get_node_count_cb, net_load_balance_api_get_set_load_level_cb); 00315 #else 00316 return -1; 00317 #endif 00318 #else 00319 return -1; 00320 #endif 00321 } 00322 00323 /** 00324 * \brief Disable automatic network load level update 00325 * 00326 * \param interface_id interface id 00327 * 00328 * \return 0 process ok -1 Unknown interface id 00329 */ 00330 int8_t net_load_balance_load_level_update_disable(int8_t interface_id) 00331 { 00332 #ifdef HAVE_RPL 00333 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00334 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00335 if (!interface_ptr) { 00336 return -1; 00337 } 00338 00339 return load_balance_network_load_monitor_disable(interface_ptr->lb_api); 00340 #else 00341 return -1; 00342 #endif 00343 #else 00344 return -1; 00345 #endif 00346 } 00347 00348 int8_t net_load_balance_set_max_probability(int8_t interface_id , uint8_t max_p) 00349 { 00350 #ifdef HAVE_6LOWPAN_ND 00351 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00352 if (!interface_ptr) { 00353 return -1; 00354 } 00355 00356 return load_balance_set_max_probability(interface_ptr->lb_api, max_p); 00357 #else 00358 return -1; 00359 #endif 00360 }
Generated on Fri Jul 22 2022 04:53:57 by
 1.7.2
 1.7.2 
    