blob: b81281b2a991870b233d44f718e80aeab751c40d [file] [log] [blame]
#include <phosphor-logging/log.hpp>
#include "main.hpp"
#include "sd_event_loop.hpp"
#include "sol_context.hpp"
#include "sol_manager.hpp"
namespace sol
{
using namespace phosphor::logging;
void Context::processInboundPayload(uint8_t seqNum,
uint8_t ackSeqNum,
uint8_t count,
bool status,
const Buffer& input)
{
uint8_t respAckSeqNum = 0;
uint8_t acceptedCount = 0;
auto ack = false;
/*
* Check if the Inbound sequence number is same as the expected one.
* If the Packet Sequence Number is 0, it is an ACK-Only packet. Multiple
* outstanding sequence numbers are not supported in this version of the SOL
* specification. Retried packets use the same sequence number as the first
* packet.
*/
if(seqNum && (seqNum != seqNums.get(true)))
{
log<level::INFO>("Out of sequence SOL packet - packet is dropped");
return;
}
/*
* Check if the expected ACK/NACK sequence number is same as the
* ACK/NACK sequence number in the packet. If packet ACK/NACK sequence
* number is 0, then it is an informational packet. No request packet being
* ACK'd or NACK'd.
*/
if (ackSeqNum && (ackSeqNum != seqNums.get(false)))
{
log<level::INFO>("Out of sequence ack number - SOL packet is dropped");
return;
}
/*
* Retry the SOL payload packet in the following conditions:
*
* a) NACK in Operation/Status
* b) Accepted Character Count does not match with the sent out SOL payload
* c) Non-zero Packet ACK/NACK Sequence Number
*/
if (status || ((count != expectedCharCount) && ackSeqNum))
{
resendPayload(noClear);
std::get<eventloop::EventLoop&>(singletonPool).switchTimer
(payloadInstance, eventloop::Timers::RETRY, false);
std::get<eventloop::EventLoop&>(singletonPool).switchTimer
(payloadInstance, eventloop::Timers::RETRY, true);
return;
}
/*
* Clear the sent data once the acknowledgment sequence number matches
* and the expected character count matches.
*/
else if ((count == expectedCharCount) && ackSeqNum)
{
// Clear the Host Console Buffer
std::get<sol::Manager&>(singletonPool).dataBuffer.erase(count);
// Once it is acknowledged stop the retry interval timer
std::get<eventloop::EventLoop&>(singletonPool).switchTimer(
payloadInstance, eventloop::Timers::RETRY, false);
retryCounter = maxRetryCount;
expectedCharCount = 0;
payloadCache.clear();
}
// Write character data to the Host Console
if (!input.empty() && seqNum)
{
auto rc = std::get<sol::Manager&>(singletonPool).writeConsoleSocket(
input);
if (rc)
{
log<level::ERR>("Writing to console socket descriptor failed");
ack = true;
}
else
{
respAckSeqNum = seqNum;
ack = false;
acceptedCount = input.size();
}
}
if (seqNum != 0)
{
seqNums.incInboundSeqNum();
prepareResponse(respAckSeqNum, acceptedCount, ack);
}
else
{
std::get<eventloop::EventLoop&>(singletonPool).switchTimer
(payloadInstance, eventloop::Timers::ACCUMULATE, true);
}
}
void Context::prepareResponse(uint8_t ackSeqNum,
uint8_t count,
bool ack)
{
}
void Context::resendPayload(bool clear)
{
}
} // namespace sol