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.
net_rpl.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 #include "nsconfig.h" 00019 #include "ns_types.h" 00020 #include <string.h> 00021 00022 #include "Core/include/address.h" 00023 #include "NWK_INTERFACE/Include/protocol.h" 00024 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00025 #include "RPL/rpl_protocol.h" 00026 #include "RPL/rpl_control.h" 00027 #include "RPL/rpl_data.h" 00028 00029 #include "net_rpl.h" 00030 00031 #ifdef HAVE_RPL 00032 00033 /** 00034 * \file net_rpl.c 00035 * \brief Router and Border Router RPL API. 00036 * 00037 * Rough backwards compatibility being roughly preserved with old RPL system 00038 */ 00039 00040 int8_t arm_nwk_6lowpan_rpl_dodag_init(int8_t interface_id, const uint8_t *dodag_id, const dodag_config_t *config, uint8_t instance_id, uint8_t flags) 00041 { 00042 (void)interface_id; 00043 00044 #ifdef HAVE_RPL_ROOT 00045 if (protocol_6lowpan_rpl_root_dodag) { 00046 return -1; 00047 } 00048 rpl_dodag_conf_t new_conf; 00049 new_conf.default_lifetime = config->LIFE_IN_SECONDS; 00050 new_conf.lifetime_unit = config->LIFETIME_UNIT; 00051 new_conf.dag_max_rank_increase = config->DAG_MAX_RANK_INC; 00052 new_conf.min_hop_rank_increase = config->DAG_MIN_HOP_RANK_INC; 00053 new_conf.dio_interval_min = config->DAG_DIO_INT_MIN; 00054 new_conf.dio_interval_doublings = config->DAG_DIO_INT_DOUB; 00055 new_conf.dio_redundancy_constant = config->DAG_DIO_REDU; 00056 new_conf.objective_code_point = config->DAG_OCP; 00057 new_conf.authentication = config->DAG_SEC_PCS & 8; 00058 new_conf.path_control_size = config->DAG_SEC_PCS & 7; 00059 rpl_data_init_root(); 00060 protocol_6lowpan_rpl_root_dodag = rpl_control_create_dodag_root(protocol_6lowpan_rpl_domain, instance_id, dodag_id, &new_conf, new_conf.min_hop_rank_increase, flags); 00061 if (!protocol_6lowpan_rpl_root_dodag) { 00062 return -2; 00063 } 00064 00065 /* Something of a hack - if we're root of a non-storing DODAG, disable hard 00066 * memory limits, and relax soft memory limit. Soft memory limit doesn't 00067 * really matter if we're just a border router - we won't have anything 00068 * freeable to keep under it anyway - but if there's another DODAG we may 00069 * find ourselves struggling to join it if RPL memory is full of our own 00070 * root storage. 00071 */ 00072 if ((flags & RPL_MODE_MASK) == RPL_MODE_NON_STORING) { 00073 rpl_control_set_memory_limits(64*1024, 0); 00074 } 00075 return 0; 00076 #else // !HAVE_RPL_ROOT 00077 return -1; 00078 #endif 00079 } 00080 00081 int8_t arm_nwk_6lowpan_rpl_memory_limit_set(size_t soft_limit, size_t hard_limit) 00082 { 00083 if (hard_limit != 0 && soft_limit > hard_limit ) { 00084 return -1; 00085 } 00086 00087 rpl_control_set_memory_limits(soft_limit, hard_limit); 00088 return 0; 00089 } 00090 00091 int8_t arm_nwk_6lowpan_rpl_dodag_remove(int8_t interface_id) 00092 { 00093 protocol_interface_info_entry_t *cur; 00094 cur = protocol_stack_interface_info_get_by_id(interface_id); 00095 if (!cur || !cur->rpl_domain) { 00096 return -1; 00097 } 00098 if (!protocol_6lowpan_rpl_root_dodag) { 00099 return -1; 00100 } 00101 rpl_control_delete_dodag_root(cur->rpl_domain, protocol_6lowpan_rpl_root_dodag); 00102 return -1; 00103 } 00104 00105 int8_t arm_nwk_6lowpan_rpl_dodag_start(int8_t interface_id) 00106 { 00107 protocol_interface_info_entry_t *cur; 00108 cur = protocol_stack_interface_info_get_by_id(interface_id); 00109 if (!cur || !cur->rpl_domain) { 00110 return -1; 00111 } 00112 rpl_control_force_leaf(cur->rpl_domain, false); 00113 return 0; 00114 } 00115 00116 int8_t arm_nwk_6lowpan_rpl_dodag_route_update(int8_t interface_id, uint8_t *route_ptr, uint8_t prefix_len, uint8_t flags, uint32_t lifetime) 00117 { 00118 (void)interface_id; 00119 00120 if (prefix_len && !route_ptr) { 00121 return -2; 00122 } 00123 if (!protocol_6lowpan_rpl_root_dodag) { 00124 return -1; 00125 } 00126 rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, route_ptr, prefix_len, flags, lifetime, false); 00127 return 0; 00128 } 00129 00130 int8_t arm_nwk_6lowpan_rpl_dodag_prefix_update(int8_t interface_id, uint8_t *prefix_ptr, uint8_t prefix_len, uint8_t flags, uint32_t lifetime) 00131 { 00132 (void)interface_id; 00133 00134 if (prefix_len && !prefix_ptr) { 00135 return -2; 00136 } 00137 if (!protocol_6lowpan_rpl_root_dodag) { 00138 return -1; 00139 } 00140 rpl_control_update_dodag_prefix(protocol_6lowpan_rpl_root_dodag, prefix_ptr, prefix_len, flags, lifetime, lifetime, false); 00141 return 0; 00142 } 00143 00144 00145 int8_t arm_nwk_6lowpan_rpl_dodag_poison(int8_t interface_id) 00146 { 00147 protocol_interface_info_entry_t *cur; 00148 cur = protocol_stack_interface_info_get_by_id(interface_id); 00149 if (!cur || !cur->rpl_domain) { 00150 return -1; 00151 } 00152 rpl_control_poison(cur->rpl_domain, 3 /* arbitrary poison count */); 00153 /* Make sure we send no more adverts after poison */ 00154 rpl_control_force_leaf(cur->rpl_domain, true); 00155 return 0; 00156 } 00157 00158 int8_t arm_nwk_6lowpan_rpl_dodag_dao_trig(int8_t interface_id) 00159 { 00160 /* New code version - specifying interface ID makes no sense - fudge to let it increase main RPL root */ 00161 protocol_interface_info_entry_t *cur; 00162 cur = protocol_stack_interface_info_get_by_id(interface_id); 00163 if (!cur || !cur->rpl_domain || cur->rpl_domain != protocol_6lowpan_rpl_domain || !protocol_6lowpan_rpl_root_dodag) { 00164 return -1; 00165 } 00166 00167 rpl_control_increment_dtsn(protocol_6lowpan_rpl_root_dodag); 00168 00169 return 0; 00170 } 00171 00172 int8_t arm_nwk_6lowpan_rpl_dodag_version_increment(int8_t interface_id) 00173 { 00174 /* New code version - specifying interface ID makes no sense - fudge to let it increase main RPL root */ 00175 protocol_interface_info_entry_t *cur; 00176 cur = protocol_stack_interface_info_get_by_id(interface_id); 00177 if (!cur || !cur->rpl_domain || cur->rpl_domain != protocol_6lowpan_rpl_domain || !protocol_6lowpan_rpl_root_dodag) { 00178 return -1; 00179 } 00180 00181 rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag); 00182 00183 return 0; 00184 } 00185 00186 int8_t arm_nwk_6lowpan_rpl_dodag_pref_set(int8_t interface_id, uint8_t preference) 00187 { 00188 /* New code version - specifying interface ID makes no sense - fudge to let it increase main RPL root */ 00189 protocol_interface_info_entry_t *cur; 00190 cur = protocol_stack_interface_info_get_by_id(interface_id); 00191 if (!cur || !cur->rpl_domain || cur->rpl_domain != protocol_6lowpan_rpl_domain || !protocol_6lowpan_rpl_root_dodag) { 00192 return -1; 00193 } 00194 00195 if (preference > RPL_DODAG_PREF_MASK) { 00196 return -2; 00197 } 00198 00199 rpl_control_set_dodag_pref(protocol_6lowpan_rpl_root_dodag, preference); 00200 00201 return 0; 00202 } 00203 00204 uint8_t rpl_instance_list_read(uint8_t *buffer_ptr, uint8_t buffer_size) 00205 { 00206 uint8_t ret_val = 0; 00207 struct rpl_instance *instance = NULL; 00208 00209 if (!protocol_6lowpan_rpl_domain) { 00210 return 0; 00211 } 00212 00213 while (buffer_size) { 00214 instance = rpl_control_enumerate_instances(protocol_6lowpan_rpl_domain, instance); 00215 if (!instance) { 00216 break; 00217 } 00218 rpl_dodag_info_t dodag_info; 00219 if (rpl_control_read_dodag_info(instance, &dodag_info)) { 00220 /* First the instance ID */ 00221 *buffer_ptr++ = dodag_info.instance_id; 00222 buffer_size--; 00223 /* Then, if local, the DODAG ID */ 00224 if (rpl_instance_id_is_local(dodag_info.instance_id)) { 00225 if (buffer_size < 16) { 00226 break; 00227 } 00228 memcpy(buffer_ptr, dodag_info.dodag_id, 16); 00229 buffer_ptr += 16; 00230 buffer_size -= 16; 00231 } 00232 ret_val++; 00233 } 00234 } 00235 00236 return ret_val; 00237 } 00238 00239 uint8_t rpl_read_dodag_info(rpl_dodag_info_t *dodag_ptr, uint8_t instance_id) 00240 { 00241 if (!protocol_6lowpan_rpl_domain) { 00242 return 0; 00243 } 00244 00245 struct rpl_instance *instance = rpl_control_lookup_instance(protocol_6lowpan_rpl_domain, instance_id, dodag_ptr->dodag_id); 00246 if (!instance) { 00247 return 0; 00248 } 00249 return rpl_control_read_dodag_info(instance, dodag_ptr); 00250 } 00251 00252 00253 #else /* HAVE_RPL */ 00254 00255 int8_t arm_nwk_6lowpan_rpl_dodag_init(int8_t interface_id, const uint8_t *dodag_id, const dodag_config_t *config, uint8_t instance_id, uint8_t flags) { 00256 (void)interface_id; 00257 (void)dodag_id; 00258 (void)config; 00259 (void)instance_id; 00260 (void)flags; 00261 return -1; 00262 } 00263 00264 int8_t arm_nwk_6lowpan_rpl_dodag_remove(int8_t interface_id) { 00265 (void)interface_id; 00266 return -1; 00267 } 00268 00269 int8_t arm_nwk_6lowpan_rpl_dodag_start(int8_t interface_id) { 00270 (void)interface_id; 00271 return -1; 00272 } 00273 00274 int8_t arm_nwk_6lowpan_rpl_dodag_prefix_update(int8_t interface_id, uint8_t *prefix_ptr, uint8_t prefix_len, uint8_t flags, uint32_t lifetime) { 00275 (void)interface_id; 00276 (void)prefix_ptr; 00277 (void)prefix_len; 00278 (void)flags; 00279 (void)lifetime; 00280 return -1; 00281 } 00282 00283 int8_t arm_nwk_6lowpan_rpl_dodag_route_update(int8_t interface_id, uint8_t *route_ptr, uint8_t prefix_len, uint8_t flags, uint32_t lifetime) { 00284 (void)interface_id; 00285 (void)route_ptr; 00286 (void)prefix_len; 00287 (void)flags; 00288 (void)lifetime; 00289 return -1; 00290 } 00291 00292 int8_t arm_nwk_6lowpan_rpl_dodag_poison(int8_t interface_id) { 00293 (void)interface_id; 00294 return -1; 00295 } 00296 00297 int8_t arm_nwk_6lowpan_rpl_dodag_dao_trig(int8_t interface_id) { 00298 (void)interface_id; 00299 return -1; 00300 } 00301 00302 int8_t arm_nwk_6lowpan_rpl_dodag_version_increment(int8_t interface_id) { 00303 (void)interface_id; 00304 return -1; 00305 } 00306 00307 uint8_t rpl_instance_list_read(uint8_t *cache_ptr, uint8_t cache_size) { 00308 (void)cache_ptr; 00309 (void)cache_size; 00310 return 0; 00311 } 00312 00313 uint8_t rpl_read_dodag_info(rpl_dodag_info_t *dodag_ptr, uint8_t instance_id) { 00314 (void)dodag_ptr; 00315 (void)instance_id; 00316 return 0; 00317 } 00318 00319 int8_t arm_nwk_6lowpan_rpl_dodag_pref_set(int8_t interface_id, uint8_t preference) { 00320 (void) interface_id; 00321 (void) preference; 00322 return 0; 00323 } 00324 #endif /* HAVE_RPL */
Generated on Tue Jul 12 2022 14:24:29 by
