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 32 inline deUint32 swapEndianess (deUint32 value) 33 { 34 deUint32 b0 = (value >> 0) & 0xFF; 35 deUint32 b1 = (value >> 8) & 0xFF; 36 deUint32 b2 = (value >> 16) & 0xFF; 37 deUint32 b3 = (value >> 24) & 0xFF; 38 return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 39 } 40 41 template <typename T> T networkToHost (T value); 42 template <typename T> T hostToNetwork (T value); 43 44 template <> int networkToHost (int value) { return (int)swapEndianess((deUint32)value); } 45 template <> int hostToNetwork (int value) { return (int)swapEndianess((deUint32)value); } 46 47 class MessageParser 48 { 49 public: 50 MessageParser (const deUint8* data, int dataSize) 51 : m_data (data) 52 , m_size (dataSize) 53 , m_pos (0) 54 { 55 } 56 57 template <typename T> 58 T get (void) 59 { 60 XS_CHECK_MSG(m_pos + (int)sizeof(T) <= m_size, "Invalid payload size"); 61 T netValue; 62 deMemcpy(&netValue, &m_data[m_pos], sizeof(T)); 63 m_pos += sizeof(T); 64 return networkToHost(netValue); 65 } 66 67 void getString (std::string& dst) 68 { 69 // \todo [2011-09-30 pyry] We should really send a size parameter instead. 70 while (m_data[m_pos] != 0) 71 { 72 dst += (char)m_data[m_pos++]; 73 XS_CHECK_MSG(m_pos < m_size, "Unterminated string payload"); 74 } 75 76 m_pos += 1; 77 } 78 79 void assumEnd (void) 80 { 81 if (m_pos != m_size) 82 XS_FAIL("Invalid payload size"); 83 } 84 85 private: 86 const deUint8* m_data; 87 int m_size; 88 int m_pos; 89 }; 90 91 class MessageWriter 92 { 93 public: 94 MessageWriter (MessageType msgType, std::vector<deUint8>& buf) 95 : m_buf(buf) 96 { 97 // Place for size. 98 put<int>(0); 99 100 // Write message type. 101 put<int>(msgType); 102 } 103 104 ~MessageWriter (void) 105 { 106 finalize(); 107 } 108 109 void finalize (void) 110 { 111 DE_ASSERT(m_buf.size() >= MESSAGE_HEADER_SIZE); 112 113 // Write actual size. 114 int size = hostToNetwork((int)m_buf.size()); 115 deMemcpy(&m_buf[0], &size, sizeof(int)); 116 } 117 118 template <typename T> 119 void put (T value) 120 { 121 T netValue = hostToNetwork(value); 122 size_t curPos = m_buf.size(); 123 m_buf.resize(curPos + sizeof(T)); 124 deMemcpy(&m_buf[curPos], &netValue, sizeof(T)); 125 } 126 127 private: 128 std::vector<deUint8>& m_buf; 129 }; 130 131 template <> 132 void MessageWriter::put<const char*> (const char* value) 133 { 134 int curPos = (int)m_buf.size(); 135 int strLen = (int)strlen(value); 136 137 m_buf.resize(curPos + strLen+1); 138 deMemcpy(&m_buf[curPos], &value[0], strLen+1); 139 } 140 141 void Message::parseHeader (const deUint8* data, int dataSize, MessageType& type, int& size) 142 { 143 XS_CHECK_MSG(dataSize >= MESSAGE_HEADER_SIZE, "Incomplete header"); 144 MessageParser parser(data, dataSize); 145 size = (MessageType)parser.get<int>(); 146 type = (MessageType)parser.get<int>(); 147 } 148 149 void Message::writeHeader (MessageType type, int messageSize, deUint8* dst, int bufSize) 150 { 151 XS_CHECK_MSG(bufSize >= MESSAGE_HEADER_SIZE, "Incomplete header"); 152 int netSize = hostToNetwork(messageSize); 153 int netType = hostToNetwork((int)type); 154 deMemcpy(dst+0, &netSize, sizeof(netSize)); 155 deMemcpy(dst+4, &netType, sizeof(netType)); 156 } 157 158 void Message::writeNoData (vector<deUint8>& buf) const 159 { 160 MessageWriter writer(type, buf); 161 } 162 163 HelloMessage::HelloMessage (const deUint8* data, int dataSize) 164 : Message(MESSAGETYPE_HELLO) 165 { 166 MessageParser parser(data, dataSize); 167 version = parser.get<int>(); 168 parser.assumEnd(); 169 } 170 171 void HelloMessage::write (vector<deUint8>& buf) const 172 { 173 MessageWriter writer(type, buf); 174 writer.put(version); 175 } 176 177 TestMessage::TestMessage (const deUint8* data, int dataSize) 178 : Message(MESSAGETYPE_TEST) 179 { 180 MessageParser parser(data, dataSize); 181 parser.getString(test); 182 parser.assumEnd(); 183 } 184 185 void TestMessage::write (vector<deUint8>& buf) const 186 { 187 MessageWriter writer(type, buf); 188 writer.put(test.c_str()); 189 } 190 191 ExecuteBinaryMessage::ExecuteBinaryMessage (const deUint8* data, int dataSize) 192 : Message(MESSAGETYPE_EXECUTE_BINARY) 193 { 194 MessageParser parser(data, dataSize); 195 parser.getString(name); 196 parser.getString(params); 197 parser.getString(workDir); 198 parser.getString(caseList); 199 parser.assumEnd(); 200 } 201 202 void ExecuteBinaryMessage::write (vector<deUint8>& buf) const 203 { 204 MessageWriter writer(type, buf); 205 writer.put(name.c_str()); 206 writer.put(params.c_str()); 207 writer.put(workDir.c_str()); 208 writer.put(caseList.c_str()); 209 } 210 211 ProcessLogDataMessage::ProcessLogDataMessage (const deUint8* data, int dataSize) 212 : Message(MESSAGETYPE_PROCESS_LOG_DATA) 213 { 214 MessageParser parser(data, dataSize); 215 parser.getString(logData); 216 parser.assumEnd(); 217 } 218 219 void ProcessLogDataMessage::write (vector<deUint8>& buf) const 220 { 221 MessageWriter writer(type, buf); 222 writer.put(logData.c_str()); 223 } 224 225 ProcessLaunchFailedMessage::ProcessLaunchFailedMessage (const deUint8* data, int dataSize) 226 : Message(MESSAGETYPE_PROCESS_LAUNCH_FAILED) 227 { 228 MessageParser parser(data, dataSize); 229 parser.getString(reason); 230 parser.assumEnd(); 231 } 232 233 void ProcessLaunchFailedMessage::write (vector<deUint8>& buf) const 234 { 235 MessageWriter writer(type, buf); 236 writer.put(reason.c_str()); 237 } 238 239 ProcessFinishedMessage::ProcessFinishedMessage (const deUint8* data, int dataSize) 240 : Message(MESSAGETYPE_PROCESS_FINISHED) 241 { 242 MessageParser parser(data, dataSize); 243 exitCode = parser.get<int>(); 244 parser.assumEnd(); 245 } 246 247 void ProcessFinishedMessage::write (vector<deUint8>& buf) const 248 { 249 MessageWriter writer(type, buf); 250 writer.put(exitCode); 251 } 252 253 InfoMessage::InfoMessage (const deUint8* data, int dataSize) 254 : Message(MESSAGETYPE_INFO) 255 { 256 MessageParser parser(data, dataSize); 257 parser.getString(info); 258 parser.assumEnd(); 259 } 260 261 void InfoMessage::write (vector<deUint8>& buf) const 262 { 263 MessageWriter writer(type, buf); 264 writer.put(info.c_str()); 265 } 266 267 } // xs 268