Implement startSOLPayloadInstance
This API would register the character accumulate interval and retry
interval timer sources for the SOL Payload instance.
Change-Id: I76a3aba110b45e99dfdd99354a1376d5248ae508
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/sd_event_loop.cpp b/sd_event_loop.cpp
index 14078ea..bfb8136 100644
--- a/sd_event_loop.cpp
+++ b/sd_event_loop.cpp
@@ -97,6 +97,69 @@
return 0;
}
+static int charAccTimerHandler(sd_event_source* s, uint64_t usec,
+ void *userdata)
+{
+ // The instance is hardcoded to 1, in the case of supporting multiple
+ // payload instances we would need to populate it from userdata
+ uint8_t instance = 1;
+ auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.size();
+
+ try
+ {
+ if(bufferSize > 0)
+ {
+ // Send the SOL payload
+ }
+
+ std::get<eventloop::EventLoop&>(singletonPool).switchTimer(
+ instance, Timers::ACCUMULATE, true);
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ }
+
+ return 0;
+}
+
+static int retryTimerHandler(sd_event_source* s, uint64_t usec,
+ void *userdata)
+{
+ // The instance is hardcoded to 1, in the case of supporting multiple
+ // payload instances we would need to populate it from userdata
+ uint8_t instance = 1;
+
+ try
+ {
+ auto& context = std::get<sol::Manager&>(singletonPool).getContext
+ (instance);
+
+ if (context.retryCounter)
+ {
+ --context.retryCounter;
+ std::get<eventloop::EventLoop&>(singletonPool).switchTimer
+ (instance, Timers::RETRY, true);
+ // Resend the SOL payload
+ }
+ else
+ {
+ context.retryCounter = context.maxRetryCount;
+ // Resend the SOL payload
+ std::get<eventloop::EventLoop&>(singletonPool).switchTimer
+ (instance, Timers::RETRY, false);
+ std::get<eventloop::EventLoop&>(singletonPool).switchTimer
+ (instance, Timers::ACCUMULATE, true);
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ }
+
+ return 0;
+}
+
int EventLoop::startEventLoop()
{
int fd = -1;
@@ -217,6 +280,85 @@
}
}
+void EventLoop::startSOLPayloadInstance(uint8_t payloadInst,
+ IntervalType accumulateInterval,
+ IntervalType retryInterval)
+{
+ auto instance = payloadInst;
+ sd_event_source* accTimerSource = nullptr;
+ sd_event_source* retryTimerSource = nullptr;
+ int rc = 0;
+ uint64_t currentTime = 0;
+
+ rc = sd_event_now(event, CLOCK_MONOTONIC, ¤tTime);
+ if (rc < 0)
+ {
+ log<level::ERR>("Failed to get the current timestamp",
+ entry("RC=%d", rc));
+ throw std::runtime_error("Failed to get current timestamp");
+ }
+
+ // Create character accumulate timer
+ rc = sd_event_add_time(event,
+ &accTimerSource,
+ CLOCK_MONOTONIC,
+ currentTime + accumulateInterval.count(),
+ 0,
+ charAccTimerHandler,
+ static_cast<void *>(&instance));
+ if (rc < 0)
+ {
+ log<level::ERR>("Failed to setup the accumulate timer",
+ entry("RC = %d", rc));
+ throw std::runtime_error("Failed to setup accumulate timer");
+ }
+
+ // Create retry interval timer and add to the event loop
+ rc = sd_event_add_time(event,
+ &retryTimerSource,
+ CLOCK_MONOTONIC,
+ currentTime + retryInterval.count(),
+ 0,
+ retryTimerHandler,
+ static_cast<void *>(&instance));
+ if (rc < 0)
+ {
+ log<level::ERR>("Failed to setup the retry timer",
+ entry("RC = %d", rc));
+ throw std::runtime_error("Failed to setup retry timer");
+ }
+
+ // Enable the Character Accumulate Timer
+ rc = sd_event_source_set_enabled(accTimerSource, SD_EVENT_ONESHOT);
+ if (rc < 0)
+ {
+ log<level::ERR>("Failed to enable the accumulate timer",
+ entry("rc = %d", rc));
+ throw std::runtime_error("Failed to enable accumulate timer");
+ }
+
+ // Disable the Retry Interval Timer
+ rc = sd_event_source_set_enabled(retryTimerSource, SD_EVENT_OFF);
+ if (rc < 0)
+ {
+ log<level::ERR>("Failed to disable the retry timer",
+ entry("RC = %d", rc));
+ throw std::runtime_error("Failed to disable retry timer");
+ }
+
+ EventSource accEventSource(accTimerSource);
+ EventSource retryEventSource(retryTimerSource);
+ accTimerSource = nullptr;
+ retryTimerSource = nullptr;
+
+ TimerMap timer;
+ timer.emplace(Timers::ACCUMULATE, std::make_tuple(std::move(accEventSource),
+ accumulateInterval));
+ timer.emplace(Timers::RETRY, std::make_tuple(std::move(retryEventSource),
+ retryInterval));
+ payloadInfo.emplace(instance, std::move(timer));
+}
+
void EventLoop::switchTimer(uint8_t payloadInst,
Timers type,
bool status)