Implement API to prepare response for inbound SOL payload

Change-Id: Ied9811e7e3176c5edf99fa299549ea1d14e9555f
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/sol/sol_context.cpp b/sol/sol_context.cpp
index b81281b..ee0eb39 100644
--- a/sol/sol_context.cpp
+++ b/sol/sol_context.cpp
@@ -108,14 +108,54 @@
     }
 }
 
-void Context::prepareResponse(uint8_t ackSeqNum,
-                              uint8_t count,
-                              bool ack)
+void Context::prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack)
+{
+    auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.
+                            size();
+
+    /* Sent a ACK only response */
+    if (payloadCache.size() != 0 || (bufferSize < sendThreshold))
+    {
+        std::get<eventloop::EventLoop&>(singletonPool).switchTimer
+                (payloadInstance, eventloop::Timers::ACCUMULATE, true);
+
+        Buffer outPayload(sizeof(Payload));
+        auto response = reinterpret_cast<Payload*>(outPayload.data());
+        response->packetSeqNum = 0;
+        response->packetAckSeqNum = ackSeqNum;
+        response->acceptedCharCount = count;
+        response->outOperation.ack = ack;
+        sendPayload(outPayload);
+        return;
+    }
+
+    auto readSize = std::min(bufferSize, MAX_PAYLOAD_SIZE);
+    payloadCache.resize(sizeof(Payload) + readSize);
+    auto response = reinterpret_cast<Payload*>(payloadCache.data());
+    response->packetAckSeqNum = ackSeqNum;
+    response->acceptedCharCount = count;
+    response->outOperation.ack = ack;
+    response->packetSeqNum = seqNums.incOutboundSeqNum();
+
+
+    auto handle = std::get<sol::Manager&>(singletonPool).dataBuffer.read();
+    std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload));
+    expectedCharCount = readSize;
+
+    std::get<eventloop::EventLoop&>(singletonPool).switchTimer(
+            payloadInstance, eventloop::Timers::RETRY, true);
+    std::get<eventloop::EventLoop&>(singletonPool).switchTimer
+            (payloadInstance, eventloop::Timers::ACCUMULATE, false);
+
+    sendPayload(payloadCache);
+}
+
+void Context::resendPayload(bool clear)
 {
 
 }
 
-void Context::resendPayload(bool clear)
+void Context::sendPayload(const Buffer& out) const
 {
 
 }