From c331a8d2a9a5f40c3f288c49edeb46d8f2fbb8d0 Mon Sep 17 00:00:00 2001 From: lamestllama Date: Fri, 3 Apr 2026 10:07:14 +1030 Subject: [PATCH] Add pluggable propagation model support via dlopen The three built-in propagation models (precomputed, 2ray, freespace) remain unchanged. Any other value for the propagationmodel config parameter now loads libpropagationmodel.so as a plugin. The plugin must export a createPropagationModel(NEMId, ConfigurationUpdate) symbol that returns a PropagationModelAlgorithm pointer. This allows external propagation models to be developed and deployed without modifying libemane. --- src/libemane/frameworkphy.cc | 42 +++++++++++++++++++++--- src/libemane/propagationmodelalgorithm.h | 2 ++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/libemane/frameworkphy.cc b/src/libemane/frameworkphy.cc index 7546850..180cfe0 100644 --- a/src/libemane/frameworkphy.cc +++ b/src/libemane/frameworkphy.cc @@ -81,6 +81,7 @@ #include "tworaypropagationmodelalgorithm.h" #include "precomputedpropagationmodelalgorithm.h" +#include #include namespace @@ -264,10 +265,11 @@ void EMANE::FrameworkPHY::initialize(Registrar & registrar) EMANE::ConfigurationProperties::DEFAULT, {"precomputed"}, "Defines the pathloss mode of operation:" - " precomputed, 2ray or freespace.", + " precomputed, 2ray or freespace are built-in." + " Any other value loads" + " libpropagationmodel.so as a plugin.", 1, - 1, - "^(precomputed|2ray|freespace)$"); + 1); configRegistrar.registerNumeric("systemnoisefigure", EMANE::ConfigurationProperties::DEFAULT, @@ -458,7 +460,6 @@ void EMANE::FrameworkPHY::configure(const ConfigurationUpdate & update) { std::string sPropagationModel{item.second[0].asString()}; - // regex has already validated values if(sPropagationModel == "precomputed") { pPropagationModelAlgorithm_.reset(new PrecomputedPropagationModelAlgorithm{id_}); @@ -467,10 +468,41 @@ void EMANE::FrameworkPHY::configure(const ConfigurationUpdate & update) { pPropagationModelAlgorithm_.reset(new TwoRayPropagationModelAlgorithm{id_}); } - else + else if(sPropagationModel == "freespace") { pPropagationModelAlgorithm_.reset(new FreeSpacePropagationModelAlgorithm{id_}); } + else + { + // load propagation model plugin: libpropagationmodel.so + std::string sLibName{"libpropagationmodel" + sPropagationModel + ".so"}; + + void * pHandle = dlopen(sLibName.c_str(), RTLD_NOW); + + if(!pHandle) + { + throw makeException( + "Failed to load propagation model plugin %s: %s", + sLibName.c_str(), + dlerror()); + } + + using CreateFunc = + PropagationModelAlgorithm * (*)(NEMId, const ConfigurationUpdate &); + + auto createFunc = + reinterpret_cast(dlsym(pHandle, "createPropagationModel")); + + if(!createFunc) + { + dlclose(pHandle); + throw makeException( + "Propagation model plugin %s missing createPropagationModel symbol", + sLibName.c_str()); + } + + pPropagationModelAlgorithm_.reset(createFunc(id_, update)); + } LOGGER_STANDARD_LOGGING(pPlatformService_->logService(), INFO_LEVEL, diff --git a/src/libemane/propagationmodelalgorithm.h b/src/libemane/propagationmodelalgorithm.h index 5b54021..55ec530 100644 --- a/src/libemane/propagationmodelalgorithm.h +++ b/src/libemane/propagationmodelalgorithm.h @@ -43,6 +43,8 @@ namespace EMANE { + class LocationInfo; + class PropagationModelAlgorithm { public: