From e989c36df2840d23483a051fbac540f332190cae Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Tue, 14 Mar 2017 17:16:50 +0530 Subject: 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 --- sd_event_loop.cpp | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'sd_event_loop.cpp') 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 @@ static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents, 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(singletonPool).dataBuffer.size(); + + try + { + if(bufferSize > 0) + { + // Send the SOL payload + } + + std::get(singletonPool).switchTimer( + instance, Timers::ACCUMULATE, true); + } + catch (std::exception& e) + { + log(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(singletonPool).getContext + (instance); + + if (context.retryCounter) + { + --context.retryCounter; + std::get(singletonPool).switchTimer + (instance, Timers::RETRY, true); + // Resend the SOL payload + } + else + { + context.retryCounter = context.maxRetryCount; + // Resend the SOL payload + std::get(singletonPool).switchTimer + (instance, Timers::RETRY, false); + std::get(singletonPool).switchTimer + (instance, Timers::ACCUMULATE, true); + } + } + catch (std::exception& e) + { + log(e.what()); + } + + return 0; +} + int EventLoop::startEventLoop() { int fd = -1; @@ -217,6 +280,85 @@ void EventLoop::stopHostConsole() } } +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("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(&instance)); + if (rc < 0) + { + log("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(&instance)); + if (rc < 0) + { + log("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("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("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) -- cgit v1.2.1