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
multicast_api.c
00001 /* 00002 * Copyright (c) 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 <string.h> 00020 #include "NWK_INTERFACE/Include/protocol.h" 00021 #include "Common_Protocols/ipv6_constants.h" 00022 #include "MPL/mpl.h" 00023 #include "multicast_api.h" 00024 00025 #ifdef MULTICAST_FORWARDING 00026 int8_t multicast_fwd_add(int8_t interface_id, const uint8_t group[16], uint32_t lifetime) 00027 { 00028 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00029 if (!cur) { 00030 return -1; 00031 } 00032 return addr_multicast_fwd_add(cur, group, lifetime) ? 0 : -1; 00033 } 00034 00035 int8_t multicast_fwd_remove(int8_t interface_id, const uint8_t group[16]) 00036 { 00037 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00038 if (!cur) { 00039 return -1; 00040 } 00041 return addr_multicast_fwd_remove(cur, group) ? 0 : -1; 00042 } 00043 00044 int8_t multicast_fwd_full_for_scope(int8_t interface_id, uint_fast8_t min_scope) 00045 { 00046 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00047 if (!cur) { 00048 return -1; 00049 } 00050 cur->ip_mcast_fwd_for_scope = min_scope; 00051 return 0; 00052 } 00053 00054 int8_t multicast_fwd_set_forwarding(int8_t interface_id, bool enable) 00055 { 00056 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00057 if (!cur) { 00058 return -1; 00059 } 00060 addr_multicast_fwd_set_forwarding(cur, enable); 00061 return 0; 00062 } 00063 00064 int8_t multicast_fwd_set_proxy_upstream(int8_t interface_id) 00065 { 00066 protocol_interface_info_entry_t *upstream; 00067 if (interface_id < 0) { 00068 upstream = NULL; 00069 } else { 00070 upstream = protocol_stack_interface_info_get_by_id(interface_id); 00071 if (!upstream || !upstream->ip_multicast_forwarding) { 00072 return -1; 00073 } 00074 } 00075 00076 protocol_interface_info_entry_t *old_upstream = protocol_core_multicast_upstream; 00077 protocol_core_multicast_upstream = upstream; 00078 00079 if (upstream != old_upstream) { 00080 /* Try to maintain correct state */ 00081 addr_multicast_fwd_adjust_upstream_full(old_upstream, false); 00082 addr_multicast_fwd_adjust_upstream_full(upstream, true); 00083 } 00084 return 0; 00085 } 00086 00087 #else // MULTICAST_FORWARDING 00088 00089 int8_t multicast_fwd_add(int8_t interface_id, const uint8_t group[16], uint32_t lifetime) 00090 { 00091 (void) interface_id; 00092 (void) group; 00093 (void) lifetime; 00094 return -1; 00095 } 00096 00097 int8_t multicast_fwd_remove(int8_t interface_id, const uint8_t group[16]) 00098 { 00099 (void) interface_id; 00100 (void) group; 00101 return -1; 00102 } 00103 00104 int8_t multicast_fwd_full_for_scope(int8_t interface_id, uint_fast8_t min_scope) 00105 { 00106 (void) interface_id; 00107 (void) min_scope; 00108 return -1; 00109 } 00110 00111 int8_t multicast_fwd_set_forwarding(int8_t interface_id, bool enable) 00112 { 00113 (void) interface_id; 00114 (void) enable; 00115 return -1; 00116 } 00117 00118 int8_t multicast_fwd_set_proxy_upstream(int8_t interface_id) 00119 { 00120 (void) interface_id; 00121 return -1; 00122 } 00123 #endif // MULTICAST_FORWARDING 00124 00125 #ifdef HAVE_MPL 00126 00127 int8_t multicast_mpl_domain_subscribe(int8_t interface_id, 00128 const uint8_t address[16], 00129 multicast_mpl_seed_id_mode_e seed_id_mode, 00130 const void *seed_id) 00131 { 00132 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00133 if (!interface) { 00134 return -1; 00135 } 00136 00137 return mpl_domain_create(interface, address, seed_id, seed_id_mode, -1, 0, NULL, NULL) ? 0 : -1; 00138 } 00139 00140 int8_t multicast_mpl_domain_subscribe_with_parameters 00141 (int8_t interface_id, 00142 const uint8_t address[16], 00143 multicast_mpl_seed_id_mode_e seed_id_mode, 00144 const void *seed_id, 00145 bool proactive_forwarding, 00146 uint16_t seed_set_entry_lifetime, 00147 uint32_t data_message_imin, 00148 uint32_t data_message_imax, 00149 uint8_t data_message_k, 00150 uint8_t data_message_timer_expirations, 00151 uint32_t control_message_imin, 00152 uint32_t control_message_imax, 00153 uint8_t control_message_k, 00154 uint8_t control_message_timer_expirations) 00155 { 00156 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00157 if (!interface) { 00158 return -1; 00159 } 00160 00161 const trickle_params_t data_params = { 00162 .Imax = MPL_MS_TO_TICKS(data_message_imax), 00163 .Imin = MPL_MS_TO_TICKS(data_message_imin), 00164 .k = data_message_k, 00165 .TimerExpirations = data_message_timer_expirations 00166 }, 00167 control_params = { 00168 .Imax = MPL_MS_TO_TICKS(control_message_imax), 00169 .Imin = MPL_MS_TO_TICKS(control_message_imin), 00170 .k = control_message_k, 00171 .TimerExpirations = control_message_timer_expirations 00172 }; 00173 return mpl_domain_create(interface, address, seed_id, seed_id_mode, proactive_forwarding, seed_set_entry_lifetime, &data_params, &control_params) ? 0 : -1; 00174 } 00175 00176 int_fast8_t multicast_mpl_set_default_parameters(int8_t interface_id, 00177 bool proactive_forwarding, 00178 uint16_t seed_set_entry_lifetime, 00179 uint32_t data_message_imin, 00180 uint32_t data_message_imax, 00181 uint8_t data_message_k, 00182 uint8_t data_message_timer_expirations, 00183 uint32_t control_message_imin, 00184 uint32_t control_message_imax, 00185 uint8_t control_message_k, 00186 uint8_t control_message_timer_expirations) 00187 { 00188 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get(interface_id); 00189 if (!interface) { 00190 return -1; 00191 } 00192 00193 interface->mpl_proactive_forwarding = proactive_forwarding; 00194 interface->mpl_seed_set_entry_lifetime = seed_set_entry_lifetime; 00195 interface->mpl_data_trickle_params.Imin = MPL_MS_TO_TICKS(data_message_imin); 00196 interface->mpl_data_trickle_params.Imax = MPL_MS_TO_TICKS(data_message_imax); 00197 interface->mpl_data_trickle_params.k = data_message_k; 00198 interface->mpl_data_trickle_params.TimerExpirations = data_message_timer_expirations; 00199 interface->mpl_control_trickle_params.Imin = MPL_MS_TO_TICKS(control_message_imin); 00200 interface->mpl_control_trickle_params.Imax = MPL_MS_TO_TICKS(control_message_imax); 00201 interface->mpl_control_trickle_params.k = control_message_k; 00202 interface->mpl_control_trickle_params.TimerExpirations = control_message_timer_expirations; 00203 00204 return 0; 00205 } 00206 00207 int_fast8_t multicast_mpl_set_default_seed_id(int8_t interface_id, 00208 multicast_mpl_seed_id_mode_e seed_id_mode, 00209 const void *seed_id) 00210 { 00211 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00212 if (!interface) { 00213 return -1; 00214 } 00215 00216 switch (seed_id_mode) { 00217 case MULTICAST_MPL_SEED_ID_128_BIT: 00218 case MULTICAST_MPL_SEED_ID_64_BIT: 00219 case MULTICAST_MPL_SEED_ID_16_BIT: 00220 memcpy(interface->mpl_seed_id, seed_id, seed_id_mode); 00221 break; 00222 case MULTICAST_MPL_SEED_ID_IPV6_SRC_FOR_DOMAIN: 00223 case MULTICAST_MPL_SEED_ID_IID_EUI64: 00224 case MULTICAST_MPL_SEED_ID_IID_SLAAC: 00225 case MULTICAST_MPL_SEED_ID_MAC: 00226 case MULTICAST_MPL_SEED_ID_MAC_SHORT: 00227 break; 00228 default: 00229 return -2; 00230 } 00231 00232 interface->mpl_seed_id_mode = seed_id_mode; 00233 00234 return 0; 00235 } 00236 00237 int8_t multicast_mpl_domain_unsubscribe(int8_t interface_id, 00238 const uint8_t address[16]) 00239 { 00240 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00241 if (!interface) { 00242 return -1; 00243 } 00244 00245 return mpl_domain_delete(interface, address) ? 0 : -1; 00246 } 00247 00248 void multicast_set_parameters(uint8_t i_min, uint8_t i_doublings, uint8_t k, uint8_t timer_expirations, uint16_t window_expiration) 00249 { 00250 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get(IF_6LoWPAN); 00251 if (!cur) { 00252 return; 00253 } 00254 00255 trickle_time_t i_max = i_min; 00256 for (; i_doublings; i_doublings--) { 00257 if (i_max <= TRICKLE_TIME_MAX / 2) { 00258 i_max *= 2; 00259 } else { 00260 i_max = TRICKLE_TIME_MAX; 00261 break; 00262 } 00263 } 00264 00265 /* Set the interface's default parameters, and also update the All-Forwarders domain */ 00266 cur->mpl_data_trickle_params.Imin = i_min; 00267 cur->mpl_data_trickle_params.Imax = i_max; 00268 cur->mpl_data_trickle_params.k = k; 00269 cur->mpl_data_trickle_params.TimerExpirations = timer_expirations; 00270 /* MPL core uses a 4:1 ratio for seed and message lifetimes - we somewhat 00271 * arbitrarily treat window expiration parameter as a request for message lifetime. 00272 */ 00273 uint32_t message_lifetime_ticks = (uint32_t) i_max * timer_expirations + window_expiration; 00274 uint32_t seed_lifetime_ticks = 4 * message_lifetime_ticks; 00275 cur->mpl_seed_set_entry_lifetime = (seed_lifetime_ticks + 20) / 20; // convert to seconds 00276 mpl_domain_t *domain = mpl_domain_lookup(cur, ADDR_ALL_MPL_FORWARDERS); 00277 if (!domain) { 00278 return; 00279 } 00280 00281 mpl_domain_change_timing(domain, &cur->mpl_data_trickle_params, cur->mpl_seed_set_entry_lifetime); 00282 } 00283 00284 #else // HAVE_MPL 00285 00286 int8_t multicast_mpl_domain_subscribe(int8_t interface_id, 00287 const uint8_t address[16], 00288 multicast_mpl_seed_id_mode_e seed_id_mode, 00289 const void *seed_id) 00290 { 00291 (void) interface_id; 00292 (void) address; 00293 (void) seed_id_mode; 00294 (void) seed_id; 00295 return -1; 00296 } 00297 00298 int8_t multicast_mpl_domain_subscribe_with_parameters 00299 (int8_t interface_id, 00300 const uint8_t address[16], 00301 multicast_mpl_seed_id_mode_e seed_id_mode, 00302 const void *seed_id, 00303 bool proactive_forwarding, 00304 uint16_t seed_set_entry_lifetime, 00305 uint32_t data_message_imin, 00306 uint32_t data_message_imax, 00307 uint8_t data_message_k, 00308 uint8_t data_message_timer_expirations, 00309 uint32_t control_message_imin, 00310 uint32_t control_message_imax, 00311 uint8_t control_message_k, 00312 uint8_t control_message_timer_expirations) 00313 { 00314 (void) interface_id; 00315 (void) address; 00316 (void) seed_id_mode; 00317 (void) seed_id; 00318 (void) proactive_forwarding; 00319 (void) seed_set_entry_lifetime; 00320 (void) data_message_imin; 00321 (void) data_message_imax; 00322 (void) data_message_k; 00323 (void) data_message_timer_expirations; 00324 (void) control_message_imin; 00325 (void) control_message_imax; 00326 (void) control_message_k; 00327 (void) control_message_timer_expirations; 00328 return -1; 00329 } 00330 00331 int_fast8_t multicast_mpl_set_default_parameters(int8_t interface_id, 00332 bool proactive_forwarding, 00333 uint16_t seed_set_entry_lifetime, 00334 uint32_t data_message_imin, 00335 uint32_t data_message_imax, 00336 uint8_t data_message_k, 00337 uint8_t data_message_timer_expirations, 00338 uint32_t control_message_imin, 00339 uint32_t control_message_imax, 00340 uint8_t control_message_k, 00341 uint8_t control_message_timer_expirations) 00342 { 00343 (void) interface_id; 00344 (void) proactive_forwarding; 00345 (void) seed_set_entry_lifetime; 00346 (void) data_message_imin; 00347 (void) data_message_imax; 00348 (void) data_message_k; 00349 (void) data_message_timer_expirations; 00350 (void) control_message_imin; 00351 (void) control_message_imax; 00352 (void) control_message_k; 00353 (void) control_message_timer_expirations; 00354 return -1; 00355 } 00356 00357 int_fast8_t multicast_mpl_set_default_seed_id(int8_t interface_id, 00358 multicast_mpl_seed_id_mode_e seed_id_mode, 00359 const void *seed_id) 00360 { 00361 (void) interface_id; 00362 (void) seed_id_mode; 00363 (void) seed_id; 00364 return -1; 00365 } 00366 00367 int8_t multicast_mpl_domain_unsubscribe(int8_t interface_id, 00368 const uint8_t address[16]) 00369 { 00370 (void) interface_id; 00371 (void) address; 00372 return -1; 00373 } 00374 00375 void multicast_set_parameters(uint8_t i_min, uint8_t i_doublings, uint8_t k, uint8_t timer_expirations, uint16_t window_expiration) 00376 { 00377 (void) i_min; 00378 (void) i_doublings; 00379 (void) k; 00380 (void) timer_expirations; 00381 (void) window_expiration; 00382 } 00383 00384 #endif // HAVE_MPL 00385 00386 uint8_t multicast_add_address(const uint8_t *address_ptr, uint8_t use_trickle MAYBE_UNUSED) 00387 { 00388 uint8_t ret_val = 1; 00389 if (!addr_is_ipv6_multicast(address_ptr)) { 00390 return 0; 00391 } 00392 00393 uint8_t scope = addr_ipv6_multicast_scope(address_ptr); 00394 if (scope == 0) { // reserved 00395 return 0; 00396 } else if (scope <= IPV6_SCOPE_LINK_LOCAL) { 00397 use_trickle = false; 00398 } 00399 00400 // Hacky hack. 00401 // Consider 6LoWPAN and Ethernet interfaces - if in the same scope zone, attach to one, 00402 // 6LoWPAN by preference. If different, attach to both. 00403 // If use_trickle is set, then 00404 // 1) Make sure MPL is enabled on 6LoWPAN by creating the ff03::fc domain 00405 // 2) Subscribe to that MPL domain if Realm Local and not acting as single domain 00406 // (If larger scope, then we don't create a domain, we tunnel in ff03::fc) 00407 protocol_interface_info_entry_t *lowpan = protocol_stack_interface_info_get(IF_6LoWPAN); 00408 protocol_interface_info_entry_t *ethernet = protocol_stack_interface_info_get(IF_IPV6); 00409 00410 if (lowpan && ethernet && 00411 lowpan->zone_index[scope] == ethernet->zone_index[scope]) { 00412 ethernet = NULL; // Both interfaces in same zone, join only on 6LoWPAN 00413 } 00414 00415 if (lowpan) { 00416 #ifdef HAVE_MPL 00417 if (use_trickle && !lowpan->mpl_seed) { 00418 mpl_domain_create(lowpan, ADDR_ALL_MPL_FORWARDERS, NULL, MULTICAST_MPL_SEED_ID_DEFAULT, -1, 0, NULL, NULL); 00419 } 00420 00421 if (use_trickle && scope == IPV6_SCOPE_REALM_LOCAL && !lowpan->mpl_treat_realm_domains_as_one) { 00422 ret_val = multicast_mpl_domain_subscribe(lowpan->id, address_ptr, MULTICAST_MPL_SEED_ID_DEFAULT, NULL); 00423 } else 00424 #endif 00425 { 00426 addr_add_group(lowpan, address_ptr); 00427 } 00428 } 00429 00430 if (ethernet) { 00431 addr_add_group(ethernet, address_ptr); 00432 } 00433 00434 return ret_val; 00435 } 00436 00437 uint8_t multicast_free_address(const uint8_t *address_ptr) 00438 { 00439 // Hacky hack 00440 protocol_interface_info_entry_t *lowpan = protocol_stack_interface_info_get(IF_6LoWPAN); 00441 if (lowpan) { 00442 #ifdef HAVE_MPL 00443 /* First try to delete from MPL - if that fails, delete as plain group */ 00444 if (multicast_mpl_domain_unsubscribe(lowpan->id, address_ptr) < 0) 00445 #endif 00446 { 00447 addr_remove_group(lowpan, address_ptr); 00448 } 00449 } 00450 00451 protocol_interface_info_entry_t *ethernet = protocol_stack_interface_info_get(IF_IPV6); 00452 if (ethernet) { 00453 addr_remove_group(ethernet, address_ptr); 00454 } 00455 return 0; 00456 }
Generated on Fri Jul 22 2022 04:53:57 by
 1.7.2
 1.7.2 
    