1a2056e9cSWilly Tu // Copyright 2021 Google LLC 2a2056e9cSWilly Tu // 3a2056e9cSWilly Tu // Licensed under the Apache License, Version 2.0 (the "License"); 4a2056e9cSWilly Tu // you may not use this file except in compliance with the License. 5a2056e9cSWilly Tu // You may obtain a copy of the License at 6a2056e9cSWilly Tu // 7a2056e9cSWilly Tu // http://www.apache.org/licenses/LICENSE-2.0 8a2056e9cSWilly Tu // 9a2056e9cSWilly Tu // Unless required by applicable law or agreed to in writing, software 10a2056e9cSWilly Tu // distributed under the License is distributed on an "AS IS" BASIS, 11a2056e9cSWilly Tu // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a2056e9cSWilly Tu // See the License for the specific language governing permissions and 13a2056e9cSWilly Tu // limitations under the License. 144d49ae65SPatrick Venture 154d49ae65SPatrick Venture #include "cable.hpp" 164d49ae65SPatrick Venture 170e9aae5dSPatrick Venture #include "commands.hpp" 18d2037c6aSPatrick Venture #include "errors.hpp" 19d2037c6aSPatrick Venture #include "handler.hpp" 204d49ae65SPatrick Venture 214d49ae65SPatrick Venture #include <cstdint> 22ce07ee0aSPatrick Venture #include <cstring> 23*ff3cd8e9SWilly Tu #include <ipmid/api-types.hpp> 244d49ae65SPatrick Venture #include <string> 25*ff3cd8e9SWilly Tu #include <vector> 264d49ae65SPatrick Venture 274d49ae65SPatrick Venture namespace google 284d49ae65SPatrick Venture { 294d49ae65SPatrick Venture namespace ipmi 304d49ae65SPatrick Venture { 314d49ae65SPatrick Venture 324d49ae65SPatrick Venture struct CableRequest 334d49ae65SPatrick Venture { 3445fad1bbSPatrick Venture uint8_t ifNameLength; 354d49ae65SPatrick Venture } __attribute__((packed)); 364d49ae65SPatrick Venture 37*ff3cd8e9SWilly Tu Resp cableCheck(const std::vector<std::uint8_t>& data, 38d2037c6aSPatrick Venture const HandlerInterface* handler) 394d49ae65SPatrick Venture { 404d49ae65SPatrick Venture // There is an IPMI LAN channel statistics command which could be used for 414d49ae65SPatrick Venture // this type of check, however, we're not able to wait for the OpenBMC 424d49ae65SPatrick Venture // implementation to stabilize related to the network management. 434d49ae65SPatrick Venture // 444d49ae65SPatrick Venture // There is a link status file, but it is "unknown" to start with... 454d49ae65SPatrick Venture // The path we're checking: /sys/class/net/eth1/statistics/rx_packets 464d49ae65SPatrick Venture 4745fad1bbSPatrick Venture // This command is expecting: [0x00][len][ifName] 48*ff3cd8e9SWilly Tu // data should have [len][ifName] 49*ff3cd8e9SWilly Tu if (data.size() < sizeof(struct CableRequest)) 504d49ae65SPatrick Venture { 51ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid command length: %u\n", 52*ff3cd8e9SWilly Tu static_cast<uint32_t>(data.size())); 53*ff3cd8e9SWilly Tu return ::ipmi::responseReqDataLenInvalid(); 544d49ae65SPatrick Venture } 554d49ae65SPatrick Venture 564d49ae65SPatrick Venture const auto request = 57*ff3cd8e9SWilly Tu reinterpret_cast<const struct CableRequest*>(data.data()); 584d49ae65SPatrick Venture 594d49ae65SPatrick Venture // Sanity check the object contents. 6045fad1bbSPatrick Venture if (request->ifNameLength == 0) 614d49ae65SPatrick Venture { 62ce07ee0aSPatrick Venture std::fprintf(stderr, "Invalid string length: %d\n", 6345fad1bbSPatrick Venture request->ifNameLength); 64*ff3cd8e9SWilly Tu return ::ipmi::responseReqDataLenInvalid(); 654d49ae65SPatrick Venture } 664d49ae65SPatrick Venture 674d49ae65SPatrick Venture // Verify the request buffer contains the object and the string. 68*ff3cd8e9SWilly Tu if (data.size() < (sizeof(struct CableRequest) + request->ifNameLength)) 694d49ae65SPatrick Venture { 70ce07ee0aSPatrick Venture std::fprintf(stderr, "*dataLen too small: %u\n", 71*ff3cd8e9SWilly Tu static_cast<uint32_t>(data.size())); 72*ff3cd8e9SWilly Tu return ::ipmi::responseReqDataLenInvalid(); 734d49ae65SPatrick Venture } 744d49ae65SPatrick Venture 754d49ae65SPatrick Venture // Maximum length one can specify, plus null terminator. 764d49ae65SPatrick Venture char nameBuf[256] = {}; 774d49ae65SPatrick Venture // Copy the string out of the request buffer. 785d789734SWilliam A. Kennington III std::memcpy(&nameBuf[0], request + 1, request->ifNameLength); 794d49ae65SPatrick Venture std::string name = nameBuf; 80d2037c6aSPatrick Venture int64_t count; 814d49ae65SPatrick Venture 824d49ae65SPatrick Venture try 834d49ae65SPatrick Venture { 84d2037c6aSPatrick Venture count = handler->getRxPackets(name); 854d49ae65SPatrick Venture } 86d2037c6aSPatrick Venture catch (const IpmiException& e) 874d49ae65SPatrick Venture { 88*ff3cd8e9SWilly Tu return ::ipmi::response(e.getIpmiError()); 894d49ae65SPatrick Venture } 904d49ae65SPatrick Venture 914d49ae65SPatrick Venture // If we have received packets then there is a cable present. 92*ff3cd8e9SWilly Tu std::uint8_t value = (count > 0) ? 1 : 0; 934d49ae65SPatrick Venture 94*ff3cd8e9SWilly Tu return ::ipmi::responseSuccess(SysOEMCommands::SysCableCheck, 95*ff3cd8e9SWilly Tu std::vector<std::uint8_t>{value}); 964d49ae65SPatrick Venture } 974d49ae65SPatrick Venture 984d49ae65SPatrick Venture } // namespace ipmi 994d49ae65SPatrick Venture } // namespace google 100