30 m_ListeningSocket = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
31 if (-1 == m_ListeningSocket)
33 std::cerr <<
": Socket construction failed: " << strerror(errno) << std::endl;
37 sockaddr_un udsAddress;
38 memset(&udsAddress, 0,
sizeof(sockaddr_un));
40 memcpy(udsAddress.sun_path + 1, udsNamespace.c_str(), strlen(udsNamespace.c_str()));
41 udsAddress.sun_family = AF_UNIX;
44 if (-1 == bind(m_ListeningSocket, reinterpret_cast<const sockaddr*>(&udsAddress),
sizeof(sockaddr_un)))
46 std::cerr <<
": Binding on socket failed: " << strerror(errno) << std::endl;
50 if (-1 == listen(m_ListeningSocket, 1))
52 std::cerr <<
": Listen call on socket failed: " << strerror(errno) << std::endl;
60 m_ClientConnection =
Sockets::Accept(m_ListeningSocket,
nullptr,
nullptr, SOCK_CLOEXEC);
61 if (-1 == m_ClientConnection)
63 std::cerr <<
": Failure when waiting for a client connection: " << strerror(errno) << std::endl;
66 return m_ClientConnection;
73 std::cout <<
"Waiting for stream meta data..." << std::endl;
77 if (!ReadFromSocket(header, 8))
85 std::cerr <<
": Protocol error. The stream_metadata_identifer was not 0." << std::endl;
90 if (!ReadFromSocket(pipeMagic, 4))
107 std::cerr <<
": Protocol read error. Unable to read PIPE_MAGIC value." << std::endl;
112 uint32_t metaDataLength = ToUint32(&header[4], m_Endianness) - 4;
114 std::vector<uint8_t> packetData(metaDataLength);
115 if (metaDataLength !=
116 boost::numeric_cast<uint32_t>(
Sockets::Read(m_ClientConnection, packetData.data(), metaDataLength)))
118 std::cerr <<
": Protocol read error. Data length mismatch." << std::endl;
122 m_StreamMetaDataVersion = ToUint32(&packetData[0], m_Endianness);
123 m_StreamMetaDataMaxDataLen = ToUint32(&packetData[4], m_Endianness);
124 m_StreamMetaDataPid = ToUint32(&packetData[8], m_Endianness);
133 std::cout <<
"Sending connection acknowledgement." << std::endl;
136 SendPacket(0, 1,
nullptr, 0);
143 std::cout <<
"Sending connection acknowledgement." << std::endl;
146 SendPacket(0, 3,
nullptr, 0);
153 std::cout <<
"Launching receiving thread." << std::endl;
159 std::cerr <<
"Failed to set socket as non blocking: " << strerror(errno) << std::endl;
162 m_ListeningThread = std::thread(&GatordMockService::ReceiveLoop,
this, std::ref(*
this));
169 if (m_CloseReceivingThread !=
true)
171 m_CloseReceivingThread.store(
true);
174 if (m_ListeningThread.joinable())
177 m_ListeningThread.join();
189 std::cout <<
"SendPeriodicCounterSelectionList: Period=" << std::dec << period <<
"uSec" << std::endl;
190 std::cout <<
"List length=" << counters.size() << std::endl;
194 uint32_t dataLength =
static_cast<uint32_t
>(4 + (counters.size() * 2));
196 std::unique_ptr<unsigned char[]> uniqueData = std::make_unique<unsigned char[]>(dataLength);
197 unsigned char* data =
reinterpret_cast<unsigned char*
>(uniqueData.get());
202 for (std::vector<uint16_t>::iterator it = counters.begin(); it != counters.end(); ++it)
209 SendPacket(0, 4, data, dataLength);
218 uint32_t iterations = timeout / 1000;
219 std::cout << std::dec <<
"Wait command with timeout of " << timeout <<
" iterations = " << iterations << std::endl;
223 std::this_thread::sleep_for(std::chrono::microseconds(1000));
228 std::cout << std::dec <<
"Wait command with timeout of " << timeout <<
" microseconds completed. " << std::endl;
234 m_CloseReceivingThread.store(
false);
235 while (!m_CloseReceivingThread.load())
248 std::cerr <<
"Packet received that could not be processed: " << e.
what() << std::endl;
253 std::cerr <<
"Receive thread closing: " << e.
what() << std::endl;
254 m_CloseReceivingThread.store(
true);
264 if (bytes_available > 8)
267 return ReceivePacket();
272 struct pollfd pollingFd[1]{};
273 pollingFd[0].fd = m_ClientConnection;
274 int pollResult =
Sockets::Poll(pollingFd, 1, static_cast<int>(timeoutMs));
290 if (pollingFd[0].revents & (POLLNVAL | POLLERR | POLLHUP))
292 if (pollingFd[0].revents == POLLNVAL)
296 if (pollingFd[0].revents == POLLERR)
301 if (pollingFd[0].revents == POLLHUP)
308 if (!(pollingFd[0].revents & (POLLIN)))
314 return ReceivePacket();
322 if (!ReadHeader(header))
327 std::unique_ptr<unsigned char[]> uniquePacketData = std::make_unique<unsigned char[]>(header[1]);
328 unsigned char* packetData =
reinterpret_cast<unsigned char*
>(uniquePacketData.get());
330 if (!ReadFromSocket(packetData, header[1]))
342 std::cout <<
"Processing packet ID= " << packetRx.
GetPacketId() <<
" Length=" << packetRx.
GetLength()
351 BOOST_ASSERT(commandHandlerFunctor);
352 commandHandlerFunctor->operator()(packetRx);
356 bool GatordMockService::SendPacket(uint32_t packetFamily, uint32_t packetId,
const uint8_t* data, uint32_t dataLength)
361 header[0] = packetFamily << 26 | packetId << 16;
362 header[1] = dataLength;
364 std::vector<uint8_t> packet(8 + dataLength);
365 InsertU32(header[0], packet.data(), m_Endianness);
366 InsertU32(header[1], packet.data() + 4, m_Endianness);
370 memcpy((packet.data() + 8), data, dataLength);
373 if (-1 ==
Sockets::Write(m_ClientConnection, packet.data(), packet.size()))
375 std::cerr <<
": Failure when writing to client socket: " << strerror(errno) << std::endl;
381 bool GatordMockService::ReadHeader(uint32_t headerAsWords[2])
385 if (!ReadFromSocket(header, 8))
390 headerAsWords[0] = ToUint32(&header[0], m_Endianness);
391 headerAsWords[1] = ToUint32(&header[4], m_Endianness);
395 bool GatordMockService::ReadFromSocket(uint8_t* packetData, uint32_t expectedLength)
398 long totalBytesRead = 0;
399 while (boost::numeric_cast<uint32_t>(totalBytesRead) < expectedLength)
401 long bytesRead =
Sockets::Read(m_ClientConnection, packetData, expectedLength);
404 std::cerr <<
": Failure when reading from client socket: " << strerror(errno) << std::endl;
409 std::cerr <<
": EOF while reading from client socket." << std::endl;
412 totalBytesRead += bytesRead;
417 void GatordMockService::EchoPacket(
PacketDirection direction, uint8_t* packet,
size_t lengthInBytes)
424 std::cout <<
"TX " << std::dec << lengthInBytes <<
" bytes : ";
428 std::cout <<
"RX Header " << std::dec << lengthInBytes <<
" bytes : ";
432 std::cout <<
"RX Data " << std::dec << lengthInBytes <<
" bytes : ";
434 for (
unsigned int i = 0; i < lengthInBytes; i++)
438 std::cout << std::endl;
440 std::cout <<
"0x" << std::setfill(
'0') << std::setw(2) << std::hex << static_cast<unsigned int>(packet[i])
443 std::cout << std::endl;
447 uint32_t GatordMockService::ToUint32(uint8_t* data,
TargetEndianness endianness)
453 return static_cast<uint32_t
>(data[0]) << 24 | static_cast<uint32_t>(data[1]) << 16 |
454 static_cast<uint32_t
>(data[2]) << 8 | static_cast<uint32_t>(data[3]);
458 return static_cast<uint32_t
>(data[3]) << 24 | static_cast<uint32_t>(data[2]) << 16 |
459 static_cast<uint32_t
>(data[1]) << 8 | static_cast<uint32_t>(data[0]);
463 void GatordMockService::InsertU32(uint32_t value, uint8_t* data,
TargetEndianness endianness)
469 *data =
static_cast<uint8_t
>((value >> 24) & 0xFF);
470 *(data + 1) = static_cast<uint8_t>((value >> 16) & 0xFF);
471 *(data + 2) = static_cast<uint8_t>((value >> 8) & 0xFF);
472 *(data + 3) = static_cast<uint8_t>(value & 0xFF);
476 *(data + 3) = static_cast<uint8_t>((value >> 24) & 0xFF);
477 *(data + 2) = static_cast<uint8_t>((value >> 16) & 0xFF);
478 *(data + 1) = static_cast<uint8_t>((value >> 8) & 0xFF);
479 *data =
static_cast<uint8_t
>(value & 0xFF);
int Poll(PollFd *fds, nfds_t numFds, int timeout)
uint32_t GetEncodedValue()
void WriteUint16(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint16_t value)
void WriteUint32(const IPacketBufferPtr &packetBuffer, unsigned int offset, uint32_t value)
Version ResolvePacketVersion(uint32_t familyId, uint32_t packetId) const
virtual const char * what() const noexcept override
bool OpenListeningSocket(std::string udsNamespace)
Establish the Unix domain socket and set it to listen for connections.
Copyright (c) 2020 ARM Limited.
int Ioctl(Socket s, unsigned long int cmd, void *arg)
bool WaitForStreamMetaData()
Once the connection is open wait to receive the stream meta data packet from the client.
uint32_t GetPacketFamily() const
void SendRequestCounterDir()
Send a request counter directory packet back to the client.
bool ReceiveThreadRunning()
bool Initialize()
Performs any required one-time setup.
bool SetNonBlocking(Socket s)
bool LaunchReceivingThread()
Start the thread that will receive all packets and print them nicely to stdout.
armnnUtils::Sockets::Socket Accept(Socket s, sockaddr *addr, socklen_t *addrlen, int flags)
A class that implements a Mock Gatord server.
uint32_t GetLength() const
void WaitCommand(uint32_t timeout)
Execute the WAIT command from the comamnd file.
void SendPeriodicCounterSelectionList(uint32_t period, std::vector< uint16_t > counters)
Send the counter list to ArmNN.
uint32_t GetPacketId() const
long Write(Socket s, const void *buf, size_t len)
void WaitForReceivingThread()
This is a placeholder method to prevent main exiting.
long Read(Socket s, void *buf, size_t len)
armnnUtils::Sockets::Socket BlockForOneClient()
Block waiting to accept one client to connect to the UDS.
void SendConnectionAck()
Send a connection acknowledged packet back to the client.