blob: 11ef469fe6b3ca99523286e6af06b8c7fcce29bf [file] [log] [blame]
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +05301#include "config.h"
Gunnar Mills94df8c92018-09-14 14:50:03 -05002
3#include "occ_pass_through.hpp"
4
5#include "elog-errors.hpp"
6
7#include <errno.h>
8#include <fcntl.h>
Chris Caina8857c52021-01-27 11:53:05 -06009#include <fmt/core.h>
Gunnar Mills94df8c92018-09-14 14:50:03 -050010#include <unistd.h>
11
12#include <algorithm>
13#include <memory>
14#include <org/open_power/OCC/Device/error.hpp>
15#include <phosphor-logging/elog.hpp>
16#include <phosphor-logging/log.hpp>
17#include <string>
Chris Caina8857c52021-01-27 11:53:05 -060018
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050019namespace open_power
20{
21namespace occ
22{
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050023
Gunnar Mills94df8c92018-09-14 14:50:03 -050024PassThrough::PassThrough(sdbusplus::bus::bus& bus, const char* path) :
25 Iface(bus, path), path(path),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053026 devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
Chris Caina8857c52021-01-27 11:53:05 -060027 occInstance(this->path.back() - '0'),
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +053028 activeStatusSignal(
Gunnar Mills94df8c92018-09-14 14:50:03 -050029 bus, sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
30 std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
Chris Caina8857c52021-01-27 11:53:05 -060031 std::placeholders::_1)),
32 occCmd(occInstance, bus, path)
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050033{
Vishwanatha Subbanna38b08d72017-04-14 18:12:14 +053034 // Nothing to do.
35}
36
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050037std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
38{
Gunnar Mills94df8c92018-09-14 14:50:03 -050039 std::vector<int32_t> response{};
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053040
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053041 // OCC only understands [bytes] so need array of bytes. Doing this
42 // because rest-server currently treats all int* as 32 bit integer.
Chris Caina8857c52021-01-27 11:53:05 -060043 std::vector<uint8_t> cmdInBytes, rsp;
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053044 cmdInBytes.resize(command.size());
45
46 // Populate uint8_t version of vector.
47 std::transform(command.begin(), command.end(), cmdInBytes.begin(),
Gunnar Mills94df8c92018-09-14 14:50:03 -050048 [](decltype(cmdInBytes)::value_type x) { return x; });
Vishwanatha Subbanna7d700e22017-05-19 19:58:01 +053049
Chris Caina8857c52021-01-27 11:53:05 -060050 rsp = send(cmdInBytes);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053051
Chris Caina8857c52021-01-27 11:53:05 -060052 response.resize(rsp.size());
53 std::transform(rsp.begin(), rsp.end(), response.begin(),
54 [](decltype(response)::value_type x) { return x; });
55
56 return response;
57}
58
59std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
60{
61 using namespace phosphor::logging;
62 using namespace sdbusplus::org::open_power::OCC::Device::Error;
63
64 std::vector<uint8_t> response{};
65
66 log<level::DEBUG>(
67 fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}",
68 command.front(), occInstance)
69 .c_str());
70 CmdStatus status = occCmd.send(command, response);
71 if (status == CmdStatus::SUCCESS)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053072 {
Chris Caina8857c52021-01-27 11:53:05 -060073 if (response.size() >= 5)
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053074 {
Chris Caina8857c52021-01-27 11:53:05 -060075 log<level::DEBUG>(fmt::format("PassThrough::send() "
76 "response had {} bytes",
77 response.size())
78 .c_str());
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053079 }
80 else
81 {
Chris Caina8857c52021-01-27 11:53:05 -060082 log<level::ERR>("PassThrough::send() Invalid OCC response");
83 dump_hex(response);
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053084 }
85 }
Chris Caina8857c52021-01-27 11:53:05 -060086 else
87 {
88 if (status == CmdStatus::OPEN_FAILURE)
89 {
90 log<level::WARNING>("PassThrough::send() - OCC not active yet");
91 }
92 else
93 {
94 log<level::ERR>("PassThrough::send() - OCC command failed!");
95 }
96 }
Eddie James4f4712d2018-06-21 15:57:02 -050097
Vishwanatha Subbanna67d50ad2017-04-17 23:21:52 +053098 return response;
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -050099}
100
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530101// Called at OCC Status change signal
102void PassThrough::activeStatusEvent(sdbusplus::message::message& msg)
103{
104 std::string statusInterface;
Patrick Williamse0962702020-05-13 17:50:22 -0500105 std::map<std::string, std::variant<bool>> msgData;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530106 msg.read(statusInterface, msgData);
107
108 auto propertyMap = msgData.find("OccActive");
109 if (propertyMap != msgData.end())
110 {
111 // Extract the OccActive property
Patrick Williams305ff8b2020-05-13 11:17:39 -0500112 if (std::get<bool>(propertyMap->second))
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530113 {
Eddie James4f4712d2018-06-21 15:57:02 -0500114 occActive = true;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530115 }
116 else
117 {
Eddie James4f4712d2018-06-21 15:57:02 -0500118 occActive = false;
Vishwanatha Subbanna3e5422e2017-08-10 18:25:26 +0530119 }
120 }
121 return;
122}
123
Deepak Kodihalli6b492fb2017-03-18 01:09:28 -0500124} // namespace occ
125} // namespace open_power