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
nd_proxy.c
00001 /* 00002 * Copyright (c) 2015-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 #ifdef HAVE_ND_PROXY 00020 #include "ns_types.h" 00021 #include "common_functions.h" 00022 #include "ns_trace.h" 00023 #include "string.h" 00024 #include "nsdynmemLIB.h" 00025 #include "ns_list.h" 00026 #include "Service_Libs/nd_proxy/nd_proxy.h" 00027 00028 #define TRACE_GROUP "prox" 00029 00030 /** 00031 * Downstream Interface list 00032 */ 00033 typedef struct nd_proxy_downstream_list { 00034 int8_t id; /**< Proxy Interface Id*/ 00035 bridge_state_update_cb *bridge_status_update; /**< Update bridge state */ 00036 nd_proxy_req_cb *nd_proxy_validation; /**< Validate NS ND proxy response */ 00037 ns_list_link_t link; 00038 } nd_proxy_downstream_list_s; 00039 00040 /** 00041 * Upstream Interface list 00042 */ 00043 typedef struct nd_proxy_upstream_list { 00044 int8_t id; /**< Upstream Interface Id*/ 00045 nd_proxy_req_cb *route_on_link_validation; /**< Mesh Can validate OnLink Route */ 00046 ns_list_link_t link; 00047 } nd_proxy_upstream_list_s; 00048 00049 /** 00050 * Linked Downstream interface list to Upstream 00051 */ 00052 typedef struct nd_proxy_downstream_interfaces_list { 00053 int8_t id; /**< Downstream Interface Id*/ 00054 ns_list_link_t link; 00055 } nd_proxy_downstream_interfaces_list_s; 00056 00057 typedef NS_LIST_HEAD (nd_proxy_upstream_list_s, link) upstream_interface_list_t; 00058 00059 typedef NS_LIST_HEAD (nd_proxy_downstream_list_s, link) downstream_interface_list_t; 00060 00061 typedef NS_LIST_HEAD (nd_proxy_downstream_interfaces_list_s, link) proxy_connected_downstream_list_t; 00062 00063 /** 00064 * Linked Upstream and Downstream interface list 00065 */ 00066 typedef struct nd_proxy_connected_list { 00067 int8_t id; /**< Upstream Interface Id*/ 00068 proxy_connected_downstream_list_t connected_downstream_list; /**< Linked Downstream Interfaces to this interface*/ 00069 ns_list_link_t link; 00070 } nd_proxy_connected_list_s; 00071 00072 typedef NS_LIST_HEAD (nd_proxy_connected_list_s, link) proxy_connected_interface_list_t; 00073 00074 /* List of registered Upstream interfaces */ 00075 static upstream_interface_list_t upstream_interface_list; 00076 00077 /* List of registered Downstream interfaces */ 00078 static downstream_interface_list_t downstream_interface_list; 00079 00080 /* List of connected Upstream interfaces */ 00081 static proxy_connected_interface_list_t paired_interface_list; 00082 00083 /** 00084 * Get or allocate new Downstream interface entry 00085 * 00086 */ 00087 static nd_proxy_downstream_list_s * proxy_cache_downstream_interface_allocate(int8_t interface , downstream_interface_list_t *list) 00088 { 00089 ns_list_foreach(nd_proxy_downstream_list_s, e, list) { 00090 if (e->id == interface) { 00091 return e; 00092 } 00093 } 00094 nd_proxy_downstream_list_s *entry = ns_dyn_mem_alloc(sizeof(nd_proxy_downstream_list_s)); 00095 if (entry) { 00096 entry->id = interface; 00097 ns_list_add_to_start(list, entry); 00098 } 00099 00100 return entry; 00101 } 00102 00103 /** 00104 * Get or allocate new Upstream interface entry 00105 * 00106 */ 00107 static nd_proxy_upstream_list_s * proxy_cache_upstream_interface_allocate(int8_t interface , upstream_interface_list_t *list) 00108 { 00109 ns_list_foreach(nd_proxy_upstream_list_s, e, list) { 00110 if (e->id == interface) { 00111 return e; 00112 } 00113 } 00114 nd_proxy_upstream_list_s *entry = ns_dyn_mem_alloc(sizeof(nd_proxy_upstream_list_s)); 00115 if (entry) { 00116 entry->id = interface; 00117 ns_list_add_to_start(list, entry); 00118 } 00119 00120 return entry; 00121 } 00122 00123 /** 00124 * Get registered Downstream interface entry 00125 * 00126 */ 00127 static nd_proxy_downstream_list_s * proxy_cache_downstream_interface_get(int8_t interface , downstream_interface_list_t *list) 00128 { 00129 ns_list_foreach(nd_proxy_downstream_list_s, e, list) { 00130 if (e->id == interface) { 00131 return e; 00132 } 00133 } 00134 return NULL; 00135 } 00136 00137 /** 00138 * Get registered Upstream interface entry 00139 * 00140 */ 00141 static nd_proxy_upstream_list_s * proxy_cache_upstream_interface_get(int8_t interface , upstream_interface_list_t *list) 00142 { 00143 ns_list_foreach(nd_proxy_upstream_list_s, e, list) { 00144 if (e->id == interface) { 00145 return e; 00146 } 00147 } 00148 return NULL; 00149 } 00150 00151 /** 00152 * Get linked proxy entry by Upstream interface id 00153 * 00154 */ 00155 static nd_proxy_connected_list_s * proxy_upstream_conection_get(int8_t interface_id) 00156 { 00157 ns_list_foreach(nd_proxy_connected_list_s, e, &paired_interface_list) { 00158 if (e->id == interface_id) { 00159 return e; 00160 } 00161 } 00162 return NULL; 00163 } 00164 00165 /** 00166 * Get or allocate new proxy entry by Upstream interface id 00167 * 00168 */ 00169 static nd_proxy_connected_list_s * proxy_upstream_connection_allocate(int8_t interface_id) 00170 { 00171 ns_list_foreach(nd_proxy_connected_list_s, e, &paired_interface_list) { 00172 if (e->id == interface_id) { 00173 return e; 00174 } 00175 } 00176 00177 nd_proxy_connected_list_s *entry = ns_dyn_mem_alloc(sizeof(nd_proxy_connected_list_s)); 00178 if (entry) { 00179 entry->id = interface_id; 00180 ns_list_init(&entry->connected_downstream_list); 00181 ns_list_add_to_start(&paired_interface_list, entry); 00182 } 00183 return entry; 00184 } 00185 00186 /** 00187 * Link Downstream interface to allocated proxy 00188 * 00189 */ 00190 static bool proxy_downstream_conection_allocate(int8_t interface_id, proxy_connected_downstream_list_t *list) 00191 { 00192 ns_list_foreach(nd_proxy_downstream_interfaces_list_s, e, list) { 00193 if (e->id == interface_id) { 00194 return true; 00195 } 00196 } 00197 00198 nd_proxy_downstream_interfaces_list_s *entry = ns_dyn_mem_alloc(sizeof(nd_proxy_downstream_interfaces_list_s)); 00199 if (entry) { 00200 entry->id = interface_id; 00201 ns_list_add_to_start(list, entry); 00202 return true; 00203 } 00204 return false; 00205 } 00206 00207 /** 00208 * Remove Downstream interface from linked Upstream list 00209 * 00210 */ 00211 static bool proxy_cache_untie_connection_by_downstream(int8_t downstream_id) 00212 { 00213 bool ret_val = false; 00214 ns_list_foreach_safe(nd_proxy_connected_list_s, e, &paired_interface_list) { 00215 00216 ns_list_foreach_safe(nd_proxy_downstream_interfaces_list_s, downstream, &e->connected_downstream_list) { 00217 if (downstream->id == downstream_id) { 00218 //Remove from the list and free 00219 ns_list_remove(&e->connected_downstream_list, downstream); 00220 ns_dyn_mem_free(downstream); 00221 ret_val = true; 00222 } 00223 } 00224 00225 /* Free proxy connection if all mesh interfaces are disconnected */ 00226 if (ns_list_is_empty(&e->connected_downstream_list)) { 00227 //Remove connection from list and free memory 00228 ns_list_remove(&paired_interface_list, e); 00229 ns_dyn_mem_free(e); 00230 } 00231 00232 } 00233 return ret_val; 00234 } 00235 00236 /** 00237 * Remove Upstream interface from connected list 00238 * 00239 * Function will tell to mesh interface by registered function pointer disabled proxy functionality 00240 * 00241 */ 00242 static bool proxy_cache_untie_connection_by_upstream(int8_t upstream_id) 00243 { 00244 nd_proxy_downstream_list_s *downstream_interface; 00245 00246 ns_list_foreach_safe(nd_proxy_connected_list_s, e, &paired_interface_list) { 00247 00248 if (e->id != upstream_id) { 00249 continue; 00250 } 00251 00252 ns_list_foreach_safe(nd_proxy_downstream_interfaces_list_s, downstream, &e->connected_downstream_list) { 00253 //Remove from the list and free 00254 downstream_interface = proxy_cache_downstream_interface_get(downstream->id, &downstream_interface_list); 00255 if (downstream_interface) { 00256 //Indicate Downstream for missing Upstream 00257 if (downstream_interface->bridge_status_update) { 00258 downstream_interface->bridge_status_update(upstream_id, downstream->id, false); 00259 } 00260 } 00261 00262 ns_list_remove(&e->connected_downstream_list, downstream); 00263 ns_dyn_mem_free(downstream); 00264 } 00265 00266 //Remove connection from list and free memory 00267 ns_list_remove(&paired_interface_list, e); 00268 ns_dyn_mem_free(e); 00269 return true; 00270 00271 } 00272 return false; 00273 } 00274 00275 /** 00276 * Generate Proxy between Upstream and Downstream interface 00277 * 00278 * Function will tell to Downstream interface by registered function pointer enabled proxy functionality 00279 * 00280 */ 00281 static int proxy_cache_interface_enable_proxy(int8_t upstream_id, int8_t downstream_id) 00282 { 00283 //validate first current connection 00284 nd_proxy_connected_list_s *proxy = NULL; 00285 nd_proxy_downstream_list_s *downstream_interface = proxy_cache_downstream_interface_get(downstream_id, &downstream_interface_list); 00286 if (!downstream_interface) { 00287 tr_error("Unknown Downstream id"); 00288 return -1; 00289 } 00290 00291 if (!proxy_cache_upstream_interface_get(upstream_id , &upstream_interface_list)) { 00292 tr_error("Unknown Upstream id"); 00293 return -1; 00294 } 00295 00296 ns_list_foreach(nd_proxy_connected_list_s, e, &paired_interface_list) { 00297 00298 if (e->id != upstream_id) { 00299 continue; 00300 } 00301 00302 //Check Downstream 00303 ns_list_foreach_safe(nd_proxy_downstream_interfaces_list_s, mesh, &e->connected_downstream_list) { 00304 if (mesh->id == downstream_id) { 00305 return 0; 00306 } 00307 } 00308 } 00309 00310 //Allocate new Upstream and connection 00311 proxy = proxy_upstream_connection_allocate(upstream_id); 00312 00313 if (!proxy) { 00314 tr_error("Proxy alloc fail"); 00315 return -1; 00316 } 00317 00318 if (!proxy_downstream_conection_allocate(downstream_id, &proxy->connected_downstream_list) ) 00319 { 00320 tr_error("Up<->Down stream connect alloc fail"); 00321 if (ns_list_is_empty(&proxy->connected_downstream_list)) { 00322 //Remove connection from list and free memory 00323 ns_list_remove(&paired_interface_list, proxy); 00324 ns_dyn_mem_free(proxy); 00325 } 00326 return -1; 00327 } 00328 00329 if (downstream_interface->bridge_status_update) { 00330 downstream_interface->bridge_status_update(upstream_id, downstream_id, true); 00331 } 00332 return 0; 00333 } 00334 00335 int nd_proxy_downstream_interface_register(int8_t interface_id, nd_proxy_req_cb *nd_proxy_req, bridge_state_update_cb * bridge_state_update) 00336 { 00337 if (interface_id < 0) { 00338 return -1; 00339 } else if (!nd_proxy_req) { 00340 return -1; 00341 } 00342 nd_proxy_downstream_list_s * entry = proxy_cache_downstream_interface_allocate(interface_id, &downstream_interface_list); 00343 if (!entry) { 00344 return -2; 00345 } 00346 //Set Function pointers 00347 entry->bridge_status_update = bridge_state_update; 00348 entry->nd_proxy_validation = nd_proxy_req; 00349 00350 ns_list_foreach(nd_proxy_upstream_list_s, e, &upstream_interface_list) { 00351 00352 if (proxy_cache_interface_enable_proxy(e->id,interface_id) == 0) { 00353 tr_debug("Proxy bridge enabled for interface %i to %i\n", e->id, interface_id); 00354 } 00355 } 00356 00357 return 0; 00358 } 00359 00360 int nd_proxy_downstream_interface_unregister(int8_t interface_id) 00361 { 00362 //Release from paired 00363 proxy_cache_untie_connection_by_downstream(interface_id); 00364 00365 ns_list_foreach(nd_proxy_downstream_list_s, e, &downstream_interface_list) { 00366 if (e->id == interface_id) { 00367 ns_list_remove(&downstream_interface_list, e); 00368 ns_dyn_mem_free(e); 00369 return 0; 00370 } 00371 } 00372 00373 return -1; 00374 } 00375 00376 int nd_proxy_upstream_interface_register(int8_t interface_id, nd_proxy_req_cb *route_validation_req) 00377 { 00378 if (interface_id < 0) { 00379 return -1; 00380 } else if (!route_validation_req) { 00381 return -1; 00382 } 00383 00384 nd_proxy_upstream_list_s * entry = proxy_cache_upstream_interface_allocate(interface_id, &upstream_interface_list); 00385 if (!entry) { 00386 return -1; 00387 } 00388 //Set Function pointers 00389 entry->route_on_link_validation = route_validation_req; 00390 00391 //Link now all available interfaces which give proxy service 00392 ns_list_foreach(nd_proxy_downstream_list_s, e, &downstream_interface_list) { 00393 00394 if (proxy_cache_interface_enable_proxy(interface_id, e->id) == 0) { 00395 tr_debug("Proxy bridge enabled for interface %i to %i \n", interface_id, e->id); 00396 } 00397 } 00398 return 0; 00399 } 00400 00401 int nd_proxy_upstream_interface_unregister(int8_t interface_id) 00402 { 00403 proxy_cache_untie_connection_by_upstream(interface_id); 00404 00405 ns_list_foreach(nd_proxy_upstream_list_s, e, &upstream_interface_list) { 00406 if (e->id == interface_id) { 00407 ns_list_remove(&upstream_interface_list, e); 00408 ns_dyn_mem_free(e); 00409 return 0; 00410 } 00411 } 00412 00413 return -1; 00414 } 00415 00416 bool nd_proxy_enabled_for_downstream(int8_t interface_id) 00417 { 00418 if (proxy_upstream_conection_get(interface_id) ) { 00419 return true; 00420 } 00421 return false; 00422 } 00423 00424 bool nd_proxy_enabled_for_upstream(int8_t interface_id) 00425 { 00426 ns_list_foreach(nd_proxy_connected_list_s, e, &paired_interface_list) { 00427 00428 ns_list_foreach(nd_proxy_downstream_interfaces_list_s, mesh, &e->connected_downstream_list) { 00429 if (mesh->id == interface_id) { 00430 return true; 00431 } 00432 } 00433 } 00434 return false; 00435 } 00436 00437 bool nd_proxy_target_address_validation(int8_t upstream_id, uint8_t *address, int8_t *downstream_id_ptr) 00438 { 00439 nd_proxy_downstream_list_s *downstream; 00440 nd_proxy_connected_list_s *upstream = proxy_upstream_conection_get(upstream_id); 00441 *downstream_id_ptr = -1; 00442 if (!upstream) { 00443 return false; 00444 } 00445 00446 ns_list_foreach(nd_proxy_downstream_interfaces_list_s, downstream_entry, &upstream->connected_downstream_list) { 00447 downstream = proxy_cache_downstream_interface_get(downstream_entry->id, &downstream_interface_list); 00448 if (downstream) { 00449 if (downstream->nd_proxy_validation(downstream_entry->id, address) == 0) { 00450 *downstream_id_ptr = downstream_entry->id; 00451 return true; 00452 } 00453 } 00454 } 00455 00456 return false; 00457 } 00458 00459 bool nd_proxy_upstream_route_onlink(int8_t downstream_id, uint8_t *address) 00460 { 00461 ns_list_foreach(nd_proxy_connected_list_s, e, &paired_interface_list) { 00462 00463 ns_list_foreach(nd_proxy_downstream_interfaces_list_s, downstream, &e->connected_downstream_list) { 00464 if (downstream->id == downstream_id) { 00465 nd_proxy_upstream_list_s *upstream = proxy_cache_upstream_interface_get(e->id, &upstream_interface_list); 00466 if (upstream) { 00467 if (upstream->route_on_link_validation(e->id, address) == 0) { 00468 return true; 00469 } 00470 } 00471 } 00472 } 00473 } 00474 return false; 00475 } 00476 #endif /* HAVE_ND_PROXY */ 00477
Generated on Fri Jul 22 2022 04:53:57 by
 1.7.2
 1.7.2 
    