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