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, ¶meterBlackboard, 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