Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
net_load_balance.c
00001 /* 00002 * Copyright (c) 2016-2019, 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, 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 (void)interface_id; 00317 (void)expected_device_count; 00318 return -1; 00319 #endif 00320 #else 00321 (void)interface_id; 00322 (void)expected_device_count; 00323 return -1; 00324 #endif 00325 } 00326 00327 /** 00328 * \brief Disable automatic network load level update 00329 * 00330 * \param interface_id interface id 00331 * 00332 * \return 0 process ok -1 Unknown interface id 00333 */ 00334 int8_t net_load_balance_load_level_update_disable(int8_t interface_id) 00335 { 00336 #ifdef HAVE_RPL 00337 #ifdef HAVE_6LOWPAN_BORDER_ROUTER 00338 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00339 if (!interface_ptr) { 00340 return -1; 00341 } 00342 00343 return load_balance_network_load_monitor_disable(interface_ptr->lb_api); 00344 #else 00345 (void)interface_id; 00346 return -1; 00347 #endif 00348 #else 00349 (void)interface_id; 00350 return -1; 00351 #endif 00352 } 00353 00354 int8_t net_load_balance_set_max_probability(int8_t interface_id, uint8_t max_p) 00355 { 00356 #ifdef HAVE_6LOWPAN_ND 00357 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id); 00358 if (!interface_ptr) { 00359 return -1; 00360 } 00361 00362 return load_balance_set_max_probability(interface_ptr->lb_api, max_p); 00363 #else 00364 return -1; 00365 #endif 00366 }
Generated on Tue Jul 12 2022 13:54:37 by
