xref: /openbmc/phosphor-host-ipmid/transport/serialbridge/serialcmd.hpp (revision e2fae4b9fe17e30149b077b38ea513d7207c5405)
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