IVGCVSW-3430 Connection Acknowledged Command Handler Implementation

Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: I0ba97a93edb283b37bd1c089c668135a4bf9550c
diff --git a/src/profiling/ConnectionAcknowledgedCommandHandler.cpp b/src/profiling/ConnectionAcknowledgedCommandHandler.cpp
new file mode 100644
index 0000000..0f83a31
--- /dev/null
+++ b/src/profiling/ConnectionAcknowledgedCommandHandler.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "ConnectionAcknowledgedCommandHandler.hpp"
+
+#include <armnn/Exceptions.hpp>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+void ConnectionAcknowledgedCommandHandler::operator()(const Packet& packet)
+{
+    if (!(packet.GetPacketFamily() == 0u && packet.GetPacketId() == 1u))
+    {
+        throw armnn::Exception(std::string("Expected Packet family = 0, id = 1 but received family =")
+                               + std::to_string(packet.GetPacketFamily())
+                               +" id = " + std::to_string(packet.GetPacketId()));
+    }
+    m_StateMachine.TransitionToState(ProfilingState::Active);
+}
+
+} // namespace profiling
+
+} // namespace armnn
+
diff --git a/src/profiling/ConnectionAcknowledgedCommandHandler.hpp b/src/profiling/ConnectionAcknowledgedCommandHandler.hpp
new file mode 100644
index 0000000..f61495e
--- /dev/null
+++ b/src/profiling/ConnectionAcknowledgedCommandHandler.hpp
@@ -0,0 +1,36 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include "CommandHandlerFunctor.hpp"
+#include "Packet.hpp"
+#include "ProfilingStateMachine.hpp"
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+class ConnectionAcknowledgedCommandHandler : public CommandHandlerFunctor
+{
+
+public:
+    ConnectionAcknowledgedCommandHandler(uint32_t packetId,
+                                         uint32_t version,
+                                         ProfilingStateMachine& profilingStateMachine)
+        : CommandHandlerFunctor(packetId, version), m_StateMachine(profilingStateMachine) {}
+
+    void operator()(const Packet& packet) override;
+
+private:
+    ProfilingStateMachine& m_StateMachine;
+};
+
+} // namespace profiling
+
+} // namespace armnn
+
diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp
index e97068f..1cf0e1e 100644
--- a/src/profiling/test/ProfilingTests.cpp
+++ b/src/profiling/test/ProfilingTests.cpp
@@ -8,6 +8,7 @@
 #include <CommandHandlerKey.hpp>
 #include <CommandHandlerFunctor.hpp>
 #include <CommandHandlerRegistry.hpp>
+#include <ConnectionAcknowledgedCommandHandler.hpp>
 #include <CounterDirectory.hpp>
 #include <EncodeVersion.hpp>
 #include <Holder.hpp>
@@ -1649,6 +1650,62 @@
     BOOST_TEST(period == 11);                       // capture period
 }
 
+BOOST_AUTO_TEST_CASE(CheckConnectionAcknowledged)
+{
+    using boost::numeric_cast;
+
+    const uint32_t connectionPacketId = 0x10000;
+    const uint32_t version = 1;
+
+    uint32_t sizeOfUint32 = numeric_cast<uint32_t>(sizeof(uint32_t));
+    uint32_t sizeOfUint16 = numeric_cast<uint32_t>(sizeof(uint16_t));
+
+    // Data with period and counters
+    uint32_t period1 = 10;
+    uint32_t dataLength1 = 8;
+    uint32_t offset = 0;
+
+    std::unique_ptr<char[]> uniqueData1 = std::make_unique<char[]>(dataLength1);
+    unsigned char* data1 = reinterpret_cast<unsigned char*>(uniqueData1.get());
+
+    WriteUint32(data1, offset, period1);
+    offset += sizeOfUint32;
+    WriteUint16(data1, offset, 4000);
+    offset += sizeOfUint16;
+    WriteUint16(data1, offset, 5000);
+
+    Packet packetA(connectionPacketId, dataLength1, uniqueData1);
+
+    ProfilingStateMachine profilingState(ProfilingState::Uninitialised);
+    BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Uninitialised);
+
+    ConnectionAcknowledgedCommandHandler commandHandler(connectionPacketId, version, profilingState);
+
+    // command handler received packet on ProfilingState::Uninitialised
+    BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
+
+    profilingState.TransitionToState(ProfilingState::NotConnected);
+    BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::NotConnected);
+    // command handler received packet on ProfilingState::NotConnected
+    BOOST_CHECK_THROW(commandHandler(packetA), armnn::Exception);
+
+    profilingState.TransitionToState(ProfilingState::WaitingForAck);
+    BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::WaitingForAck);
+    // command handler received packet on ProfilingState::WaitingForAck
+    commandHandler(packetA);
+    BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
+
+    // command handler received packet on ProfilingState::Active
+    commandHandler(packetA);
+    BOOST_CHECK(profilingState.GetCurrentState() == ProfilingState::Active);
+
+    // command handler received different packet
+    const uint32_t differentPacketId = 0x40000;
+    Packet packetB(differentPacketId, dataLength1, uniqueData1);
+    ConnectionAcknowledgedCommandHandler differentCommandHandler(differentPacketId, version, profilingState);
+    BOOST_CHECK_THROW(differentCommandHandler(packetB), armnn::Exception);
+}
+
 BOOST_AUTO_TEST_CASE(CheckSocketProfilingConnection)
 {
     // Check that creating a SocketProfilingConnection results in an exception as the Gator UDS doesn't exist.