1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Execution Server
3*35238bceSAndroid Build Coastguard Worker * ---------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Execution Server Protocol.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "xsProtocol.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker using std::string;
27*35238bceSAndroid Build Coastguard Worker using std::vector;
28*35238bceSAndroid Build Coastguard Worker
29*35238bceSAndroid Build Coastguard Worker namespace xs
30*35238bceSAndroid Build Coastguard Worker {
31*35238bceSAndroid Build Coastguard Worker
swapEndianess(uint32_t value)32*35238bceSAndroid Build Coastguard Worker inline uint32_t swapEndianess(uint32_t value)
33*35238bceSAndroid Build Coastguard Worker {
34*35238bceSAndroid Build Coastguard Worker uint32_t b0 = (value >> 0) & 0xFF;
35*35238bceSAndroid Build Coastguard Worker uint32_t b1 = (value >> 8) & 0xFF;
36*35238bceSAndroid Build Coastguard Worker uint32_t b2 = (value >> 16) & 0xFF;
37*35238bceSAndroid Build Coastguard Worker uint32_t b3 = (value >> 24) & 0xFF;
38*35238bceSAndroid Build Coastguard Worker return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
39*35238bceSAndroid Build Coastguard Worker }
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker template <typename T>
42*35238bceSAndroid Build Coastguard Worker T networkToHost(T value);
43*35238bceSAndroid Build Coastguard Worker template <typename T>
44*35238bceSAndroid Build Coastguard Worker T hostToNetwork(T value);
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker template <>
networkToHost(int value)47*35238bceSAndroid Build Coastguard Worker int networkToHost(int value)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker return (int)swapEndianess((uint32_t)value);
50*35238bceSAndroid Build Coastguard Worker }
51*35238bceSAndroid Build Coastguard Worker template <>
hostToNetwork(int value)52*35238bceSAndroid Build Coastguard Worker int hostToNetwork(int value)
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker return (int)swapEndianess((uint32_t)value);
55*35238bceSAndroid Build Coastguard Worker }
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker class MessageParser
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker public:
MessageParser(const uint8_t * data,size_t dataSize)60*35238bceSAndroid Build Coastguard Worker MessageParser(const uint8_t *data, size_t dataSize) : m_data(data), m_size(dataSize), m_pos(0)
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker }
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker template <typename T>
get(void)65*35238bceSAndroid Build Coastguard Worker T get(void)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker XS_CHECK_MSG(m_pos + sizeof(T) <= m_size, "Invalid payload size");
68*35238bceSAndroid Build Coastguard Worker T netValue;
69*35238bceSAndroid Build Coastguard Worker deMemcpy(&netValue, &m_data[m_pos], sizeof(T));
70*35238bceSAndroid Build Coastguard Worker m_pos += sizeof(T);
71*35238bceSAndroid Build Coastguard Worker return networkToHost(netValue);
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker
getString(std::string & dst)74*35238bceSAndroid Build Coastguard Worker void getString(std::string &dst)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker // \todo [2011-09-30 pyry] We should really send a size parameter instead.
77*35238bceSAndroid Build Coastguard Worker while (m_data[m_pos] != 0)
78*35238bceSAndroid Build Coastguard Worker {
79*35238bceSAndroid Build Coastguard Worker dst += (char)m_data[m_pos++];
80*35238bceSAndroid Build Coastguard Worker XS_CHECK_MSG(m_pos < m_size, "Unterminated string payload");
81*35238bceSAndroid Build Coastguard Worker }
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker m_pos += 1;
84*35238bceSAndroid Build Coastguard Worker }
85*35238bceSAndroid Build Coastguard Worker
assumEnd(void)86*35238bceSAndroid Build Coastguard Worker void assumEnd(void)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker if (m_pos != m_size)
89*35238bceSAndroid Build Coastguard Worker XS_FAIL("Invalid payload size");
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker private:
93*35238bceSAndroid Build Coastguard Worker const uint8_t *m_data;
94*35238bceSAndroid Build Coastguard Worker size_t m_size;
95*35238bceSAndroid Build Coastguard Worker size_t m_pos;
96*35238bceSAndroid Build Coastguard Worker };
97*35238bceSAndroid Build Coastguard Worker
98*35238bceSAndroid Build Coastguard Worker class MessageWriter
99*35238bceSAndroid Build Coastguard Worker {
100*35238bceSAndroid Build Coastguard Worker public:
MessageWriter(MessageType msgType,std::vector<uint8_t> & buf)101*35238bceSAndroid Build Coastguard Worker MessageWriter(MessageType msgType, std::vector<uint8_t> &buf) : m_buf(buf)
102*35238bceSAndroid Build Coastguard Worker {
103*35238bceSAndroid Build Coastguard Worker // Place for size.
104*35238bceSAndroid Build Coastguard Worker put<int>(0);
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker // Write message type.
107*35238bceSAndroid Build Coastguard Worker put<int>(msgType);
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker
~MessageWriter(void)110*35238bceSAndroid Build Coastguard Worker ~MessageWriter(void)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker finalize();
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker
finalize(void)115*35238bceSAndroid Build Coastguard Worker void finalize(void)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_buf.size() >= MESSAGE_HEADER_SIZE);
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker // Write actual size.
120*35238bceSAndroid Build Coastguard Worker int size = hostToNetwork((int)m_buf.size());
121*35238bceSAndroid Build Coastguard Worker deMemcpy(&m_buf[0], &size, sizeof(int));
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker
124*35238bceSAndroid Build Coastguard Worker template <typename T>
put(T value)125*35238bceSAndroid Build Coastguard Worker void put(T value)
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker T netValue = hostToNetwork(value);
128*35238bceSAndroid Build Coastguard Worker size_t curPos = m_buf.size();
129*35238bceSAndroid Build Coastguard Worker m_buf.resize(curPos + sizeof(T));
130*35238bceSAndroid Build Coastguard Worker deMemcpy(&m_buf[curPos], &netValue, sizeof(T));
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker
133*35238bceSAndroid Build Coastguard Worker private:
134*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> &m_buf;
135*35238bceSAndroid Build Coastguard Worker };
136*35238bceSAndroid Build Coastguard Worker
137*35238bceSAndroid Build Coastguard Worker template <>
put(const char * value)138*35238bceSAndroid Build Coastguard Worker void MessageWriter::put<const char *>(const char *value)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker int curPos = (int)m_buf.size();
141*35238bceSAndroid Build Coastguard Worker int strLen = (int)strlen(value);
142*35238bceSAndroid Build Coastguard Worker
143*35238bceSAndroid Build Coastguard Worker m_buf.resize(curPos + strLen + 1);
144*35238bceSAndroid Build Coastguard Worker deMemcpy(&m_buf[curPos], &value[0], strLen + 1);
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker
parseHeader(const uint8_t * data,size_t dataSize,MessageType & type,size_t & size)147*35238bceSAndroid Build Coastguard Worker void Message::parseHeader(const uint8_t *data, size_t dataSize, MessageType &type, size_t &size)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker XS_CHECK_MSG(dataSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
150*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
151*35238bceSAndroid Build Coastguard Worker size = (size_t)(MessageType)parser.get<int>();
152*35238bceSAndroid Build Coastguard Worker type = (MessageType)parser.get<int>();
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker
writeHeader(MessageType type,size_t messageSize,uint8_t * dst,size_t bufSize)155*35238bceSAndroid Build Coastguard Worker void Message::writeHeader(MessageType type, size_t messageSize, uint8_t *dst, size_t bufSize)
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker XS_CHECK_MSG(bufSize >= MESSAGE_HEADER_SIZE, "Incomplete header");
158*35238bceSAndroid Build Coastguard Worker int netSize = hostToNetwork((int)messageSize);
159*35238bceSAndroid Build Coastguard Worker int netType = hostToNetwork((int)type);
160*35238bceSAndroid Build Coastguard Worker deMemcpy(dst + 0, &netSize, sizeof(netSize));
161*35238bceSAndroid Build Coastguard Worker deMemcpy(dst + 4, &netType, sizeof(netType));
162*35238bceSAndroid Build Coastguard Worker }
163*35238bceSAndroid Build Coastguard Worker
writeNoData(vector<uint8_t> & buf) const164*35238bceSAndroid Build Coastguard Worker void Message::writeNoData(vector<uint8_t> &buf) const
165*35238bceSAndroid Build Coastguard Worker {
166*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker
HelloMessage(const uint8_t * data,size_t dataSize)169*35238bceSAndroid Build Coastguard Worker HelloMessage::HelloMessage(const uint8_t *data, size_t dataSize) : Message(MESSAGETYPE_HELLO)
170*35238bceSAndroid Build Coastguard Worker {
171*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
172*35238bceSAndroid Build Coastguard Worker version = parser.get<int>();
173*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const176*35238bceSAndroid Build Coastguard Worker void HelloMessage::write(vector<uint8_t> &buf) const
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
179*35238bceSAndroid Build Coastguard Worker writer.put(version);
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker
TestMessage(const uint8_t * data,size_t dataSize)182*35238bceSAndroid Build Coastguard Worker TestMessage::TestMessage(const uint8_t *data, size_t dataSize) : Message(MESSAGETYPE_TEST)
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
185*35238bceSAndroid Build Coastguard Worker parser.getString(test);
186*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const189*35238bceSAndroid Build Coastguard Worker void TestMessage::write(vector<uint8_t> &buf) const
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
192*35238bceSAndroid Build Coastguard Worker writer.put(test.c_str());
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker
ExecuteBinaryMessage(const uint8_t * data,size_t dataSize)195*35238bceSAndroid Build Coastguard Worker ExecuteBinaryMessage::ExecuteBinaryMessage(const uint8_t *data, size_t dataSize) : Message(MESSAGETYPE_EXECUTE_BINARY)
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
198*35238bceSAndroid Build Coastguard Worker parser.getString(name);
199*35238bceSAndroid Build Coastguard Worker parser.getString(params);
200*35238bceSAndroid Build Coastguard Worker parser.getString(workDir);
201*35238bceSAndroid Build Coastguard Worker parser.getString(caseList);
202*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const205*35238bceSAndroid Build Coastguard Worker void ExecuteBinaryMessage::write(vector<uint8_t> &buf) const
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
208*35238bceSAndroid Build Coastguard Worker writer.put(name.c_str());
209*35238bceSAndroid Build Coastguard Worker writer.put(params.c_str());
210*35238bceSAndroid Build Coastguard Worker writer.put(workDir.c_str());
211*35238bceSAndroid Build Coastguard Worker writer.put(caseList.c_str());
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker
ProcessLogDataMessage(const uint8_t * data,size_t dataSize)214*35238bceSAndroid Build Coastguard Worker ProcessLogDataMessage::ProcessLogDataMessage(const uint8_t *data, size_t dataSize)
215*35238bceSAndroid Build Coastguard Worker : Message(MESSAGETYPE_PROCESS_LOG_DATA)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
218*35238bceSAndroid Build Coastguard Worker parser.getString(logData);
219*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
220*35238bceSAndroid Build Coastguard Worker }
221*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const222*35238bceSAndroid Build Coastguard Worker void ProcessLogDataMessage::write(vector<uint8_t> &buf) const
223*35238bceSAndroid Build Coastguard Worker {
224*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
225*35238bceSAndroid Build Coastguard Worker writer.put(logData.c_str());
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker
ProcessLaunchFailedMessage(const uint8_t * data,size_t dataSize)228*35238bceSAndroid Build Coastguard Worker ProcessLaunchFailedMessage::ProcessLaunchFailedMessage(const uint8_t *data, size_t dataSize)
229*35238bceSAndroid Build Coastguard Worker : Message(MESSAGETYPE_PROCESS_LAUNCH_FAILED)
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
232*35238bceSAndroid Build Coastguard Worker parser.getString(reason);
233*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const236*35238bceSAndroid Build Coastguard Worker void ProcessLaunchFailedMessage::write(vector<uint8_t> &buf) const
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
239*35238bceSAndroid Build Coastguard Worker writer.put(reason.c_str());
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker
ProcessFinishedMessage(const uint8_t * data,size_t dataSize)242*35238bceSAndroid Build Coastguard Worker ProcessFinishedMessage::ProcessFinishedMessage(const uint8_t *data, size_t dataSize)
243*35238bceSAndroid Build Coastguard Worker : Message(MESSAGETYPE_PROCESS_FINISHED)
244*35238bceSAndroid Build Coastguard Worker {
245*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
246*35238bceSAndroid Build Coastguard Worker exitCode = parser.get<int>();
247*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
248*35238bceSAndroid Build Coastguard Worker }
249*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const250*35238bceSAndroid Build Coastguard Worker void ProcessFinishedMessage::write(vector<uint8_t> &buf) const
251*35238bceSAndroid Build Coastguard Worker {
252*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
253*35238bceSAndroid Build Coastguard Worker writer.put(exitCode);
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker
InfoMessage(const uint8_t * data,size_t dataSize)256*35238bceSAndroid Build Coastguard Worker InfoMessage::InfoMessage(const uint8_t *data, size_t dataSize) : Message(MESSAGETYPE_INFO)
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker MessageParser parser(data, dataSize);
259*35238bceSAndroid Build Coastguard Worker parser.getString(info);
260*35238bceSAndroid Build Coastguard Worker parser.assumEnd();
261*35238bceSAndroid Build Coastguard Worker }
262*35238bceSAndroid Build Coastguard Worker
write(vector<uint8_t> & buf) const263*35238bceSAndroid Build Coastguard Worker void InfoMessage::write(vector<uint8_t> &buf) const
264*35238bceSAndroid Build Coastguard Worker {
265*35238bceSAndroid Build Coastguard Worker MessageWriter writer(type, buf);
266*35238bceSAndroid Build Coastguard Worker writer.put(info.c_str());
267*35238bceSAndroid Build Coastguard Worker }
268*35238bceSAndroid Build Coastguard Worker
269*35238bceSAndroid Build Coastguard Worker } // namespace xs
270