#include "secsgem/hsms/header.hpp" namespace secsgem::hsms { const char* stype_name(SType s) { switch (s) { case SType::Data: return "Data"; case SType::SelectReq: return "Select.req"; case SType::SelectRsp: return "Select.rsp"; case SType::DeselectReq: return "Deselect.req"; case SType::DeselectRsp: return "Deselect.rsp"; case SType::LinktestReq: return "Linktest.req"; case SType::LinktestRsp: return "Linktest.rsp"; case SType::RejectReq: return "Reject.req"; case SType::SeparateReq: return "Separate.req"; } return "?"; } std::array Header::encode() const { std::array b{}; b[0] = static_cast(session_id >> 8); b[1] = static_cast(session_id & 0xFF); b[2] = byte2; b[3] = byte3; b[4] = ptype; b[5] = static_cast(stype); b[6] = static_cast(system_bytes >> 24); b[7] = static_cast(system_bytes >> 16); b[8] = static_cast(system_bytes >> 8); b[9] = static_cast(system_bytes & 0xFF); return b; } Header Header::decode(const uint8_t* d) { Header h; h.session_id = static_cast((d[0] << 8) | d[1]); h.byte2 = d[2]; h.byte3 = d[3]; h.ptype = d[4]; h.stype = static_cast(d[5]); h.system_bytes = (static_cast(d[6]) << 24) | (static_cast(d[7]) << 16) | (static_cast(d[8]) << 8) | static_cast(d[9]); return h; } std::string Header::describe() const { std::string out = stype_name(stype); if (stype == SType::Data) { out = "S" + std::to_string(stream()) + "F" + std::to_string(function()); if (w_bit()) out += " W"; } out += " (sys=" + std::to_string(system_bytes) + ")"; return out; } std::vector Frame::encode() const { const std::size_t payload_len = kHeaderSize + body.size(); std::vector out; out.reserve(kLengthPrefixSize + payload_len); out.push_back(static_cast(payload_len >> 24)); out.push_back(static_cast(payload_len >> 16)); out.push_back(static_cast(payload_len >> 8)); out.push_back(static_cast(payload_len & 0xFF)); const auto hdr = header.encode(); out.insert(out.end(), hdr.begin(), hdr.end()); out.insert(out.end(), body.begin(), body.end()); return out; } Frame Frame::decode(const uint8_t* payload, std::size_t len) { if (len < kHeaderSize) throw FrameError("HSMS payload shorter than the 10-byte header"); Frame f; f.header = Header::decode(payload); f.body.assign(payload + kHeaderSize, payload + len); return f; } } // namespace secsgem::hsms