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
CParameterMgr(const string & strConfigurationFilePath,log::ILogger & logger)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 
~CParameterMgr()338 CParameterMgr::~CParameterMgr()
339 {
340     // Children
341     delete _pRemoteProcessorServer;
342     delete _pMainParameterBlackboard;
343     delete _pElementLibrarySet;
344 }
345 
getKind() const346 string CParameterMgr::getKind() const
347 {
348     return "ParameterMgr";
349 }
350 
351 // Version
getVersion() const352 string CParameterMgr::getVersion() const
353 {
354     return PARAMETER_FRAMEWORK_VERSION;
355 }
356 
load(string & strError)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 
loadFrameworkConfiguration(string & strError)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 
loadSubsystems(std::string & error)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 
loadStructure(string & strError)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 
loadSettings(string & strError)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 
loadSettingsFromConfigFile(string & strError)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
xmlParse(CXmlElementSerializingContext & elementSerializingContext,CElement * pRootElement,_xmlDoc * doc,const string & baseUri,CParameterMgr::ElementLibrary eElementLibrary,bool replace,const string & strNameAttributeName)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
init(string & strError)652 bool CParameterMgr::init(string &strError)
653 {
654     return base::init(strError);
655 }
656 
657 // Selection criteria interface
createSelectionCriterionType(bool bIsInclusive)658 CSelectionCriterionType *CParameterMgr::createSelectionCriterionType(bool bIsInclusive)
659 {
660     // Propagate
661     return getSelectionCriteria()->createSelectionCriterionType(bIsInclusive);
662 }
663 
createSelectionCriterion(const string & strName,const CSelectionCriterionType * pSelectionCriterionType)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
getSelectionCriterion(const string & strName)673 CSelectionCriterion *CParameterMgr::getSelectionCriterion(const string &strName)
674 {
675     // Propagate
676     return getSelectionCriteria()->getSelectionCriterion(strName);
677 }
678 
679 // Configuration application
applyConfigurations()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 
getConfigurableElement(const string & strPath,string & strError) const697 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 
getConfigurableElement(const string & strPath,string & strError)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
createParameterHandle(const string & strPath,string & strError)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
createElementHandle(const std::string & path,std::string & error)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 
getSettingsAsBytes(const CConfigurableElement & element,std::vector<uint8_t> & settings) const784 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 
setSettingsAsBytes(const CConfigurableElement & element,const std::vector<uint8_t> & settings,std::string & error)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 
setFailureOnMissingSubsystem(bool bFail)819 void CParameterMgr::setFailureOnMissingSubsystem(bool bFail)
820 {
821     _bFailOnMissingSubsystem = bFail;
822 }
823 
getFailureOnMissingSubsystem() const824 bool CParameterMgr::getFailureOnMissingSubsystem() const
825 {
826     return _bFailOnMissingSubsystem;
827 }
828 
setFailureOnFailedSettingsLoad(bool bFail)829 void CParameterMgr::setFailureOnFailedSettingsLoad(bool bFail)
830 {
831     _bFailOnFailedSettingsLoad = bFail;
832 }
833 
getFailureOnFailedSettingsLoad() const834 bool CParameterMgr::getFailureOnFailedSettingsLoad() const
835 {
836     return _bFailOnFailedSettingsLoad;
837 }
838 
getSchemaUri() const839 const string &CParameterMgr::getSchemaUri() const
840 {
841     return _schemaUri;
842 }
843 
setSchemaUri(const string & schemaUri)844 void CParameterMgr::setSchemaUri(const string &schemaUri)
845 {
846     _schemaUri = schemaUri;
847 }
848 
setValidateSchemasOnStart(bool bValidate)849 void CParameterMgr::setValidateSchemasOnStart(bool bValidate)
850 {
851     _bValidateSchemasOnStart = bValidate;
852 }
853 
getValidateSchemasOnStart() const854 bool CParameterMgr::getValidateSchemasOnStart() const
855 {
856     return _bValidateSchemasOnStart;
857 }
858 
859 /////////////////// Remote command parsers
860 /// Version
versionCommandProcess(const IRemoteCommand &,string & strResult)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
statusCommandProcess(const IRemoteCommand &,string & strResult)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
setTuningModeCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getTuningModeCommandProcess(const IRemoteCommand &,string & strResult)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
setValueSpaceCommandProcess(const IRemoteCommand & remoteCommand,string &)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 
getValueSpaceCommandProcess(const IRemoteCommand &,string & strResult)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
setOutputRawFormatCommandProcess(const IRemoteCommand & remoteCommand,string &)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 
getOutputRawFormatCommandProcess(const IRemoteCommand &,string & strResult)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
setAutoSyncCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getAutoSyncCommandProcess(const IRemoteCommand &,string & strResult)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 
syncCommandProcess(const IRemoteCommand &,string & strResult)1051 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::syncCommandProcess(
1052     const IRemoteCommand &, string &strResult)
1053 {
1054     return sync(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed;
1055 }
1056 
1057 /// Criteria
listCriteriaCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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
listDomainsCommandProcess(const IRemoteCommand &,string & strResult)1113 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listDomainsCommandProcess(
1114     const IRemoteCommand & /*command*/, string &strResult)
1115 {
1116     getConfigurableDomains()->listDomains(strResult);
1117 
1118     return CCommandHandler::ESucceeded;
1119 }
1120 
createDomainCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
deleteDomainCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
deleteAllDomainsCommandProcess(const IRemoteCommand &,string & strResult)1135 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::deleteAllDomainsCommandProcess(
1136     const IRemoteCommand & /*command*/, string &strResult)
1137 {
1138     return deleteAllDomains(strResult) ? CCommandHandler::EDone : CCommandHandler::EFailed;
1139 }
1140 
renameDomainCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
setSequenceAwarenessCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getSequenceAwarenessCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
listDomainElementsCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
addElementCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
removeElementCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
splitDomainCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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
listConfigurationsCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
dumpDomainsCommandProcess(const IRemoteCommand &,string & strResult)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 
createConfigurationCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
deleteConfigurationCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
renameConfigurationCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
saveConfigurationCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
restoreConfigurationCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
setElementSequenceCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getElementSequenceCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
setRuleCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
clearRuleCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getRuleCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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
listElementsCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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
listParametersCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getElementStructureXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getElementBytesCommandProcess(const IRemoteCommand & remoteCommand,std::string & strResult)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 
setElementBytesCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getSettingsAsXML(const CConfigurableElement * configurableElement,string & result) const1523 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 
setSettingsAsXML(CConfigurableElement * configurableElement,const string & settings,string & error)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 
getElementXMLCommandProcess(const IRemoteCommand & remoteCommand,string & result)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 
setElementXMLCommandProcess(const IRemoteCommand & remoteCommand,string & result)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 
dumpElementCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getElementSizeCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
showPropertiesCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
getParameterCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
setParameterCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
listBelongingDomainsCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
listAssociatedDomainsCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
listAssociatedElementsCommandProcess(const IRemoteCommand &,string & strResult)1757 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listAssociatedElementsCommandProcess(
1758     const IRemoteCommand & /*command*/, string &strResult)
1759 {
1760     getConfigurableDomains()->listAssociatedElements(strResult);
1761 
1762     return CCommandHandler::ESucceeded;
1763 }
1764 
listConflictingElementsCommandProcess(const IRemoteCommand &,string & strResult)1765 CParameterMgr::CCommandHandler::CommandStatus CParameterMgr::listConflictingElementsCommandProcess(
1766     const IRemoteCommand & /*command*/, string &strResult)
1767 {
1768     getConfigurableDomains()->listConflictingElements(strResult);
1769 
1770     return CCommandHandler::ESucceeded;
1771 }
1772 
listRogueElementsCommandProcess(const IRemoteCommand &,string & strResult)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::
getConfigurationParameterCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
setConfigurationParameterCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
showMappingCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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
exportDomainsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
importDomainsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
exportDomainsWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
exportDomainWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & result)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::
importDomainsWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
importDomainWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
getDomainsWithSettingsXMLCommandProcess(const IRemoteCommand &,string & strResult)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 
getDomainWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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::
setDomainsWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & strResult)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 
setDomainWithSettingsXMLCommandProcess(const IRemoteCommand & remoteCommand,string & result)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 
getSystemClassXMLCommandProcess(const IRemoteCommand &,string & strResult)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
accessParameterValue(const string & strPath,string & strValue,bool bSet,string & strError)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
getParameterMapping(const string & strPath,string & strResult) const1982 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
accessConfigurationValue(const string & strDomain,const string & strConfiguration,const string & strPath,string & strValue,bool bSet,string & strError)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
accessValue(CParameterAccessContext & parameterAccessContext,const string & strPath,string & strValue,bool bSet,string & strError)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
setTuningMode(bool bOn,string & strError)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 
tuningModeOn() const2142 bool CParameterMgr::tuningModeOn() const
2143 {
2144     return _bTuningModeIsOn;
2145 }
2146 
2147 // Current value space for user set/get value interpretation
setValueSpace(bool bIsRaw)2148 void CParameterMgr::setValueSpace(bool bIsRaw)
2149 {
2150     _bValueSpaceIsRaw = bIsRaw;
2151 }
2152 
valueSpaceIsRaw()2153 bool CParameterMgr::valueSpaceIsRaw()
2154 {
2155     return _bValueSpaceIsRaw;
2156 }
2157 
2158 // Current Output Raw Format for user get value interpretation
setOutputRawFormat(bool bIsHex)2159 void CParameterMgr::setOutputRawFormat(bool bIsHex)
2160 {
2161     _bOutputRawFormatIsHex = bIsHex;
2162 }
2163 
outputRawFormatIsHex()2164 bool CParameterMgr::outputRawFormatIsHex()
2165 {
2166     return _bOutputRawFormatIsHex;
2167 }
2168 
2169 /// Sync
2170 // Automatic hardware synchronization control (during tuning session)
setAutoSync(bool bAutoSyncOn,string & strError)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 
autoSyncOn() const2190 bool CParameterMgr::autoSyncOn() const
2191 {
2192     return _bAutoSyncOn;
2193 }
2194 
2195 // Manual hardware synchronization control (during tuning session)
sync(string & strError)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
createDomain(const string & strName,string & strError)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 
deleteDomain(const string & strName,string & strError)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 
renameDomain(const string & strName,const string & strNewName,string & strError)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 
deleteAllDomains(string & strError)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 
setSequenceAwareness(const string & strName,bool bSequenceAware,string & strResult)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 
getSequenceAwareness(const string & strName,bool & bSequenceAware,string & strResult)2295 bool CParameterMgr::getSequenceAwareness(const string &strName, bool &bSequenceAware,
2296                                          string &strResult)
2297 {
2298     return getConfigurableDomains()->getSequenceAwareness(strName, bSequenceAware, strResult);
2299 }
2300 
createConfiguration(const string & strDomain,const string & strConfiguration,string & strError)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 }
renameConfiguration(const string & strDomain,const string & strConfiguration,const string & strNewConfiguration,string & strError)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 
deleteConfiguration(const string & strDomain,const string & strConfiguration,string & strError)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 
restoreConfiguration(const string & strDomain,const string & strConfiguration,core::Results & errors)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 
saveConfiguration(const string & strDomain,const string & strConfiguration,string & strError)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
addConfigurableElementToDomain(const string & strDomain,const string & strConfigurableElementPath,string & strError)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 
removeConfigurableElementFromDomain(const string & strDomain,const string & strConfigurableElementPath,string & strError)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 
split(const string & strDomain,const string & strConfigurableElementPath,string & strError)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 
setElementSequence(const string & strDomain,const string & strConfiguration,const std::vector<string> & astrNewElementSequence,string & strError)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 
getApplicationRule(const string & strDomain,const string & strConfiguration,string & strResult)2518 bool CParameterMgr::getApplicationRule(const string &strDomain, const string &strConfiguration,
2519                                        string &strResult)
2520 {
2521     return getConfigurableDomains()->getApplicationRule(strDomain, strConfiguration, strResult);
2522 }
2523 
setApplicationRule(const string & strDomain,const string & strConfiguration,const string & strApplicationRule,string & strError)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 
clearApplicationRule(const string & strDomain,const string & strConfiguration,string & strError)2532 bool CParameterMgr::clearApplicationRule(const string &strDomain, const string &strConfiguration,
2533                                          string &strError)
2534 {
2535     return getConfigurableDomains()->clearApplicationRule(strDomain, strConfiguration, strError);
2536 }
2537 
importDomainsXml(const string & xmlSource,bool withSettings,bool fromFile,string & errorMsg)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 
importSingleDomainXml(const string & xmlSource,bool overwrite,bool withSettings,bool fromFile,string & errorMsg)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 
wrapLegacyXmlImport(const string & xmlSource,bool fromFile,bool withSettings,CElement & element,const string & nameAttributeName,string & errorMsg)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 
serializeElement(std::ostream & output,CXmlSerializingContext & xmlSerializingContext,const CElement & element) const2614 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 
exportDomainsXml(string & xmlDest,bool withSettings,bool toFile,string & errorMsg) const2636 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 
exportSingleDomainXml(string & xmlDest,const string & domainName,bool withSettings,bool toFile,string & errorMsg) const2647 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 
wrapLegacyXmlExport(string & xmlDest,bool toFile,bool withSettings,const CElement & element,string & errorMsg) const2664 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 
wrapLegacyXmlExportToFile(string & xmlDest,const CElement & element,CXmlDomainExportContext & context) const2677 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 
wrapLegacyXmlExportToString(string & xmlDest,const CElement & element,CXmlDomainExportContext & context) const2698 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
checkTuningModeOn(string & strError) const2713 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
getBlackboardMutex()2726 std::mutex &CParameterMgr::getBlackboardMutex()
2727 {
2728     return _blackboardMutex;
2729 }
2730 
2731 // Blackboard reference (dynamic parameter handling)
getParameterBlackboard()2732 CParameterBlackboard *CParameterMgr::getParameterBlackboard()
2733 {
2734     return _pMainParameterBlackboard;
2735 }
2736 
2737 // Dynamic creation library feeding
feedElementLibraries()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 
getForceNoRemoteInterface() const2815 bool CParameterMgr::getForceNoRemoteInterface() const
2816 {
2817     return _bForceNoRemoteInterface;
2818 }
2819 
setForceNoRemoteInterface(bool bForceNoRemoteInterface)2820 void CParameterMgr::setForceNoRemoteInterface(bool bForceNoRemoteInterface)
2821 {
2822     _bForceNoRemoteInterface = bForceNoRemoteInterface;
2823 }
2824 
createCommandHandler()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 
isRemoteInterfaceRequired()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
handleRemoteProcessingInterface(string & strError)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
getFrameworkConfiguration()2882 CParameterFrameworkConfiguration *CParameterMgr::getFrameworkConfiguration()
2883 {
2884     return static_cast<CParameterFrameworkConfiguration *>(getChild(EFrameworkConfiguration));
2885 }
2886 
getConstFrameworkConfiguration()2887 const CParameterFrameworkConfiguration *CParameterMgr::getConstFrameworkConfiguration()
2888 {
2889     return getFrameworkConfiguration();
2890 }
2891 
getSelectionCriteria()2892 CSelectionCriteria *CParameterMgr::getSelectionCriteria()
2893 {
2894     return static_cast<CSelectionCriteria *>(getChild(ESelectionCriteria));
2895 }
2896 
getConstSelectionCriteria()2897 const CSelectionCriteria *CParameterMgr::getConstSelectionCriteria()
2898 {
2899     return static_cast<const CSelectionCriteria *>(getChild(ESelectionCriteria));
2900 }
2901 
getSystemClass()2902 CSystemClass *CParameterMgr::getSystemClass()
2903 {
2904     return static_cast<CSystemClass *>(getChild(ESystemClass));
2905 }
2906 
getConstSystemClass() const2907 const CSystemClass *CParameterMgr::getConstSystemClass() const
2908 {
2909     return static_cast<const CSystemClass *>(getChild(ESystemClass));
2910 }
2911 
2912 // Configurable Domains
getConfigurableDomains()2913 CConfigurableDomains *CParameterMgr::getConfigurableDomains()
2914 {
2915     return static_cast<CConfigurableDomains *>(getChild(EConfigurableDomains));
2916 }
2917 
getConstConfigurableDomains()2918 const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains()
2919 {
2920     return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains));
2921 }
2922 
getConstConfigurableDomains() const2923 const CConfigurableDomains *CParameterMgr::getConstConfigurableDomains() const
2924 {
2925     return static_cast<const CConfigurableDomains *>(getChild(EConfigurableDomains));
2926 }
2927 
2928 // Apply configurations
doApplyConfigurations(bool bForce)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
exportElementToXMLString(const IXmlSource * pXmlSource,const string & strRootElementType,CXmlSerializingContext && xmlSerializingContext,string & strResult) const2949 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 
logResult(bool isSuccess,const std::string & result)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 
info()2982 log::details::Info CParameterMgr::info()
2983 {
2984     return _logger.info();
2985 }
2986 
warning()2987 log::details::Warning CParameterMgr::warning()
2988 {
2989     return _logger.warning();
2990 }
2991