]> git.basschouten.com Git - openhab-addons.git/blob
f74d0ddbd7d815995d2bb518223503a57daecbe8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.enocean.internal.messages;
14
15 import java.nio.charset.Charset;
16 import java.util.Arrays;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.enocean.internal.messages.BasePacket.ESPPacketType;
21 import org.openhab.binding.enocean.internal.messages.ERP1Message.RORG;
22 import org.openhab.binding.enocean.internal.messages.ESP2Packet.ESP2PacketType;
23 import org.openhab.binding.enocean.internal.messages.Response.ResponseType;
24 import org.openhab.core.util.HexUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  *
30  * @author Daniel Weber - Initial contribution
31  */
32 @NonNullByDefault
33 public class ESP2PacketConverter {
34
35     protected static Logger logger = LoggerFactory.getLogger(ESP2PacketConverter.class);
36
37     private static final int ESP3PACKET_BASE_LENGTH = ESP3Packet.ESP3_RORG_LENGTH + ESP3Packet.ESP3_SENDERID_LENGTH
38             + ESP3Packet.ESP3_STATUS_LENGTH;
39
40     private static @Nullable BasePacket handleRadioTelegram(int dataLength, byte packetType, byte[] payload) {
41         switch (ESP2Packet.ORG.getORG(payload[1])) {
42             case _RPS:
43                 return ESP3PacketFactory.buildPacket(ESP3PACKET_BASE_LENGTH + RORG.RPS.getDataLength(), 0,
44                         ESPPacketType.RADIO_ERP1.getValue(), new byte[] { RORG.RPS.getValue(), payload[2], payload[6],
45                                 payload[7], payload[8], payload[9], payload[10] });
46             case _1BS:
47                 return ESP3PacketFactory.buildPacket(ESP3PACKET_BASE_LENGTH + RORG._1BS.getDataLength(), 0,
48                         ESPPacketType.RADIO_ERP1.getValue(), new byte[] { RORG._1BS.getValue(), payload[2], payload[6],
49                                 payload[7], payload[8], payload[9], payload[10] });
50
51             case _4BS:
52                 return ESP3PacketFactory.buildPacket(ESP3PACKET_BASE_LENGTH + RORG._4BS.getDataLength(), 0,
53                         ESPPacketType.RADIO_ERP1.getValue(), new byte[] { RORG._4BS.getValue(), payload[2], payload[3],
54                                 payload[4], payload[5], payload[6], payload[7], payload[8], payload[9], payload[10] });
55             default:
56                 logger.debug("Received unsupported ORG: {}", payload[1]);
57                 return null;
58         }
59     }
60
61     private static @Nullable BasePacket handleMessageTelegram(int dataLength, byte packetType, byte[] payload) {
62         switch (ESP2Packet.ESP2Response.getResponse(payload[1])) {
63             case OK:
64                 return ESP3PacketFactory.buildPacket(1, 0, ESPPacketType.RESPONSE.getValue(),
65                         new byte[] { ResponseType.RET_OK.getValue() });
66             case ERR:
67                 return ESP3PacketFactory.buildPacket(1, 0, ESPPacketType.RESPONSE.getValue(),
68                         new byte[] { ResponseType.RET_ERROR.getValue() });
69             case INF_SW_VERSION: {
70                 byte[] data = new byte[33];
71                 Arrays.fill(data, (byte) 0);
72                 data[0] = ResponseType.RET_OK.getValue();
73                 System.arraycopy(payload, 1, data, 1, 4);
74
75                 byte[] description = "TCM 210".getBytes(Charset.forName("ASCII"));
76                 System.arraycopy(description, 0, data, 17, description.length);
77                 return ESP3PacketFactory.buildPacket(data.length, 0, ESPPacketType.RESPONSE.getValue(), data);
78             }
79             case UNKOWN: // try to interpret it as a radio telegram
80                 return handleRadioTelegram(dataLength, packetType, payload);
81
82             case ERR_IDRANGE:
83             case ERR_MODEM_DUP_ID:
84             case ERR_MODEM_NOTACK:
85             case ERR_MODEM_NOTWANTEDACK:
86             case ERR_SYNTAX_CHECKSUM:
87             case ERR_SYNTAX_HSEQ:
88             case ERR_SYNTAX_LENGTH:
89             case ERR_SYNTAX_ORG:
90             case ERR_TX_IDRANGE:
91             case INF_IDBase:
92             case INF_MODEM_STATUS:
93             case INF_RX_SENSITIVITY:
94             default:
95                 logger.debug("Received unsupported message telegram: {}",
96                         ESP2Packet.ESP2Response.getResponse(payload[1]).name());
97                 return null;
98         }
99     }
100
101     public static @Nullable BasePacket buildPacket(int dataLength, byte packetType, byte[] payload) {
102         ESP2PacketType type = ESP2PacketType.getPacketType(packetType);
103
104         switch (type) {
105             case Receive_Radio_Telegram: // RRT
106                 logger.debug("Received ESP2 radio telegram: {}", HexUtils.bytesToHex(payload));
107                 return handleRadioTelegram(dataLength, packetType, payload);
108
109             case Receive_Message_Telegram: // RMT => Response
110                 logger.debug("Received ESP2 message telegram: {}", HexUtils.bytesToHex(payload));
111                 return handleMessageTelegram(dataLength, packetType, payload);
112
113             case Transmit_Radio_Telegram: // TRT
114                 // This should never happen, as this telegram is just for outbound data
115                 logger.trace("Received Transmit_Radio_Telegram: {}", HexUtils.bytesToHex(payload));
116                 break;
117
118             case Transmit_Command_Telegram: // TCT => CommonCommand
119                 // this should also never happen, as this telegram is also just for outbound data
120                 // however FAM14 receives periodically 0xABFC messages
121                 if (payload[1] == (byte) 0xFC) {
122                     return null;
123                 }
124
125                 logger.trace("Received Transmit_Command_Telegram: {}", HexUtils.bytesToHex(payload));
126                 break;
127         }
128
129         return null;
130     }
131 }