bridgingcommands.cpp (e95b0e5512f55e7c0b764462e7c815187589a598) | bridgingcommands.cpp (fcd2d3a943c4fb518d399d8a0addd1cc661e5628) |
---|---|
1/* 2// Copyright (c) 2018 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16 | 1/* 2// Copyright (c) 2018 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16 |
17#include <bitset> | |
18#include <bridgingcommands.hpp> | 17#include <bridgingcommands.hpp> |
19#include <cstring> | |
20#include <ipmid/api.hpp> 21#include <ipmid/utils.hpp> 22#include <manufacturingcommands.hpp> 23#include <phosphor-logging/log.hpp> 24#include <sdbusplus/bus.hpp> 25#include <sdbusplus/bus/match.hpp> 26#include <sdbusplus/message.hpp> 27#include <storagecommands.hpp> | 18#include <ipmid/api.hpp> 19#include <ipmid/utils.hpp> 20#include <manufacturingcommands.hpp> 21#include <phosphor-logging/log.hpp> 22#include <sdbusplus/bus.hpp> 23#include <sdbusplus/bus/match.hpp> 24#include <sdbusplus/message.hpp> 25#include <storagecommands.hpp> |
26 27#include <bitset> 28#include <cstring> |
|
28#include <vector> 29 | 29#include <vector> 30 |
30static constexpr const char *wdtService = "xyz.openbmc_project.Watchdog"; 31static constexpr const char *wdtInterface = | 31static constexpr const char* wdtService = "xyz.openbmc_project.Watchdog"; 32static constexpr const char* wdtInterface = |
32 "xyz.openbmc_project.State.Watchdog"; | 33 "xyz.openbmc_project.State.Watchdog"; |
33static constexpr const char *wdtObjPath = "/xyz/openbmc_project/watchdog/host0"; 34static constexpr const char *wdtInterruptFlagProp = | 34static constexpr const char* wdtObjPath = "/xyz/openbmc_project/watchdog/host0"; 35static constexpr const char* wdtInterruptFlagProp = |
35 "PreTimeoutInterruptOccurFlag"; 36 | 36 "PreTimeoutInterruptOccurFlag"; 37 |
37static constexpr const char *ipmbBus = "xyz.openbmc_project.Ipmi.Channel.Ipmb"; 38static constexpr const char *ipmbObj = "/xyz/openbmc_project/Ipmi/Channel/Ipmb"; 39static constexpr const char *ipmbIntf = "org.openbmc.Ipmb"; | 38static constexpr const char* ipmbBus = "xyz.openbmc_project.Ipmi.Channel.Ipmb"; 39static constexpr const char* ipmbObj = "/xyz/openbmc_project/Ipmi/Channel/Ipmb"; 40static constexpr const char* ipmbIntf = "org.openbmc.Ipmb"; |
40 41static Bridging bridging; 42static bool eventMessageBufferFlag = false; 43 44void Bridging::clearResponseQueue() 45{ 46 responseQueue.clear(); 47} 48 49/** 50 * @brief utils for checksum 51 */ | 41 42static Bridging bridging; 43static bool eventMessageBufferFlag = false; 44 45void Bridging::clearResponseQueue() 46{ 47 responseQueue.clear(); 48} 49 50/** 51 * @brief utils for checksum 52 */ |
52static bool ipmbChecksumValidate(const uint8_t *data, uint8_t length) | 53static bool ipmbChecksumValidate(const uint8_t* data, uint8_t length) |
53{ 54 if (data == nullptr) 55 { 56 return false; 57 } 58 59 uint8_t checksum = 0; 60 --- 5 unchanged lines hidden (view full) --- 66 if (0 == checksum) 67 { 68 return true; 69 } 70 71 return false; 72} 73 | 54{ 55 if (data == nullptr) 56 { 57 return false; 58 } 59 60 uint8_t checksum = 0; 61 --- 5 unchanged lines hidden (view full) --- 67 if (0 == checksum) 68 { 69 return true; 70 } 71 72 return false; 73} 74 |
74static uint8_t ipmbChecksumCompute(uint8_t *data, uint8_t length) | 75static uint8_t ipmbChecksumCompute(uint8_t* data, uint8_t length) |
75{ 76 if (data == nullptr) 77 { 78 return 0; 79 } 80 81 uint8_t checksum = 0; 82 83 for (uint8_t idx = 0; idx < length; idx++) 84 { 85 checksum += data[idx]; 86 } 87 88 checksum = (~checksum) + 1; 89 return checksum; 90} 91 92static inline bool | 76{ 77 if (data == nullptr) 78 { 79 return 0; 80 } 81 82 uint8_t checksum = 0; 83 84 for (uint8_t idx = 0; idx < length; idx++) 85 { 86 checksum += data[idx]; 87 } 88 89 checksum = (~checksum) + 1; 90 return checksum; 91} 92 93static inline bool |
93 ipmbConnectionHeaderChecksumValidate(const ipmbHeader *ipmbHeader) | 94 ipmbConnectionHeaderChecksumValidate(const ipmbHeader* ipmbHeader) |
94{ | 95{ |
95 return ipmbChecksumValidate(reinterpret_cast<const uint8_t *>(ipmbHeader), | 96 return ipmbChecksumValidate(reinterpret_cast<const uint8_t*>(ipmbHeader), |
96 ipmbConnectionHeaderLength); 97} 98 | 97 ipmbConnectionHeaderLength); 98} 99 |
99static inline bool ipmbDataChecksumValidate(const ipmbHeader *ipmbHeader, | 100static inline bool ipmbDataChecksumValidate(const ipmbHeader* ipmbHeader, |
100 uint8_t length) 101{ | 101 uint8_t length) 102{ |
102 return ipmbChecksumValidate((reinterpret_cast<const uint8_t *>(ipmbHeader) + | 103 return ipmbChecksumValidate((reinterpret_cast<const uint8_t*>(ipmbHeader) + |
103 ipmbConnectionHeaderLength), 104 (length - ipmbConnectionHeaderLength)); 105} 106 | 104 ipmbConnectionHeaderLength), 105 (length - ipmbConnectionHeaderLength)); 106} 107 |
107static bool isFrameValid(const ipmbHeader *frame, uint8_t length) | 108static bool isFrameValid(const ipmbHeader* frame, uint8_t length) |
108{ 109 if ((length < ipmbMinFrameLength) || (length > ipmbMaxFrameLength)) 110 { 111 return false; 112 } 113 114 if (false == ipmbConnectionHeaderChecksumValidate(frame)) 115 { 116 return false; 117 } 118 119 if (false == ipmbDataChecksumValidate(frame, length)) 120 { 121 return false; 122 } 123 124 return true; 125} 126 | 109{ 110 if ((length < ipmbMinFrameLength) || (length > ipmbMaxFrameLength)) 111 { 112 return false; 113 } 114 115 if (false == ipmbConnectionHeaderChecksumValidate(frame)) 116 { 117 return false; 118 } 119 120 if (false == ipmbDataChecksumValidate(frame, length)) 121 { 122 return false; 123 } 124 125 return true; 126} 127 |
127IpmbRequest::IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength) | 128IpmbRequest::IpmbRequest(const ipmbHeader* ipmbBuffer, size_t bufferLength) |
128{ 129 address = ipmbBuffer->Header.Req.address; 130 netFn = ipmbNetFnGet(ipmbBuffer->Header.Req.rsNetFnLUN); 131 rsLun = ipmbLunFromNetFnLunGet(ipmbBuffer->Header.Req.rsNetFnLUN); 132 rqSA = ipmbBuffer->Header.Req.rqSA; 133 seq = ipmbSeqGet(ipmbBuffer->Header.Req.rqSeqLUN); 134 rqLun = ipmbLunFromSeqLunGet(ipmbBuffer->Header.Req.rqSeqLUN); 135 cmd = ipmbBuffer->Header.Req.cmd; --- 7 unchanged lines hidden (view full) --- 143 data.insert(data.end(), ipmbBuffer->Header.Req.data, 144 &ipmbBuffer->Header.Req.data[dataLength]); 145 } 146} 147 148IpmbResponse::IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, 149 uint8_t rsSA, uint8_t seq, uint8_t rsLun, 150 uint8_t cmd, uint8_t completionCode, | 129{ 130 address = ipmbBuffer->Header.Req.address; 131 netFn = ipmbNetFnGet(ipmbBuffer->Header.Req.rsNetFnLUN); 132 rsLun = ipmbLunFromNetFnLunGet(ipmbBuffer->Header.Req.rsNetFnLUN); 133 rqSA = ipmbBuffer->Header.Req.rqSA; 134 seq = ipmbSeqGet(ipmbBuffer->Header.Req.rqSeqLUN); 135 rqLun = ipmbLunFromSeqLunGet(ipmbBuffer->Header.Req.rqSeqLUN); 136 cmd = ipmbBuffer->Header.Req.cmd; --- 7 unchanged lines hidden (view full) --- 144 data.insert(data.end(), ipmbBuffer->Header.Req.data, 145 &ipmbBuffer->Header.Req.data[dataLength]); 146 } 147} 148 149IpmbResponse::IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, 150 uint8_t rsSA, uint8_t seq, uint8_t rsLun, 151 uint8_t cmd, uint8_t completionCode, |
151 std::vector<uint8_t> &inputData) : | 152 std::vector<uint8_t>& inputData) : |
152 address(address), 153 netFn(netFn), rqLun(rqLun), rsSA(rsSA), seq(seq), rsLun(rsLun), cmd(cmd), 154 completionCode(completionCode) 155{ 156 data.reserve(ipmbMaxDataSize); 157 158 if (inputData.size() > 0) 159 { 160 data = std::move(inputData); 161 } 162} 163 | 153 address(address), 154 netFn(netFn), rqLun(rqLun), rsSA(rsSA), seq(seq), rsLun(rsLun), cmd(cmd), 155 completionCode(completionCode) 156{ 157 data.reserve(ipmbMaxDataSize); 158 159 if (inputData.size() > 0) 160 { 161 data = std::move(inputData); 162 } 163} 164 |
164void IpmbResponse::ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength) | 165void IpmbResponse::ipmbToi2cConstruct(uint8_t* buffer, size_t* bufferLength) |
165{ | 166{ |
166 ipmbHeader *ipmbBuffer = (ipmbHeader *)buffer; | 167 ipmbHeader* ipmbBuffer = (ipmbHeader*)buffer; |
167 168 ipmbBuffer->Header.Resp.address = address; 169 ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun); 170 ipmbBuffer->Header.Resp.rsSA = rsSA; 171 ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun); 172 ipmbBuffer->Header.Resp.cmd = cmd; 173 ipmbBuffer->Header.Resp.completionCode = completionCode; 174 --- 10 unchanged lines hidden (view full) --- 185 *bufferLength = data.size() + ipmbResponseDataHeaderLength + 186 ipmbConnectionHeaderLength + ipmbChecksumSize; 187 188 buffer[*bufferLength - ipmbChecksumSize] = 189 ipmbChecksumCompute(&buffer[ipmbChecksum2StartOffset], 190 (ipmbResponseDataHeaderLength + data.size())); 191} 192 | 168 169 ipmbBuffer->Header.Resp.address = address; 170 ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun); 171 ipmbBuffer->Header.Resp.rsSA = rsSA; 172 ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun); 173 ipmbBuffer->Header.Resp.cmd = cmd; 174 ipmbBuffer->Header.Resp.completionCode = completionCode; 175 --- 10 unchanged lines hidden (view full) --- 186 *bufferLength = data.size() + ipmbResponseDataHeaderLength + 187 ipmbConnectionHeaderLength + ipmbChecksumSize; 188 189 buffer[*bufferLength - ipmbChecksumSize] = 190 ipmbChecksumCompute(&buffer[ipmbChecksum2StartOffset], 191 (ipmbResponseDataHeaderLength + data.size())); 192} 193 |
193void IpmbRequest::prepareRequest(sdbusplus::message::message &mesg) | 194void IpmbRequest::prepareRequest(sdbusplus::message::message& mesg) |
194{ 195 mesg.append(ipmbMeChannelNum, netFn, rqLun, cmd, data); 196} 197 198static constexpr unsigned int makeCmdKey(unsigned int netFn, unsigned int cmd) 199{ 200 return (netFn << 8) | cmd; 201} --- 33 unchanged lines hidden (view full) --- 235 return false; 236 default: 237 return true; 238 } 239} 240 241ipmi::Cc Bridging::handleIpmbChannel(ipmi::Context::ptr ctx, 242 const uint8_t tracking, | 195{ 196 mesg.append(ipmbMeChannelNum, netFn, rqLun, cmd, data); 197} 198 199static constexpr unsigned int makeCmdKey(unsigned int netFn, unsigned int cmd) 200{ 201 return (netFn << 8) | cmd; 202} --- 33 unchanged lines hidden (view full) --- 236 return false; 237 default: 238 return true; 239 } 240} 241 242ipmi::Cc Bridging::handleIpmbChannel(ipmi::Context::ptr ctx, 243 const uint8_t tracking, |
243 const std::vector<uint8_t> &msgData, 244 std::vector<uint8_t> &rspData) | 244 const std::vector<uint8_t>& msgData, 245 std::vector<uint8_t>& rspData) |
245{ 246 ipmi::Manufacturing mtm; 247 248 size_t msgLen = msgData.size(); 249 if ((msgLen < ipmbMinFrameLength) || (msgLen > ipmbMaxFrameLength)) 250 { 251 phosphor::logging::log<phosphor::logging::level::INFO>( 252 "handleIpmbChannel, IPMB data length is invalid"); 253 return ipmi::ccReqDataLenInvalid; 254 } 255 256 // Bridging to ME requires Administrator lvl 257 if ((ctx->priv) != ipmi::Privilege::Admin) 258 { 259 return ipmi::ccInsufficientPrivilege; 260 } 261 | 246{ 247 ipmi::Manufacturing mtm; 248 249 size_t msgLen = msgData.size(); 250 if ((msgLen < ipmbMinFrameLength) || (msgLen > ipmbMaxFrameLength)) 251 { 252 phosphor::logging::log<phosphor::logging::level::INFO>( 253 "handleIpmbChannel, IPMB data length is invalid"); 254 return ipmi::ccReqDataLenInvalid; 255 } 256 257 // Bridging to ME requires Administrator lvl 258 if ((ctx->priv) != ipmi::Privilege::Admin) 259 { 260 return ipmi::ccInsufficientPrivilege; 261 } 262 |
262 auto sendMsgReqData = reinterpret_cast<const ipmbHeader *>(msgData.data()); | 263 auto sendMsgReqData = reinterpret_cast<const ipmbHeader*>(msgData.data()); |
263 264 // allow bridging to ME only 265 if (sendMsgReqData->Header.Req.address != ipmbMeSlaveAddress) 266 { 267 phosphor::logging::log<phosphor::logging::level::INFO>( 268 "handleIpmbChannel, IPMB address invalid"); 269 return ipmi::ccParmOutOfRange; 270 } --- 118 unchanged lines hidden (view full) --- 389 * @return IPMI completion code plus response data on success. 390 * - rspData - response data 391 **/ 392ipmi::RspType<std::vector<uint8_t> // responseData 393 > 394 ipmiAppSendMessage(ipmi::Context::ptr ctx, const uint4_t channelNumber, 395 const bool authenticationEnabled, 396 const bool encryptionEnabled, const uint2_t tracking, | 264 265 // allow bridging to ME only 266 if (sendMsgReqData->Header.Req.address != ipmbMeSlaveAddress) 267 { 268 phosphor::logging::log<phosphor::logging::level::INFO>( 269 "handleIpmbChannel, IPMB address invalid"); 270 return ipmi::ccParmOutOfRange; 271 } --- 118 unchanged lines hidden (view full) --- 390 * @return IPMI completion code plus response data on success. 391 * - rspData - response data 392 **/ 393ipmi::RspType<std::vector<uint8_t> // responseData 394 > 395 ipmiAppSendMessage(ipmi::Context::ptr ctx, const uint4_t channelNumber, 396 const bool authenticationEnabled, 397 const bool encryptionEnabled, const uint2_t tracking, |
397 ipmi::message::Payload &msg) | 398 ipmi::message::Payload& msg) |
398{ 399 // check message fields: 400 // encryption not supported 401 if (encryptionEnabled) 402 { 403 phosphor::logging::log<phosphor::logging::level::INFO>( 404 "ipmiAppSendMessage, encryption not supported"); 405 return ipmi::responseParmOutOfRange(); --- 135 unchanged lines hidden (view full) --- 541 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); 542 ipmi::Value variant = ipmi::getDbusProperty( 543 *dbus, wdtService, wdtObjPath, wdtInterface, wdtInterruptFlagProp); 544 if (std::get<bool>(variant)) 545 { 546 getMsgFlagsRes.set(getMsgFlagWatchdogPreTimeOutBit); 547 } 548 } | 399{ 400 // check message fields: 401 // encryption not supported 402 if (encryptionEnabled) 403 { 404 phosphor::logging::log<phosphor::logging::level::INFO>( 405 "ipmiAppSendMessage, encryption not supported"); 406 return ipmi::responseParmOutOfRange(); --- 135 unchanged lines hidden (view full) --- 542 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); 543 ipmi::Value variant = ipmi::getDbusProperty( 544 *dbus, wdtService, wdtObjPath, wdtInterface, wdtInterruptFlagProp); 545 if (std::get<bool>(variant)) 546 { 547 getMsgFlagsRes.set(getMsgFlagWatchdogPreTimeOutBit); 548 } 549 } |
549 catch (sdbusplus::exception::SdBusError &e) | 550 catch (sdbusplus::exception::SdBusError& e) |
550 { 551 phosphor::logging::log<phosphor::logging::level::ERR>( 552 "ipmiAppGetMessageFlags, dbus call exception"); 553 return ipmi::responseUnspecifiedError(); 554 } 555 556 return ipmi::responseSuccess(getMsgFlagsRes); 557} --- 32 unchanged lines hidden (view full) --- 590 } 591 592 try 593 { 594 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); 595 ipmi::setDbusProperty(*dbus, wdtService, wdtObjPath, wdtInterface, 596 wdtInterruptFlagProp, false); 597 } | 551 { 552 phosphor::logging::log<phosphor::logging::level::ERR>( 553 "ipmiAppGetMessageFlags, dbus call exception"); 554 return ipmi::responseUnspecifiedError(); 555 } 556 557 return ipmi::responseSuccess(getMsgFlagsRes); 558} --- 32 unchanged lines hidden (view full) --- 591 } 592 593 try 594 { 595 std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus(); 596 ipmi::setDbusProperty(*dbus, wdtService, wdtObjPath, wdtInterface, 597 wdtInterruptFlagProp, false); 598 } |
598 catch (const sdbusplus::exception::SdBusError &e) | 599 catch (const sdbusplus::exception::SdBusError& e) |
599 { 600 phosphor::logging::log<phosphor::logging::level::ERR>( 601 "ipmiAppClearMessageFlags: can't Clear/Set " 602 "PreTimeoutInterruptOccurFlag"); 603 return ipmi::responseUnspecifiedError(); 604 } 605 606 return ipmi::responseSuccess(); --- 84 unchanged lines hidden --- | 600 { 601 phosphor::logging::log<phosphor::logging::level::ERR>( 602 "ipmiAppClearMessageFlags: can't Clear/Set " 603 "PreTimeoutInterruptOccurFlag"); 604 return ipmi::responseUnspecifiedError(); 605 } 606 607 return ipmi::responseSuccess(); --- 84 unchanged lines hidden --- |