IVGCVSW-3434 Create the SendCounterPacket interface

Signed-off-by: Ferran Balaguer <ferran.balaguer@arm.com>
Change-Id: I0d9b0ab12f17cb86544163ce3f0dc4945151e9e1
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f5cc9c..8cc1d2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -427,6 +427,8 @@
     src/profiling/PacketVersionResolver.hpp
     src/profiling/ProfilingConnectionFactory.cpp
     src/profiling/ProfilingConnectionFactory.hpp
+    src/profiling/IBufferWrapper.hpp
+    src/profiling/ISendCounterPacket.hpp
     third-party/half/half.hpp
     )
 
@@ -534,6 +536,7 @@
         src/armnnUtils/test/PrototxtConversionsTest.cpp
         src/armnnUtils/test/ParserHelperTest.cpp
         src/profiling/test/ProfilingTests.cpp
+        src/profiling/test/SendCounterPacketTests.cpp
         )
 
     if(ARMNNREF)
diff --git a/src/profiling/IBufferWrapper.hpp b/src/profiling/IBufferWrapper.hpp
new file mode 100644
index 0000000..5128521
--- /dev/null
+++ b/src/profiling/IBufferWrapper.hpp
@@ -0,0 +1,28 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class IBufferWrapper
+{
+public:
+    virtual unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) = 0;
+
+    virtual void Commit(unsigned int size) = 0;
+
+    virtual const unsigned char* GetReadBuffer(unsigned int& size) = 0;
+
+    virtual void Release(unsigned int size) = 0;
+};
+
+} // namespace profiling
+
+} // namespace armnn
\ No newline at end of file
diff --git a/src/profiling/ISendCounterPacket.hpp b/src/profiling/ISendCounterPacket.hpp
new file mode 100644
index 0000000..eeec5d4
--- /dev/null
+++ b/src/profiling/ISendCounterPacket.hpp
@@ -0,0 +1,41 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "CounterDirectory.hpp"
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class ISendCounterPacket
+{
+public:
+    /// Create and write a StreamMetaDataPacket in the buffer
+    virtual void SendStreamMetaDataPacket() = 0;
+
+    /// Create and write a CounterDirectoryPacket from the parameters to the buffer.
+    virtual void SendCounterDirectoryPacket(const Category& category, const std::vector<Counter>& counters) = 0;
+
+    /// Create and write a PeriodicCounterCapturePacket from the parameters to the buffer.
+    virtual void SendPeriodicCounterCapturePacket(uint64_t timestamp, const std::vector<uint32_t>& counterValues,
+                                                  const std::vector<uint16_t>& counterUids) = 0;
+
+    /// Create and write a PeriodicCounterSelectionPacket from the parameters to the buffer.
+    virtual void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
+                                                    const std::vector<uint16_t>& selectedCounterIds) = 0;
+
+    /// Set a "ready to read" flag in the buffer to notify the reading thread to start reading it.
+    virtual void SetReadyToRead() = 0;
+
+};
+
+} // namespace profiling
+
+} // namespace armnn
+
diff --git a/src/profiling/test/SendCounterPacketTests.cpp b/src/profiling/test/SendCounterPacketTests.cpp
new file mode 100644
index 0000000..9a314c1
--- /dev/null
+++ b/src/profiling/test/SendCounterPacketTests.cpp
@@ -0,0 +1,131 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "../IBufferWrapper.hpp"
+#include "../ISendCounterPacket.hpp"
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+
+BOOST_AUTO_TEST_SUITE(SendCounterPacketTests)
+
+using namespace armnn::profiling;
+
+class MockBuffer : public IBufferWrapper
+{
+public:
+    MockBuffer() : m_Buffer() {}
+
+    unsigned char* Reserve(unsigned int requestedSize, unsigned int& reservedSize) override
+    {
+        if (requestedSize > m_BufferSize)
+        {
+            reservedSize = m_BufferSize;
+        }
+        else
+        {
+            reservedSize = requestedSize;
+        }
+
+        return m_Buffer;
+    }
+
+    void Commit(unsigned int size) override {}
+
+    const unsigned char* GetReadBuffer(unsigned int& size) override
+    {
+        size = static_cast<unsigned int>(strlen(reinterpret_cast<const char*>(m_Buffer)) + 1);
+        return m_Buffer;
+    }
+
+    void Release( unsigned int size) override {}
+
+private:
+    static const unsigned int m_BufferSize = 512;
+    unsigned char m_Buffer[m_BufferSize];
+};
+
+class MockSendCounterPacket : public ISendCounterPacket
+{
+public:
+    MockSendCounterPacket(IBufferWrapper& sendBuffer) : m_Buffer(sendBuffer) {}
+
+    void SendStreamMetaDataPacket() override
+    {
+        std::string message("SendStreamMetaDataPacket");
+        unsigned int reserved = 0;
+        unsigned char* buffer = m_Buffer.Reserve(1024, reserved);
+        memcpy(buffer, message.c_str(), static_cast<unsigned int>(message.size()) + 1);
+    }
+
+    void SendCounterDirectoryPacket(const Category& category, const std::vector<Counter>& counters) override
+    {
+        std::string message("SendCounterDirectoryPacket");
+        unsigned int reserved = 0;
+        unsigned char* buffer = m_Buffer.Reserve(1024, reserved);
+        memcpy(buffer, message.c_str(), static_cast<unsigned int>(message.size()) + 1);
+    }
+
+    void SendPeriodicCounterCapturePacket(uint64_t timestamp, const std::vector<uint32_t>& counterValues,
+                                          const std::vector<uint16_t>& counterUids) override
+    {
+        std::string message("SendPeriodicCounterCapturePacket");
+        unsigned int reserved = 0;
+        unsigned char* buffer = m_Buffer.Reserve(1024, reserved);
+        memcpy(buffer, message.c_str(), static_cast<unsigned int>(message.size()) + 1);
+    }
+
+    void SendPeriodicCounterSelectionPacket(uint32_t capturePeriod,
+                                            const std::vector<uint16_t>& selectedCounterIds) override
+    {
+        std::string message("SendPeriodicCounterSelectionPacket");
+        unsigned int reserved = 0;
+        unsigned char* buffer = m_Buffer.Reserve(1024, reserved);
+        memcpy(buffer, message.c_str(), static_cast<unsigned int>(message.size()) + 1);
+        m_Buffer.Commit(reserved);
+    }
+
+    void SetReadyToRead() override
+    {}
+
+private:
+    IBufferWrapper& m_Buffer;
+};
+
+BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
+{
+    unsigned int size = 0;
+
+    MockBuffer mockBuffer;
+    MockSendCounterPacket sendCounterPacket(mockBuffer);
+
+    sendCounterPacket.SendStreamMetaDataPacket();
+    const char* buffer = reinterpret_cast<const char*>(mockBuffer.GetReadBuffer(size));
+
+    BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
+
+    Category category;
+    std::vector<Counter> counters;
+    sendCounterPacket.SendCounterDirectoryPacket(category, counters);
+
+    BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);
+
+    uint64_t timestamp = 0;
+    std::vector<uint32_t> counterValues;
+    std::vector<uint16_t> counterUids;
+    sendCounterPacket.SendPeriodicCounterCapturePacket(timestamp, counterValues, counterUids);
+
+    BOOST_TEST(strcmp(buffer, "SendPeriodicCounterCapturePacket") == 0);
+
+    uint32_t capturePeriod = 0;
+    std::vector<uint16_t> selectedCounterIds;
+    sendCounterPacket.SendPeriodicCounterSelectionPacket(capturePeriod, selectedCounterIds);
+
+    BOOST_TEST(strcmp(buffer, "SendPeriodicCounterSelectionPacket") == 0);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()