1 /*
2  * Copyright (c) 2011-2014, 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 #pragma once
31 
32 #include "ConfigurableElement.h"
33 #include "ConfigurableElementWithMapping.h"
34 #include "Mapper.h"
35 #include "MappingContext.h"
36 #include <list>
37 #include <stack>
38 #include <string>
39 #include <vector>
40 
41 class CInstanceDefinition;
42 class CComponentLibrary;
43 class CSubsystemObject;
44 class CSubsystemObjectCreator;
45 class CInstanceConfigurableElement;
46 class CMappingData;
47 
48 class CSubsystem : public CConfigurableElementWithMapping, private IMapper
49 {
50     // Subsystem objects iterator
51     typedef std::list<CSubsystemObject*>::const_iterator SubsystemObjectListIterator;
52 public:
53     CSubsystem(const std::string& strName);
54     virtual ~CSubsystem();
55 
56     // From IXmlSink
57     virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
58 
59     // Susbsystem Endianness
60     bool isBigEndian() const;
61 
62     // Susbsystem sanity
63     virtual bool isAlive() const;
64 
65     // Resynchronization after subsystem restart needed
66     virtual bool needResync(bool bClear);
67 
68     // XML configuration settings parsing
69     virtual bool serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const;
70 
71     // from CElement
72     virtual std::string getKind() const;
73 
74     virtual bool getMappingData(const std::string& strKey, const std::string*& pStrValue) const;
75 
76     /**
77      * Fetch mapping data of an element.
78      *
79      * The mapping is represented as a std::string of all the mapping data (key:value) defined in the
80      * context of the element.
81      * This method gathers the mapping data found in each Element of the configurableElementPath
82      * list to format the resulting std::string.
83      *
84      * @param[in] configurableElementPath List of all the ConfigurableElements found
85      * that have a mapping. Elements are added at the end of the list, so the root Element will be
86      * the last one.
87      *
88      * @return Formatted std::string of the mapping data
89      */
90     virtual std::string getMapping(std::list<const CConfigurableElement*>& configurableElementPath) const;
91 
92 protected:
93     // Parameter access
94     virtual bool accessValue(CPathNavigator& pathNavigator, std::string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const;
95     virtual void logValue(std::string& strValue, CErrorContext& errorContext) const;
96     // Used for simulation and virtual subsystems
97     virtual void setDefaultValues(CParameterAccessContext& parameterAccessContext) const;
98 
99     /// Functionality intendedn for derived Subsystems
100     // Subsystem context mapping keys publication
101     void addContextMappingKey(const std::string& strMappingKey);
102     // Subsystem object creator publication (strong reference)
103     void addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator);
104 private:
105     CSubsystem(const CSubsystem&);
106     CSubsystem& operator=(const CSubsystem&);
107 
108     // Belonging subsystem
109     virtual const CSubsystem* getBelongingSubsystem() const;
110 
111     // Mapping execution
112     bool mapSubsystemElements(std::string& strError);
113 
114     /**
115      * Handle a configurable element mapping.
116      *
117      * Add context mappings to the context and instantiate a subsystem object if needed.
118      *
119      * @param[in:out] pInstanceConfigurableElement The configurable element
120      * @param[out] bKeepDiving Keep diving for mapping keys
121                    Is set to true if a subsystem object (tree leave) has been instantiated.
122                    Undetermined on error
123      * @param[out] strError String filled with an human readable error on error,
124                    left unmodified otherwise
125      *
126      * @return true on success, false on failure
127      */
128     virtual bool mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, bool& bKeepDiving, std::string& strError);
129     virtual void mapEnd();
130 
131     // Mapping access
132     /**
133      * Generic mapping error handling
134      *
135      * Format an human readable error std::string from a key and a message in case of mapping error
136      *
137      * @param[in] strKey The key on which the error refers
138      * @param[in] strMessage The error message
139      * @param[in] pConfigurableElementWithMapping The element on which the error refers
140      *
141      * returns The formated error std::string
142      */
143     std::string getMappingError(
144             const std::string& strKey,
145             const std::string& strMessage,
146             const CConfigurableElementWithMapping* pConfigurableElementWithMapping) const;
147 
148     /**
149      * Format the mapping data of the ConfigurableElements that have been gathered through recursive
150      * calls to the getMapping() method.
151      * These elements shall be evaluated from the root level to the leaves level, so the list must
152      * be parsed in reverse order.
153      *
154      * @param[in] configurableElementPath List of ConfigurableElements containing mapping data
155      *
156      * @return String containing the formatted mapping
157      */
158     std::string formatMappingDataList(
159             const std::list<const CConfigurableElement*>& configurableElementPath) const;
160 
161     /**
162      * Find the SubystemObject which contains a specific CInstanceConfigurableElement.
163      *
164      * @param[in] pInstanceConfigurableElement The CInstanceConfigurableElement that is related to
165      * the wanted SubsystemObject. Each SubsystemObject of the Subystem internal list is checked in
166      * order to find a match.
167      *
168      * @return A pointer to the SubsystemObject related to pInstanceConfigurableElement
169      */
170     const CSubsystemObject* findSubsystemObjectFromConfigurableElement(
171             const CInstanceConfigurableElement* pInstanceConfigurableElement) const;
172 
173     /**
174      * Find the mapping data defined for the CInstanceConfigurableElement given in parameter, that
175      * corresponds to Subsystem level mapping (Subsystem level mapping keys are defined in
176      * CSubsystemObjectCreator classes).
177      * The CInstanceConfigurableElement might as well contain local mapping data.
178      *
179      * @param[in] pInstanceConfigurableElement The element which mapping data will be parsed for
180      * a match
181      * @param[out] strMappingKey Mapping key defined at the Subsystem level
182      * @param[out] strMappingValue Mapping value contained in pInstanceConfigurableElement
183      */
184     void findSubsystemLevelMappingKeyValue(
185             const CInstanceConfigurableElement* pInstanceConfigurableElement,
186             std::string& strMappingKey,
187             std::string& strMappingValue) const;
188 
189     /**
190      * Formats the mapping of a SubsystemObject
191      *
192      * @param[in] pInstanceConfigurableElement Element corresponding to a SubsystemObject
193      *
194      * @return String containing the formatted mapping
195      */
196     std::string getFormattedSubsystemMappingData(
197             const CInstanceConfigurableElement* pInstanceConfigurableElement) const;
198     /**
199      * Generic context handling
200      *
201      * Feed context with mapping data of the current element
202      *
203      * @param[in] pConfigurableElementWithMapping The element containing mapping data
204      * @param[out] context The context mapping to update with the current element mapping values
205      * @param[out] strError The formated error std::string
206      *
207      * @return true on success
208      */
209     bool handleMappingContext(
210             const CConfigurableElementWithMapping* pConfigurableElementWithMapping,
211             CMappingContext& context,
212             std::string& strError) const;
213 
214     /**
215      * Looks if a subsystem object needs to be instantiated for the given configurable
216      * element, then instantiate it if needed.
217      *
218      * @param[in:out] pInstanceConfigurableElement The configurable element to check
219      *            for instanciation
220      * @param[in] context The mapping values container
221      * @param[out] bHasCreatedSubsystemObject If a subsystem object has been instantiated.
222                    Undetermined on error
223      * @param[out] strError String filled with an human readable error on error,
224                    left unmodified otherwise
225      *
226      * @return true on success, false on failure
227      */
228     bool handleSubsystemObjectCreation(CInstanceConfigurableElement* pInstanceConfigurableElement,
229                                        CMappingContext& context, bool& bHasCreatedSubsystemObject,
230                                        std::string& strError);
231 
232     // Subsystem context mapping keys
233     std::vector<std::string> _contextMappingKeyArray;
234 
235     // Subsystem object creator map
236     std::vector<CSubsystemObjectCreator*> _subsystemObjectCreatorArray;
237 
238     // Subsystem sync objects (house keeping)
239     std::list<CSubsystemObject*> _subsystemObjectList;
240 
241     // Mapping Context stack
242     std::stack<CMappingContext> _contextStack;
243 
244     // Subelements
245     CComponentLibrary* _pComponentLibrary;
246     CInstanceDefinition* _pInstanceDefinition;
247 
248     // Endianness
249     bool _bBigEndian;
250 
251     //! Contains the mapping info at Subsystem level
252     CMappingData* _pMappingData;
253 };
254