import java.nio.charset.StandardCharsets;

public class Main {

    public static void main(String[] args) {
        int cmdId = 0xF105; // cmdID
        String[] strValues = { ""};

        for (String str : strValues) {
            StringBuilder stringBuilder = new StringBuilder();
            byte[] bytes = constructReplyPkt(cmdId, str);

            for (byte b : bytes) {
                String s = Integer.toHexString(b & 0xFF) + " ";
                if (s.length() < 3) {
                    s = "0" + s;
                }
                stringBuilder.append(s);
            }

            System.out.println("Packet for str=\"" + str + "\": " + stringBuilder);
        }
    }

    protected static byte[] constructReplyPkt(int nCmdId, String sDataContent) {
        if (sDataContent == null) {
            sDataContent = "";
        }
        byte[] baDataContent = sDataContent.getBytes(StandardCharsets.US_ASCII);
        return constructReplyPkt(nCmdId, baDataContent);
    }

    protected static byte[] constructReplyPkt(int nCmdId, byte[] baDataContent) {
        return constructReplyPkt(nCmdId, baDataContent, 1, 1);
    }

    public static final byte PKT_HEAD_BYTE = (byte) 0x27;
    public static final byte PKT_DIR_PCtoTV = (byte) 0x01;
    public static final byte PKT_TAIL_BYTE = (byte) 0xFB;

    protected static byte[] constructReplyPkt(int nCmdId, byte[] baDataContent, int nFrameNo, int nTotalFrameCnt) {
        int nbaDataContentLen = (baDataContent != null) ? baDataContent.length : 0;
        int nPktTotalLen = 9 + nbaDataContentLen;

        if (nPktTotalLen > 255) {
            return null; // 若封包長度超過255則返回null
        }

        byte[] onePkt = new byte[nPktTotalLen];
        onePkt[0] = PKT_HEAD_BYTE;
        onePkt[1] = PKT_DIR_PCtoTV;
        onePkt[2] = (byte) ((nCmdId & 0xFF00) >> 8);
        onePkt[3] = (byte) (nCmdId & 0x00FF);
        onePkt[4] = (byte) nbaDataContentLen;

        if (baDataContent != null) {
            System.arraycopy(baDataContent, 0, onePkt, 5, nbaDataContentLen);
        }

        onePkt[5 + nbaDataContentLen] = (byte) nFrameNo;
        onePkt[6 + nbaDataContentLen] = (byte) nTotalFrameCnt;

        byte nChksum = 0;
        for (int nByteId = 1; nByteId < onePkt.length - 2; nByteId++) {
            nChksum ^= onePkt[nByteId];
        }

        onePkt[7 + nbaDataContentLen] = nChksum;
        onePkt[8 + nbaDataContentLen] = PKT_TAIL_BYTE;

        return onePkt;
    }
}
