2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.paradoxalarm.internal.communication.messages;
15 import java.nio.ByteBuffer;
16 import java.nio.ByteOrder;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.paradoxalarm.internal.communication.crypto.EncryptionHandler;
20 import org.openhab.binding.paradoxalarm.internal.util.ParadoxUtil;
23 * The {@link ParadoxIPPacket} This class is object representing a full IP request packet. Header and payload together.
25 * @author Konstantin Polihronov - Initial contribution
28 public class ParadoxIPPacket implements IPPacket {
30 public static final byte[] EMPTY_PAYLOAD = new byte[0];
32 private PacketHeader header;
33 private byte[] payload;
35 public ParadoxIPPacket(byte[] bytes) {
39 @SuppressWarnings("null")
40 public ParadoxIPPacket(byte[] payload, boolean isChecksumRequired) {
41 this.payload = payload != null ? payload : new byte[0];
42 if (isChecksumRequired) {
43 payload[payload.length - 1] = ParadoxUtil.calculateChecksum(payload);
45 short payloadLength = (short) (payload != null ? payload.length : 0);
46 header = new PacketHeader(payloadLength);
50 public byte[] getBytes() {
51 final byte[] headerBytes = header.getBytes();
52 int bufferLength = headerBytes.length + payload.length;
54 byte[] bufferArray = new byte[bufferLength];
55 ByteBuffer buf = ByteBuffer.wrap(bufferArray);
62 public ParadoxIPPacket setCommand(HeaderCommand command) {
63 header.command = command.getValue();
67 public ParadoxIPPacket setMessageType(HeaderMessageType messageType) {
68 header.messageType = messageType.getValue();
72 public ParadoxIPPacket setUnknown0(byte unknownByteValue) {
73 header.unknown0 = unknownByteValue;
78 public PacketHeader getHeader() {
83 public byte[] getPayload() {
88 public void encrypt() {
89 EncryptionHandler encryptionHandler = EncryptionHandler.getInstance();
90 payload = encryptionHandler.encrypt(payload);
91 header.encryption = 0x09;
95 public String toString() {
96 return "ParadoxIPPacket [" + ParadoxUtil.byteArrayToString(getBytes()) + "]";
99 public class PacketHeader {
101 public PacketHeader(short payloadLength) {
102 this.payloadLength = payloadLength;
105 private static final int BYTES_LENGTH = 9;
108 * Start of header - always 0xAA
110 private byte startOfHeader = (byte) 0xAA;
113 * Payload length - 2 bytes (LL HH)
115 private short payloadLength = 0;
118 * "Message Type: 0x01: IP responses 0x02: Serial/pass through cmd response
119 * 0x03: IP requests 0x04: Serial/pass through cmd requests"
121 private byte messageType = 0x03;
124 * "IP Encryption Disabled=0x08, Enabled=0x09"
126 private byte encryption = 0x08;
127 private byte command = 0;
128 private byte subCommand = 0;
129 private byte unknown0 = 0x00;
130 private byte unknown1 = 0x01;
132 public byte[] getBytes() {
133 byte[] bufferArray = new byte[BYTES_LENGTH];
134 ByteBuffer buf = ByteBuffer.wrap(bufferArray);
135 buf.put(startOfHeader);
136 buf.order(ByteOrder.LITTLE_ENDIAN).putShort(payloadLength);
137 buf.put(messageType);
143 return ParadoxUtil.extendArray(bufferArray, 16);