blob: 8efec1fee2eacedeee7767239d9f0722191aed5e [file] [log] [blame]
Kevin Rocard93250d12012-07-19 17:48:30 +02001/*
David Wagnerb76c9d62014-02-05 18:30:24 +01002 * 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.
Patrick Benavoli68a91282011-08-31 11:23:23 +020029 */
30#include "Message.h"
31#include <assert.h>
32#include "Socket.h"
33#include "RemoteProcessorProtocol.h"
34#include <string.h>
35#include <assert.h>
36
37CMessage::CMessage(uint8_t ucMsgId) : _ucMsgId(ucMsgId), _pucData(NULL), _uiDataSize(0), _uiIndex(0)
38{
39}
40
Patrick Benavoli930075c2011-08-31 17:09:06 +020041CMessage::CMessage() : _ucMsgId((uint8_t)-1), _pucData(NULL), _uiDataSize(0), _uiIndex(0)
Patrick Benavoli68a91282011-08-31 11:23:23 +020042{
43}
44
45CMessage::~CMessage()
46{
47 delete [] _pucData;
48}
49
50// Msg Id
51uint8_t CMessage::getMsgId() const
52{
53 return _ucMsgId;
54}
55
56// Data
57void CMessage::writeData(const void* pvData, uint32_t uiSize)
58{
59 assert(_uiIndex + uiSize <= _uiDataSize);
60
61 // Copy
62 memcpy(&_pucData[_uiIndex], pvData, uiSize);
63
64 // Index
65 _uiIndex += uiSize;
66}
67
68void CMessage::readData(void* pvData, uint32_t uiSize)
69{
70 assert(_uiIndex + uiSize <= _uiDataSize);
71
72 // Copy
73 memcpy(pvData, &_pucData[_uiIndex], uiSize);
74
75 // Index
76 _uiIndex += uiSize;
77}
78
79void CMessage::writeString(const string& strData)
80{
81 // Size
82 uint32_t uiSize = strData.length();
83
84 writeData(&uiSize, sizeof(uiSize));
85
86 // Content
87 writeData(strData.c_str(), uiSize);
88}
89
90void CMessage::readString(string& strData)
91{
92 // Size
93 uint32_t uiSize;
94
95 readData(&uiSize, sizeof(uiSize));
96
97 // Data
98 char* pcData = new char[uiSize + 1];
99
100 // Content
101 readData(pcData, uiSize);
102
103 // NULL-terminate string
104 pcData[uiSize] = '\0';
105
106 // Output
107 strData = pcData;
108
109 // Delete
110 delete [] pcData;
111}
112
113uint32_t CMessage::getStringSize(const string& strData) const
114{
115 // Return string length plus room to store its length
116 return strData.length() + sizeof(uint32_t);
117}
118
119// Remaining data size
120uint32_t CMessage::getRemainingDataSize() const
121{
122 return _uiDataSize - _uiIndex;
123}
124
125// Send/Receive
126bool CMessage::serialize(CSocket* pSocket, bool bOut)
127{
128 if (bOut) {
129
130 // Make room for data to send
131 allocateData(getDataSize());
132
133 // Get data from derived
134 fillDataToSend();
135
136 // Finished providing data?
137 assert(_uiIndex == _uiDataSize);
138
139 // First send sync word
140 uint16_t uiSyncWord = SYNC_WORD;
141
142 if (!pSocket->write(&uiSyncWord, sizeof(uiSyncWord))) {
143
144 return false;
145 }
146
147 // Size
148 uint32_t uiSize = sizeof(_ucMsgId) + _uiDataSize;
149
150 if (!pSocket->write(&uiSize, sizeof(uiSize))) {
151
152 return false;
153 }
154
155 // Msg Id
156 if (!pSocket->write(&_ucMsgId, sizeof(_ucMsgId))) {
157
158 return false;
159 }
160
161 // Data
162 if (!pSocket->write(_pucData, _uiDataSize)) {
163
164 return false;
165 }
166
167 // Checksum
168 uint8_t ucChecksum = computeChecksum();
169
170 if (!pSocket->write(&ucChecksum, sizeof(ucChecksum))) {
171
172 return false;
173 }
174
175 } else {
176 // First read sync word
177 uint16_t uiSyncWord;
178
179 if (!pSocket->read(&uiSyncWord, sizeof(uiSyncWord))) {
180
181 return false;
182 }
183
184 // Check Sync word
185 if (uiSyncWord != SYNC_WORD) {
186
187 return false;
188 }
189
190 // Size
191 uint32_t uiSize;
192
193 if (!pSocket->read(&uiSize, sizeof(uiSize))) {
194
195 return false;
196 }
197
198 // Msg Id
199 if (!pSocket->read(&_ucMsgId, sizeof(_ucMsgId))) {
200
201 return false;
202 }
203
204 // Data
205
206 // Allocate
207 allocateData(uiSize - sizeof(_ucMsgId));
208
209 // Data receive
210 if (!pSocket->read(_pucData, _uiDataSize)) {
211
212 return false;
213 }
214
215 // Checksum
216 uint8_t ucChecksum;
217
218 if (!pSocket->read(&ucChecksum, sizeof(ucChecksum))) {
219
220 return false;
221 }
222 // Compare
223 if (ucChecksum != computeChecksum()) {
224
225 return false;
226 }
227
228 // Collect data in derived
229 collectReceivedData();
230 }
231
232 return true;
233}
234
235// Checksum
236uint8_t CMessage::computeChecksum() const
237{
Patrick Benavoli1387bda2011-08-31 11:23:24 +0200238 uint8_t uiChecksum = _ucMsgId;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200239
240 uint32_t uiIndex;
241
242 for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) {
243
244 uiChecksum += _pucData[uiIndex];
245 }
246
247 return uiChecksum;
248}
249
250// Data allocation
251void CMessage::allocateData(uint32_t uiSize)
252{
253 // Remove previous one
254 if (_pucData) {
255
256 delete [] _pucData;
257 }
258 // Do allocate
259 _pucData = new uint8_t[uiSize];
260
261 // Record size
262 _uiDataSize = uiSize;
263
264 // Reset Index
265 _uiIndex = 0;
266}