blob: ee3ba0bcd007ecc7ad51f22e4105ca0cebab500c [file] [log] [blame]
Tom Joseph22c5ad32017-03-14 18:04:22 +05301#include <sys/socket.h>
2#include <sys/un.h>
Tom Joseph2e44e0e2017-03-14 18:09:11 +05303#include <chrono>
Tom Joseph22c5ad32017-03-14 18:04:22 +05304#include <cmath>
5#include <phosphor-logging/log.hpp>
6#include "main.hpp"
7#include "sol_context.hpp"
8#include "sol_manager.hpp"
9
10namespace sol
11{
12
13using namespace phosphor::logging;
14
Tom Josephb81f7612017-04-25 17:59:02 +053015CustomFD::~CustomFD()
16{
17 if(fd >= 0)
18 {
19 // Remove the host console descriptor from the sd_event_loop
20 std::get<eventloop::EventLoop&>(singletonPool).stopHostConsole();
21 close(fd);
22 }
23}
24
Tom Joseph22c5ad32017-03-14 18:04:22 +053025void Manager::initHostConsoleFd()
26{
27 struct sockaddr_un addr;
28 int rc = 0;
29 int fd = 0;
30
31 fd = socket(AF_UNIX, SOCK_STREAM, 0);
32 if (fd < 0)
33 {
34 log<level::ERR>("Failed to open the host console socket",
35 entry("ERRNO=%d", errno));
36 throw std::runtime_error("Failed to open the host console socket");
37 }
38
39 memset(&addr, 0, sizeof(addr));
40 addr.sun_family = AF_UNIX;
41 memcpy(&addr.sun_path, &CONSOLE_SOCKET_PATH, CONSOLE_SOCKET_PATH_LEN);
42 consoleFD = std::make_unique<CustomFD>(fd);
43 auto& conFD = *(consoleFD.get());
44
45 rc = connect(conFD(), (struct sockaddr *)&addr, sizeof(addr));
46 if (rc < 0)
47 {
48 log<level::ERR>("Failed to connect to host console socket address",
49 entry("ERRNO=%d", errno));
50 consoleFD.reset();
51 throw std::runtime_error("Failed to connect to console server");
52 }
53}
54
Tom Josephb51f6412017-03-14 18:08:14 +053055int Manager::writeConsoleSocket(const Buffer& input) const
56{
57 auto inBuffer = input.data();
58 auto inBufferSize = input.size();
59 size_t pos = 0;
60 ssize_t rc = 0;
61 int errVal = 0;
62 auto& conFD = *(consoleFD.get());
63
64 for (pos = 0; pos < inBufferSize; pos += rc)
65 {
66 rc = write(conFD(), inBuffer + pos, inBufferSize - pos);
67 if (rc <= 0)
68 {
69 if (errno == EINTR)
70 {
71 log<level::INFO>(" Retrying to handle EINTR",
72 entry("ERRNO=%d", errno));
73 rc = 0;
74 continue;
75 }
76 else
77 {
78 errVal = errno;
79 log<level::ERR>("Failed to write to host console socket",
80 entry("ERRNO=%d", errno));
81 return -errVal;
82 }
83 }
84 }
85
86 return 0;
87}
88
Tom Joseph2e44e0e2017-03-14 18:09:11 +053089void Manager::startPayloadInstance(uint8_t payloadInstance,
90 session::SessionID sessionID)
91{
92 if (payloadMap.empty())
93 {
94 initHostConsoleFd();
95
96 // Register the fd in the sd_event_loop
97 std::get<eventloop::EventLoop&>(singletonPool).startHostConsole(
98 *(consoleFD.get()));
99 }
100
101 // Create the SOL Context data for payload instance
102 auto context = std::make_unique<Context>(
Tom Joseph32f07b82017-04-25 20:19:44 +0530103 retryCount, sendThreshold, payloadInstance, sessionID);
Tom Joseph2e44e0e2017-03-14 18:09:11 +0530104
105 /*
106 * Start payload event instance
107 *
108 * Accumulate interval is in 5 ms(milli secs) increments, since
109 * sd_event_add_time takes in micro secs, it is converted to micro secs.
110 * The Retry interval is in 10 ms (milli secs) increments.
111 */
112 using namespace std::chrono_literals;
113
114 auto accInterval = 5ms * accumulateInterval;
115 auto retryInterval = 10ms * retryThreshold;
116
117 std::get<eventloop::EventLoop&>(singletonPool).startSOLPayloadInstance(
118 payloadInstance,
119 std::chrono::duration_cast<eventloop::IntervalType>(accInterval),
120 std::chrono::duration_cast<eventloop::IntervalType>(retryInterval));
121
122 payloadMap.emplace(payloadInstance, std::move(context));
123}
124
Tom Joseph4ff14b52017-03-14 18:10:52 +0530125void Manager::stopPayloadInstance(uint8_t payloadInstance)
126{
127 auto iter = payloadMap.find(payloadInstance);
128 if (iter == payloadMap.end())
129 {
130 throw std::runtime_error("SOL Payload instance not found ");
131 }
132
133 payloadMap.erase(iter);
134
135 std::get<eventloop::EventLoop&>(singletonPool).stopSOLPayloadInstance(
136 payloadInstance);
137
138 if (payloadMap.empty())
139 {
Tom Joseph4ff14b52017-03-14 18:10:52 +0530140 consoleFD.reset();
141 }
142}
143
Tom Joseph22c5ad32017-03-14 18:04:22 +0530144} // namespace sol