xref: /aosp_15_r20/external/deqp/external/vulkancts/vkscserver/vksNetwork.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
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 
21 #include "vksNetwork.hpp"
22 #include "vksSerializer.hpp"
23 
24 #include <sstream>
25 
26 #include "deSocket.hpp"
27 
28 namespace vksc_server
29 {
30 
StringToAddress(const string & str,string & host,int & port)31 void StringToAddress(const string &str, string &host, int &port)
32 {
33     auto pos = str.find_last_of(':');
34     if (pos == string::npos)
35     {
36         host = str.c_str();
37         port = DefaultPort;
38     }
39     else
40     {
41         host = str.substr(0, pos);
42         std::stringstream{str.substr(pos + 1)} >> port;
43     }
44 }
45 
ProccessNetworkData(vector<u8> & buffer,const std::function<void (u32,vector<u8>)> & packetInterpreter)46 bool ProccessNetworkData(vector<u8> &buffer, const std::function<void(u32, vector<u8>)> &packetInterpreter)
47 {
48     constexpr msize headerSize = 8;
49 
50     if (buffer.size() >= headerSize)
51     {
52         u32 classHash;
53         u32 packetSize;
54 
55         Serializer<ToRead>{buffer}.Serialize(classHash, packetSize);
56 
57         if (buffer.size() >= packetSize + headerSize)
58         {
59             auto itbeging = buffer.begin() + headerSize;
60             auto itend    = itbeging + packetSize;
61             packetInterpreter(classHash, vector<u8>(itbeging, itend));
62             buffer.erase(buffer.begin(), itend);
63             return buffer.size() >= headerSize; // Try again?
64         }
65     }
66 
67     return false;
68 }
69 
Send(de::Socket * socket,const vector<u8> & buffer)70 void Send(de::Socket *socket, const vector<u8> &buffer)
71 {
72     msize sent_total{};
73     do
74     {
75         msize sent{};
76         auto result = socket->send(buffer.data() + sent_total, buffer.size() - sent_total, &sent);
77         if (result != DE_SOCKETRESULT_SUCCESS)
78             throw std::runtime_error("Can't send data to socket");
79         sent_total += sent;
80     } while (sent_total < buffer.size());
81 }
82 
RecvSome(de::Socket * socket,vector<u8> & recvb)83 void RecvSome(de::Socket *socket, vector<u8> &recvb)
84 {
85     msize received;
86     u8 data[8 * 1024];
87     auto result = socket->receive(data, sizeof(data), &received);
88     if (result != DE_SOCKETRESULT_SUCCESS)
89         throw std::runtime_error("Can't receive data from socket");
90     recvb.insert(recvb.end(), data, data + received);
91 }
92 
SendPayloadWithHeader(de::Socket * socket,u32 type,const std::vector<u8> & payload)93 void SendPayloadWithHeader(de::Socket *socket, u32 type, const std::vector<u8> &payload)
94 {
95     u32 size = static_cast<u32>(payload.size());
96 
97     vector<u8> header;
98     Serializer<ToWrite> header_serializer(header);
99     header_serializer.Serialize(type, size);
100 
101     Send(socket, header);
102     Send(socket, payload);
103 }
104 
RecvPacket(de::Socket * socket,vector<u8> & recvb,u32 type)105 vector<u8> RecvPacket(de::Socket *socket, vector<u8> &recvb, u32 type)
106 {
107     bool result = false;
108     vector<u8> packet;
109 
110     while (socket->isConnected() && !result)
111     {
112         RecvSome(socket, recvb);
113 
114         auto interpret = [&](u32 classHash, vector<u8> bufferData)
115         {
116             if (classHash != type)
117                 throw std::runtime_error("Unexpected packet type received");
118             packet = std::move(bufferData);
119             result = true;
120         };
121 
122         ProccessNetworkData(recvb, interpret);
123     }
124 
125     if (!result)
126         throw std::runtime_error("connection lost before we could get data");
127 
128     return packet;
129 }
130 
131 }; // namespace vksc_server
132