13e5422edSVishwanatha Subbanna #include "config.h"
294df8c90SGunnar Mills 
394df8c90SGunnar Mills #include "occ_pass_through.hpp"
494df8c90SGunnar Mills 
594df8c90SGunnar Mills #include "elog-errors.hpp"
694df8c90SGunnar Mills 
794df8c90SGunnar Mills #include <errno.h>
894df8c90SGunnar Mills #include <fcntl.h>
9*a8857c50SChris Cain #include <fmt/core.h>
1094df8c90SGunnar Mills #include <unistd.h>
1194df8c90SGunnar Mills 
1294df8c90SGunnar Mills #include <algorithm>
1394df8c90SGunnar Mills #include <memory>
1494df8c90SGunnar Mills #include <org/open_power/OCC/Device/error.hpp>
1594df8c90SGunnar Mills #include <phosphor-logging/elog.hpp>
1694df8c90SGunnar Mills #include <phosphor-logging/log.hpp>
1794df8c90SGunnar Mills #include <string>
18*a8857c50SChris Cain 
196b492fbfSDeepak Kodihalli namespace open_power
206b492fbfSDeepak Kodihalli {
216b492fbfSDeepak Kodihalli namespace occ
226b492fbfSDeepak Kodihalli {
236b492fbfSDeepak Kodihalli 
2494df8c90SGunnar Mills PassThrough::PassThrough(sdbusplus::bus::bus& bus, const char* path) :
2594df8c90SGunnar Mills     Iface(bus, path), path(path),
263e5422edSVishwanatha Subbanna     devicePath(OCC_DEV_PATH + std::to_string((this->path.back() - '0') + 1)),
27*a8857c50SChris Cain     occInstance(this->path.back() - '0'),
283e5422edSVishwanatha Subbanna     activeStatusSignal(
2994df8c90SGunnar Mills         bus, sdbusRule::propertiesChanged(path, "org.open_power.OCC.Status"),
3094df8c90SGunnar Mills         std::bind(std::mem_fn(&PassThrough::activeStatusEvent), this,
31*a8857c50SChris Cain                   std::placeholders::_1)),
32*a8857c50SChris Cain     occCmd(occInstance, bus, path)
336b492fbfSDeepak Kodihalli {
3438b08d79SVishwanatha Subbanna     // Nothing to do.
3538b08d79SVishwanatha Subbanna }
3638b08d79SVishwanatha Subbanna 
376b492fbfSDeepak Kodihalli std::vector<int32_t> PassThrough::send(std::vector<int32_t> command)
386b492fbfSDeepak Kodihalli {
3967d50ad6SVishwanatha Subbanna     std::vector<int32_t> response{};
4067d50ad6SVishwanatha Subbanna 
417d700e26SVishwanatha Subbanna     // OCC only understands [bytes] so need array of bytes. Doing this
427d700e26SVishwanatha Subbanna     // because rest-server currently treats all int* as 32 bit integer.
43*a8857c50SChris Cain     std::vector<uint8_t> cmdInBytes, rsp;
447d700e26SVishwanatha Subbanna     cmdInBytes.resize(command.size());
457d700e26SVishwanatha Subbanna 
467d700e26SVishwanatha Subbanna     // Populate uint8_t version of vector.
477d700e26SVishwanatha Subbanna     std::transform(command.begin(), command.end(), cmdInBytes.begin(),
487d700e26SVishwanatha Subbanna                    [](decltype(cmdInBytes)::value_type x) { return x; });
497d700e26SVishwanatha Subbanna 
50*a8857c50SChris Cain     rsp = send(cmdInBytes);
51*a8857c50SChris Cain 
52*a8857c50SChris Cain     response.resize(rsp.size());
53*a8857c50SChris Cain     std::transform(rsp.begin(), rsp.end(), response.begin(),
54*a8857c50SChris Cain                    [](decltype(response)::value_type x) { return x; });
55*a8857c50SChris Cain 
56*a8857c50SChris Cain     return response;
576b492fbfSDeepak Kodihalli }
586b492fbfSDeepak Kodihalli 
59*a8857c50SChris Cain std::vector<uint8_t> PassThrough::send(std::vector<uint8_t> command)
6067d50ad6SVishwanatha Subbanna {
61*a8857c50SChris Cain     using namespace phosphor::logging;
62*a8857c50SChris Cain     using namespace sdbusplus::org::open_power::OCC::Device::Error;
63*a8857c50SChris Cain 
64*a8857c50SChris Cain     std::vector<uint8_t> response{};
65*a8857c50SChris Cain 
66*a8857c50SChris Cain     log<level::DEBUG>(
67*a8857c50SChris Cain         fmt::format("PassThrough::send() Sending 0x{:02X} command to OCC{}",
68*a8857c50SChris Cain                     command.front(), occInstance)
69*a8857c50SChris Cain             .c_str());
70*a8857c50SChris Cain     CmdStatus status = occCmd.send(command, response);
71*a8857c50SChris Cain     if (status == CmdStatus::SUCCESS)
7267d50ad6SVishwanatha Subbanna     {
73*a8857c50SChris Cain         if (response.size() >= 5)
7467d50ad6SVishwanatha Subbanna         {
75*a8857c50SChris Cain             log<level::DEBUG>(fmt::format("PassThrough::send() "
76*a8857c50SChris Cain                                           "response had {} bytes",
77*a8857c50SChris Cain                                           response.size())
78*a8857c50SChris Cain                                   .c_str());
7967d50ad6SVishwanatha Subbanna         }
8067d50ad6SVishwanatha Subbanna         else
8167d50ad6SVishwanatha Subbanna         {
82*a8857c50SChris Cain             log<level::ERR>("PassThrough::send() Invalid OCC response");
83*a8857c50SChris Cain             dump_hex(response);
8467d50ad6SVishwanatha Subbanna         }
8567d50ad6SVishwanatha Subbanna     }
86*a8857c50SChris Cain     else
87*a8857c50SChris Cain     {
88*a8857c50SChris Cain         if (status == CmdStatus::OPEN_FAILURE)
89*a8857c50SChris Cain         {
90*a8857c50SChris Cain             log<level::WARNING>("PassThrough::send() - OCC not active yet");
91*a8857c50SChris Cain         }
92*a8857c50SChris Cain         else
93*a8857c50SChris Cain         {
94*a8857c50SChris Cain             log<level::ERR>("PassThrough::send() - OCC command failed!");
95*a8857c50SChris Cain         }
96*a8857c50SChris Cain     }
974f4712d8SEddie James 
9867d50ad6SVishwanatha Subbanna     return response;
9967d50ad6SVishwanatha Subbanna }
10067d50ad6SVishwanatha Subbanna 
1013e5422edSVishwanatha Subbanna // Called at OCC Status change signal
1023e5422edSVishwanatha Subbanna void PassThrough::activeStatusEvent(sdbusplus::message::message& msg)
1033e5422edSVishwanatha Subbanna {
1043e5422edSVishwanatha Subbanna     std::string statusInterface;
105e0962703SPatrick Williams     std::map<std::string, std::variant<bool>> msgData;
1063e5422edSVishwanatha Subbanna     msg.read(statusInterface, msgData);
1073e5422edSVishwanatha Subbanna 
1083e5422edSVishwanatha Subbanna     auto propertyMap = msgData.find("OccActive");
1093e5422edSVishwanatha Subbanna     if (propertyMap != msgData.end())
1103e5422edSVishwanatha Subbanna     {
1113e5422edSVishwanatha Subbanna         // Extract the OccActive property
112305ff8b1SPatrick Williams         if (std::get<bool>(propertyMap->second))
1133e5422edSVishwanatha Subbanna         {
1144f4712d8SEddie James             occActive = true;
1153e5422edSVishwanatha Subbanna         }
1163e5422edSVishwanatha Subbanna         else
1173e5422edSVishwanatha Subbanna         {
1184f4712d8SEddie James             occActive = false;
1193e5422edSVishwanatha Subbanna         }
1203e5422edSVishwanatha Subbanna     }
1213e5422edSVishwanatha Subbanna     return;
1223e5422edSVishwanatha Subbanna }
1233e5422edSVishwanatha Subbanna 
1246b492fbfSDeepak Kodihalli } // namespace occ
1256b492fbfSDeepak Kodihalli } // namespace open_power
126