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