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