1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & 3 * AFFILIATES. All rights reserved. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "oemcommands.hpp" 8 9 #include <ipmid/api.hpp> 10 #include <ipmid/types.hpp> 11 #include <ipmid/utils.hpp> 12 #include <phosphor-logging/lg2.hpp> 13 14 #include <cstdint> 15 16 void registerBootstrapCredentialsOemCommands() __attribute__((constructor)); 17 18 namespace ipmi 19 { 20 ipmi::RspType<uint8_t, uint8_t> ipmiGetUsbVendorIdProductId(uint8_t type) 21 { 22 constexpr uint8_t descriptorVendorId = 1; 23 constexpr uint8_t descriptorProductId = 2; 24 25 // IPMI OEM USB Linux Gadget info 26 constexpr uint16_t usbVendorId = 0x0525; 27 constexpr uint16_t usbProductId = 0xA4A2; 28 29 if (type == descriptorVendorId) 30 { 31 return ipmi::responseSuccess(static_cast<uint8_t>(usbVendorId >> 8), 32 static_cast<uint8_t>(usbVendorId & 0xFF)); 33 } 34 else if (type == descriptorProductId) 35 { 36 return ipmi::responseSuccess(static_cast<uint8_t>(usbProductId >> 8), 37 static_cast<uint8_t>(usbProductId & 0xFF)); 38 } 39 return ipmi::responseInvalidFieldRequest(); 40 } 41 42 ipmi::RspType<ipmi::message::Payload> ipmiGetUsbSerialNumber() 43 { 44 static constexpr uint8_t usbSerialNumber = 0x00; 45 ipmi::message::Payload usbSerialNumberPayload; 46 usbSerialNumberPayload.pack(usbSerialNumber); 47 return ipmi::responseSuccess(usbSerialNumberPayload); 48 } 49 50 ipmi::RspType<ipmi::message::Payload> ipmiGetRedfishHostName( 51 ipmi::Context::ptr ctx) 52 { 53 std::string service{}; 54 constexpr auto networkConfigObj = "/xyz/openbmc_project/network/config"; 55 constexpr auto networkConfigIface = 56 "xyz.openbmc_project.Network.SystemConfiguration"; 57 boost::system::error_code ec = 58 ipmi::getService(ctx, networkConfigIface, networkConfigObj, service); 59 if (ec) 60 { 61 lg2::error("ipmiGetRedfishHostName failed to get Network SystemConfig " 62 "object: {STATUS}", 63 "STATUS", ec.message()); 64 return ipmi::responseResponseError(); 65 } 66 67 std::string hostName{}; 68 ec = ipmi::getDbusProperty<std::string>( 69 ctx, service, networkConfigObj, networkConfigIface, "HostName", 70 hostName); 71 if (ec) 72 { 73 lg2::error("ipmiGetRedfishHostName failed to get HostName from Network " 74 "SystemConfig service: {STATUS}", 75 "STATUS", ec.message()); 76 return ipmi::responseResponseError(); 77 } 78 ipmi::message::Payload hostNamePayload; 79 hostNamePayload.pack( 80 std::vector<uint8_t>(hostName.begin(), hostName.end())); 81 return ipmi::responseSuccess(hostNamePayload); 82 } 83 84 ipmi::RspType<uint8_t> ipmiGetIpmiChannelRfHi() 85 { 86 constexpr auto redfishHostInterfaceChannel = "usb0"; 87 uint8_t chNum = ipmi::getChannelByName(redfishHostInterfaceChannel); 88 ChannelInfo chInfo{}; 89 Cc compCode = ipmi::getChannelInfo(chNum, chInfo); 90 if (compCode != ipmi::ccSuccess) 91 { 92 lg2::error( 93 "ipmiGetIpmiChannelRfHi failed for channel {CHANNEL} with error {ERROR}", 94 "CHANNEL", chNum, "ERROR", compCode); 95 return ipmi::responseUnspecifiedError(); 96 } 97 98 if (chInfo.mediumType != 99 static_cast<uint8_t>(EChannelMediumType::lan8032) || 100 chInfo.protocolType != 101 static_cast<uint8_t>(EChannelProtocolType::ipmbV10) || 102 chInfo.sessionSupported != 103 static_cast<uint8_t>(EChannelSessSupported::multi) || 104 chInfo.isIpmi != true) 105 { 106 lg2::error( 107 "ipmiGetIpmiChannelRfHi: channel {CHANNEL} lacks required config", 108 "CHANNEL", chNum); 109 return responseSensorInvalid(); 110 } 111 return ipmi::responseSuccess(static_cast<uint8_t>(chNum)); 112 } 113 114 } // namespace ipmi 115 116 void registerBootstrapCredentialsOemCommands() 117 { 118 ipmi::registerHandler( 119 ipmi::prioOemBase, ipmi::groupNvidia, 120 ipmi::bootstrap_credentials_oem::cmdGetUsbVendorIdProductId, 121 ipmi::Privilege::Admin, ipmi::ipmiGetUsbVendorIdProductId); 122 123 ipmi::registerHandler( 124 ipmi::prioOemBase, ipmi::groupNvidia, 125 ipmi::bootstrap_credentials_oem::cmdGetUsbSerialNumber, 126 ipmi::Privilege::Admin, ipmi::ipmiGetUsbSerialNumber); 127 128 ipmi::registerHandler( 129 ipmi::prioOemBase, ipmi::groupNvidia, 130 ipmi::bootstrap_credentials_oem::cmdGetRedfishHostName, 131 ipmi::Privilege::Admin, ipmi::ipmiGetRedfishHostName); 132 133 ipmi::registerHandler( 134 ipmi::prioOemBase, ipmi::groupNvidia, 135 ipmi::bootstrap_credentials_oem::cmdGetIpmiChannelRfHi, 136 ipmi::Privilege::Admin, ipmi::ipmiGetIpmiChannelRfHi); 137 } 138