1 #pragma once 2 #include <sdbusplus/bus.hpp> 3 #include <sdbusplus/message.hpp> 4 #include <sdbusplus/slot.hpp> 5 #include <stdplus/fd/intf.hpp> 6 7 namespace serialbridge 8 { 9 10 static constexpr auto bmStart = 0xA0; 11 static constexpr auto bmStop = 0xA5; 12 static constexpr auto bmHandshake = 0xA6; 13 static constexpr auto bmEscape = 0xAA; 14 15 static constexpr auto ipmiSerialConnectionHeaderLength = 3; 16 static constexpr auto ipmiSerialChecksumSize = 1; 17 static constexpr auto ipmiSerialMaxBufferSize = 256; 18 19 /** 20 * @brief IPMI Serial Message Structure 21 */ 22 struct IpmiSerialHeader 23 { 24 uint8_t rsAddr; 25 uint8_t rsNetFnLUN; 26 uint8_t checksum1; 27 uint8_t rqAddr; 28 uint8_t rqSeqLUN; 29 uint8_t cmd; 30 } __attribute__((packed)); 31 32 class SerialChannel 33 { 34 public: 35 static constexpr uint8_t netFnShift = 2; 36 static constexpr uint8_t lunMask = (1 << netFnShift) - 1; 37 SerialChannel(bool debug)38 SerialChannel(bool debug) : verbose(debug), msgState(MsgState::msgIdle) {}; 39 40 int write(stdplus::Fd& uart, uint8_t rsAddr, uint8_t rqAddr, uint8_t seq, 41 sdbusplus::message_t&& m); 42 void read(stdplus::Fd& serial, sdbusplus::bus_t& bus, 43 sdbusplus::slot_t& outstanding); 44 uint8_t calculateChecksum(std::span<uint8_t> data); 45 uint8_t getUnescapedCharacter(uint8_t c); 46 int consumeIpmiSerialPacket(std::span<uint8_t>& escapedDataBytes, 47 std::vector<uint8_t>& unescapedDataBytes); 48 uint8_t processEscapedCharacter(std::vector<uint8_t>& buffer, 49 const std::vector<uint8_t>& data); 50 51 private: 52 bool verbose; 53 enum class MsgState 54 { 55 msgIdle = 0, 56 msgInProgress, 57 msgInEscape, 58 }; 59 MsgState msgState; 60 std::vector<uint8_t> requestBuffer; 61 std::vector<uint8_t> responseBuffer; 62 }; 63 64 } // namespace serialbridge 65