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