1/*
2 * Copyright (c) 2011-2015, 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 "convert.hpp"
38#include <assert.h>
39#include <stdlib.h>
40#include <string.h>
41#include <sstream>
42#include <stdarg.h>
43
44using std::string;
45
46CSubsystemObject::CSubsystemObject(CInstanceConfigurableElement *pInstanceConfigurableElement,
47                                   core::log::Logger &logger)
48    : _logger(logger), _pInstanceConfigurableElement(pInstanceConfigurableElement),
49      _dataSize(pInstanceConfigurableElement->getFootPrint())
50{
51    // Syncer
52    _pInstanceConfigurableElement->setSyncer(this);
53}
54
55CSubsystemObject::~CSubsystemObject()
56{
57    _pInstanceConfigurableElement->unsetSyncer();
58}
59
60string CSubsystemObject::getFormattedMappingValue() const
61{
62    // Default formatted mapping value is empty
63    return "";
64}
65
66// Blackboard data location
67uint8_t *CSubsystemObject::getBlackboardLocation() const
68{
69    return _blackboard->getLocation(getOffset());
70}
71
72// Size
73size_t CSubsystemObject::getSize() const
74{
75    return _dataSize;
76}
77
78int CSubsystemObject::toPlainInteger(
79    const CInstanceConfigurableElement *instanceConfigurableElement, int sizeOptimizedData)
80{
81    if (instanceConfigurableElement) {
82
83        // Get actual element type
84        const CTypeElement *typeElement =
85            static_cast<const CParameterType *>(instanceConfigurableElement->getTypeElement());
86
87        // Do the extension
88        return typeElement->toPlainInteger(sizeOptimizedData);
89    }
90
91    return sizeOptimizedData;
92}
93
94// Default back synchronization
95void CSubsystemObject::setDefaultValues(CParameterBlackboard &parameterBlackboard) const
96{
97    string strError;
98
99    // Create access context
100    CParameterAccessContext parameterAccessContext(strError, &parameterBlackboard);
101
102    // Just implement back synchronization with default values
103    _pInstanceConfigurableElement->setDefaultValues(parameterAccessContext);
104}
105
106// Synchronization
107bool CSubsystemObject::sync(CParameterBlackboard &parameterBlackboard, bool bBack, string &strError)
108{
109    // Get blackboard location
110    _blackboard = &parameterBlackboard;
111    // Access index init
112    _accessedIndex = 0;
113
114#ifdef SIMULATION
115    return true;
116#endif
117
118    // Retrieve subsystem
119    const CSubsystem *pSubsystem = _pInstanceConfigurableElement->getBelongingSubsystem();
120
121    // Get it's health insdicator
122    bool bIsSubsystemAlive = pSubsystem->isAlive();
123
124    // Check subsystem health
125    if (!bIsSubsystemAlive) {
126
127        strError = "Susbsystem not alive";
128    }
129
130    // Synchronize to/from HW
131    if (!bIsSubsystemAlive || !accessHW(bBack, strError)) {
132
133        // Fall back to parameter default initialization
134        if (bBack) {
135
136            setDefaultValues(parameterBlackboard);
137        }
138        return false;
139    }
140
141    return true;
142}
143
144// Sync to/from HW
145bool CSubsystemObject::sendToHW(string &strError)
146{
147    strError = "Send to HW interface not implemented at subsystem level";
148
149    return false;
150}
151
152bool CSubsystemObject::receiveFromHW(string & /*strError*/)
153{
154    // Back synchronization is not supported at subsystem level.
155    // Rely on blackboard content
156
157    return true;
158}
159
160// Fall back HW access
161bool CSubsystemObject::accessHW(bool bReceive, string &strError)
162{
163    // Default access fall back
164    if (bReceive) {
165
166        return receiveFromHW(strError);
167    } else {
168
169        return sendToHW(strError);
170    }
171}
172
173// Blackboard access from subsystems
174void CSubsystemObject::blackboardRead(void *pvData, size_t size)
175{
176    _blackboard->readBuffer(pvData, size, getOffset() + _accessedIndex);
177
178    _accessedIndex += size;
179}
180
181void CSubsystemObject::blackboardWrite(const void *pvData, size_t size)
182{
183    _blackboard->writeBuffer(pvData, size, getOffset() + _accessedIndex);
184
185    _accessedIndex += size;
186}
187
188// Configurable element retrieval
189const CInstanceConfigurableElement *CSubsystemObject::getConfigurableElement() const
190{
191    return _pInstanceConfigurableElement;
192}
193// Belonging Subsystem retrieval
194const CSubsystem *CSubsystemObject::getSubsystem() const
195{
196    return _pInstanceConfigurableElement->getBelongingSubsystem();
197}
198
199size_t CSubsystemObject::getOffset() const
200{
201    return _pInstanceConfigurableElement->getOffset();
202}
203