]> git.basschouten.com Git - openhab-addons.git/blob
5954fcdb9b9307505ee5d0503fa23534c3c81e3d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.paradoxalarm.internal.communication.messages;
14
15 import java.nio.ByteBuffer;
16 import java.nio.ByteOrder;
17
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;
21
22 /**
23  * The {@link ParadoxIPPacket} This class is object representing a full IP request packet. Header and payload together.
24  *
25  * @author Konstantin Polihronov - Initial contribution
26  */
27 @NonNullByDefault
28 public class ParadoxIPPacket implements IPPacket {
29
30     public static final byte[] EMPTY_PAYLOAD = new byte[0];
31
32     private PacketHeader header;
33     private byte[] payload;
34
35     public ParadoxIPPacket(byte[] bytes) {
36         this(bytes, true);
37     }
38
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);
44         }
45         short payloadLength = (short) (payload != null ? payload.length : 0);
46         header = new PacketHeader(payloadLength);
47     }
48
49     @Override
50     public byte[] getBytes() {
51         final byte[] headerBytes = header.getBytes();
52         int bufferLength = headerBytes.length + payload.length;
53
54         byte[] bufferArray = new byte[bufferLength];
55         ByteBuffer buf = ByteBuffer.wrap(bufferArray);
56         buf.put(headerBytes);
57         buf.put(payload);
58
59         return bufferArray;
60     }
61
62     public ParadoxIPPacket setCommand(HeaderCommand command) {
63         header.command = command.getValue();
64         return this;
65     }
66
67     public ParadoxIPPacket setMessageType(HeaderMessageType messageType) {
68         header.messageType = messageType.getValue();
69         return this;
70     }
71
72     public ParadoxIPPacket setUnknown0(byte unknownByteValue) {
73         header.unknown0 = unknownByteValue;
74         return this;
75     }
76
77     @Override
78     public PacketHeader getHeader() {
79         return header;
80     }
81
82     @Override
83     public byte[] getPayload() {
84         return payload;
85     }
86
87     @Override
88     public void encrypt() {
89         EncryptionHandler encryptionHandler = EncryptionHandler.getInstance();
90         payload = encryptionHandler.encrypt(payload);
91         header.encryption = 0x09;
92     }
93
94     @Override
95     public String toString() {
96         return "ParadoxIPPacket [" + ParadoxUtil.byteArrayToString(getBytes()) + "]";
97     }
98
99     public class PacketHeader {
100
101         public PacketHeader(short payloadLength) {
102             this.payloadLength = payloadLength;
103         }
104
105         private static final int BYTES_LENGTH = 9;
106
107         /**
108          * Start of header - always 0xAA
109          */
110         private byte startOfHeader = (byte) 0xAA;
111
112         /**
113          * Payload length - 2 bytes (LL HH)
114          */
115         private short payloadLength = 0;
116
117         /**
118          * "Message Type: 0x01: IP responses 0x02: Serial/pass through cmd response
119          * 0x03: IP requests 0x04: Serial/pass through cmd requests"
120          */
121         private byte messageType = 0x03;
122
123         /**
124          * "IP Encryption Disabled=0x08, Enabled=0x09"
125          */
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;
131
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);
138             buf.put(encryption);
139             buf.put(command);
140             buf.put(subCommand);
141             buf.put(unknown0);
142             buf.put(unknown1);
143             return ParadoxUtil.extendArray(bufferArray, 16);
144         }
145     }
146 }