blob: f01d58386df71d5e163ab51ae361c06969ef29d3 [file] [log] [blame]
Kevin Rocard93250d12012-07-19 17:48:30 +02001/*
Patrick Benavoli68a91282011-08-31 11:23:23 +02002 * INTEL CONFIDENTIAL
3 * Copyright © 2011 Intel
4 * Corporation All Rights Reserved.
5 *
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material contains trade secrets and proprietary
10 * and confidential information of Intel or its suppliers and licensors. The
11 * Material is protected by worldwide copyright and trade secret laws and
12 * treaty provisions. No part of the Material may be used, copied, reproduced,
13 * modified, published, uploaded, posted, transmitted, distributed, or
14 * disclosed in any way without Intel’s prior express written permission.
15 *
16 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Intel in writing.
21 *
Patrick Benavoli68a91282011-08-31 11:23:23 +020022 * CREATED: 2011-06-01
23 * UPDATED: 2011-07-27
Patrick Benavoli68a91282011-08-31 11:23:23 +020024 */
25#include "Message.h"
26#include <assert.h>
27#include "Socket.h"
28#include "RemoteProcessorProtocol.h"
29#include <string.h>
30#include <assert.h>
31
32CMessage::CMessage(uint8_t ucMsgId) : _ucMsgId(ucMsgId), _pucData(NULL), _uiDataSize(0), _uiIndex(0)
33{
34}
35
Patrick Benavoli930075c2011-08-31 17:09:06 +020036CMessage::CMessage() : _ucMsgId((uint8_t)-1), _pucData(NULL), _uiDataSize(0), _uiIndex(0)
Patrick Benavoli68a91282011-08-31 11:23:23 +020037{
38}
39
40CMessage::~CMessage()
41{
42 delete [] _pucData;
43}
44
45// Msg Id
46uint8_t CMessage::getMsgId() const
47{
48 return _ucMsgId;
49}
50
51// Data
52void CMessage::writeData(const void* pvData, uint32_t uiSize)
53{
54 assert(_uiIndex + uiSize <= _uiDataSize);
55
56 // Copy
57 memcpy(&_pucData[_uiIndex], pvData, uiSize);
58
59 // Index
60 _uiIndex += uiSize;
61}
62
63void CMessage::readData(void* pvData, uint32_t uiSize)
64{
65 assert(_uiIndex + uiSize <= _uiDataSize);
66
67 // Copy
68 memcpy(pvData, &_pucData[_uiIndex], uiSize);
69
70 // Index
71 _uiIndex += uiSize;
72}
73
74void CMessage::writeString(const string& strData)
75{
76 // Size
77 uint32_t uiSize = strData.length();
78
79 writeData(&uiSize, sizeof(uiSize));
80
81 // Content
82 writeData(strData.c_str(), uiSize);
83}
84
85void CMessage::readString(string& strData)
86{
87 // Size
88 uint32_t uiSize;
89
90 readData(&uiSize, sizeof(uiSize));
91
92 // Data
93 char* pcData = new char[uiSize + 1];
94
95 // Content
96 readData(pcData, uiSize);
97
98 // NULL-terminate string
99 pcData[uiSize] = '\0';
100
101 // Output
102 strData = pcData;
103
104 // Delete
105 delete [] pcData;
106}
107
108uint32_t CMessage::getStringSize(const string& strData) const
109{
110 // Return string length plus room to store its length
111 return strData.length() + sizeof(uint32_t);
112}
113
114// Remaining data size
115uint32_t CMessage::getRemainingDataSize() const
116{
117 return _uiDataSize - _uiIndex;
118}
119
120// Send/Receive
121bool CMessage::serialize(CSocket* pSocket, bool bOut)
122{
123 if (bOut) {
124
125 // Make room for data to send
126 allocateData(getDataSize());
127
128 // Get data from derived
129 fillDataToSend();
130
131 // Finished providing data?
132 assert(_uiIndex == _uiDataSize);
133
134 // First send sync word
135 uint16_t uiSyncWord = SYNC_WORD;
136
137 if (!pSocket->write(&uiSyncWord, sizeof(uiSyncWord))) {
138
139 return false;
140 }
141
142 // Size
143 uint32_t uiSize = sizeof(_ucMsgId) + _uiDataSize;
144
145 if (!pSocket->write(&uiSize, sizeof(uiSize))) {
146
147 return false;
148 }
149
150 // Msg Id
151 if (!pSocket->write(&_ucMsgId, sizeof(_ucMsgId))) {
152
153 return false;
154 }
155
156 // Data
157 if (!pSocket->write(_pucData, _uiDataSize)) {
158
159 return false;
160 }
161
162 // Checksum
163 uint8_t ucChecksum = computeChecksum();
164
165 if (!pSocket->write(&ucChecksum, sizeof(ucChecksum))) {
166
167 return false;
168 }
169
170 } else {
171 // First read sync word
172 uint16_t uiSyncWord;
173
174 if (!pSocket->read(&uiSyncWord, sizeof(uiSyncWord))) {
175
176 return false;
177 }
178
179 // Check Sync word
180 if (uiSyncWord != SYNC_WORD) {
181
182 return false;
183 }
184
185 // Size
186 uint32_t uiSize;
187
188 if (!pSocket->read(&uiSize, sizeof(uiSize))) {
189
190 return false;
191 }
192
193 // Msg Id
194 if (!pSocket->read(&_ucMsgId, sizeof(_ucMsgId))) {
195
196 return false;
197 }
198
199 // Data
200
201 // Allocate
202 allocateData(uiSize - sizeof(_ucMsgId));
203
204 // Data receive
205 if (!pSocket->read(_pucData, _uiDataSize)) {
206
207 return false;
208 }
209
210 // Checksum
211 uint8_t ucChecksum;
212
213 if (!pSocket->read(&ucChecksum, sizeof(ucChecksum))) {
214
215 return false;
216 }
217 // Compare
218 if (ucChecksum != computeChecksum()) {
219
220 return false;
221 }
222
223 // Collect data in derived
224 collectReceivedData();
225 }
226
227 return true;
228}
229
230// Checksum
231uint8_t CMessage::computeChecksum() const
232{
Patrick Benavoli1387bda2011-08-31 11:23:24 +0200233 uint8_t uiChecksum = _ucMsgId;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200234
235 uint32_t uiIndex;
236
237 for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) {
238
239 uiChecksum += _pucData[uiIndex];
240 }
241
242 return uiChecksum;
243}
244
245// Data allocation
246void CMessage::allocateData(uint32_t uiSize)
247{
248 // Remove previous one
249 if (_pucData) {
250
251 delete [] _pucData;
252 }
253 // Do allocate
254 _pucData = new uint8_t[uiSize];
255
256 // Record size
257 _uiDataSize = uiSize;
258
259 // Reset Index
260 _uiIndex = 0;
261}