cable.cpp (a2056e9ca86e767a774d621c5117939562c5aa54) | cable.cpp (ff3cd8e91958cadd6a9f72f2ad69c00abae3c7cf) |
---|---|
1// Copyright 2021 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// --- 6 unchanged lines hidden (view full) --- 15#include "cable.hpp" 16 17#include "commands.hpp" 18#include "errors.hpp" 19#include "handler.hpp" 20 21#include <cstdint> 22#include <cstring> | 1// Copyright 2021 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// --- 6 unchanged lines hidden (view full) --- 15#include "cable.hpp" 16 17#include "commands.hpp" 18#include "errors.hpp" 19#include "handler.hpp" 20 21#include <cstdint> 22#include <cstring> |
23#include <ipmid/api-types.hpp> |
|
23#include <string> | 24#include <string> |
25#include <vector> |
|
24 25namespace google 26{ 27namespace ipmi 28{ 29 30struct CableRequest 31{ | 26 27namespace google 28{ 29namespace ipmi 30{ 31 32struct CableRequest 33{ |
32 uint8_t subcommand; | |
33 uint8_t ifNameLength; 34} __attribute__((packed)); 35 | 34 uint8_t ifNameLength; 35} __attribute__((packed)); 36 |
36ipmi_ret_t cableCheck(const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen, 37 const HandlerInterface* handler) | 37Resp cableCheck(const std::vector<std::uint8_t>& data, 38 const HandlerInterface* handler) |
38{ 39 // There is an IPMI LAN channel statistics command which could be used for 40 // this type of check, however, we're not able to wait for the OpenBMC 41 // implementation to stabilize related to the network management. 42 // 43 // There is a link status file, but it is "unknown" to start with... 44 // The path we're checking: /sys/class/net/eth1/statistics/rx_packets 45 46 // This command is expecting: [0x00][len][ifName] | 39{ 40 // There is an IPMI LAN channel statistics command which could be used for 41 // this type of check, however, we're not able to wait for the OpenBMC 42 // implementation to stabilize related to the network management. 43 // 44 // There is a link status file, but it is "unknown" to start with... 45 // The path we're checking: /sys/class/net/eth1/statistics/rx_packets 46 47 // This command is expecting: [0x00][len][ifName] |
47 if ((*dataLen) < sizeof(struct CableRequest) + sizeof(uint8_t)) | 48 // data should have [len][ifName] 49 if (data.size() < sizeof(struct CableRequest)) |
48 { 49 std::fprintf(stderr, "Invalid command length: %u\n", | 50 { 51 std::fprintf(stderr, "Invalid command length: %u\n", |
50 static_cast<uint32_t>(*dataLen)); 51 return IPMI_CC_REQ_DATA_LEN_INVALID; | 52 static_cast<uint32_t>(data.size())); 53 return ::ipmi::responseReqDataLenInvalid(); |
52 } 53 54 const auto request = | 54 } 55 56 const auto request = |
55 reinterpret_cast<const struct CableRequest*>(&reqBuf[0]); | 57 reinterpret_cast<const struct CableRequest*>(data.data()); |
56 57 // Sanity check the object contents. 58 if (request->ifNameLength == 0) 59 { 60 std::fprintf(stderr, "Invalid string length: %d\n", 61 request->ifNameLength); | 58 59 // Sanity check the object contents. 60 if (request->ifNameLength == 0) 61 { 62 std::fprintf(stderr, "Invalid string length: %d\n", 63 request->ifNameLength); |
62 return IPMI_CC_REQ_DATA_LEN_INVALID; | 64 return ::ipmi::responseReqDataLenInvalid(); |
63 } 64 65 // Verify the request buffer contains the object and the string. | 65 } 66 67 // Verify the request buffer contains the object and the string. |
66 if ((*dataLen) < (sizeof(struct CableRequest) + request->ifNameLength)) | 68 if (data.size() < (sizeof(struct CableRequest) + request->ifNameLength)) |
67 { 68 std::fprintf(stderr, "*dataLen too small: %u\n", | 69 { 70 std::fprintf(stderr, "*dataLen too small: %u\n", |
69 static_cast<uint32_t>(*dataLen)); 70 return IPMI_CC_REQ_DATA_LEN_INVALID; | 71 static_cast<uint32_t>(data.size())); 72 return ::ipmi::responseReqDataLenInvalid(); |
71 } 72 73 // Maximum length one can specify, plus null terminator. 74 char nameBuf[256] = {}; 75 // Copy the string out of the request buffer. 76 std::memcpy(&nameBuf[0], request + 1, request->ifNameLength); 77 std::string name = nameBuf; 78 int64_t count; 79 80 try 81 { 82 count = handler->getRxPackets(name); 83 } 84 catch (const IpmiException& e) 85 { | 73 } 74 75 // Maximum length one can specify, plus null terminator. 76 char nameBuf[256] = {}; 77 // Copy the string out of the request buffer. 78 std::memcpy(&nameBuf[0], request + 1, request->ifNameLength); 79 std::string name = nameBuf; 80 int64_t count; 81 82 try 83 { 84 count = handler->getRxPackets(name); 85 } 86 catch (const IpmiException& e) 87 { |
86 return e.getIpmiError(); | 88 return ::ipmi::response(e.getIpmiError()); |
87 } 88 | 89 } 90 |
89 struct CableReply reply; 90 reply.subcommand = SysCableCheck; 91 | |
92 // If we have received packets then there is a cable present. | 91 // If we have received packets then there is a cable present. |
93 reply.value = (count > 0) ? 1 : 0; | 92 std::uint8_t value = (count > 0) ? 1 : 0; |
94 | 93 |
95 // Return the subcommand and the result. 96 std::memcpy(&replyBuf[0], &reply, sizeof(struct CableReply)); 97 (*dataLen) = sizeof(struct CableReply); 98 99 return IPMI_CC_OK; | 94 return ::ipmi::responseSuccess(SysOEMCommands::SysCableCheck, 95 std::vector<std::uint8_t>{value}); |
100} 101 102} // namespace ipmi 103} // namespace google | 96} 97 98} // namespace ipmi 99} // namespace google |