1 /* 2 * Copyright (c) 2011-2016, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #include "version.h" 31 #include "ParameterMgr.h" 32 #include "ConfigurationAccessContext.h" 33 #include "XmlParameterSerializingContext.h" 34 #include "XmlElementSerializingContext.h" 35 #include "SystemClass.h" 36 #include "ElementLibrarySet.h" 37 #include "SubsystemLibrary.h" 38 #include "NamedElementBuilderTemplate.h" 39 #include "KindElementBuilderTemplate.h" 40 #include "ElementBuilderTemplate.h" 41 #include "SelectionCriterionType.h" 42 #include "SubsystemElementBuilder.h" 43 #include "FileIncluderElementBuilder.h" 44 #include "SelectionCriteria.h" 45 #include "ComponentType.h" 46 #include "ComponentInstance.h" 47 #include "ParameterBlockType.h" 48 #include "BooleanParameterType.h" 49 #include "IntegerParameterType.h" 50 #include "FixedPointParameterType.h" 51 #include "FloatingPointParameterType.h" 52 #include "ParameterBlackboard.h" 53 #include "Parameter.h" 54 #include "ParameterAccessContext.h" 55 #include "ParameterFrameworkConfiguration.h" 56 #include "FrameworkConfigurationGroup.h" 57 #include "PluginLocation.h" 58 #include "SubsystemPlugins.h" 59 #include "FrameworkConfigurationLocation.h" 60 #include "ConfigurableDomains.h" 61 #include "ConfigurableDomain.h" 62 #include "DomainConfiguration.h" 63 #include "XmlDomainSerializingContext.h" 64 #include "XmlDomainExportContext.h" 65 #include "XmlDomainImportContext.h" 66 #include "BitParameterBlockType.h" 67 #include "BitParameterType.h" 68 #include "StringParameterType.h" 69 #include "EnumParameterType.h" 70 #include "BackgroundRemoteProcessorServer.h" 71 #include "ElementLocator.h" 72 #include "CompoundRule.h" 73 #include "SelectionCriterionRule.h" 74 #include "SimulatedBackSynchronizer.h" 75 #include "HardwareBackSynchronizer.h" 76 #include <cassert> 77 #include "ParameterHandle.h" 78 #include "LinearParameterAdaptation.h" 79 #include "LogarithmicParameterAdaptation.h" 80 #include "EnumValuePair.h" 81 #include "Subsystem.h" 82 #include "XmlStreamDocSink.h" 83 #include "XmlMemoryDocSink.h" 84 #include "XmlDocSource.h" 85 #include "XmlMemoryDocSource.h" 86 #include "SelectionCriteriaDefinition.h" 87 #include "Utility.h" 88 #include "Memory.hpp" 89 #include <sstream> 90 #include <fstream> 91 #include <algorithm> 92 #include <stdexcept> 93 #include <mutex> 94 #include <iomanip> 95 #include "convert.hpp" 96 97 #define base CElement 98 99 /** Private macro helper to declare a new context 100 * 101 * Context declaration always need logger and logging prefix to be 102 * passed as parameters. 103 * This macro aims to avoid this boring notation. 104 * This macro should be called only once in a scope. Nested scopes can 105 * call this macro too, as variable shadowing is supported. 106 */ 107 #define LOG_CONTEXT(contextTitle) core::log::Context context(_logger, contextTitle) 108 109 #ifdef SIMULATION 110 // In simulation, back synchronization of the blackboard won't probably work 111 // We need to ensure though the blackboard is initialized with valid data 112 typedef CSimulatedBackSynchronizer BackSynchronizer; 113 #else 114 // Real back synchronizer from subsystems 115 typedef CHardwareBackSynchronizer BackSynchronizer; 116 #endif 117 118 using std::string; 119 using std::list; 120 using std::vector; 121 using std::ostringstream; 122 using std::ofstream; 123 using std::ifstream; 124 using std::mutex; 125 using std::lock_guard; 126 127 // FIXME: integrate ParameterMgr to core namespace 128 using namespace core; 129 130 // Used for remote processor server creation 131 typedef IRemoteProcessorServerInterface *(*CreateRemoteProcessorServer)( 132 uint16_t uiPort, IRemoteCommandHandler *pCommandHandler); 133 134 // Config File System looks normally like this: 135 // --------------------------------------------- 136 //|-- <ParameterFrameworkConfiguration>.xml 137 //|-- schemas 138 //| `-- *.xsd 139 //|-- Settings 140 //| `-- <SystemClassName folder>* 141 //| |-- <ConfigurableDomains>.xml 142 //| `-- <Settings>.bin? 143 //`-- Structure 144 // `-- <SystemClassName folder>* 145 // |-- <SystemClassName>Class.xml 146 // `-- <Subsystem>.xml* 147 // -------------------------------------------- 148 149 // Remote command parser array 150 const CParameterMgr::SRemoteCommandParserItem CParameterMgr::gastRemoteCommandParserItems[] = { 151 152 /// Version 153 {"version", &CParameterMgr::versionCommandProcess, 0, "", "Show version"}, 154 155 /// Status 156 {"status", &CParameterMgr::statusCommandProcess, 0, "", "Show current status"}, 157 158 /// Tuning Mode 159 {"setTuningMode", &CParameterMgr::setTuningModeCommandProcess, 1, "on|off*", 160 "Turn on or off Tuning Mode"}, 161 {"getTuningMode", &CParameterMgr::getTuningModeCommandProcess, 0, "", "Show Tuning Mode"}, 162 163 /// Value Space 164 {"setValueSpace", &CParameterMgr::setValueSpaceCommandProcess, 1, "raw|real*", 165 "Assigns Value Space used for parameter value interpretation"}, 166 {"getValueSpace", &CParameterMgr::getValueSpaceCommandProcess, 0, "", "Show Value Space"}, 167 168 /// Output Raw Format 169 {"setOutputRawFormat", &CParameterMgr::setOutputRawFormatCommandProcess, 1, "dec*|hex", 170 "Assigns format used to output parameter values when in raw Value Space"}, 171 {"getOutputRawFormat", &CParameterMgr::getOutputRawFormatCommandProcess, 0, "", 172 "Show Output Raw Format"}, 173 174 /// Sync 175 {"setAutoSync", &CParameterMgr::setAutoSyncCommandProcess, 1, "on*|off", 176 "Turn on or off automatic synchronization to hardware while in Tuning Mode"}, 177 {"getAutoSync", &CParameterMgr::getAutoSyncCommandProcess, 0, "", "Show Auto Sync state"}, 178 {"sync", &CParameterMgr::syncCommandProcess, 0, "", 179 "Synchronize current settings to hardware while in Tuning Mode and Auto Sync off"}, 180 181 /// Criteria 182 {"listCriteria", &CParameterMgr::listCriteriaCommandProcess, 0, "[CSV|XML]", 183 "List selection criteria"}, 184 185 /// Domains 186 {"listDomains", &CParameterMgr::listDomainsCommandProcess, 0, "", "List configurable domains"}, 187 {"dumpDomains", &CParameterMgr::dumpDomainsCommandProcess, 0, "", 188 "Show all domains and configurations, including applicability conditions"}, 189 {"createDomain", &CParameterMgr::createDomainCommandProcess, 1, "<domain>", 190 "Create new configurable domain"}, 191 {"deleteDomain", &CParameterMgr::deleteDomainCommandProcess, 1, "<domain>", 192 "Delete configurable domain"}, 193 {"deleteAllDomains", &CParameterMgr::deleteAllDomainsCommandProcess, 0, "", 194 "Delete all configurable domains"}, 195 {"renameDomain", &CParameterMgr::renameDomainCommandProcess, 2, "<domain> <new name>", 196 "Rename configurable domain"}, 197 {"setSequenceAwareness", &CParameterMgr::setSequenceAwarenessCommandProcess, 1, 198 "<domain> true|false*", "Set configurable domain sequence awareness"}, 199 {"getSequenceAwareness", &CParameterMgr::getSequenceAwarenessCommandProcess, 1, "<domain>", 200 "Get configurable domain sequence awareness"}, 201 {"listDomainElements", &CParameterMgr::listDomainElementsCommandProcess, 1, "<domain>", 202 "List elements associated to configurable domain"}, 203 {"addElement", &CParameterMgr::addElementCommandProcess, 2, "<domain> <elem path>", 204 "Associate element at given path to configurable domain"}, 205 {"removeElement", &CParameterMgr::removeElementCommandProcess, 2, "<domain> <elem path>", 206 "Dissociate element at given path from configurable domain"}, 207 {"splitDomain", &CParameterMgr::splitDomainCommandProcess, 2, "<domain> <elem path>", 208 "Split configurable domain at given associated element path"}, 209 210 /// Configurations 211 {"listConfigurations", &CParameterMgr::listConfigurationsCommandProcess, 1, "<domain>", 212 "List domain configurations"}, 213 {"createConfiguration", &CParameterMgr::createConfigurationCommandProcess, 2, 214 "<domain> <configuration>", "Create new domain configuration"}, 215 {"deleteConfiguration", &CParameterMgr::deleteConfigurationCommandProcess, 2, 216 "<domain> <configuration>", "Delete domain configuration"}, 217 {"renameConfiguration", &CParameterMgr::renameConfigurationCommandProcess, 3, 218 "<domain> <configuration> <new name>", "Rename domain configuration"}, 219 {"saveConfiguration", &CParameterMgr::saveConfigurationCommandProcess, 2, 220 "<domain> <configuration>", "Save current settings into configuration"}, 221 {"restoreConfiguration", &CParameterMgr::restoreConfigurationCommandProcess, 2, 222 "<domain> <configuration>", "Restore current settings from configuration"}, 223 {"setElementSequence", &CParameterMgr::setElementSequenceCommandProcess, 3, 224 "<domain> <configuration> <elem path list>", 225 "Set element application order for configuration"}, 226 {"getElementSequence", &CParameterMgr::getElementSequenceCommandProcess, 2, 227 "<domain> <configuration>", "Get element application order for configuration"}, 228 {"setRule", &CParameterMgr::setRuleCommandProcess, 3, "<domain> <configuration> <rule>", 229 "Set configuration application rule"}, 230 {"clearRule", &CParameterMgr::clearRuleCommandProcess, 2, "<domain> <configuration>", 231 "Clear configuration application rule"}, 232 {"getRule", &CParameterMgr::getRuleCommandProcess, 2, "<domain> <configuration>", 233 "Get configuration application rule"}, 234 235 /// Elements/Parameters 236 {"listElements", &CParameterMgr::listElementsCommandProcess, 1, "<elem path>|/", 237 "List elements under element at given path or root"}, 238 {"listParameters", &CParameterMgr::listParametersCommandProcess, 1, "<elem path>|/", 239 "List parameters under element at given path or root"}, 240 {"getElementStructureXML", &CParameterMgr::getElementStructureXMLCommandProcess, 1, 241 "<elem path>", "Get structure of element at given path in XML format"}, 242 {"getElementBytes", &CParameterMgr::getElementBytesCommandProcess, 1, "<elem path>", 243 "Get settings of element at given path in Byte Array format"}, 244 {"setElementBytes", &CParameterMgr::setElementBytesCommandProcess, 2, "<elem path> <values>", 245 "Set settings of element at given path in Byte Array format"}, 246 {"getElementXML", &CParameterMgr::getElementXMLCommandProcess, 1, "<elem path>", 247 "Get settings of element at given path in XML format"}, 248 {"setElementXML", &CParameterMgr::setElementXMLCommandProcess, 2, "<elem path> <values>", 249 "Set settings of element at given path in XML format"}, 250 {"dumpElement", &CParameterMgr::dumpElementCommandProcess, 1, "<elem path>", 251 "Dump structure and content of element at given path"}, 252 {"getElementSize", &CParameterMgr::getElementSizeCommandProcess, 1, "<elem path>", 253 "Show size of element at given path"}, 254 {"showProperties", &CParameterMgr::showPropertiesCommandProcess, 1, "<elem path>", 255 "Show properties of element at given path"}, 256 {"getParameter", &CParameterMgr::getParameterCommandProcess, 1, "<param path>", 257 "Get value for parameter at given path"}, 258 {"setParameter", &CParameterMgr::setParameterCommandProcess, 2, "<param path> <value>", 259 "Set value for parameter at given path"}, 260 {"listBelongingDomains", &CParameterMgr::listBelongingDomainsCommandProcess, 1, "<elem path>", 261 "List domain(s) element at given path belongs to"}, 262 {"listAssociatedDomains", &CParameterMgr::listAssociatedDomainsCommandProcess, 1, "<elem path>", 263 "List domain(s) element at given path is associated to"}, 264 {"getConfigurationParameter", &CParameterMgr::getConfigurationParameterCommandProcess, 3, 265 "<domain> <configuration> <param path>", 266 "Get value for parameter at given path from configuration"}, 267 {"setConfigurationParameter", &CParameterMgr::setConfigurationParameterCommandProcess, 4, 268 "<domain> <configuration> <param path> <value>", 269 "Set value for parameter at given path to configuration"}, 270 {"showMapping", &CParameterMgr::showMappingCommandProcess, 1, "<elem path>", 271 "Show mapping for an element at given path"}, 272 273 /// Browse 274 {"listAssociatedElements", &CParameterMgr::listAssociatedElementsCommandProcess, 0, "", 275 "List element sub-trees associated to at least one configurable domain"}, 276 {"listConflictingElements", &CParameterMgr::listConflictingElementsCommandProcess, 0, "", 277 "List element sub-trees contained in more than one configurable domain"}, 278 {"listRogueElements", &CParameterMgr::listRogueElementsCommandProcess, 0, "", 279 "List element sub-trees owned by no configurable domain"}, 280 281 /// Settings Import/Export 282 {"exportDomainsXML", &CParameterMgr::exportDomainsXMLCommandProcess, 1, "<file path> ", 283 "Export domains to an XML file (provide an absolute path or relative" 284 "to the client's working directory)"}, 285 {"importDomainsXML", &CParameterMgr::importDomainsXMLCommandProcess, 1, "<file path>", 286 "Import domains from an XML file (provide an absolute path or relative" 287 "to the client's working directory)"}, 288 {"exportDomainsWithSettingsXML", &CParameterMgr::exportDomainsWithSettingsXMLCommandProcess, 1, 289 "<file path> ", 290 "Export domains including settings to XML file (provide an absolute path or relative" 291 "to the client's working directory)"}, 292 {"exportDomainWithSettingsXML", &CParameterMgr::exportDomainWithSettingsXMLCommandProcess, 2, 293 "<domain> <file path> ", "Export a single given domain including settings to XML file" 294 " (provide an absolute path or relative to the client's" 295 " working directory)"}, 296 {"importDomainsWithSettingsXML", &CParameterMgr::importDomainsWithSettingsXMLCommandProcess, 1, 297 "<file path>", 298 "Import domains including settings from XML file (provide an absolute path or relative" 299 "to the client's working directory)"}, 300 {"importDomainWithSettingsXML", &CParameterMgr::importDomainWithSettingsXMLCommandProcess, 1, 301 "<file path> [overwrite]", 302 "Import a single domain including settings from XML file." 303 " Does not overwrite an existing domain unless 'overwrite' is passed as second" 304 " argument. Provide an absolute path or relative to the client's working directory)"}, 305 {"getDomainsWithSettingsXML", &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, "", 306 "Print domains including settings as XML"}, 307 {"getDomainWithSettingsXML", &CParameterMgr::getDomainWithSettingsXMLCommandProcess, 1, 308 "<domain>", "Print the given domain including settings as XML"}, 309 {"setDomainsWithSettingsXML", &CParameterMgr::setDomainsWithSettingsXMLCommandProcess, 1, 310 "<xml configurable domains>", "Import domains including settings from XML string"}, 311 {"setDomainWithSettingsXML", &CParameterMgr::setDomainWithSettingsXMLCommandProcess, 1, 312 "<xml configurable domain> [overwrite]", 313 "Import domains including settings from XML" 314 " string. Does not overwrite an existing domain unless 'overwrite' is passed as second" 315 " argument"}, 316 /// Structure Export 317 {"getSystemClassXML", &CParameterMgr::getSystemClassXMLCommandProcess, 0, "", 318 "Print parameter structure as XML"}, 319 /// Deprecated Commands 320 {"getDomainsXML", &CParameterMgr::getDomainsWithSettingsXMLCommandProcess, 0, "", 321 "DEPRECATED COMMAND, please use getDomainsWithSettingsXML"}, 322 323 }; 324 325 // Remote command parsers array Size 326 CParameterMgr::CParameterMgr(const string &strConfigurationFilePath, log::ILogger &logger) 327 : _pMainParameterBlackboard(new CParameterBlackboard), 328 _pElementLibrarySet(new CElementLibrarySet), 329 _xmlConfigurationUri(CXmlDocSource::mkUri(strConfigurationFilePath, "")), _logger(logger) 330 { 331 // Deal with children 332 addChild(new CParameterFrameworkConfiguration); 333 addChild(new CSelectionCriteria); 334 addChild(new CSystemClass(_logger)); 335 addChild(new CConfigurableDomains); 336 } 337 338 CParameterMgr::~CParameterMgr() 339 { 340 // Children 341 delete _pRemoteProcessorServer; 342 delete _pMainParameterBlackboard; 343 delete _pElementLibrarySet; 344 } 345 346 string CParameterMgr::getKind() const 347 { 348 return "ParameterMgr"; 349 } 350 351 // Version 352 string CParameterMgr::getVersion() const 353 { 354 return PARAMETER_FRAMEWORK_VERSION; 355 } 356 357 bool CParameterMgr::load(string &strError) 358 { 359 LOG_CONTEXT("Loading"); 360 361 feedElementLibraries(); 362 363 // Load Framework configuration 364 if (!loadFrameworkConfiguration(strError)) { 365 366 return false; 367 } 368 369 if (!loadSubsystems(strError)) { 370 371 return false; 372 } 373 374 // Load structure 375 if (!loadStructure(strError)) { 376 377 return false; 378 } 379 380 // Load settings 381 if (!loadSettings(strError)) { 382 383 return false; 384 } 385 386 // Init flow of element tree 387 if (!init(strError)) { 388 389 return false; 390 } 391 392 { 393 LOG_CONTEXT("Main blackboard back synchronization"); 394 395 // Back synchronization for areas in parameter blackboard not covered by any domain 396 BackSynchronizer(getConstSystemClass(), _pMainParameterBlackboard).sync(); 397 } 398 399 // We're done loading the settings and back synchronizing 400 CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); 401 402 // We need to ensure all domains are valid 403 pConfigurableDomains->validate(_pMainParameterBlackboard); 404 405 // Log selection criterion states 406 { 407 LOG_CONTEXT("Criterion states"); 408 409 const CSelectionCriteria *selectionCriteria = getConstSelectionCriteria(); 410 411 list<string> criteria; 412 selectionCriteria->listSelectionCriteria(criteria, true, false); 413 414 info() << criteria; 415 } 416 417 // Subsystem can not ask for resync as they have not been synced yet 418 getSystemClass()->cleanSubsystemsNeedToResync(); 419 420 // At initialization, check subsystems that need resync 421 doApplyConfigurations(true); 422 423 // Start remote processor server if appropriate 424 return handleRemoteProcessingInterface(strError); 425 } 426 427 bool CParameterMgr::loadFrameworkConfiguration(string &strError) 428 { 429 LOG_CONTEXT("Loading framework configuration"); 430 431 // Parse Structure XML file 432 CXmlElementSerializingContext elementSerializingContext(strError); 433 434 _xmlDoc *doc = 435 CXmlDocSource::mkXmlDoc(_xmlConfigurationUri, true, true, elementSerializingContext); 436 if (doc == NULL) { 437 return false; 438 } 439 440 if (!xmlParse(elementSerializingContext, getFrameworkConfiguration(), doc, _xmlConfigurationUri, 441 EFrameworkConfigurationLibrary)) { 442 443 return false; 444 } 445 // Set class name to system class and configurable domains 446 getSystemClass()->setName(getConstFrameworkConfiguration()->getSystemClassName()); 447 getConfigurableDomains()->setName(getConstFrameworkConfiguration()->getSystemClassName()); 448 449 // Get subsystem plugins elements 450 _pSubsystemPlugins = static_cast<const CSubsystemPlugins *>( 451 getConstFrameworkConfiguration()->findChild("SubsystemPlugins")); 452 453 if (!_pSubsystemPlugins) { 454 455 strError = "Parameter Framework Configuration: couldn't find SubsystemPlugins element"; 456 457 return false; 458 } 459 460 // Log tuning availability 461 info() << "Tuning " 462 << (getConstFrameworkConfiguration()->isTuningAllowed() ? "allowed" : "prohibited"); 463 464 return true; 465 } 466 467 bool CParameterMgr::loadSubsystems(std::string &error) 468 { 469 LOG_CONTEXT("Loading subsystem plugins"); 470 471 // Load subsystems 472 bool isSuccess = 473 getSystemClass()->loadSubsystems(error, _pSubsystemPlugins, !_bFailOnMissingSubsystem); 474 475 if (isSuccess) { 476 info() << "All subsystem plugins successfully loaded"; 477 478 if (!error.empty()) { 479 // Log missing subsystems as info 480 info() << error; 481 } 482 } else { 483 warning() << error; 484 } 485 return isSuccess; 486 } 487 488 bool CParameterMgr::loadStructure(string &strError) 489 { 490 // Retrieve system to load structure to 491 CSystemClass *pSystemClass = getSystemClass(); 492 493 LOG_CONTEXT("Loading " + pSystemClass->getName() + " system class structure"); 494 495 // Get structure description element 496 const CFrameworkConfigurationLocation *pStructureDescriptionFileLocation = 497 static_cast<const CFrameworkConfigurationLocation *>( 498 getConstFrameworkConfiguration()->findChildOfKind("StructureDescriptionFileLocation")); 499 500 if (!pStructureDescriptionFileLocation) { 501 502 strError = "No StructureDescriptionFileLocation element found for SystemClass " + 503 pSystemClass->getName(); 504 505 return false; 506 } 507 508 // Parse Structure XML file 509 CParameterAccessContext accessContext(strError); 510 CXmlParameterSerializingContext parameterBuildContext(accessContext, strError); 511 512 { 513 // Get structure URI 514 string structureUri = 515 CXmlDocSource::mkUri(_xmlConfigurationUri, pStructureDescriptionFileLocation->getUri()); 516 517 LOG_CONTEXT("Importing system structure from file " + structureUri); 518 519 _xmlDoc *doc = CXmlDocSource::mkXmlDoc(structureUri, true, true, parameterBuildContext); 520 if (doc == NULL) { 521 return false; 522 } 523 524 if (!xmlParse(parameterBuildContext, pSystemClass, doc, structureUri, 525 EParameterCreationLibrary)) { 526 527 return false; 528 } 529 } 530 531 // Initialize offsets 532 pSystemClass->setOffset(0); 533 534 // Initialize main blackboard's size 535 _pMainParameterBlackboard->setSize(pSystemClass->getFootPrint()); 536 537 return true; 538 } 539 540 bool CParameterMgr::loadSettings(string &strError) 541 { 542 string strLoadError; 543 bool success = loadSettingsFromConfigFile(strLoadError); 544 545 if (!success && !_bFailOnFailedSettingsLoad) { 546 // Load can not fail, ie continue but log the load errors 547 warning() << strLoadError; 548 warning() << "Failed to load settings, continue without domains."; 549 success = true; 550 } 551 552 if (!success) { 553 // Propagate the litteral error only if the function fails 554 strError = strLoadError; 555 return false; 556 } 557 558 return true; 559 } 560 561 bool CParameterMgr::loadSettingsFromConfigFile(string &strError) 562 { 563 LOG_CONTEXT("Loading settings"); 564 565 // Get settings configuration element 566 const CFrameworkConfigurationGroup *pParameterConfigurationGroup = 567 static_cast<const CFrameworkConfigurationGroup *>( 568 getConstFrameworkConfiguration()->findChildOfKind("SettingsConfiguration")); 569 570 if (!pParameterConfigurationGroup) { 571 572 // No settings to load 573 574 return true; 575 } 576 577 // Get configurable domains element 578 const CFrameworkConfigurationLocation *pConfigurableDomainsFileLocation = 579 static_cast<const CFrameworkConfigurationLocation *>( 580 pParameterConfigurationGroup->findChildOfKind("ConfigurableDomainsFileLocation")); 581 582 if (!pConfigurableDomainsFileLocation) { 583 584 strError = "No ConfigurableDomainsFileLocation element found for SystemClass " + 585 getSystemClass()->getName(); 586 587 return false; 588 } 589 // Get destination root element 590 CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); 591 592 // Get Xml configuration domains URI 593 string configurationDomainsUri = 594 CXmlDocSource::mkUri(_xmlConfigurationUri, pConfigurableDomainsFileLocation->getUri()); 595 596 // Parse configuration domains XML file 597 CXmlDomainImportContext xmlDomainImportContext(strError, true, *getSystemClass()); 598 599 // Selection criteria definition for rule creation 600 xmlDomainImportContext.setSelectionCriteriaDefinition( 601 getConstSelectionCriteria()->getSelectionCriteriaDefinition()); 602 603 // Auto validation of configurations 604 xmlDomainImportContext.setAutoValidationRequired(true); 605 606 info() << "Importing configurable domains from file " << configurationDomainsUri 607 << " with settings"; 608 609 _xmlDoc *doc = 610 CXmlDocSource::mkXmlDoc(configurationDomainsUri, true, true, xmlDomainImportContext); 611 if (doc == NULL) { 612 return false; 613 } 614 615 return xmlParse(xmlDomainImportContext, pConfigurableDomains, doc, _xmlConfigurationUri, 616 EParameterConfigurationLibrary, true, "SystemClassName"); 617 } 618 619 // XML parsing 620 bool CParameterMgr::xmlParse(CXmlElementSerializingContext &elementSerializingContext, 621 CElement *pRootElement, _xmlDoc *doc, const string &baseUri, 622 CParameterMgr::ElementLibrary eElementLibrary, bool replace, 623 const string &strNameAttributeName) 624 { 625 // Init serializing context 626 elementSerializingContext.set(_pElementLibrarySet->getElementLibrary(eElementLibrary), baseUri); 627 628 CXmlDocSource docSource(doc, _bValidateSchemasOnStart, pRootElement->getXmlElementName(), 629 pRootElement->getName(), strNameAttributeName); 630 631 docSource.setSchemaBaseUri(getSchemaUri()); 632 633 // Start clean 634 auto clean = [replace, &pRootElement] { 635 if (replace) { 636 pRootElement->clean(); 637 } 638 }; 639 clean(); 640 641 CXmlMemoryDocSink memorySink(pRootElement); 642 643 if (!memorySink.process(docSource, elementSerializingContext)) { 644 clean(); 645 return false; 646 } 647 648 return true; 649 } 650 651 // Init 652 bool CParameterMgr::init(string &strError) 653 { 654 return base::init(strError); 655 } 656 657 // Selection criteria interface 658 CSelectionCriterionType *CParameterMgr::createSelectionCriterionType(bool bIsInclusive) 659 { 660 // Propagate 661 return getSelectionCriteria()->createSelectionCriterionType(bIsInclusive); 662 } 663 664 CSelectionCriterion *CParameterMgr::createSelectionCriterion( 665 const string &strName, const CSelectionCriterionType *pSelectionCriterionType) 666 { 667 // Propagate 668 return getSelectionCriteria()->createSelectionCriterion(strName, pSelectionCriterionType, 669 _logger); 670 } 671 672 // Selection criterion retrieval 673 CSelectionCriterion *CParameterMgr::getSelectionCriterion(const string &strName) 674 { 675 // Propagate 676 return getSelectionCriteria()->getSelectionCriterion(strName); 677 } 678 679 // Configuration application 680 void CParameterMgr::applyConfigurations() 681 { 682 LOG_CONTEXT("Configuration application request"); 683 684 // Lock state 685 lock_guard<mutex> autoLock(getBlackboardMutex()); 686 687 if (!_bTuningModeIsOn) { 688 689 // Apply configuration(s) 690 doApplyConfigurations(false); 691 } else { 692 693 warning() << "Configurations were not applied because the TuningMode is on"; 694 } 695 } 696 697 const CConfigurableElement *CParameterMgr::getConfigurableElement(const string &strPath, 698 string &strError) const 699 { 700 CPathNavigator pathNavigator(strPath); 701 702 // Nagivate through system class 703 if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strError)) { 704 705 return NULL; 706 } 707 708 // Find element 709 const CElement *pElement = getConstSystemClass()->findDescendant(pathNavigator); 710 711 if (!pElement) { 712 713 strError = "Path not found: " + strPath; 714 715 return NULL; 716 } 717 718 // Check found element is a parameter 719 const CConfigurableElement *pConfigurableElement = 720 static_cast<const CConfigurableElement *>(pElement); 721 722 return pConfigurableElement; 723 } 724 725 CConfigurableElement *CParameterMgr::getConfigurableElement(const string &strPath, string &strError) 726 { 727 // Implement the mutable version by calling the const one and removing 728 // the const from the result. 729 const auto *constThis = this; 730 return const_cast<CConfigurableElement *>(constThis->getConfigurableElement(strPath, strError)); 731 } 732 733 // Dynamic parameter handling 734 CParameterHandle *CParameterMgr::createParameterHandle(const string &strPath, string &strError) 735 { 736 CConfigurableElement *pConfigurableElement = getConfigurableElement(strPath, strError); 737 738 if (!pConfigurableElement) { 739 740 // Element not found 741 strError = "Element not found: " + strPath; 742 return NULL; 743 } 744 745 if (!pConfigurableElement->isParameter()) { 746 747 // Element is not parameter 748 strError = "Not a parameter: " + strPath; 749 750 return NULL; 751 } 752 753 // Convert as parameter and return new handle 754 return new CParameterHandle(static_cast<CBaseParameter &>(*pConfigurableElement), *this); 755 } 756 757 // Dynamic element handling 758 ElementHandle *CParameterMgr::createElementHandle(const std::string &path, std::string &error) 759 { 760 CConfigurableElement *pConfigurableElement; 761 762 if (path == "/") { 763 // Attempt to access root configurable element 764 pConfigurableElement = getSystemClass(); 765 } else { 766 pConfigurableElement = getConfigurableElement(path, error); 767 } 768 769 if (!pConfigurableElement) { 770 771 // Element not found 772 error = "Element not found: " + path; 773 return nullptr; 774 } 775 776 // The only reason why a heap object is returned instead of retuning by copy 777 // is to inform the client of a failure through a nullptr. 778 // It could be avoided (return by copy) with an 779 // - optional equivalent (see boost::optional or std::experimental::optional) 780 // - exception (but the api is noexcept) 781 return new ElementHandle(*pConfigurableElement, *this); 782 } 783 784 void CParameterMgr::getSettingsAsBytes(const CConfigurableElement &element, 785 std::vector<uint8_t> &settings) const 786 { 787 // Not useful as the get can not fail, 788 // but the current design forces all serialization and deserialization to 789 // have an error out string 790 std::string error; 791 792 // Prepare parameter access context for main blackboard. 793 // No need to handle output raw format and value space as Byte arrays are hexa formatted 794 CParameterAccessContext parameterAccessContext(error); 795 parameterAccessContext.setParameterBlackboard(_pMainParameterBlackboard); 796 797 // Get the settings 798 element.getSettingsAsBytes(settings, parameterAccessContext); 799 } 800 801 bool CParameterMgr::setSettingsAsBytes(const CConfigurableElement &element, 802 const std::vector<uint8_t> &settings, std::string &error) 803 { 804 // Prepare parameter access context for main blackboard. 805 // Notes: 806 // - No need to handle output raw format and value space as Byte arrays are interpreted as 807 // raw formatted 808 // - No check is done as to the intgrity of the input data. 809 // This may lead to undetected out of range value assignment. 810 // Use this functionality with caution 811 CParameterAccessContext parameterAccessContext(error); 812 parameterAccessContext.setParameterBlackboard(_pMainParameterBlackboard); 813 parameterAccessContext.setAutoSync(autoSyncOn()); 814 815 // Set the settings 816 return element.setSettingsAsBytes(settings, parameterAccessContext); 817 } 818 819 void CParameterMgr::setFailureOnMissingSubsystem(bool bFail) 820 { 821 _bFailOnMissingSubsystem = bFail; 822 } 823 824 bool CParameterMgr::getFailureOnMissingSubsystem() const 825 { 826 return _bFailOnMissingSubsystem; 827 } 828 829 void CParameterMgr::setFailureOnFailedSettingsLoad(bool bFail) 830 { 831 _bFailOnFailedSettingsLoad = bFail; 832 } 833 834 bool CParameterMgr::getFailureOnFailedSettingsLoad() const 835 { 836 return _bFailOnFailedSettingsLoad; 837 } 838 839 const string &CParameterMgr::getSchemaUri() const 840 { 841 return _schemaUri; 842 } 843 844 void CParameterMgr::setSchemaUri(const string &schemaUri) 845 { 846 _schemaUri = schemaUri; 847 } 848 849 void CParameterMgr::setValidateSchemasOnStart(bool bValidate) 850 { 851 _bValidateSchemasOnStart = bValidate; 852 } 853 854 bool CParameterMgr::getValidateSchemasOnStart() const 855 { 856 return _bValidateSchemasOnStart; 857 } 858 859 /////////////////// Remote command parsers 860 /// Version 861 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::versionCommandProcess( 862 const IRemoteCommand & /*command*/, string &strResult) 863 { 864 // Show version 865 strResult = getVersion(); 866 867 return CCommandHandler::ESucceeded; 868 } 869 870 /// Status 871 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::statusCommandProcess( 872 const IRemoteCommand & /*command*/, string &strResult) 873 { 874 // System class 875 const CSystemClass *pSystemClass = getSystemClass(); 876 877 // Show status 878 /// General section 879 utility::appendTitle(strResult, "General:"); 880 // System class 881 strResult += "System Class: "; 882 strResult += pSystemClass->getName(); 883 strResult += "\n"; 884 885 // Tuning mode 886 strResult += "Tuning Mode: "; 887 strResult += tuningModeOn() ? "on" : "off"; 888 strResult += "\n"; 889 890 // Value space 891 strResult += "Value Space: "; 892 strResult += valueSpaceIsRaw() ? "raw" : "real"; 893 strResult += "\n"; 894 895 // Output raw format 896 strResult += "Output Raw Format: "; 897 strResult += outputRawFormatIsHex() ? "hex" : "dec"; 898 strResult += "\n"; 899 900 // Auto Sync 901 strResult += "Auto Sync: "; 902 strResult += autoSyncOn() ? "on" : "off"; 903 strResult += "\n"; 904 905 /// Subsystem list 906 utility::appendTitle(strResult, "Subsystems:"); 907 string strSubsystemList; 908 pSystemClass->listChildrenPaths(strSubsystemList); 909 strResult += strSubsystemList; 910 911 /// Last applied configurations 912 utility::appendTitle(strResult, "Last Applied [Pending] Configurations:"); 913 string strLastAppliedConfigurations; 914 getConfigurableDomains()->listLastAppliedConfigurations(strLastAppliedConfigurations); 915 strResult += strLastAppliedConfigurations; 916 917 /// Criteria states 918 utility::appendTitle(strResult, "Selection Criteria:"); 919 list<string> lstrSelectionCriteria; 920 getSelectionCriteria()->listSelectionCriteria(lstrSelectionCriteria, false, true); 921 // Concatenate the criterion list as the command result 922 strResult += utility::asString(lstrSelectionCriteria); 923 924 return CCommandHandler::ESucceeded; 925 } 926 927 /// Tuning Mode 928 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setTuningModeCommandProcess( 929 const IRemoteCommand &remoteCommand, string &strResult) 930 { 931 if (remoteCommand.getArgument(0) == "on") { 932 933 if (setTuningMode(true, strResult)) { 934 935 return CCommandHandler::EDone; 936 } 937 } else if (remoteCommand.getArgument(0) == "off") { 938 939 if (setTuningMode(false, strResult)) { 940 941 return CCommandHandler::EDone; 942 } 943 } else { 944 // Show usage 945 return CCommandHandler::EShowUsage; 946 } 947 return CCommandHandler::EFailed; 948 } 949 950 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getTuningModeCommandProcess( 951 const IRemoteCommand & /*command*/, string &strResult) 952 { 953 strResult = tuningModeOn() ? "on" : "off"; 954 955 return CCommandHandler::ESucceeded; 956 } 957 958 /// Value Space 959 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setValueSpaceCommandProcess( 960 const IRemoteCommand &remoteCommand, string & /*strResult*/) 961 { 962 if (remoteCommand.getArgument(0) == "raw") { 963 964 setValueSpace(true); 965 966 return CCommandHandler::EDone; 967 968 } else if (remoteCommand.getArgument(0) == "real") { 969 970 setValueSpace(false); 971 972 return CCommandHandler::EDone; 973 974 } else { 975 // Show usage 976 return CCommandHandler::EShowUsage; 977 } 978 return CCommandHandler::EFailed; 979 } 980 981 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getValueSpaceCommandProcess( 982 const IRemoteCommand & /*command*/, string &strResult) 983 { 984 strResult = valueSpaceIsRaw() ? "raw" : "real"; 985 986 return CCommandHandler::ESucceeded; 987 } 988 989 /// Output Raw Format 990 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setOutputRawFormatCommandProcess( 991 const IRemoteCommand &remoteCommand, string & /*strResult*/) 992 { 993 if (remoteCommand.getArgument(0) == "hex") { 994 995 setOutputRawFormat(true); 996 997 return CCommandHandler::EDone; 998 999 } else if (remoteCommand.getArgument(0) == "dec") { 1000 1001 setOutputRawFormat(false); 1002 1003 return CCommandHandler::EDone; 1004 1005 } else { 1006 // Show usage 1007 return CCommandHandler::EShowUsage; 1008 } 1009 return CCommandHandler::EFailed; 1010 } 1011 1012 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getOutputRawFormatCommandProcess( 1013 const IRemoteCommand & /*command*/, string &strResult) 1014 { 1015 strResult = outputRawFormatIsHex() ? "hex" : "dec"; 1016 1017 return CCommandHandler::ESucceeded; 1018 } 1019 1020 /// Sync 1021 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setAutoSyncCommandProcess( 1022 const IRemoteCommand &remoteCommand, string &strResult) 1023 { 1024 if (remoteCommand.getArgument(0) == "on") { 1025 1026 if (setAutoSync(true, strResult)) { 1027 1028 return CCommandHandler::EDone; 1029 } 1030 } else if (remoteCommand.getArgument(0) == "off") { 1031 1032 if (setAutoSync(false, strResult)) { 1033 1034 return CCommandHandler::EDone; 1035 } 1036 } else { 1037 // Show usage 1038 return CCommandHandler::EShowUsage; 1039 } 1040 return CCommandHandler::EFailed; 1041 } 1042 1043 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getAutoSyncCommandProcess( 1044 const IRemoteCommand & /*command*/, string &strResult) 1045 { 1046 strResult = autoSyncOn() ? "on" : "off"; 1047 1048 return CCommandHandler::ESucceeded; 1049 } 1050 1051 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::syncCommandProcess( 1052 const IRemoteCommand &, string &strResult) 1053 { 1054 return sync(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; 1055 } 1056 1057 /// Criteria 1058 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listCriteriaCommandProcess( 1059 const IRemoteCommand &remoteCommand, string &strResult) 1060 { 1061 if (remoteCommand.getArgumentCount() > 1) { 1062 1063 return CCommandHandler::EShowUsage; 1064 } 1065 1066 string strOutputFormat; 1067 1068 // Look for optional arguments 1069 if (remoteCommand.getArgumentCount() == 1) { 1070 1071 // Get requested format 1072 strOutputFormat = remoteCommand.getArgument(0); 1073 1074 // Capitalize 1075 std::transform(strOutputFormat.begin(), strOutputFormat.end(), strOutputFormat.begin(), 1076 ::toupper); 1077 1078 if (strOutputFormat != "XML" && strOutputFormat != "CSV") { 1079 1080 return CCommandHandler::EShowUsage; 1081 } 1082 } 1083 1084 if (strOutputFormat == "XML") { 1085 // Get Root element where to export from 1086 const CSelectionCriteriaDefinition *pSelectionCriteriaDefinition = 1087 getConstSelectionCriteria()->getSelectionCriteriaDefinition(); 1088 1089 if (!exportElementToXMLString(pSelectionCriteriaDefinition, "SelectionCriteria", 1090 CXmlSerializingContext{strResult}, strResult)) { 1091 1092 return CCommandHandler::EFailed; 1093 } 1094 1095 // Succeeded 1096 return CCommandHandler::ESucceeded; 1097 } else { 1098 1099 // Requested format will be either CSV or human readable based on strOutputFormat content 1100 bool bHumanReadable = strOutputFormat.empty(); 1101 1102 list<string> lstrResult; 1103 getSelectionCriteria()->listSelectionCriteria(lstrResult, true, bHumanReadable); 1104 1105 // Concatenate the criterion list as the command result 1106 strResult += utility::asString(lstrResult); 1107 1108 return CCommandHandler::ESucceeded; 1109 } 1110 } 1111 1112 /// Domains 1113 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainsCommandProcess( 1114 const IRemoteCommand & /*command*/, string &strResult) 1115 { 1116 getConfigurableDomains()->listDomains(strResult); 1117 1118 return CCommandHandler::ESucceeded; 1119 } 1120 1121 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createDomainCommandProcess( 1122 const IRemoteCommand &remoteCommand, string &strResult) 1123 { 1124 return createDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone 1125 : CCommandHandler::EFailed; 1126 } 1127 1128 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteDomainCommandProcess( 1129 const IRemoteCommand &remoteCommand, string &strResult) 1130 { 1131 return deleteDomain(remoteCommand.getArgument(0), strResult) ? CCommandHandler::EDone 1132 : CCommandHandler::EFailed; 1133 } 1134 1135 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteAllDomainsCommandProcess( 1136 const IRemoteCommand & /*command*/, string &strResult) 1137 { 1138 return deleteAllDomains(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed; 1139 } 1140 1141 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameDomainCommandProcess( 1142 const IRemoteCommand &remoteCommand, string &strResult) 1143 { 1144 return renameDomain(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) 1145 ? CCommandHandler::EDone 1146 : CCommandHandler::EFailed; 1147 } 1148 1149 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setSequenceAwarenessCommandProcess( 1150 const IRemoteCommand &remoteCommand, string &strResult) 1151 { 1152 // Set property 1153 bool bSequenceAware; 1154 1155 if (remoteCommand.getArgument(1) == "true") { 1156 1157 bSequenceAware = true; 1158 1159 } else if (remoteCommand.getArgument(1) == "false") { 1160 1161 bSequenceAware = false; 1162 1163 } else { 1164 // Show usage 1165 return CCommandHandler::EShowUsage; 1166 } 1167 1168 return setSequenceAwareness(remoteCommand.getArgument(0), bSequenceAware, strResult) 1169 ? CCommandHandler::EDone 1170 : CCommandHandler::EFailed; 1171 } 1172 1173 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSequenceAwarenessCommandProcess( 1174 const IRemoteCommand &remoteCommand, string &strResult) 1175 { 1176 // Get property 1177 bool bSequenceAware; 1178 1179 if (!getSequenceAwareness(remoteCommand.getArgument(0), bSequenceAware, strResult)) { 1180 1181 return CCommandHandler::EFailed; 1182 } 1183 1184 strResult = bSequenceAware ? "true" : "false"; 1185 1186 return CCommandHandler::ESucceeded; 1187 } 1188 1189 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainElementsCommandProcess( 1190 const IRemoteCommand &remoteCommand, string &strResult) 1191 { 1192 return getConfigurableDomains()->listDomainElements(remoteCommand.getArgument(0), strResult) 1193 ? CCommandHandler::ESucceeded 1194 : CCommandHandler::EFailed; 1195 } 1196 1197 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::addElementCommandProcess( 1198 const IRemoteCommand &remoteCommand, string &strResult) 1199 { 1200 return addConfigurableElementToDomain(remoteCommand.getArgument(0), 1201 remoteCommand.getArgument(1), strResult) 1202 ? CCommandHandler::EDone 1203 : CCommandHandler::EFailed; 1204 } 1205 1206 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::removeElementCommandProcess( 1207 const IRemoteCommand &remoteCommand, string &strResult) 1208 { 1209 return removeConfigurableElementFromDomain(remoteCommand.getArgument(0), 1210 remoteCommand.getArgument(1), strResult) 1211 ? CCommandHandler::EDone 1212 : CCommandHandler::EFailed; 1213 } 1214 1215 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::splitDomainCommandProcess( 1216 const IRemoteCommand &remoteCommand, string &strResult) 1217 { 1218 return split(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) 1219 ? CCommandHandler::EDone 1220 : CCommandHandler::EFailed; 1221 } 1222 1223 /// Configurations 1224 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConfigurationsCommandProcess( 1225 const IRemoteCommand &remoteCommand, string &strResult) 1226 { 1227 return getConstConfigurableDomains()->listConfigurations(remoteCommand.getArgument(0), 1228 strResult) 1229 ? CCommandHandler::ESucceeded 1230 : CCommandHandler::EFailed; 1231 } 1232 1233 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpDomainsCommandProcess( 1234 const IRemoteCommand & /*command*/, string &strResult) 1235 { 1236 // Dummy error context 1237 string strError; 1238 utility::ErrorContext errorContext(strError); 1239 1240 // Dump 1241 strResult = getConstConfigurableDomains()->dumpContent(errorContext); 1242 1243 return CCommandHandler::ESucceeded; 1244 } 1245 1246 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::createConfigurationCommandProcess( 1247 const IRemoteCommand &remoteCommand, string &strResult) 1248 { 1249 return createConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1250 strResult) 1251 ? CCommandHandler::EDone 1252 : CCommandHandler::EFailed; 1253 } 1254 1255 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteConfigurationCommandProcess( 1256 const IRemoteCommand &remoteCommand, string &strResult) 1257 { 1258 return deleteConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1259 strResult) 1260 ? CCommandHandler::EDone 1261 : CCommandHandler::EFailed; 1262 } 1263 1264 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::renameConfigurationCommandProcess( 1265 const IRemoteCommand &remoteCommand, string &strResult) 1266 { 1267 return renameConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1268 remoteCommand.getArgument(2), strResult) 1269 ? CCommandHandler::EDone 1270 : CCommandHandler::EFailed; 1271 } 1272 1273 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::saveConfigurationCommandProcess( 1274 const IRemoteCommand &remoteCommand, string &strResult) 1275 { 1276 return saveConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) 1277 ? CCommandHandler::EDone 1278 : CCommandHandler::EFailed; 1279 } 1280 1281 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::restoreConfigurationCommandProcess( 1282 const IRemoteCommand &remoteCommand, string &strResult) 1283 { 1284 core::Results result; 1285 if (!restoreConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), result)) { 1286 // Concatenate the error list as the command result 1287 strResult = utility::asString(result); 1288 1289 return CCommandHandler::EFailed; 1290 } 1291 return CCommandHandler::EDone; 1292 } 1293 1294 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementSequenceCommandProcess( 1295 const IRemoteCommand &remoteCommand, string &strResult) 1296 { 1297 // Build configurable element path list 1298 std::vector<string> astrNewElementSequence; 1299 1300 for (size_t argument = 2; argument < remoteCommand.getArgumentCount(); argument++) { 1301 1302 astrNewElementSequence.push_back(remoteCommand.getArgument(argument)); 1303 } 1304 1305 // Delegate to configurable domains 1306 return setElementSequence(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1307 astrNewElementSequence, strResult) 1308 ? CCommandHandler::EDone 1309 : CCommandHandler::EFailed; 1310 } 1311 1312 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSequenceCommandProcess( 1313 const IRemoteCommand &remoteCommand, string &strResult) 1314 { 1315 // Delegate to configurable domains 1316 return getConfigurableDomains()->getElementSequence(remoteCommand.getArgument(0), 1317 remoteCommand.getArgument(1), strResult) 1318 ? CCommandHandler::ESucceeded 1319 : CCommandHandler::EFailed; 1320 } 1321 1322 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setRuleCommandProcess( 1323 const IRemoteCommand &remoteCommand, string &strResult) 1324 { 1325 // Delegate to configurable domains 1326 return setApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1327 remoteCommand.packArguments(2, remoteCommand.getArgumentCount() - 2), 1328 strResult) 1329 ? CCommandHandler::EDone 1330 : CCommandHandler::EFailed; 1331 } 1332 1333 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::clearRuleCommandProcess( 1334 const IRemoteCommand &remoteCommand, string &strResult) 1335 { 1336 // Delegate to configurable domains 1337 return clearApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1338 strResult) 1339 ? CCommandHandler::EDone 1340 : CCommandHandler::EFailed; 1341 } 1342 1343 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getRuleCommandProcess( 1344 const IRemoteCommand &remoteCommand, string &strResult) 1345 { 1346 // Delegate to configurable domains 1347 return getApplicationRule(remoteCommand.getArgument(0), remoteCommand.getArgument(1), strResult) 1348 ? CCommandHandler::ESucceeded 1349 : CCommandHandler::EFailed; 1350 } 1351 1352 /// Elements/Parameters 1353 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listElementsCommandProcess( 1354 const IRemoteCommand &remoteCommand, string &strResult) 1355 { 1356 CElementLocator elementLocator(getSystemClass(), false); 1357 1358 CElement *pLocatedElement = NULL; 1359 1360 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1361 1362 return CCommandHandler::EFailed; 1363 } 1364 1365 if (!pLocatedElement) { 1366 1367 // List from root folder 1368 1369 // Return system class qualified name 1370 pLocatedElement = getSystemClass(); 1371 } 1372 1373 // Return sub-elements 1374 strResult += pLocatedElement->listQualifiedPaths(false); 1375 1376 return CCommandHandler::ESucceeded; 1377 } 1378 1379 /// Elements/Parameters 1380 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listParametersCommandProcess( 1381 const IRemoteCommand &remoteCommand, string &strResult) 1382 { 1383 CElementLocator elementLocator(getSystemClass(), false); 1384 1385 CElement *pLocatedElement = NULL; 1386 1387 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1388 1389 return CCommandHandler::EFailed; 1390 } 1391 1392 if (!pLocatedElement) { 1393 1394 // List from root folder 1395 1396 // Return system class qualified name 1397 pLocatedElement = getSystemClass(); 1398 } 1399 1400 // Return sub-elements 1401 strResult += pLocatedElement->listQualifiedPaths(true); 1402 1403 return CCommandHandler::ESucceeded; 1404 } 1405 1406 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementStructureXMLCommandProcess( 1407 const IRemoteCommand &remoteCommand, string &strResult) 1408 { 1409 CElementLocator elementLocator(getSystemClass()); 1410 1411 CElement *pLocatedElement = NULL; 1412 1413 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1414 1415 return CCommandHandler::EFailed; 1416 } 1417 1418 // Use default access context for structure export 1419 CParameterAccessContext accessContext(strResult); 1420 if (!exportElementToXMLString(pLocatedElement, pLocatedElement->getXmlElementName(), 1421 CXmlParameterSerializingContext{accessContext, strResult}, 1422 strResult)) { 1423 1424 return CCommandHandler::EFailed; 1425 } 1426 1427 return CCommandHandler::ESucceeded; 1428 } 1429 1430 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementBytesCommandProcess( 1431 const IRemoteCommand &remoteCommand, std::string &strResult) 1432 { 1433 CElementLocator elementLocator(getSystemClass()); 1434 1435 CElement *pLocatedElement = NULL; 1436 1437 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1438 1439 return CCommandHandler::EFailed; 1440 } 1441 1442 const CConfigurableElement *pConfigurableElement = 1443 static_cast<CConfigurableElement *>(pLocatedElement); 1444 1445 // Get the settings 1446 vector<uint8_t> bytes; 1447 getSettingsAsBytes(*pConfigurableElement, bytes); 1448 1449 // Hexa formatting 1450 std::ostringstream ostream; 1451 ostream << std::hex << std::setfill('0'); 1452 1453 // Format bytes 1454 for (auto byte : bytes) { 1455 1456 // Convert to an int in order to avoid the "char" overload that would 1457 // print characters instead of numbers. 1458 ostream << "0x" << std::setw(2) << int{byte} << " "; 1459 } 1460 1461 strResult = ostream.str(); 1462 if (not strResult.empty()) { 1463 // Remove the trailing space 1464 strResult.pop_back(); 1465 } 1466 1467 return CCommandHandler::ESucceeded; 1468 } 1469 1470 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementBytesCommandProcess( 1471 const IRemoteCommand &remoteCommand, string &strResult) 1472 { 1473 // Check tuning mode 1474 if (!checkTuningModeOn(strResult)) { 1475 1476 return CCommandHandler::EFailed; 1477 } 1478 1479 // Retrieve configurable element 1480 CElementLocator elementLocator(getSystemClass()); 1481 1482 CElement *pLocatedElement = NULL; 1483 1484 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1485 1486 return CCommandHandler::EFailed; 1487 } 1488 1489 const CConfigurableElement *pConfigurableElement = 1490 static_cast<CConfigurableElement *>(pLocatedElement); 1491 1492 // Convert input data to binary 1493 vector<uint8_t> bytes; 1494 1495 auto first = remoteCommand.getArguments().cbegin() + 1; 1496 auto last = remoteCommand.getArguments().cend(); 1497 1498 try { 1499 std::transform(first, last, begin(bytes), [](decltype(*first) input) { 1500 uint8_t byte; 1501 1502 if (!convertTo(input, byte)) { 1503 throw std::domain_error("Some values out of byte range"); 1504 } 1505 1506 return byte; 1507 }); 1508 } catch (const std::domain_error &e) { 1509 strResult = e.what(); 1510 1511 return CCommandHandler::EFailed; 1512 } 1513 1514 // Set the settings 1515 if (!setSettingsAsBytes(*pConfigurableElement, bytes, strResult)) { 1516 1517 return CCommandHandler::EFailed; 1518 } 1519 1520 return CCommandHandler::EDone; 1521 } 1522 1523 bool CParameterMgr::getSettingsAsXML(const CConfigurableElement *configurableElement, 1524 string &result) const 1525 { 1526 string error; 1527 CConfigurationAccessContext configContext(error, _pMainParameterBlackboard, _bValueSpaceIsRaw, 1528 _bOutputRawFormatIsHex, true); 1529 1530 CXmlParameterSerializingContext xmlParameterContext(configContext, error); 1531 1532 // Use a doc source by loading data from instantiated Configurable Domains 1533 CXmlMemoryDocSource memorySource(configurableElement, false, 1534 configurableElement->getXmlElementName()); 1535 1536 // Use a doc sink that write the doc data in a string 1537 ostringstream output; 1538 CXmlStreamDocSink streamSink(output); 1539 1540 if (not streamSink.process(memorySource, xmlParameterContext)) { 1541 result = error; 1542 return false; 1543 } 1544 result = output.str(); 1545 return true; 1546 } 1547 1548 bool CParameterMgr::setSettingsAsXML(CConfigurableElement *configurableElement, 1549 const string &settings, string &error) 1550 { 1551 CConfigurationAccessContext configContext(error, _pMainParameterBlackboard, _bValueSpaceIsRaw, 1552 _bOutputRawFormatIsHex, false); 1553 1554 CXmlParameterSerializingContext xmlParameterContext(configContext, error); 1555 1556 // It doesn't make sense to resolve XIncludes on an imported file because 1557 // we can't reliably decide of a "base url" 1558 _xmlDoc *doc = CXmlDocSource::mkXmlDoc(settings, false, false, xmlParameterContext); 1559 if (doc == nullptr) { 1560 return false; 1561 } 1562 if (not xmlParse(xmlParameterContext, configurableElement, doc, "", 1563 EParameterConfigurationLibrary, false)) { 1564 return false; 1565 } 1566 if (_bAutoSyncOn) { 1567 CSyncerSet syncerSet; 1568 static_cast<CConfigurableElement *>(configurableElement)->fillSyncerSet(syncerSet); 1569 core::Results errors; 1570 if (not syncerSet.sync(*_pMainParameterBlackboard, false, &errors)) { 1571 error = utility::asString(errors); 1572 1573 return false; 1574 } 1575 } 1576 return true; 1577 } 1578 1579 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementXMLCommandProcess( 1580 const IRemoteCommand &remoteCommand, string &result) 1581 { 1582 CElementLocator elementLocator(getSystemClass()); 1583 1584 CElement *locatedElement = nullptr; 1585 1586 if (not elementLocator.locate(remoteCommand.getArgument(0), &locatedElement, result)) { 1587 1588 return CCommandHandler::EFailed; 1589 } 1590 1591 if (not getSettingsAsXML(static_cast<CConfigurableElement *>(locatedElement), result)) { 1592 return CCommandHandler::EFailed; 1593 } 1594 return CCommandHandler::ESucceeded; 1595 } 1596 1597 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setElementXMLCommandProcess( 1598 const IRemoteCommand &remoteCommand, string &result) 1599 { 1600 if (!checkTuningModeOn(result)) { 1601 1602 return CCommandHandler::EFailed; 1603 } 1604 1605 CElementLocator elementLocator(getSystemClass()); 1606 1607 CElement *locatedElement = nullptr; 1608 1609 if (not elementLocator.locate(remoteCommand.getArgument(0), &locatedElement, result)) { 1610 1611 return CCommandHandler::EFailed; 1612 } 1613 if (not setSettingsAsXML(static_cast<CConfigurableElement *>(locatedElement), 1614 remoteCommand.getArgument(1), result)) { 1615 return CCommandHandler::EFailed; 1616 } 1617 return CCommandHandler::EDone; 1618 } 1619 1620 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::dumpElementCommandProcess( 1621 const IRemoteCommand &remoteCommand, string &strResult) 1622 { 1623 CElementLocator elementLocator(getSystemClass()); 1624 1625 CElement *pLocatedElement = NULL; 1626 1627 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1628 1629 return CCommandHandler::EFailed; 1630 } 1631 1632 string strError; 1633 1634 CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, 1635 _bValueSpaceIsRaw, _bOutputRawFormatIsHex); 1636 1637 // Dump elements 1638 strResult = pLocatedElement->dumpContent(parameterAccessContext); 1639 1640 return CCommandHandler::ESucceeded; 1641 } 1642 1643 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getElementSizeCommandProcess( 1644 const IRemoteCommand &remoteCommand, string &strResult) 1645 { 1646 CElementLocator elementLocator(getSystemClass()); 1647 1648 CElement *pLocatedElement = NULL; 1649 1650 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1651 1652 return CCommandHandler::EFailed; 1653 } 1654 1655 // Converted to actual sizable element 1656 const CConfigurableElement *pConfigurableElement = 1657 static_cast<const CConfigurableElement *>(pLocatedElement); 1658 1659 // Get size as string 1660 strResult = pConfigurableElement->getFootprintAsString(); 1661 1662 return CCommandHandler::ESucceeded; 1663 } 1664 1665 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showPropertiesCommandProcess( 1666 const IRemoteCommand &remoteCommand, string &strResult) 1667 { 1668 CElementLocator elementLocator(getSystemClass()); 1669 1670 CElement *pLocatedElement = NULL; 1671 1672 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1673 1674 return CCommandHandler::EFailed; 1675 } 1676 1677 // Convert element 1678 const CConfigurableElement *pConfigurableElement = 1679 static_cast<const CConfigurableElement *>(pLocatedElement); 1680 1681 // Return element properties 1682 pConfigurableElement->showProperties(strResult); 1683 1684 return CCommandHandler::ESucceeded; 1685 } 1686 1687 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getParameterCommandProcess( 1688 const IRemoteCommand &remoteCommand, string &strResult) 1689 { 1690 string strValue; 1691 1692 if (!accessParameterValue(remoteCommand.getArgument(0), strValue, false, strResult)) { 1693 1694 return CCommandHandler::EFailed; 1695 } 1696 // Succeeded 1697 strResult = strValue; 1698 1699 return CCommandHandler::ESucceeded; 1700 } 1701 1702 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setParameterCommandProcess( 1703 const IRemoteCommand &remoteCommand, string &strResult) 1704 { 1705 // Get value to set 1706 string strValue = remoteCommand.packArguments(1, remoteCommand.getArgumentCount() - 1); 1707 1708 return accessParameterValue(remoteCommand.getArgument(0), strValue, true, strResult) 1709 ? CCommandHandler::EDone 1710 : CCommandHandler::EFailed; 1711 } 1712 1713 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listBelongingDomainsCommandProcess( 1714 const IRemoteCommand &remoteCommand, string &strResult) 1715 { 1716 CElementLocator elementLocator(getSystemClass()); 1717 1718 CElement *pLocatedElement = NULL; 1719 1720 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1721 1722 return CCommandHandler::EFailed; 1723 } 1724 1725 // Convert element 1726 const CConfigurableElement *pConfigurableElement = 1727 static_cast<const CConfigurableElement *>(pLocatedElement); 1728 1729 // Return element belonging domains 1730 pConfigurableElement->listBelongingDomains(strResult); 1731 1732 return CCommandHandler::ESucceeded; 1733 } 1734 1735 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedDomainsCommandProcess( 1736 const IRemoteCommand &remoteCommand, string &strResult) 1737 { 1738 CElementLocator elementLocator(getSystemClass()); 1739 1740 CElement *pLocatedElement = NULL; 1741 1742 if (!elementLocator.locate(remoteCommand.getArgument(0), &pLocatedElement, strResult)) { 1743 1744 return CCommandHandler::EFailed; 1745 } 1746 1747 // Convert element 1748 const CConfigurableElement *pConfigurableElement = 1749 static_cast<const CConfigurableElement *>(pLocatedElement); 1750 1751 // Return element belonging domains 1752 pConfigurableElement->listAssociatedDomains(strResult); 1753 1754 return CCommandHandler::ESucceeded; 1755 } 1756 1757 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedElementsCommandProcess( 1758 const IRemoteCommand & /*command*/, string &strResult) 1759 { 1760 getConfigurableDomains()->listAssociatedElements(strResult); 1761 1762 return CCommandHandler::ESucceeded; 1763 } 1764 1765 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConflictingElementsCommandProcess( 1766 const IRemoteCommand & /*command*/, string &strResult) 1767 { 1768 getConfigurableDomains()->listConflictingElements(strResult); 1769 1770 return CCommandHandler::ESucceeded; 1771 } 1772 1773 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listRogueElementsCommandProcess( 1774 const IRemoteCommand & /*command*/, string &strResult) 1775 { 1776 getSystemClass()->listRogueElements(strResult); 1777 1778 return CCommandHandler::ESucceeded; 1779 } 1780 1781 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1782 getConfigurationParameterCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) 1783 { 1784 string strOutputValue; 1785 string strError; 1786 1787 if (!accessConfigurationValue(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1788 remoteCommand.getArgument(2), strOutputValue, false, strError)) { 1789 1790 strResult = strError; 1791 return CCommandHandler::EFailed; 1792 } 1793 // Succeeded 1794 strResult = strOutputValue; 1795 1796 return CCommandHandler::ESucceeded; 1797 } 1798 1799 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1800 setConfigurationParameterCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) 1801 { 1802 // Get value to set 1803 string strValue = remoteCommand.packArguments(3, remoteCommand.getArgumentCount() - 3); 1804 1805 bool bSuccess = 1806 accessConfigurationValue(remoteCommand.getArgument(0), remoteCommand.getArgument(1), 1807 remoteCommand.getArgument(2), strValue, true, strResult); 1808 1809 return bSuccess ? CCommandHandler::EDone : CCommandHandler::EFailed; 1810 } 1811 1812 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::showMappingCommandProcess( 1813 const IRemoteCommand &remoteCommand, string &strResult) 1814 { 1815 if (!getParameterMapping(remoteCommand.getArgument(0), strResult)) { 1816 1817 return CCommandHandler::EFailed; 1818 } 1819 1820 return CCommandHandler::ESucceeded; 1821 } 1822 1823 /// Settings Import/Export 1824 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::exportDomainsXMLCommandProcess( 1825 const IRemoteCommand &remoteCommand, string &strResult) 1826 { 1827 string strFileName = remoteCommand.getArgument(0); 1828 return exportDomainsXml(strFileName, false, true, strResult) ? CCommandHandler::EDone 1829 : CCommandHandler::EFailed; 1830 } 1831 1832 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::importDomainsXMLCommandProcess( 1833 const IRemoteCommand &remoteCommand, string &strResult) 1834 { 1835 return importDomainsXml(remoteCommand.getArgument(0), false, true, strResult) 1836 ? CCommandHandler::EDone 1837 : CCommandHandler::EFailed; 1838 } 1839 1840 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1841 exportDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, 1842 string &strResult) 1843 { 1844 string strFileName = remoteCommand.getArgument(0); 1845 return exportDomainsXml(strFileName, true, true, strResult) ? CCommandHandler::EDone 1846 : CCommandHandler::EFailed; 1847 } 1848 1849 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1850 exportDomainWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, string &result) 1851 { 1852 string domainName = remoteCommand.getArgument(0); 1853 string fileName = remoteCommand.getArgument(1); 1854 return exportSingleDomainXml(fileName, domainName, true, true, result) 1855 ? CCommandHandler::EDone 1856 : CCommandHandler::EFailed; 1857 } 1858 1859 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1860 importDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, 1861 string &strResult) 1862 { 1863 return importDomainsXml(remoteCommand.getArgument(0), true, true, strResult) 1864 ? CCommandHandler::EDone 1865 : CCommandHandler::EFailed; 1866 } 1867 1868 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1869 importDomainWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, 1870 string &strResult) 1871 { 1872 bool bOverwrite = false; 1873 1874 // Look for optional arguments 1875 if (remoteCommand.getArgumentCount() > 1) { 1876 1877 if (remoteCommand.getArgument(1) == "overwrite") { 1878 1879 bOverwrite = true; 1880 } else { 1881 // Show usage 1882 return CCommandHandler::EShowUsage; 1883 } 1884 } 1885 1886 return importSingleDomainXml(remoteCommand.getArgument(0), bOverwrite, true, true, strResult) 1887 ? CCommandHandler::EDone 1888 : CCommandHandler::EFailed; 1889 } 1890 1891 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1892 getDomainsWithSettingsXMLCommandProcess(const IRemoteCommand & /*command*/, string &strResult) 1893 { 1894 if (!exportDomainsXml(strResult, true, false, strResult)) { 1895 1896 return CCommandHandler::EFailed; 1897 } 1898 // Succeeded 1899 return CCommandHandler::ESucceeded; 1900 } 1901 1902 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getDomainWithSettingsXMLCommandProcess( 1903 const IRemoteCommand &remoteCommand, string &strResult) 1904 { 1905 string strDomainName = remoteCommand.getArgument(0); 1906 1907 return exportSingleDomainXml(strResult, strDomainName, true, false, strResult) 1908 ? CCommandHandler::ESucceeded 1909 : CCommandHandler::EFailed; 1910 } 1911 1912 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr:: 1913 setDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &remoteCommand, string &strResult) 1914 { 1915 return importDomainsXml(remoteCommand.getArgument(0), true, false, strResult) 1916 ? CCommandHandler::EDone 1917 : CCommandHandler::EFailed; 1918 } 1919 1920 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::setDomainWithSettingsXMLCommandProcess( 1921 const IRemoteCommand &remoteCommand, string &result) 1922 { 1923 bool overwrite = false; 1924 1925 if (remoteCommand.getArgumentCount() > 1) { 1926 1927 if (remoteCommand.getArgument(1) == "overwrite") { 1928 1929 overwrite = true; 1930 } else { 1931 // Show usage 1932 return CCommandHandler::EShowUsage; 1933 } 1934 } 1935 1936 return importSingleDomainXml(remoteCommand.getArgument(0), overwrite, true, false, result) 1937 ? CCommandHandler::EDone 1938 : CCommandHandler::EFailed; 1939 } 1940 1941 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::getSystemClassXMLCommandProcess( 1942 const IRemoteCommand & /*command*/, string &strResult) 1943 { 1944 // Get Root element where to export from 1945 const CSystemClass *pSystemClass = getSystemClass(); 1946 1947 // Use default access context for structure export 1948 CParameterAccessContext accessContext(strResult); 1949 if (!exportElementToXMLString(pSystemClass, pSystemClass->getXmlElementName(), 1950 CXmlParameterSerializingContext{accessContext, strResult}, 1951 strResult)) { 1952 return CCommandHandler::EFailed; 1953 } 1954 // Succeeded 1955 return CCommandHandler::ESucceeded; 1956 } 1957 1958 // User set/get parameters in main BlackBoard 1959 bool CParameterMgr::accessParameterValue(const string &strPath, string &strValue, bool bSet, 1960 string &strError) 1961 { 1962 // Forbid write access when not in TuningMode 1963 if (bSet && !checkTuningModeOn(strError)) { 1964 1965 return false; 1966 } 1967 1968 // Define context 1969 CParameterAccessContext parameterAccessContext(strError, _pMainParameterBlackboard, 1970 _bValueSpaceIsRaw, _bOutputRawFormatIsHex); 1971 1972 // Activate the auto synchronization with the hardware 1973 if (bSet) { 1974 1975 parameterAccessContext.setAutoSync(_bAutoSyncOn); 1976 } 1977 1978 return accessValue(parameterAccessContext, strPath, strValue, bSet, strError); 1979 } 1980 1981 // User get parameter mapping 1982 bool CParameterMgr::getParameterMapping(const string &strPath, string &strResult) const 1983 { 1984 // Get the ConfigurableElement corresponding to strPath 1985 const CConfigurableElement *pConfigurableElement = getConfigurableElement(strPath, strResult); 1986 if (!pConfigurableElement) { 1987 1988 return false; 1989 } 1990 1991 // Find the list of the ancestors of the current ConfigurableElement that have a mapping 1992 auto configurableElementPath = pConfigurableElement->getConfigurableElementContext(); 1993 1994 // Get the Subsystem containing the ConfigurableElement 1995 const CSubsystem *pSubsystem = pConfigurableElement->getBelongingSubsystem(); 1996 if (!pSubsystem) { 1997 1998 strResult = "Unable to find the Subsystem containing the parameter"; 1999 return false; 2000 } 2001 2002 // Fetch the mapping corresponding to the ConfigurableElement 2003 strResult = pSubsystem->getMapping(configurableElementPath); 2004 2005 return true; 2006 } 2007 2008 // User set/get parameters in specific Configuration BlackBoard 2009 bool CParameterMgr::accessConfigurationValue(const string &strDomain, 2010 const string &strConfiguration, const string &strPath, 2011 string &strValue, bool bSet, string &strError) 2012 { 2013 CElementLocator elementLocator(getSystemClass()); 2014 2015 CElement *pLocatedElement = NULL; 2016 2017 if (!elementLocator.locate(strPath, &pLocatedElement, strError)) { 2018 2019 return false; 2020 } 2021 2022 // Convert element 2023 const CConfigurableElement *pConfigurableElement = 2024 static_cast<const CConfigurableElement *>(pLocatedElement); 2025 2026 // Get the Configuration blackboard and the Base Offset of the configurable element in this 2027 // blackboard 2028 size_t baseOffset; 2029 bool bIsLastApplied; 2030 2031 CParameterBlackboard *pConfigurationBlackboard = NULL; 2032 2033 { 2034 pConfigurationBlackboard = getConstConfigurableDomains()->findConfigurationBlackboard( 2035 strDomain, strConfiguration, pConfigurableElement, baseOffset, bIsLastApplied, 2036 strError); 2037 if (!pConfigurationBlackboard) { 2038 2039 warning() << "Fail: " << strError; 2040 return false; 2041 } 2042 } 2043 2044 info() << "Element " << strPath << " in Domain " << strDomain 2045 << ", offset: " << pConfigurableElement->getOffset() << ", base offset: " << baseOffset; 2046 2047 /// Update the Configuration Blackboard 2048 2049 // Define Configuration context using Base Offset and keep Auto Sync off to prevent access to HW 2050 CParameterAccessContext parameterAccessContext( 2051 strError, pConfigurationBlackboard, _bValueSpaceIsRaw, _bOutputRawFormatIsHex, baseOffset); 2052 2053 // Deactivate the auto synchronization with the hardware during the Configuration Blackboard 2054 // access (only Main Blackboard shall be synchronized, Configurations Blackboards are copied 2055 // into the Main Blackboard each time a configuration is restored but they are not synchronized 2056 // directly). 2057 if (bSet) { 2058 2059 parameterAccessContext.setAutoSync(false); 2060 } 2061 2062 // Access Value in the Configuration Blackboard 2063 if (!accessValue(parameterAccessContext, strPath, strValue, bSet, strError)) { 2064 2065 return false; 2066 } 2067 2068 /// If the Configuration is the last one applied, update the Main Blackboard as well 2069 2070 if (bIsLastApplied) { 2071 2072 // Define Main context 2073 parameterAccessContext.setParameterBlackboard(_pMainParameterBlackboard); 2074 2075 // Activate the auto synchronization with the hardware 2076 if (bSet) { 2077 2078 parameterAccessContext.setAutoSync(_bAutoSyncOn); 2079 } 2080 2081 // Access Value in the Main Blackboard 2082 return accessValue(parameterAccessContext, strPath, strValue, bSet, strError); 2083 } 2084 2085 return true; 2086 } 2087 2088 // User set/get parameters 2089 bool CParameterMgr::accessValue(CParameterAccessContext ¶meterAccessContext, 2090 const string &strPath, string &strValue, bool bSet, 2091 string &strError) 2092 { 2093 // Lock state 2094 lock_guard<mutex> autoLock(getBlackboardMutex()); 2095 2096 CPathNavigator pathNavigator(strPath); 2097 2098 // Nagivate through system class 2099 if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strError)) { 2100 2101 parameterAccessContext.setError(strError); 2102 2103 return false; 2104 } 2105 2106 // Do the get 2107 return getConstSystemClass()->accessValue(pathNavigator, strValue, bSet, 2108 parameterAccessContext); 2109 } 2110 2111 // Tuning mode 2112 bool CParameterMgr::setTuningMode(bool bOn, string &strError) 2113 { 2114 if (bOn == tuningModeOn()) { 2115 strError = "Tuning mode is already in the state requested"; 2116 return false; 2117 } 2118 // Tuning allowed? 2119 if (bOn && !getConstFrameworkConfiguration()->isTuningAllowed()) { 2120 2121 strError = "Tuning prohibited"; 2122 2123 return false; 2124 } 2125 // Lock state 2126 lock_guard<mutex> autoLock(getBlackboardMutex()); 2127 2128 // Warn domains about exiting tuning mode 2129 if (!bOn) { 2130 2131 // Ensure application of currently selected configurations 2132 // Force-apply configurations 2133 doApplyConfigurations(true); 2134 } 2135 2136 // Store 2137 _bTuningModeIsOn = bOn; 2138 2139 return true; 2140 } 2141 2142 bool CParameterMgr::tuningModeOn() const 2143 { 2144 return _bTuningModeIsOn; 2145 } 2146 2147 // Current value space for user set/get value interpretation 2148 void CParameterMgr::setValueSpace(bool bIsRaw) 2149 { 2150 _bValueSpaceIsRaw = bIsRaw; 2151 } 2152 2153 bool CParameterMgr::valueSpaceIsRaw() 2154 { 2155 return _bValueSpaceIsRaw; 2156 } 2157 2158 // Current Output Raw Format for user get value interpretation 2159 void CParameterMgr::setOutputRawFormat(bool bIsHex) 2160 { 2161 _bOutputRawFormatIsHex = bIsHex; 2162 } 2163 2164 bool CParameterMgr::outputRawFormatIsHex() 2165 { 2166 return _bOutputRawFormatIsHex; 2167 } 2168 2169 /// Sync 2170 // Automatic hardware synchronization control (during tuning session) 2171 bool CParameterMgr::setAutoSync(bool bAutoSyncOn, string &strError) 2172 { 2173 // Warn domains about turning auto sync back on 2174 if (bAutoSyncOn && !_bAutoSyncOn) { 2175 2176 // Do the synchronization at system class level (could be optimized by keeping track of all 2177 // modified parameters) 2178 if (!sync(strError)) { 2179 2180 return false; 2181 } 2182 } 2183 2184 // Set Auto sync 2185 _bAutoSyncOn = bAutoSyncOn; 2186 2187 return true; 2188 } 2189 2190 bool CParameterMgr::autoSyncOn() const 2191 { 2192 return _bAutoSyncOn; 2193 } 2194 2195 // Manual hardware synchronization control (during tuning session) 2196 bool CParameterMgr::sync(string &strError) 2197 { 2198 // Warn domains about turning auto sync back on 2199 if (_bAutoSyncOn) { 2200 2201 strError = "Feature unavailable when Auto Sync is on"; 2202 2203 return false; 2204 } 2205 2206 // Get syncer set 2207 CSyncerSet syncerSet; 2208 // ... from system class 2209 getConstSystemClass()->fillSyncerSet(syncerSet); 2210 2211 // Sync 2212 core::Results error; 2213 if (!syncerSet.sync(*_pMainParameterBlackboard, false, &error)) { 2214 2215 strError = utility::asString(error); 2216 return false; 2217 }; 2218 2219 return true; 2220 } 2221 2222 // Configuration/Domains handling 2223 bool CParameterMgr::createDomain(const string &strName, string &strError) 2224 { 2225 LOG_CONTEXT("Creating configurable domain " + strName); 2226 // Check tuning mode 2227 if (!checkTuningModeOn(strError)) { 2228 2229 return false; 2230 } 2231 2232 // Delegate to configurable domains 2233 return logResult(getConfigurableDomains()->createDomain(strName, strError), strError); 2234 } 2235 2236 bool CParameterMgr::deleteDomain(const string &strName, string &strError) 2237 { 2238 LOG_CONTEXT("Deleting configurable domain '" + strName + "'"); 2239 2240 // Check tuning mode 2241 if (!checkTuningModeOn(strError)) { 2242 2243 warning() << "Fail: " << strError; 2244 return false; 2245 } 2246 2247 // Delegate to configurable domains 2248 return logResult(getConfigurableDomains()->deleteDomain(strName, strError), strError); 2249 } 2250 2251 bool CParameterMgr::renameDomain(const string &strName, const string &strNewName, string &strError) 2252 { 2253 LOG_CONTEXT("Renaming configurable domain '" + strName + "' to '" + strNewName + "'"); 2254 2255 // Delegate to configurable domains 2256 return logResult(getConfigurableDomains()->renameDomain(strName, strNewName, strError), 2257 strError); 2258 } 2259 2260 bool CParameterMgr::deleteAllDomains(string &strError) 2261 { 2262 LOG_CONTEXT("Deleting all configurable domains"); 2263 2264 // Check tuning mode 2265 if (!checkTuningModeOn(strError)) { 2266 2267 warning() << "Fail: " << strError; 2268 return false; 2269 } 2270 2271 // Delegate to configurable domains 2272 getConfigurableDomains()->deleteAllDomains(); 2273 2274 info() << "Success"; 2275 return true; 2276 } 2277 2278 bool CParameterMgr::setSequenceAwareness(const string &strName, bool bSequenceAware, 2279 string &strResult) 2280 { 2281 LOG_CONTEXT("Making domain '" + strName + "' sequence " + 2282 (bSequenceAware ? "aware" : "unaware")); 2283 // Check tuning mode 2284 if (!checkTuningModeOn(strResult)) { 2285 2286 warning() << "Fail: " << strResult; 2287 return false; 2288 } 2289 2290 return logResult( 2291 getConfigurableDomains()->setSequenceAwareness(strName, bSequenceAware, strResult), 2292 strResult); 2293 } 2294 2295 bool CParameterMgr::getSequenceAwareness(const string &strName, bool &bSequenceAware, 2296 string &strResult) 2297 { 2298 return getConfigurableDomains()->getSequenceAwareness(strName, bSequenceAware, strResult); 2299 } 2300 2301 bool CParameterMgr::createConfiguration(const string &strDomain, const string &strConfiguration, 2302 string &strError) 2303 { 2304 LOG_CONTEXT("Creating domain configuration '" + strConfiguration + "' into domain '" + 2305 strDomain + "'"); 2306 // Check tuning mode 2307 if (!checkTuningModeOn(strError)) { 2308 2309 warning() << "Fail: " << strError; 2310 return false; 2311 } 2312 2313 // Delegate to configurable domains 2314 return logResult(getConfigurableDomains()->createConfiguration( 2315 strDomain, strConfiguration, _pMainParameterBlackboard, strError), 2316 strError); 2317 } 2318 bool CParameterMgr::renameConfiguration(const string &strDomain, const string &strConfiguration, 2319 const string &strNewConfiguration, string &strError) 2320 { 2321 LOG_CONTEXT("Renaming domain '" + strDomain + "''s configuration '" + strConfiguration + 2322 "' to '" + strNewConfiguration + "'"); 2323 2324 return logResult(getConfigurableDomains()->renameConfiguration(strDomain, strConfiguration, 2325 strNewConfiguration, strError), 2326 strError); 2327 } 2328 2329 bool CParameterMgr::deleteConfiguration(const string &strDomain, const string &strConfiguration, 2330 string &strError) 2331 { 2332 LOG_CONTEXT("Deleting configuration '" + strConfiguration + "' from domain '" + strDomain + 2333 "'"); 2334 2335 // Check tuning mode 2336 if (!checkTuningModeOn(strError)) { 2337 2338 warning() << "Fail:" << strError; 2339 return false; 2340 } 2341 2342 // Delegate to configurable domains 2343 return logResult( 2344 getConfigurableDomains()->deleteConfiguration(strDomain, strConfiguration, strError), 2345 strError); 2346 } 2347 2348 bool CParameterMgr::restoreConfiguration(const string &strDomain, const string &strConfiguration, 2349 core::Results &errors) 2350 { 2351 string strError; 2352 LOG_CONTEXT("Restoring domain '" + strDomain + "''s configuration '" + strConfiguration + 2353 "' to parameter blackboard"); 2354 // Check tuning mode 2355 if (!checkTuningModeOn(strError)) { 2356 2357 errors.push_back(strError); 2358 warning() << "Fail:" << strError; 2359 return false; 2360 } 2361 2362 // Delegate to configurable domains 2363 return logResult( 2364 getConstConfigurableDomains()->restoreConfiguration( 2365 strDomain, strConfiguration, _pMainParameterBlackboard, _bAutoSyncOn, errors), 2366 strError); 2367 } 2368 2369 bool CParameterMgr::saveConfiguration(const string &strDomain, const string &strConfiguration, 2370 string &strError) 2371 { 2372 LOG_CONTEXT("Saving domain '" + strDomain + "' configuration '" + strConfiguration + 2373 "' from parameter blackboard"); 2374 // Check tuning mode 2375 if (!checkTuningModeOn(strError)) { 2376 2377 warning() << "Fail:" << strError; 2378 return false; 2379 } 2380 2381 // Delegate to configurable domains 2382 return logResult(getConfigurableDomains()->saveConfiguration( 2383 strDomain, strConfiguration, _pMainParameterBlackboard, strError), 2384 strError); 2385 } 2386 2387 // Configurable element - domain association 2388 bool CParameterMgr::addConfigurableElementToDomain(const string &strDomain, 2389 const string &strConfigurableElementPath, 2390 string &strError) 2391 { 2392 LOG_CONTEXT("Adding configurable element '" + strConfigurableElementPath + "' to domain '" + 2393 strDomain + "'"); 2394 // Check tuning mode 2395 if (!checkTuningModeOn(strError)) { 2396 2397 warning() << "Fail: " << strError; 2398 return false; 2399 } 2400 2401 CElementLocator elementLocator(getSystemClass()); 2402 2403 CElement *pLocatedElement = NULL; 2404 2405 if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { 2406 2407 warning() << "Fail: " << strError; 2408 return false; 2409 } 2410 2411 // Convert element 2412 CConfigurableElement *pConfigurableElement = 2413 static_cast<CConfigurableElement *>(pLocatedElement); 2414 2415 // Delegate 2416 core::Results infos; 2417 bool isSuccess = getConfigurableDomains()->addConfigurableElementToDomain( 2418 strDomain, pConfigurableElement, _pMainParameterBlackboard, infos); 2419 2420 if (isSuccess) { 2421 info() << infos; 2422 } else { 2423 warning() << infos; 2424 } 2425 2426 strError = utility::asString(infos); 2427 return isSuccess; 2428 } 2429 2430 bool CParameterMgr::removeConfigurableElementFromDomain(const string &strDomain, 2431 const string &strConfigurableElementPath, 2432 string &strError) 2433 { 2434 LOG_CONTEXT("Removing configurable element '" + strConfigurableElementPath + "' from domain '" + 2435 strDomain + "'"); 2436 2437 // Check tuning mode 2438 if (!checkTuningModeOn(strError)) { 2439 2440 warning() << "Fail:" << strError; 2441 return false; 2442 } 2443 2444 CElementLocator elementLocator(getSystemClass()); 2445 2446 CElement *pLocatedElement = NULL; 2447 2448 if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { 2449 2450 warning() << "Fail:" << strError; 2451 return false; 2452 } 2453 2454 // Convert element 2455 CConfigurableElement *pConfigurableElement = 2456 static_cast<CConfigurableElement *>(pLocatedElement); 2457 2458 // Delegate 2459 return logResult(getConfigurableDomains()->removeConfigurableElementFromDomain( 2460 strDomain, pConfigurableElement, strError), 2461 strError); 2462 } 2463 2464 bool CParameterMgr::split(const string &strDomain, const string &strConfigurableElementPath, 2465 string &strError) 2466 { 2467 LOG_CONTEXT("Splitting configurable element '" + strConfigurableElementPath + "' domain '" + 2468 strDomain + "'"); 2469 // Check tuning mode 2470 if (!checkTuningModeOn(strError)) { 2471 2472 warning() << "Fail:" << strError; 2473 return false; 2474 } 2475 2476 CElementLocator elementLocator(getSystemClass()); 2477 2478 CElement *pLocatedElement = NULL; 2479 2480 if (!elementLocator.locate(strConfigurableElementPath, &pLocatedElement, strError)) { 2481 2482 warning() << "Fail: " << strError; 2483 return false; 2484 } 2485 2486 // Convert element 2487 CConfigurableElement *pConfigurableElement = 2488 static_cast<CConfigurableElement *>(pLocatedElement); 2489 2490 // Delegate 2491 core::Results infos; 2492 bool isSuccess = getConfigurableDomains()->split(strDomain, pConfigurableElement, infos); 2493 2494 if (isSuccess) { 2495 info() << infos; 2496 } else { 2497 warning() << infos; 2498 } 2499 2500 strError = utility::asString(infos); 2501 return isSuccess; 2502 } 2503 2504 bool CParameterMgr::setElementSequence(const string &strDomain, const string &strConfiguration, 2505 const std::vector<string> &astrNewElementSequence, 2506 string &strError) 2507 { 2508 // Check tuning mode 2509 if (!checkTuningModeOn(strError)) { 2510 2511 return false; 2512 } 2513 2514 return getConfigurableDomains()->setElementSequence(strDomain, strConfiguration, 2515 astrNewElementSequence, strError); 2516 } 2517 2518 bool CParameterMgr::getApplicationRule(const string &strDomain, const string &strConfiguration, 2519 string &strResult) 2520 { 2521 return getConfigurableDomains()->getApplicationRule(strDomain, strConfiguration, strResult); 2522 } 2523 2524 bool CParameterMgr::setApplicationRule(const string &strDomain, const string &strConfiguration, 2525 const string &strApplicationRule, string &strError) 2526 { 2527 return getConfigurableDomains()->setApplicationRule( 2528 strDomain, strConfiguration, strApplicationRule, 2529 getConstSelectionCriteria()->getSelectionCriteriaDefinition(), strError); 2530 } 2531 2532 bool CParameterMgr::clearApplicationRule(const string &strDomain, const string &strConfiguration, 2533 string &strError) 2534 { 2535 return getConfigurableDomains()->clearApplicationRule(strDomain, strConfiguration, strError); 2536 } 2537 2538 bool CParameterMgr::importDomainsXml(const string &xmlSource, bool withSettings, bool fromFile, 2539 string &errorMsg) 2540 { 2541 // Check tuning mode 2542 if (!checkTuningModeOn(errorMsg)) { 2543 2544 return false; 2545 } 2546 2547 LOG_CONTEXT("Importing domains from " + 2548 (fromFile ? ("\"" + xmlSource + "\"") : "a user-provided buffer")); 2549 2550 // Root element 2551 CConfigurableDomains *pConfigurableDomains = getConfigurableDomains(); 2552 2553 bool importSuccess = wrapLegacyXmlImport(xmlSource, fromFile, withSettings, 2554 *pConfigurableDomains, "SystemClassName", errorMsg); 2555 2556 if (importSuccess) { 2557 2558 // Validate domains after XML import 2559 pConfigurableDomains->validate(_pMainParameterBlackboard); 2560 } 2561 2562 return importSuccess; 2563 } 2564 2565 bool CParameterMgr::importSingleDomainXml(const string &xmlSource, bool overwrite, 2566 bool withSettings, bool fromFile, string &errorMsg) 2567 { 2568 if (!checkTuningModeOn(errorMsg)) { 2569 2570 return false; 2571 } 2572 2573 LOG_CONTEXT("Importing a single domain from " + 2574 (fromFile ? ('"' + xmlSource + '"') : "a user-provided buffer")); 2575 2576 // We initialize the domain with an empty name but since we have set the isDomainStandalone 2577 // context, the name will be retrieved during de-serialization 2578 auto standaloneDomain = utility::make_unique<CConfigurableDomain>(); 2579 2580 if (!wrapLegacyXmlImport(xmlSource, fromFile, withSettings, *standaloneDomain, "", errorMsg)) { 2581 return false; 2582 } 2583 2584 if (!getConfigurableDomains()->addDomain(*standaloneDomain, overwrite, errorMsg)) { 2585 return false; 2586 } 2587 2588 // ownership has been transfered to the ConfigurableDomains object 2589 standaloneDomain.release(); 2590 return true; 2591 } 2592 2593 bool CParameterMgr::wrapLegacyXmlImport(const string &xmlSource, bool fromFile, bool withSettings, 2594 CElement &element, const string &nameAttributeName, 2595 string &errorMsg) 2596 { 2597 CXmlDomainImportContext xmlDomainImportContext(errorMsg, withSettings, *getSystemClass()); 2598 2599 // Selection criteria definition for rule creation 2600 xmlDomainImportContext.setSelectionCriteriaDefinition( 2601 getConstSelectionCriteria()->getSelectionCriteriaDefinition()); 2602 2603 // It doesn't make sense to resolve XIncludes on an imported file because 2604 // we can't reliably decide of a "base url" 2605 _xmlDoc *doc = CXmlDocSource::mkXmlDoc(xmlSource, fromFile, false, xmlDomainImportContext); 2606 if (doc == NULL) { 2607 return false; 2608 } 2609 2610 return xmlParse(xmlDomainImportContext, &element, doc, "", EParameterConfigurationLibrary, true, 2611 nameAttributeName); 2612 } 2613 2614 bool CParameterMgr::serializeElement(std::ostream &output, 2615 CXmlSerializingContext &xmlSerializingContext, 2616 const CElement &element) const 2617 { 2618 if (!output.good()) { 2619 xmlSerializingContext.setError("Can't write XML: the output is in a bad state."); 2620 return false; 2621 } 2622 2623 // Use a doc source by loading data from instantiated Configurable Domains 2624 CXmlMemoryDocSource memorySource(&element, _bValidateSchemasOnStart, 2625 element.getXmlElementName(), "parameter-framework", 2626 getVersion()); 2627 2628 // Use a doc sink to write the doc data in a stream 2629 CXmlStreamDocSink sink(output); 2630 2631 bool processSuccess = sink.process(memorySource, xmlSerializingContext); 2632 2633 return processSuccess; 2634 } 2635 2636 bool CParameterMgr::exportDomainsXml(string &xmlDest, bool withSettings, bool toFile, 2637 string &errorMsg) const 2638 { 2639 LOG_CONTEXT("Exporting domains to " + 2640 (toFile ? ('"' + xmlDest + '"') : "a user-provided buffer")); 2641 2642 const CConfigurableDomains *configurableDomains = getConstConfigurableDomains(); 2643 2644 return wrapLegacyXmlExport(xmlDest, toFile, withSettings, *configurableDomains, errorMsg); 2645 } 2646 2647 bool CParameterMgr::exportSingleDomainXml(string &xmlDest, const string &domainName, 2648 bool withSettings, bool toFile, string &errorMsg) const 2649 { 2650 LOG_CONTEXT("Exporting single domain '" + domainName + "' to " + 2651 (toFile ? ('"' + xmlDest + '"') : "a user-provided buffer")); 2652 2653 // Element to be serialized 2654 const CConfigurableDomain *requestedDomain = 2655 getConstConfigurableDomains()->findConfigurableDomain(domainName, errorMsg); 2656 2657 if (requestedDomain == NULL) { 2658 return false; 2659 } 2660 2661 return wrapLegacyXmlExport(xmlDest, toFile, withSettings, *requestedDomain, errorMsg); 2662 } 2663 2664 bool CParameterMgr::wrapLegacyXmlExport(string &xmlDest, bool toFile, bool withSettings, 2665 const CElement &element, string &errorMsg) const 2666 { 2667 CXmlDomainExportContext context(errorMsg, withSettings, _bValueSpaceIsRaw, 2668 _bOutputRawFormatIsHex); 2669 2670 if (toFile) { 2671 return wrapLegacyXmlExportToFile(xmlDest, element, context); 2672 } else { 2673 return wrapLegacyXmlExportToString(xmlDest, element, context); 2674 } 2675 } 2676 2677 bool CParameterMgr::wrapLegacyXmlExportToFile(string &xmlDest, const CElement &element, 2678 CXmlDomainExportContext &context) const 2679 { 2680 try { 2681 std::ofstream output; 2682 // Force stream to throw instead of using fail/bad bit 2683 // in order to retreive an error message. 2684 output.exceptions(~std::ifstream::goodbit); 2685 2686 output.open(xmlDest.c_str()); 2687 bool status = serializeElement(output, context, element); 2688 output.close(); // Explicit close to detect errors 2689 2690 return status; 2691 2692 } catch (std::ofstream::failure &e) { 2693 context.setError("Failed to open \"" + xmlDest + "\" for writing: " + e.what()); 2694 return false; 2695 } 2696 } 2697 2698 bool CParameterMgr::wrapLegacyXmlExportToString(string &xmlDest, const CElement &element, 2699 CXmlDomainExportContext &context) const 2700 { 2701 std::ostringstream output; 2702 2703 if (!serializeElement(output, context, element)) { 2704 return false; 2705 } 2706 2707 xmlDest = output.str(); 2708 2709 return true; 2710 } 2711 2712 // For tuning, check we're in tuning mode 2713 bool CParameterMgr::checkTuningModeOn(string &strError) const 2714 { 2715 // Tuning Mode on? 2716 if (!_bTuningModeIsOn) { 2717 2718 strError = "Tuning Mode must be on"; 2719 2720 return false; 2721 } 2722 return true; 2723 } 2724 2725 // Tuning mutex dynamic parameter handling 2726 std::mutex &CParameterMgr::getBlackboardMutex() 2727 { 2728 return _blackboardMutex; 2729 } 2730 2731 // Blackboard reference (dynamic parameter handling) 2732 CParameterBlackboard *CParameterMgr::getParameterBlackboard() 2733 { 2734 return _pMainParameterBlackboard; 2735 } 2736 2737 // Dynamic creation library feeding 2738 void CParameterMgr::feedElementLibraries() 2739 { 2740 // Global Configuration handling 2741 CElementLibrary *pFrameworkConfigurationLibrary = new CElementLibrary; 2742 2743 pFrameworkConfigurationLibrary->addElementBuilder( 2744 "ParameterFrameworkConfiguration", 2745 new TElementBuilderTemplate<CParameterFrameworkConfiguration>()); 2746 pFrameworkConfigurationLibrary->addElementBuilder( 2747 "SubsystemPlugins", new TKindElementBuilderTemplate<CSubsystemPlugins>()); 2748 pFrameworkConfigurationLibrary->addElementBuilder( 2749 "Location", new TKindElementBuilderTemplate<CPluginLocation>()); 2750 pFrameworkConfigurationLibrary->addElementBuilder( 2751 "StructureDescriptionFileLocation", 2752 new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); 2753 pFrameworkConfigurationLibrary->addElementBuilder( 2754 "SettingsConfiguration", new TKindElementBuilderTemplate<CFrameworkConfigurationGroup>()); 2755 pFrameworkConfigurationLibrary->addElementBuilder( 2756 "ConfigurableDomainsFileLocation", 2757 new TKindElementBuilderTemplate<CFrameworkConfigurationLocation>()); 2758 2759 _pElementLibrarySet->addElementLibrary(pFrameworkConfigurationLibrary); 2760 2761 // Parameter creation 2762 CElementLibrary *pParameterCreationLibrary = new CElementLibrary; 2763 2764 pParameterCreationLibrary->addElementBuilder( 2765 "Subsystem", new CSubsystemElementBuilder(getSystemClass()->getSubsystemLibrary())); 2766 pParameterCreationLibrary->addElementBuilder( 2767 "ComponentType", new TNamedElementBuilderTemplate<CComponentType>()); 2768 pParameterCreationLibrary->addElementBuilder( 2769 "Component", new TNamedElementBuilderTemplate<CComponentInstance>()); 2770 pParameterCreationLibrary->addElementBuilder( 2771 "BitParameter", new TNamedElementBuilderTemplate<CBitParameterType>()); 2772 pParameterCreationLibrary->addElementBuilder( 2773 "BitParameterBlock", new TNamedElementBuilderTemplate<CBitParameterBlockType>()); 2774 pParameterCreationLibrary->addElementBuilder( 2775 "StringParameter", new TNamedElementBuilderTemplate<CStringParameterType>()); 2776 pParameterCreationLibrary->addElementBuilder( 2777 "ParameterBlock", new TNamedElementBuilderTemplate<CParameterBlockType>()); 2778 pParameterCreationLibrary->addElementBuilder( 2779 "BooleanParameter", new TNamedElementBuilderTemplate<CBooleanParameterType>()); 2780 pParameterCreationLibrary->addElementBuilder( 2781 "IntegerParameter", new TNamedElementBuilderTemplate<CIntegerParameterType>()); 2782 pParameterCreationLibrary->addElementBuilder( 2783 "LinearAdaptation", new TElementBuilderTemplate<CLinearParameterAdaptation>()); 2784 pParameterCreationLibrary->addElementBuilder( 2785 "LogarithmicAdaptation", new TElementBuilderTemplate<CLogarithmicParameterAdaptation>()); 2786 pParameterCreationLibrary->addElementBuilder( 2787 "EnumParameter", new TNamedElementBuilderTemplate<CEnumParameterType>()); 2788 pParameterCreationLibrary->addElementBuilder("ValuePair", 2789 new TElementBuilderTemplate<CEnumValuePair>()); 2790 pParameterCreationLibrary->addElementBuilder( 2791 "FixedPointParameter", new TNamedElementBuilderTemplate<CFixedPointParameterType>()); 2792 pParameterCreationLibrary->addElementBuilder( 2793 "FloatingPointParameter", new TNamedElementBuilderTemplate<CFloatingPointParameterType>); 2794 pParameterCreationLibrary->addElementBuilder( 2795 "SubsystemInclude", 2796 new CFileIncluderElementBuilder(_bValidateSchemasOnStart, getSchemaUri())); 2797 2798 _pElementLibrarySet->addElementLibrary(pParameterCreationLibrary); 2799 2800 // Parameter Configuration Domains creation 2801 CElementLibrary *pParameterConfigurationLibrary = new CElementLibrary; 2802 2803 pParameterConfigurationLibrary->addElementBuilder( 2804 "ConfigurableDomain", new TElementBuilderTemplate<CConfigurableDomain>()); 2805 pParameterConfigurationLibrary->addElementBuilder( 2806 "Configuration", new TNamedElementBuilderTemplate<CDomainConfiguration>()); 2807 pParameterConfigurationLibrary->addElementBuilder("CompoundRule", 2808 new TElementBuilderTemplate<CCompoundRule>()); 2809 pParameterConfigurationLibrary->addElementBuilder( 2810 "SelectionCriterionRule", new TElementBuilderTemplate<CSelectionCriterionRule>()); 2811 2812 _pElementLibrarySet->addElementLibrary(pParameterConfigurationLibrary); 2813 } 2814 2815 bool CParameterMgr::getForceNoRemoteInterface() const 2816 { 2817 return _bForceNoRemoteInterface; 2818 } 2819 2820 void CParameterMgr::setForceNoRemoteInterface(bool bForceNoRemoteInterface) 2821 { 2822 _bForceNoRemoteInterface = bForceNoRemoteInterface; 2823 } 2824 2825 CParameterMgr::CommandHandler CParameterMgr::createCommandHandler() 2826 { 2827 auto commandHandler = utility::make_unique<CCommandHandler>(this); 2828 2829 // Add command parsers 2830 for (const auto &remoteCommandParserItem : gastRemoteCommandParserItems) { 2831 commandHandler->addCommandParser( 2832 remoteCommandParserItem._pcCommandName, remoteCommandParserItem._pfnParser, 2833 remoteCommandParserItem._minArgumentCount, remoteCommandParserItem._pcHelp, 2834 remoteCommandParserItem._pcDescription); 2835 } 2836 2837 return commandHandler; 2838 } 2839 2840 bool CParameterMgr::isRemoteInterfaceRequired() 2841 { 2842 // The remote interface should only be started if the client didn't 2843 // explicitly forbid it and if the configuration file allows it. 2844 return (not _bForceNoRemoteInterface) and getConstFrameworkConfiguration()->isTuningAllowed(); 2845 } 2846 2847 // Remote Processor Server connection handling 2848 bool CParameterMgr::handleRemoteProcessingInterface(string &strError) 2849 { 2850 LOG_CONTEXT("Handling remote processing interface"); 2851 2852 if (not isRemoteInterfaceRequired()) { 2853 return true; 2854 } 2855 2856 auto port = getConstFrameworkConfiguration()->getServerPort(); 2857 2858 try { 2859 // The ownership of remoteComandHandler is given to Bg remote processor server. 2860 _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); 2861 } catch (std::runtime_error &e) { 2862 strError = string("ParameterMgr: Unable to create Remote Processor Server: ") + e.what(); 2863 return false; 2864 } 2865 2866 if (_pRemoteProcessorServer == NULL) { 2867 strError = "ParameterMgr: Unable to create Remote Processor Server"; 2868 return false; 2869 } 2870 2871 if (!_pRemoteProcessorServer->start(strError)) { 2872 ostringstream oss; 2873 oss << "ParameterMgr: Unable to start remote processor server on port " << port; 2874 strError = oss.str() + ": " + strError; 2875 return false; 2876 } 2877 info() << "Remote Processor Server started on port " << port; 2878 return true; 2879 } 2880 2881 // Children typwise access 2882 CParameterFrameworkConfiguration *CParameterMgr::getFrameworkConfiguration() 2883 { 2884 return static_cast<CParameterFrameworkConfiguration *>(getChild(EFrameworkConfiguration)); 2885 } 2886 2887 const CParameterFrameworkConfiguration *CParameterMgr::getConstFrameworkConfiguration() 2888 { 2889 return getFrameworkConfiguration(); 2890 } 2891 2892 CSelectionCriteria *CParameterMgr::getSelectionCriteria() 2893 { 2894 return static_cast<CSelectionCriteria *>(getChild(ESelectionCriteria)); 2895 } 2896 2897 const CSelectionCriteria *CParameterMgr::getConstSelectionCriteria() 2898 { 2899 return static_cast<const CSelectionCriteria *>(getChild(ESelectionCriteria)); 2900 } 2901 2902 CSystemClass *CParameterMgr::getSystemClass() 2903 { 2904 return static_cast<CSystemClass *>(getChild(ESystemClass)); 2905 } 2906 2907 const CSystemClass *CParameterMgr::getConstSystemClass() const 2908 { 2909 return static_cast<const CSystemClass *>(getChild(ESystemClass)); 2910 } 2911 2912 // Configurable Domains 2913 CConfigurableDomains *CParameterMgr::getConfigurableDomains() 2914 { 2915 return static_cast<CConfigurableDomains *>(getChild(EConfigurableDomains)); 2916 } 2917 2918 const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains() 2919 { 2920 return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains)); 2921 } 2922 2923 const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains() const 2924 { 2925 return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains)); 2926 } 2927 2928 // Apply configurations 2929 void CParameterMgr::doApplyConfigurations(bool bForce) 2930 { 2931 LOG_CONTEXT("Applying configurations"); 2932 2933 CSyncerSet syncerSet; 2934 2935 core::Results infos; 2936 // Check subsystems that need resync 2937 getSystemClass()->checkForSubsystemsToResync(syncerSet, infos); 2938 2939 // Ensure application of currently selected configurations 2940 getConfigurableDomains()->apply(_pMainParameterBlackboard, syncerSet, bForce, infos); 2941 info() << infos; 2942 2943 // Reset the modified status of the current criteria to indicate that a new configuration has 2944 // been applied 2945 getSelectionCriteria()->resetModifiedStatus(); 2946 } 2947 2948 // Export to XML string 2949 bool CParameterMgr::exportElementToXMLString(const IXmlSource *pXmlSource, 2950 const string &strRootElementType, 2951 CXmlSerializingContext &&xmlSerializingContext, 2952 string &strResult) const 2953 { 2954 // Use a doc source by loading data from instantiated Configurable Domains 2955 CXmlMemoryDocSource memorySource(pXmlSource, false, strRootElementType); 2956 2957 // Use a doc sink that write the doc data in a string 2958 ostringstream output; 2959 CXmlStreamDocSink streamSink(output); 2960 2961 // Do the export 2962 bool bProcessSuccess = streamSink.process(memorySource, xmlSerializingContext); 2963 2964 strResult = output.str(); 2965 2966 return bProcessSuccess; 2967 } 2968 2969 bool CParameterMgr::logResult(bool isSuccess, const std::string &result) 2970 { 2971 std::string log = result.empty() ? "" : ": " + result; 2972 2973 if (isSuccess) { 2974 info() << "Success" << log; 2975 } else { 2976 warning() << "Fail" << log; 2977 } 2978 2979 return isSuccess; 2980 } 2981 2982 log::details::Info CParameterMgr::info() 2983 { 2984 return _logger.info(); 2985 } 2986 2987 log::details::Warning CParameterMgr::warning() 2988 { 2989 return _logger.warning(); 2990 } 2991