blob: fcba043b18e4cf881eeb18c6af93b7ae29207371 [file] [log] [blame]
Dung Caofaf6a6a2020-12-28 04:44:45 +00001/*
2 * Copyright (c) 2021 Ampere Computing LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * This is a daemon that forwards requests and receive responses from SSIF over
17 * the D-Bus IPMI Interface.
18 */
19
20#include <getopt.h>
21#include <linux/ipmi_bmc.h>
22
23#include <CLI/CLI.hpp>
24#include <boost/algorithm/string/replace.hpp>
Ed Tanousd289aea2024-02-06 20:33:26 -080025#include <boost/asio/completion_condition.hpp>
26#include <boost/asio/io_context.hpp>
27#include <boost/asio/read.hpp>
28#include <boost/asio/steady_timer.hpp>
29#include <boost/asio/write.hpp>
Dung Caofaf6a6a2020-12-28 04:44:45 +000030#include <phosphor-logging/log.hpp>
31#include <sdbusplus/asio/connection.hpp>
32#include <sdbusplus/asio/object_server.hpp>
Patrick Williams8b050c92023-10-20 11:19:32 -050033#include <sdbusplus/timer.hpp>
Dung Caofaf6a6a2020-12-28 04:44:45 +000034
35#include <iostream>
36
Dung Cao51835392022-10-27 04:29:54 +000037/* Max length of ipmi ssif message included netfn and cmd field */
Ed Tanous7fa7e6c2024-02-14 14:33:32 -080038constexpr const size_t ipmiSsifPayloadMax = 254;
Dung Cao51835392022-10-27 04:29:54 +000039
Ed Tanous498b87f2024-02-14 09:07:34 -080040using phosphor::logging::level;
41using phosphor::logging::log;
Dung Caofaf6a6a2020-12-28 04:44:45 +000042
Ed Tanousa1585be2024-02-14 10:57:31 -080043struct IpmiCmd
Patrick Williams8b050c92023-10-20 11:19:32 -050044{
45 uint8_t netfn;
46 uint8_t lun;
47 uint8_t cmd;
Ed Tanous7fa7e6c2024-02-14 14:33:32 -080048};
quang.ampere14480ee2022-10-18 09:04:51 +070049
Ed Tanous7fa7e6c2024-02-14 14:33:32 -080050static constexpr std::string_view devBase = "/dev/ipmi-ssif-host";
Dung Caofaf6a6a2020-12-28 04:44:45 +000051/* SSIF use IPMI SSIF channel */
Ed Tanousa1585be2024-02-14 10:57:31 -080052
Quang Nguyenf2994dc2022-11-25 16:31:49 +070053/* The timer of driver is set to 15 seconds, need to send
54 * response before timeout occurs
55 */
56static constexpr const unsigned int hostReqTimeout = 14000000;
Dung Caofaf6a6a2020-12-28 04:44:45 +000057
Patrick Williams8b050c92023-10-20 11:19:32 -050058class SsifChannel
59{
60 public:
Ed Tanous7fa7e6c2024-02-14 14:33:32 -080061 static constexpr size_t ssifMessageSize = ipmiSsifPayloadMax +
Patrick Williams8b050c92023-10-20 11:19:32 -050062 sizeof(unsigned int);
63 size_t sizeofLenField = sizeof(unsigned int);
64 static constexpr uint8_t netFnShift = 2;
65 static constexpr uint8_t lunMask = (1 << netFnShift) - 1;
Dung Caofaf6a6a2020-12-28 04:44:45 +000066
Patrick Williams8b050c92023-10-20 11:19:32 -050067 SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
68 std::shared_ptr<sdbusplus::asio::connection>& bus,
Ed Tanous98f55c72024-02-14 16:23:30 -080069 const std::string& device, bool verbose);
Patrick Williams8b050c92023-10-20 11:19:32 -050070 bool initOK() const
71 {
Ed Tanousfcd0ea42024-02-14 09:15:41 -080072 return dev.is_open();
Patrick Williams8b050c92023-10-20 11:19:32 -050073 }
74 void channelAbort(const char* msg, const boost::system::error_code& ec);
Ed Tanousa1585be2024-02-14 10:57:31 -080075 void asyncRead();
Ed Tanousb6ad9dc2024-02-14 09:28:20 -080076 using IpmiDbusRspType =
77 std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>;
78
79 void afterMethodCall(const boost::system::error_code& ec,
80 const IpmiDbusRspType& response);
Patrick Williams8b050c92023-10-20 11:19:32 -050081 void processMessage(const boost::system::error_code& ecRd, size_t rlen);
Ed Tanousa1585be2024-02-14 10:57:31 -080082 int showNumOfReqNotRsp() const;
Ed Tanousfcd0ea42024-02-14 09:15:41 -080083 boost::asio::posix::stream_descriptor dev;
Ed Tanous7fa7e6c2024-02-14 14:33:32 -080084 IpmiCmd prevReqCmd{};
Dung Caofaf6a6a2020-12-28 04:44:45 +000085
Patrick Williams8b050c92023-10-20 11:19:32 -050086 protected:
Ed Tanousa1585be2024-02-14 10:57:31 -080087 std::array<uint8_t, ssifMessageSize> xferBuffer{};
Patrick Williams8b050c92023-10-20 11:19:32 -050088 std::shared_ptr<boost::asio::io_context> io;
89 std::shared_ptr<sdbusplus::asio::connection> bus;
90 std::shared_ptr<sdbusplus::asio::object_server> server;
91 bool verbose;
92 /* This variable is always 0 when a request is responsed properly,
93 * any value larger than 0 meaning there is/are request(s) which
94 * not processed properly
95 * */
Ed Tanous98f55c72024-02-14 16:23:30 -080096 int numberOfReqNotRsp = 0;
Ed Tanous4ae3b9e2024-02-14 08:54:03 -080097
98 boost::asio::steady_timer rspTimer;
Dung Caofaf6a6a2020-12-28 04:44:45 +000099};
100
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800101// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700102std::unique_ptr<SsifChannel> ssifchannel = nullptr;
103
Patrick Williams8b050c92023-10-20 11:19:32 -0500104SsifChannel::SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
105 std::shared_ptr<sdbusplus::asio::connection>& bus,
Ed Tanous98f55c72024-02-14 16:23:30 -0800106 const std::string& device, bool verbose) :
Ed Tanousfcd0ea42024-02-14 09:15:41 -0800107 dev(*io),
Ed Tanous98f55c72024-02-14 16:23:30 -0800108 io(io), bus(bus), verbose(verbose), rspTimer(*io)
Dung Caofaf6a6a2020-12-28 04:44:45 +0000109{
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800110 std::string devName(devBase);
Patrick Williams8b050c92023-10-20 11:19:32 -0500111 if (!device.empty())
112 {
113 devName = device;
114 }
Dung Caofaf6a6a2020-12-28 04:44:45 +0000115
Patrick Williams8b050c92023-10-20 11:19:32 -0500116 // open device
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800117 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
Patrick Williams8b050c92023-10-20 11:19:32 -0500118 int fd = open(devName.c_str(), O_RDWR | O_NONBLOCK);
119 if (fd < 0)
120 {
121 std::string msgToLog = "Couldn't open SSIF driver with flags O_RDWR."
122 " FILENAME=" +
123 devName + " ERROR=" + strerror(errno);
124 log<level::ERR>(msgToLog.c_str());
125 return;
126 }
Dung Caofaf6a6a2020-12-28 04:44:45 +0000127
Ed Tanousa1585be2024-02-14 10:57:31 -0800128 dev.assign(fd);
129
130 asyncRead();
Patrick Williams8b050c92023-10-20 11:19:32 -0500131 // register interfaces...
132 server = std::make_shared<sdbusplus::asio::object_server>(bus);
133 std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
Ed Tanousa1585be2024-02-14 10:57:31 -0800134 server->add_interface("/xyz/openbmc_project/Ipmi/Channel/ipmi_ssif",
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800135 "xyz.openbmc_project.Ipmi.Channel.ipmi_ssif");
Patrick Williams8b050c92023-10-20 11:19:32 -0500136 iface->initialize();
Dung Caofaf6a6a2020-12-28 04:44:45 +0000137}
138
Patrick Williams8b050c92023-10-20 11:19:32 -0500139void SsifChannel::channelAbort(const char* msg,
140 const boost::system::error_code& ec)
Dung Caofaf6a6a2020-12-28 04:44:45 +0000141{
Patrick Williams8b050c92023-10-20 11:19:32 -0500142 std::string msgToLog = std::string(msg) + " ERROR=" + ec.message();
143 log<level::ERR>(msgToLog.c_str());
144 // bail; maybe a restart from systemd can clear the error
145 io->stop();
Dung Caofaf6a6a2020-12-28 04:44:45 +0000146}
147
Ed Tanousa1585be2024-02-14 10:57:31 -0800148void SsifChannel::asyncRead()
Dung Caofaf6a6a2020-12-28 04:44:45 +0000149{
Ed Tanousfcd0ea42024-02-14 09:15:41 -0800150 boost::asio::async_read(dev,
Patrick Williams8b050c92023-10-20 11:19:32 -0500151 boost::asio::buffer(xferBuffer, xferBuffer.size()),
152 boost::asio::transfer_at_least(2),
153 [this](const boost::system::error_code& ec,
154 size_t rlen) { processMessage(ec, rlen); });
Dung Caofaf6a6a2020-12-28 04:44:45 +0000155}
156
Ed Tanousa1585be2024-02-14 10:57:31 -0800157int SsifChannel::showNumOfReqNotRsp() const
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700158{
Patrick Williams8b050c92023-10-20 11:19:32 -0500159 return numberOfReqNotRsp;
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700160}
161
Ed Tanousd289aea2024-02-06 20:33:26 -0800162void rspTimerHandler(const boost::system::error_code& ec)
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700163{
Ed Tanousd289aea2024-02-06 20:33:26 -0800164 if (ec == boost::asio::error::operation_aborted)
165 {
166 return;
167 }
Patrick Williams8b050c92023-10-20 11:19:32 -0500168 std::vector<uint8_t> rsp;
169 constexpr uint8_t ccResponseNotAvailable = 0xce;
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800170 IpmiCmd& prevReqCmd = ssifchannel->prevReqCmd;
Ed Tanousa1585be2024-02-14 10:57:31 -0800171 rsp.resize(ssifchannel->sizeofLenField + sizeof(prevReqCmd.cmd) +
172 sizeof(prevReqCmd.netfn) + sizeof(ccResponseNotAvailable));
Patrick Williams8b050c92023-10-20 11:19:32 -0500173 std::string msgToLog = "timeout, send response to keep host alive"
174 " netfn=" +
Ed Tanousa1585be2024-02-14 10:57:31 -0800175 std::to_string(prevReqCmd.netfn) +
176 " lun=" + std::to_string(prevReqCmd.lun) +
177 " cmd=" + std::to_string(prevReqCmd.cmd) +
Patrick Williams8b050c92023-10-20 11:19:32 -0500178 " cc=" + std::to_string(ccResponseNotAvailable) +
179 " numberOfReqNotRsp=" +
180 std::to_string(ssifchannel->showNumOfReqNotRsp());
181 log<level::INFO>(msgToLog.c_str());
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800182 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
183 unsigned int* t = reinterpret_cast<unsigned int*>(rsp.data());
Patrick Williams8b050c92023-10-20 11:19:32 -0500184 *t = 3;
Ed Tanousa1585be2024-02-14 10:57:31 -0800185 rsp[ssifchannel->sizeofLenField] = ((prevReqCmd.netfn + 1)
186 << ssifchannel->netFnShift) |
187 (prevReqCmd.lun & ssifchannel->lunMask);
188 rsp[ssifchannel->sizeofLenField + 1] = prevReqCmd.cmd;
Patrick Williams8b050c92023-10-20 11:19:32 -0500189 rsp[ssifchannel->sizeofLenField + 2] = ccResponseNotAvailable;
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700190
Patrick Williams8b050c92023-10-20 11:19:32 -0500191 boost::system::error_code ecWr;
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700192
Ed Tanousfcd0ea42024-02-14 09:15:41 -0800193 size_t wlen = boost::asio::write(ssifchannel->dev, boost::asio::buffer(rsp),
194 ecWr);
Patrick Williams8b050c92023-10-20 11:19:32 -0500195 if (ecWr || wlen != rsp.size())
196 {
197 msgToLog =
198 "Failed to send ssif respond message:"
199 " size=" +
200 std::to_string(wlen) + " expect=" + std::to_string(rsp.size()) +
201 " error=" + ecWr.message() +
Ed Tanousa1585be2024-02-14 10:57:31 -0800202 " netfn=" + std::to_string(prevReqCmd.netfn + 1) +
203 " lun=" + std::to_string(prevReqCmd.lun) +
Patrick Williams8b050c92023-10-20 11:19:32 -0500204 " cmd=" + std::to_string(rsp[ssifchannel->sizeofLenField + 1]) +
205 " cc=" + std::to_string(ccResponseNotAvailable);
206 log<level::ERR>(msgToLog.c_str());
207 }
Quang Nguyenf2994dc2022-11-25 16:31:49 +0700208}
209
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800210void SsifChannel::afterMethodCall(const boost::system::error_code& ec,
211 const IpmiDbusRspType& response)
212{
213 std::vector<uint8_t> rsp;
214 const auto& [netfn, lun, cmd, cc, payload] = response;
215 numberOfReqNotRsp--;
216 if (ec)
217 {
218 std::string msgToLog =
219 "ssif<->ipmid bus error:"
220 " netfn=" +
221 std::to_string(netfn) + " lun=" + std::to_string(lun) +
222 " cmd=" + std::to_string(cmd) + " error=" + ec.message();
223 log<level::ERR>(msgToLog.c_str());
224 rsp.resize(sizeofLenField + sizeof(netfn) + sizeof(cmd) + sizeof(cc));
225 /* if dbusTimeout, just return and do not send any response
226 * to let host continue with other commands, response here
227 * is potentially make the response duplicated
228 * */
229 return;
230 }
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800231
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800232 if ((prevReqCmd.netfn != (netfn - 1) || prevReqCmd.lun != lun ||
233 prevReqCmd.cmd != cmd) ||
234 ((prevReqCmd.netfn == (netfn - 1) && prevReqCmd.lun == lun &&
235 prevReqCmd.cmd == cmd) &&
236 numberOfReqNotRsp != 0))
237 {
238 /* Only send response to the last request command to void
239 * duplicated response which makes host driver confused and
240 * failed to create interface
241 *
242 * Drop responses which are (1) different from the request
243 * (2) parameters are the same as request but handshake flow
244 * are in dupplicate request state
245 * */
246 if (verbose)
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800247 {
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800248 std::string msgToLog =
249 "Drop ssif respond message with"
250 " len=" +
251 std::to_string(payload.size() + 3) +
252 " netfn=" + std::to_string(netfn) +
253 " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
254 " cc=" + std::to_string(cc) +
255 " numberOfReqNotRsp=" + std::to_string(numberOfReqNotRsp);
256 log<level::INFO>(msgToLog.c_str());
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800257 }
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800258 return;
259 }
260 rsp.resize(sizeofLenField + sizeof(netfn) + sizeof(cmd) + sizeof(cc) +
261 payload.size());
262
263 // write the response
264 auto rspIter = rsp.begin();
265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
266 unsigned int* p = reinterpret_cast<unsigned int*>(&rspIter[0]);
267 *p = payload.size() + 3;
268 rspIter[sizeofLenField] = (netfn << netFnShift) | (lun & lunMask);
269 rspIter[sizeofLenField + 1] = cmd;
270 rspIter[sizeofLenField + 2] = cc;
271 if (static_cast<unsigned int>(!payload.empty()) != 0U)
272 {
273 std::copy(payload.cbegin(), payload.cend(),
274 rspIter + sizeofLenField + 3);
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800275 }
276 if (verbose)
277 {
278 std::string msgToLog =
279 "Send ssif respond message with"
280 " len=" +
281 std::to_string(payload.size() + 3) +
282 " netfn=" + std::to_string(netfn) + " lun=" + std::to_string(lun) +
283 " cmd=" + std::to_string(cmd) + " cc=" + std::to_string(cc) +
284 " numberOfReqNotRsp=" + std::to_string(numberOfReqNotRsp);
285 log<level::INFO>(msgToLog.c_str());
286 }
287 boost::system::error_code ecWr;
288 size_t wlen = boost::asio::write(dev, boost::asio::buffer(rsp), ecWr);
289 if (ecWr || wlen != rsp.size())
290 {
291 std::string msgToLog =
292 "Failed to send ssif respond message:"
293 " size=" +
294 std::to_string(wlen) + " expect=" + std::to_string(rsp.size()) +
295 " error=" + ecWr.message() + " netfn=" + std::to_string(netfn) +
296 " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
297 " cc=" + std::to_string(cc);
298 log<level::ERR>(msgToLog.c_str());
299 }
300 rspTimer.cancel();
301}
302
Patrick Williams8b050c92023-10-20 11:19:32 -0500303void SsifChannel::processMessage(const boost::system::error_code& ecRd,
304 size_t rlen)
Dung Caofaf6a6a2020-12-28 04:44:45 +0000305{
Patrick Williams8b050c92023-10-20 11:19:32 -0500306 if (ecRd || rlen < 2)
307 {
308 channelAbort("Failed to read req msg", ecRd);
309 return;
310 }
Ed Tanousa1585be2024-02-14 10:57:31 -0800311 asyncRead();
Dung Caofaf6a6a2020-12-28 04:44:45 +0000312
Ed Tanousa1585be2024-02-14 10:57:31 -0800313 const auto* rawIter = xferBuffer.cbegin();
314 const auto* rawEnd = rawIter + rlen;
Patrick Williams8b050c92023-10-20 11:19:32 -0500315 uint8_t netfn = rawIter[sizeofLenField] >> netFnShift;
316 uint8_t lun = rawIter[sizeofLenField] & lunMask;
317 uint8_t cmd = rawIter[sizeofLenField + 1];
quang.ampere14480ee2022-10-18 09:04:51 +0700318
Patrick Williams8b050c92023-10-20 11:19:32 -0500319 /* keep track of previous request */
Ed Tanousa1585be2024-02-14 10:57:31 -0800320 prevReqCmd.netfn = netfn;
321 prevReqCmd.lun = lun;
322 prevReqCmd.cmd = cmd;
quang.ampere14480ee2022-10-18 09:04:51 +0700323
Patrick Williams8b050c92023-10-20 11:19:32 -0500324 /* there is a request coming */
325 numberOfReqNotRsp++;
326 /* start response timer */
Ed Tanous4ae3b9e2024-02-14 08:54:03 -0800327 rspTimer.expires_after(std::chrono::microseconds(hostReqTimeout));
328 rspTimer.async_wait(rspTimerHandler);
quang.name507782a2022-11-20 17:05:20 +0700329
Patrick Williams8b050c92023-10-20 11:19:32 -0500330 if (verbose)
331 {
Ed Tanousa1585be2024-02-14 10:57:31 -0800332 unsigned int lenRecv = 0;
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800333 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
334 const unsigned int* p = reinterpret_cast<const unsigned int*>(rawIter);
Patrick Williams8b050c92023-10-20 11:19:32 -0500335 lenRecv = p[0];
336 std::string msgToLog =
337 "Read ssif request message with"
338 " len=" +
339 std::to_string(lenRecv) + " netfn=" + std::to_string(netfn) +
340 " lun=" + std::to_string(lun) + " cmd=" + std::to_string(cmd) +
341 " numberOfReqNotRsp=" + std::to_string(numberOfReqNotRsp);
342 log<level::INFO>(msgToLog.c_str());
343 }
344 // copy out payload
345 std::vector<uint8_t> data(rawIter + sizeofLenField + 2, rawEnd);
346 // non-session bridges still need to pass an empty options map
347 std::map<std::string, std::variant<int>> options;
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800348 static constexpr const char* ipmiQueueService =
Patrick Williams8b050c92023-10-20 11:19:32 -0500349 "xyz.openbmc_project.Ipmi.Host";
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800350 static constexpr const char* ipmiQueuePath = "/xyz/openbmc_project/Ipmi";
351 static constexpr const char* ipmiQueueIntf =
Patrick Williams8b050c92023-10-20 11:19:32 -0500352 "xyz.openbmc_project.Ipmi.Server";
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800353 static constexpr const char* ipmiQueueMethod = "execute";
Patrick Williams8b050c92023-10-20 11:19:32 -0500354 /* now, we do not care dbus timeout, since we already have actions
355 * before dbus timeout occurs
356 */
357 static constexpr unsigned int dbusTimeout = 60000000;
358 bus->async_method_call_timed(
Ed Tanousb6ad9dc2024-02-14 09:28:20 -0800359 [this](const boost::system::error_code& ec,
360 const IpmiDbusRspType& response) {
361 afterMethodCall(ec, response);
Patrick Williams8b050c92023-10-20 11:19:32 -0500362 },
363 ipmiQueueService, ipmiQueuePath, ipmiQueueIntf, ipmiQueueMethod,
364 dbusTimeout, netfn, lun, cmd, data, options);
Dung Caofaf6a6a2020-12-28 04:44:45 +0000365}
366
Patrick Williams8b050c92023-10-20 11:19:32 -0500367int main(int argc, char* argv[])
Dung Caofaf6a6a2020-12-28 04:44:45 +0000368{
Patrick Williams8b050c92023-10-20 11:19:32 -0500369 CLI::App app("SSIF IPMI bridge");
370 std::string device;
371 app.add_option("-d,--device", device,
372 "use <DEVICE> file. Default is /dev/ipmi-ssif-host");
373 bool verbose = false;
Patrick Williams8b050c92023-10-20 11:19:32 -0500374 app.add_option("-v,--verbose", verbose, "print more verbose output");
375 CLI11_PARSE(app, argc, argv);
Dung Caofaf6a6a2020-12-28 04:44:45 +0000376
Patrick Williams8b050c92023-10-20 11:19:32 -0500377 auto io = std::make_shared<boost::asio::io_context>();
Dung Caofaf6a6a2020-12-28 04:44:45 +0000378
Ed Tanousd289aea2024-02-06 20:33:26 -0800379 auto bus = std::make_shared<sdbusplus::asio::connection>(*io);
Ed Tanous7fa7e6c2024-02-14 14:33:32 -0800380 bus->request_name("xyz.openbmc_project.Ipmi.Channel.ipmi_ssif");
Patrick Williams8b050c92023-10-20 11:19:32 -0500381 // Create the SSIF channel, listening on D-Bus and on the SSIF device
Ed Tanous98f55c72024-02-14 16:23:30 -0800382 ssifchannel = make_unique<SsifChannel>(io, bus, device, verbose);
Patrick Williams8b050c92023-10-20 11:19:32 -0500383 if (!ssifchannel->initOK())
384 {
385 return EXIT_FAILURE;
386 }
Patrick Williams8b050c92023-10-20 11:19:32 -0500387 io->run();
Thang Q. Nguyen4300d212023-05-15 12:22:53 +0700388
Patrick Williams8b050c92023-10-20 11:19:32 -0500389 return 0;
Dung Caofaf6a6a2020-12-28 04:44:45 +0000390}