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.enocean.internal.messages;
15 import java.nio.charset.Charset;
16 import java.util.Arrays;
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;
30 * @author Daniel Weber - Initial contribution
33 public class ESP2PacketConverter {
35 protected static Logger logger = LoggerFactory.getLogger(ESP2PacketConverter.class);
37 private static final int ESP3PACKET_BASE_LENGTH = ESP3Packet.ESP3_RORG_LENGTH + ESP3Packet.ESP3_SENDERID_LENGTH
38 + ESP3Packet.ESP3_STATUS_LENGTH;
40 private static @Nullable BasePacket handleRadioTelegram(int dataLength, byte packetType, byte[] payload) {
41 switch (ESP2Packet.ORG.getORG(payload[1])) {
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] });
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] });
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] });
56 logger.debug("Received unsupported ORG: {}", payload[1]);
61 private static @Nullable BasePacket handleMessageTelegram(int dataLength, byte packetType, byte[] payload) {
62 switch (ESP2Packet.ESP2Response.getResponse(payload[1])) {
64 return ESP3PacketFactory.buildPacket(1, 0, ESPPacketType.RESPONSE.getValue(),
65 new byte[] { ResponseType.RET_OK.getValue() });
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);
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);
79 case UNKOWN: // try to interpret it as a radio telegram
80 return handleRadioTelegram(dataLength, packetType, payload);
83 case ERR_MODEM_DUP_ID:
84 case ERR_MODEM_NOTACK:
85 case ERR_MODEM_NOTWANTEDACK:
86 case ERR_SYNTAX_CHECKSUM:
88 case ERR_SYNTAX_LENGTH:
92 case INF_MODEM_STATUS:
93 case INF_RX_SENSITIVITY:
95 logger.debug("Received unsupported message telegram: {}",
96 ESP2Packet.ESP2Response.getResponse(payload[1]).name());
101 public static @Nullable BasePacket buildPacket(int dataLength, byte packetType, byte[] payload) {
102 ESP2PacketType type = ESP2PacketType.getPacketType(packetType);
105 case Receive_Radio_Telegram: // RRT
106 logger.debug("Received ESP2 radio telegram: {}", HexUtils.bytesToHex(payload));
107 return handleRadioTelegram(dataLength, packetType, payload);
109 case Receive_Message_Telegram: // RMT => Response
110 logger.debug("Received ESP2 message telegram: {}", HexUtils.bytesToHex(payload));
111 return handleMessageTelegram(dataLength, packetType, payload);
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));
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) {
125 logger.trace("Received Transmit_Command_Telegram: {}", HexUtils.bytesToHex(payload));