1 // 2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #pragma once 7 8 #include <common/include/NetworkSockets.hpp> 9 #include <common/include/Packet.hpp> 10 #include <common/include/SocketConnectionException.hpp> 11 #include <common/include/TargetEndianess.hpp> 12 13 #include <string> 14 #include <atomic> 15 16 namespace arm 17 { 18 19 namespace pipe 20 { 21 22 enum class PacketDirection 23 { 24 Sending, 25 ReceivedHeader, 26 ReceivedData 27 }; 28 class ConnectionHandler; 29 30 class BasePipeServer 31 { 32 33 public: 34 BasePipeServer(arm::pipe::Socket clientConnection,bool echoPackets)35 BasePipeServer(arm::pipe::Socket clientConnection, bool echoPackets) 36 : m_ClientConnection(clientConnection) 37 , m_EchoPackets(echoPackets) 38 {} 39 ~BasePipeServer()40 ~BasePipeServer() 41 { 42 // We have set SOCK_CLOEXEC on this socket but we'll close it to be good citizens. 43 arm::pipe::Close(m_ClientConnection); 44 } 45 46 BasePipeServer(const BasePipeServer&) = delete; 47 BasePipeServer& operator=(const BasePipeServer&) = delete; 48 49 BasePipeServer(BasePipeServer&&) = delete; 50 BasePipeServer& operator=(BasePipeServer&&) = delete; 51 52 /// Close the client connection 53 /// @return 0 if successful Close()54 int Close() 55 { 56 return arm::pipe::Close(m_ClientConnection); 57 } 58 59 /// Send a packet to the client 60 /// @return true if a valid packet has been sent. 61 bool SendPacket(uint32_t packetFamily, uint32_t packetId, const uint8_t* data, uint32_t dataLength); 62 63 /// Set the client socket to nonblocking 64 /// @return true if successful. SetNonBlocking()65 bool SetNonBlocking() 66 { 67 return arm::pipe::SetNonBlocking(m_ClientConnection); 68 } 69 70 /// Block on the client connection until a complete packet has been received. 71 /// @return true if a valid packet has been received. 72 arm::pipe::Packet WaitForPacket(uint32_t timeoutMs); 73 74 /// Once the connection is open wait to receive the stream meta data packet from the client. Reading this 75 /// packet differs from others as we need to determine endianness. 76 /// @return true only if a valid stream meta data packet has been received. 77 bool WaitForStreamMetaData(); 78 GetStreamMetadataVersion()79 uint32_t GetStreamMetadataVersion() 80 { 81 return m_StreamMetaDataVersion; 82 } 83 GetStreamMetadataMaxDataLen()84 uint32_t GetStreamMetadataMaxDataLen() 85 { 86 return m_StreamMetaDataMaxDataLen; 87 } 88 GetStreamMetadataPid()89 uint32_t GetStreamMetadataPid() 90 { 91 return m_StreamMetaDataPid; 92 } 93 94 private: 95 96 void EchoPacket(PacketDirection direction, uint8_t* packet, size_t lengthInBytes); 97 bool ReadFromSocket(uint8_t* packetData, uint32_t expectedLength); 98 bool ReadHeader(uint32_t headerAsWords[2]); 99 100 arm::pipe::Packet ReceivePacket(); 101 102 uint32_t ToUint32(uint8_t* data, TargetEndianness endianness); 103 void InsertU32(uint32_t value, uint8_t* data, TargetEndianness endianness); 104 105 arm::pipe::Socket m_ClientConnection; 106 bool m_EchoPackets; 107 TargetEndianness m_Endianness; 108 109 uint32_t m_StreamMetaDataVersion; 110 uint32_t m_StreamMetaDataMaxDataLen; 111 uint32_t m_StreamMetaDataPid; 112 }; 113 114 } // namespace pipe 115 } // namespace arm 116