Home | History | Annotate | Download | only in parameter
      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 &parameterAccessContext,
   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