1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan CTS Framework 3e5c31af7Sopenharmony_ci * -------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *-------------------------------------------------------------------------*/ 20e5c31af7Sopenharmony_ci 21e5c31af7Sopenharmony_ci#include "vksIPC.hpp" 22e5c31af7Sopenharmony_ci#include "vksStore.hpp" 23e5c31af7Sopenharmony_ci#include "vksClient.hpp" 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include <future> 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_cinamespace vksc_server 28e5c31af7Sopenharmony_ci{ 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_cinamespace ipc 31e5c31af7Sopenharmony_ci{ 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciconstexpr int DefaultPortIPC = 57323; 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_cistruct ChildConnection 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_ci int id; 38e5c31af7Sopenharmony_ci std::unique_ptr<de::Socket> socket; 39e5c31af7Sopenharmony_ci std::atomic<bool>& appactive; 40e5c31af7Sopenharmony_ci vector<u8> recvb; 41e5c31af7Sopenharmony_ci}; 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cistruct PacketsLoop 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci ChildConnection client; 46e5c31af7Sopenharmony_ci Store& fileStore; 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ci template <typename T> 49e5c31af7Sopenharmony_ci static void SendResponse (ChildConnection& c, T& data) 50e5c31af7Sopenharmony_ci { 51e5c31af7Sopenharmony_ci SendPayloadWithHeader(c.socket.get(), T::Type(), Serialize(data)); 52e5c31af7Sopenharmony_ci } 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ci void ProcessPacketsOnServer (ChildConnection& c, u32 type, vector<u8> packet) 55e5c31af7Sopenharmony_ci { 56e5c31af7Sopenharmony_ci switch (type) 57e5c31af7Sopenharmony_ci { 58e5c31af7Sopenharmony_ci case StoreContentRequest::Type(): 59e5c31af7Sopenharmony_ci { 60e5c31af7Sopenharmony_ci auto req = Deserialize<StoreContentRequest>(packet); 61e5c31af7Sopenharmony_ci bool ok = fileStore.Set(req.name, req.data); 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci StoreContentResponse res; 64e5c31af7Sopenharmony_ci res.status = ok; 65e5c31af7Sopenharmony_ci SendResponse(c, res); 66e5c31af7Sopenharmony_ci } 67e5c31af7Sopenharmony_ci break; 68e5c31af7Sopenharmony_ci case GetContentRequest::Type(): 69e5c31af7Sopenharmony_ci { 70e5c31af7Sopenharmony_ci auto req = Deserialize<GetContentRequest>(packet); 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci vector<u8> content; 73e5c31af7Sopenharmony_ci bool ok = fileStore.Get(req.path, content, req.removeAfter); 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci GetContentResponse res; 76e5c31af7Sopenharmony_ci res.status = ok; 77e5c31af7Sopenharmony_ci res.data = std::move(content); 78e5c31af7Sopenharmony_ci SendResponse(c, res); 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci break; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci default: 83e5c31af7Sopenharmony_ci throw std::runtime_error("ipc communication error"); 84e5c31af7Sopenharmony_ci } 85e5c31af7Sopenharmony_ci } 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ci void Loop () 88e5c31af7Sopenharmony_ci { 89e5c31af7Sopenharmony_ci while (client.socket->isConnected() && client.appactive) 90e5c31af7Sopenharmony_ci { 91e5c31af7Sopenharmony_ci RecvSome(client.socket.get(), client.recvb); 92e5c31af7Sopenharmony_ci auto interpret = [this](u32 type, vector<u8> packet) { ProcessPacketsOnServer(client, type, std::move(packet)); }; 93e5c31af7Sopenharmony_ci while (ProccessNetworkData(client.recvb, interpret)) {} 94e5c31af7Sopenharmony_ci } 95e5c31af7Sopenharmony_ci } 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci void operator() () 98e5c31af7Sopenharmony_ci { 99e5c31af7Sopenharmony_ci try { Loop(); } 100e5c31af7Sopenharmony_ci catch (const std::exception& ) { client.socket->close(); } 101e5c31af7Sopenharmony_ci } 102e5c31af7Sopenharmony_ci}; 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_cistruct ParentImpl 105e5c31af7Sopenharmony_ci{ 106e5c31af7Sopenharmony_ci Store fileStore; 107e5c31af7Sopenharmony_ci int m_portOffset; 108e5c31af7Sopenharmony_ci std::thread listenerLoop; 109e5c31af7Sopenharmony_ci std::atomic<bool> appActive{true}; 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_ci void ParentLoop () 112e5c31af7Sopenharmony_ci { 113e5c31af7Sopenharmony_ci vector<std::future<void>> clients; 114e5c31af7Sopenharmony_ci int id{}; 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci try 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci de::SocketAddress addr; 119e5c31af7Sopenharmony_ci addr.setHost("localhost"); 120e5c31af7Sopenharmony_ci addr.setPort(DefaultPortIPC+m_portOffset); 121e5c31af7Sopenharmony_ci de::Socket listener; 122e5c31af7Sopenharmony_ci listener.listen(addr); 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci while (appActive) 125e5c31af7Sopenharmony_ci { 126e5c31af7Sopenharmony_ci remove_erase_if(clients, [](const std::future<void>& c) { return is_ready(c); }); 127e5c31af7Sopenharmony_ci ChildConnection client{ ++id, std::unique_ptr<de::Socket>(listener.accept()), appActive, vector<u8>{} }; 128e5c31af7Sopenharmony_ci clients.push_back(CreateClientThread(std::move(client))); 129e5c31af7Sopenharmony_ci } 130e5c31af7Sopenharmony_ci } 131e5c31af7Sopenharmony_ci catch (const std::exception&) { appActive = false; } 132e5c31af7Sopenharmony_ci } 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci ParentImpl (const int portOffset) 135e5c31af7Sopenharmony_ci : m_portOffset { portOffset } 136e5c31af7Sopenharmony_ci , listenerLoop {[this](){ParentLoop();}} 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci } 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci ~ParentImpl () 141e5c31af7Sopenharmony_ci { 142e5c31af7Sopenharmony_ci appActive = false; 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci // Dummy connection to trigger accept() 145e5c31af7Sopenharmony_ci de::SocketAddress addr; 146e5c31af7Sopenharmony_ci addr.setHost("localhost"); 147e5c31af7Sopenharmony_ci addr.setPort(DefaultPortIPC + m_portOffset); 148e5c31af7Sopenharmony_ci de::Socket socket; 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci try 151e5c31af7Sopenharmony_ci { 152e5c31af7Sopenharmony_ci socket.connect(addr); 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci catch (const de::SocketError&) 155e5c31af7Sopenharmony_ci { 156e5c31af7Sopenharmony_ci } 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci try 159e5c31af7Sopenharmony_ci { 160e5c31af7Sopenharmony_ci socket.close(); 161e5c31af7Sopenharmony_ci } 162e5c31af7Sopenharmony_ci catch (const de::SocketError&) 163e5c31af7Sopenharmony_ci { 164e5c31af7Sopenharmony_ci } 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci listenerLoop.join(); 167e5c31af7Sopenharmony_ci } 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci std::future<void> CreateClientThread (ChildConnection client) 170e5c31af7Sopenharmony_ci { 171e5c31af7Sopenharmony_ci return std::async( PacketsLoop{ std::move(client), fileStore } ); 172e5c31af7Sopenharmony_ci } 173e5c31af7Sopenharmony_ci}; 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ciParent::Parent (const int portOffset) 176e5c31af7Sopenharmony_ci{ 177e5c31af7Sopenharmony_ci impl.reset( new ParentImpl(portOffset) ); 178e5c31af7Sopenharmony_ci} 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ciParent::~Parent () 181e5c31af7Sopenharmony_ci{ 182e5c31af7Sopenharmony_ci} 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_cibool Parent::SetFile (const string& name, const std::vector<u8>& content) 186e5c31af7Sopenharmony_ci{ 187e5c31af7Sopenharmony_ci return impl->fileStore.Set(name, content); 188e5c31af7Sopenharmony_ci} 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_civector<u8> Parent::GetFile (const string& name) 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ci vector<u8> content; 193e5c31af7Sopenharmony_ci bool result = impl->fileStore.Get(name, content, false); 194e5c31af7Sopenharmony_ci if (result) return content; 195e5c31af7Sopenharmony_ci else return {}; 196e5c31af7Sopenharmony_ci} 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_cistruct ChildImpl 199e5c31af7Sopenharmony_ci{ 200e5c31af7Sopenharmony_ci ChildImpl(const int portOffset) 201e5c31af7Sopenharmony_ci : m_portOffset(portOffset) 202e5c31af7Sopenharmony_ci { 203e5c31af7Sopenharmony_ci connection.reset(new Server{ "localhost:" + std::to_string(DefaultPortIPC + m_portOffset) }); 204e5c31af7Sopenharmony_ci } 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci int m_portOffset; 207e5c31af7Sopenharmony_ci std::unique_ptr<Server> connection; 208e5c31af7Sopenharmony_ci}; 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ciChild::Child (const int portOffset) 211e5c31af7Sopenharmony_ci{ 212e5c31af7Sopenharmony_ci impl.reset( new ChildImpl(portOffset) ); 213e5c31af7Sopenharmony_ci} 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ciChild::~Child () 216e5c31af7Sopenharmony_ci{ 217e5c31af7Sopenharmony_ci} 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_cibool Child::SetFile (const string& name, const std::vector<u8>& content) 220e5c31af7Sopenharmony_ci{ 221e5c31af7Sopenharmony_ci StoreContentRequest request; 222e5c31af7Sopenharmony_ci request.name = name; 223e5c31af7Sopenharmony_ci request.data = content; 224e5c31af7Sopenharmony_ci StoreContentResponse response; 225e5c31af7Sopenharmony_ci impl->connection->SendRequest(request, response); 226e5c31af7Sopenharmony_ci return response.status; 227e5c31af7Sopenharmony_ci} 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_cistd::vector<u8> Child::GetFile (const string& name) 230e5c31af7Sopenharmony_ci{ 231e5c31af7Sopenharmony_ci GetContentRequest request; 232e5c31af7Sopenharmony_ci request.path = name; 233e5c31af7Sopenharmony_ci request.physicalFile = false; 234e5c31af7Sopenharmony_ci request.removeAfter = false; 235e5c31af7Sopenharmony_ci GetContentResponse response; 236e5c31af7Sopenharmony_ci impl->connection->SendRequest(request, response); 237e5c31af7Sopenharmony_ci if (response.status == true) return response.data; 238e5c31af7Sopenharmony_ci else return {}; 239e5c31af7Sopenharmony_ci} 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci} // ipc 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci} // vksc_server 244