xref: /openbmc/fb-ipmi-oem/src/biccommands.cpp (revision e1ff81fa)
1 /*
2  * Copyright (c)  2018 Intel Corporation.
3  * Copyright (c)  2018-present Facebook.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <ipmid/api.hpp>
19 #include <ipmid/api-types.hpp>
20 
21 #include <commandutils.hpp>
22 #include <biccommands.hpp>
23 #include <phosphor-logging/log.hpp>
24 
25 #include <vector>
26 #include <variant>
27 #include <iostream>
28 
29 namespace ipmi
30 {
31 
32 using namespace phosphor::logging;
33 
34 #ifdef BIC_ENABLED
35 static void registerBICFunctions() __attribute__((constructor));
36 #endif
37 
38 extern message::Response::ptr executeIpmiCommand(message::Request::ptr);
39 
40 //----------------------------------------------------------------------
41 // ipmiOemBicHandler (IPMI/Section - ) (CMD_OEM_BIC_INFO)
42 // This Function will handle BIC request for netfn=0x38 and cmd=1
43 // send the response back to the sender.
44 //----------------------------------------------------------------------
45 
46 ipmi::RspType<std::array<uint8_t, 3>, uint8_t, uint2_t, uint6_t, uint8_t,
47               uint8_t, ipmi::message::Payload>
48     ipmiOemBicHandler(ipmi::Context::ptr ctx, std::array<uint8_t, 3> iana,
49                       uint8_t interface, uint2_t lun, uint6_t netFnReq,
50                       uint8_t cmdReq, SecureBuffer data)
51 {
52 
53     ipmi::message::Response::ptr res;
54 
55     // Updating the correct netfn and cmd in the ipmi Context
56     ctx->netFn = ((uint8_t)netFnReq);
57     ctx->cmd = cmdReq;
58 
59     // creating ipmi message request for calling executeIpmiCommand function
60     auto req = std::make_shared<ipmi::message::Request>(ctx, std::move(data));
61 
62     // Calling executeIpmiCommand request function
63     res = ipmi::executeIpmiCommand(req);
64 
65     // sending the response with headers and payload
66     return ipmi::responseSuccess(iana, interface, lun, ++netFnReq, cmdReq,
67                                  res->cc, res->payload);
68 }
69 
70 //----------------------------------------------------------------------
71 // ipmiOemPostCodeHandler (CMD_OEM_BIC_POST_BUFFER_INFO)
72 // This Function will handle BIC incomming postcode from multi-host for
73 // netfn=0x38 and cmd=0x08 send the response back to the sender.
74 //----------------------------------------------------------------------
75 
76 ipmi::RspType<std::array<uint8_t, 3>>
77     ipmiOemPostCodeHandler(ipmi::Context::ptr ctx, std::array<uint8_t, 3> iana,
78                            uint8_t dataLen, std::vector<uint8_t> data)
79 {
80     // creating bus connection
81     auto conn = getSdBus();
82 
83     using postcode_t = std::tuple<uint64_t, std::vector<uint8_t>>;
84 
85     std::string dbusObjStr = dbusObj + std::to_string((ctx->hostIdx + 1));
86 
87     for (unsigned int index = 0; index < dataLen; index++)
88     {
89         uint64_t primaryPostCode = static_cast<uint64_t>(data[index]);
90         auto postCode = postcode_t(primaryPostCode, {});
91 
92         try
93         {
94             auto method = conn->new_method_call(
95                 "xyz.openbmc_project.State.Boot.Raw", dbusObjStr.c_str(),
96                 "org.freedesktop.DBus.Properties", "Set");
97 
98             // Adding paramters to method call
99             method.append(dbusService, "Value",
100                           std::variant<postcode_t>(postCode));
101 
102             // Invoke method call function
103             auto reply = conn->call(method);
104         }
105 
106         catch (std::exception& e)
107         {
108             phosphor::logging::log<phosphor::logging::level::ERR>(
109                 "post code handler error\n");
110 
111             // sending the Error response
112             return ipmi::responseResponseError();
113         }
114     }
115 
116     return ipmi::responseSuccess(iana);
117 }
118 
119 [[maybe_unused]] static void registerBICFunctions(void)
120 {
121 
122     phosphor::logging::log<phosphor::logging::level::INFO>(
123         "Registering BIC commands");
124 
125     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
126                           cmdOemBicInfo, ipmi::Privilege::User,
127                           ipmiOemBicHandler);
128     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
129                           cmdOemSendPostBufferToBMC, ipmi::Privilege::User,
130                           ipmiOemPostCodeHandler);
131     return;
132 }
133 
134 } // namespace ipmi
135