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 #include "SubsystemObject.h"
31 #include "Subsystem.h"
32 #include "InstanceConfigurableElement.h"
33 #include "ParameterBlackboard.h"
34 #include "ParameterAccessContext.h"
35 #include "MappingContext.h"
36 #include "ParameterType.h"
37 #include <assert.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sstream>
41 #include <stdarg.h>
42 
43 using std::string;
44 
CSubsystemObject(CInstanceConfigurableElement * pInstanceConfigurableElement)45 CSubsystemObject::CSubsystemObject(CInstanceConfigurableElement* pInstanceConfigurableElement)
46     : _pInstanceConfigurableElement(pInstanceConfigurableElement),
47       _uiDataSize(pInstanceConfigurableElement->getFootPrint()),
48       _pucBlackboardLocation(NULL),
49       _uiAccessedIndex(0)
50 {
51     // Syncer
52     _pInstanceConfigurableElement->setSyncer(this);
53 }
54 
~CSubsystemObject()55 CSubsystemObject::~CSubsystemObject()
56 {
57     _pInstanceConfigurableElement->unsetSyncer();
58 }
59 
getFormattedMappingValue() const60 string CSubsystemObject::getFormattedMappingValue() const
61 {
62     // Default formatted mapping value is empty
63     return "";
64 }
65 
66 // Blackboard data location
getBlackboardLocation() const67 uint8_t* CSubsystemObject::getBlackboardLocation() const
68 {
69     return _pucBlackboardLocation;
70 }
71 
72 // Size
getSize() const73 uint32_t CSubsystemObject::getSize() const
74 {
75     return _uiDataSize;
76 }
77 
78 // Conversion utility
asInteger(const string & strValue)79 uint32_t CSubsystemObject::asInteger(const string& strValue)
80 {
81     return strtoul(strValue.c_str(), NULL, 0);
82 }
83 
asString(uint32_t uiValue)84 string CSubsystemObject::asString(uint32_t uiValue)
85 {
86     std::ostringstream ostr;
87 
88     ostr << uiValue;
89 
90     return ostr.str();
91 }
92 
toPlainInteger(const CInstanceConfigurableElement * instanceConfigurableElement,int sizeOptimizedData)93 int CSubsystemObject::toPlainInteger(
94         const CInstanceConfigurableElement *instanceConfigurableElement,
95         int sizeOptimizedData)
96 {
97     if (instanceConfigurableElement) {
98 
99         // Get actual element type
100         const CTypeElement *typeElement =
101             static_cast<const CParameterType *>(instanceConfigurableElement->getTypeElement());
102 
103         // Do the extension
104         return typeElement->toPlainInteger(sizeOptimizedData);
105     }
106 
107     return sizeOptimizedData;
108 }
109 
110 // Default back synchronization
setDefaultValues(CParameterBlackboard & parameterBlackboard) const111 void CSubsystemObject::setDefaultValues(CParameterBlackboard& parameterBlackboard) const
112 {
113     string strError;
114 
115     // Create access context
116     CParameterAccessContext parameterAccessContext(strError, &parameterBlackboard, false);
117 
118     // Just implement back synchronization with default values
119     _pInstanceConfigurableElement->setDefaultValues(parameterAccessContext);
120 }
121 
122 // Synchronization
sync(CParameterBlackboard & parameterBlackboard,bool bBack,string & strError)123 bool CSubsystemObject::sync(CParameterBlackboard& parameterBlackboard, bool bBack, string& strError)
124 {
125     // Get blackboard location
126     _pucBlackboardLocation = parameterBlackboard.getLocation(_pInstanceConfigurableElement->getOffset());
127     // Access index init
128     _uiAccessedIndex = 0;
129 
130 #ifdef SIMULATION
131     return true;
132 #endif
133 
134     // Retrieve subsystem
135     const CSubsystem* pSubsystem = _pInstanceConfigurableElement->getBelongingSubsystem();
136 
137     // Get it's health insdicator
138     bool bIsSubsystemAlive = pSubsystem->isAlive();
139 
140     // Check subsystem health
141     if (!bIsSubsystemAlive) {
142 
143         strError = "Susbsystem not alive";
144     }
145 
146     // Synchronize to/from HW
147     if (!bIsSubsystemAlive || !accessHW(bBack, strError)) {
148 
149         strError = string("Unable to ") + (bBack ? "back" : "forward") + " synchronize configurable element " +
150                 _pInstanceConfigurableElement->getPath() + ": " + strError;
151 
152         log_warning("%s", strError.c_str());
153 
154         // Fall back to parameter default initialization
155         if (bBack) {
156 
157            setDefaultValues(parameterBlackboard);
158         }
159         return false;
160     }
161 
162     return true;
163 }
164 
165 // Sync to/from HW
sendToHW(string & strError)166 bool CSubsystemObject::sendToHW(string& strError)
167 {
168     strError = "Send to HW interface not implemented at subsystem level";
169 
170     return false;
171 }
172 
receiveFromHW(string & strError)173 bool CSubsystemObject::receiveFromHW(string& strError)
174 {
175     (void)strError;
176 
177     // Back synchronization is not supported at subsystem level.
178     // Rely on blackboard content
179 
180     return true;
181 }
182 
183 // Fall back HW access
accessHW(bool bReceive,string & strError)184 bool CSubsystemObject::accessHW(bool bReceive, string& strError)
185 {
186     // Default access fall back
187     if (bReceive) {
188 
189         return receiveFromHW(strError);
190     } else {
191 
192         return sendToHW(strError);
193     }
194 }
195 
196 // Blackboard access from subsystems
blackboardRead(void * pvData,uint32_t uiSize)197 void CSubsystemObject::blackboardRead(void* pvData, uint32_t uiSize)
198 {
199     assert(_uiAccessedIndex + uiSize <= _uiDataSize);
200 
201     memcpy(pvData, _pucBlackboardLocation + _uiAccessedIndex, uiSize);
202 
203     _uiAccessedIndex += uiSize;
204 }
205 
blackboardWrite(const void * pvData,uint32_t uiSize)206 void CSubsystemObject::blackboardWrite(const void* pvData, uint32_t uiSize)
207 {
208     assert(_uiAccessedIndex + uiSize <= _uiDataSize);
209 
210     memcpy(_pucBlackboardLocation + _uiAccessedIndex, pvData, uiSize);
211 
212     _uiAccessedIndex += uiSize;
213 }
214 
215 // Logging
log_info(std::string strMessage,...) const216 void CSubsystemObject::log_info(std::string strMessage, ...) const
217 {
218     char *pacBuffer;
219     va_list listPointer;
220 
221     va_start(listPointer, strMessage);
222 
223     vasprintf(&pacBuffer, strMessage.c_str(), listPointer);
224 
225     va_end(listPointer);
226 
227     if (pacBuffer != NULL) {
228         _pInstanceConfigurableElement->log_info("%s", pacBuffer);
229     }
230 
231     free(pacBuffer);
232 }
233 
log_warning(std::string strMessage,...) const234 void CSubsystemObject::log_warning(std::string strMessage, ...) const
235 {
236     char *pacBuffer;
237     va_list listPointer;
238 
239     va_start(listPointer, strMessage);
240 
241     vasprintf(&pacBuffer, strMessage.c_str(), listPointer);
242 
243     va_end(listPointer);
244 
245     if (pacBuffer != NULL) {
246         _pInstanceConfigurableElement->log_warning("%s", pacBuffer);
247     }
248 
249     free(pacBuffer);
250 }
251 
252 // Configurable element retrieval
getConfigurableElement() const253 const CInstanceConfigurableElement* CSubsystemObject::getConfigurableElement() const
254 {
255     return _pInstanceConfigurableElement;
256 }
257 // Belonging Subsystem retrieval
getSubsystem() const258 const CSubsystem* CSubsystemObject::getSubsystem() const
259 {
260     return _pInstanceConfigurableElement->getBelongingSubsystem();
261 }
262