]> git.basschouten.com Git - openhab-addons.git/blob
503d74e4fab6b0b994d8ec8aa5c17a696fd9c2ac
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.transceiver;
14
15 import java.io.IOException;
16 import java.util.Arrays;
17 import java.util.concurrent.ScheduledExecutorService;
18
19 import org.openhab.binding.enocean.internal.EnOceanException;
20 import org.openhab.binding.enocean.internal.messages.BasePacket;
21 import org.openhab.binding.enocean.internal.messages.ERP1Message;
22 import org.openhab.binding.enocean.internal.messages.ERP1Message.RORG;
23 import org.openhab.binding.enocean.internal.messages.ESP3Packet;
24 import org.openhab.binding.enocean.internal.messages.ESP3PacketFactory;
25 import org.openhab.binding.enocean.internal.messages.Response;
26 import org.openhab.core.io.transport.serial.SerialPortManager;
27 import org.openhab.core.util.HexUtils;
28
29 /**
30  *
31  * @author Daniel Weber - Initial contribution
32  */
33 public class EnOceanESP3Transceiver extends EnOceanTransceiver {
34
35     public EnOceanESP3Transceiver(String path, TransceiverErrorListener errorListener,
36             ScheduledExecutorService scheduler, SerialPortManager serialPortManager) {
37         super(path, errorListener, scheduler, serialPortManager);
38     }
39
40     enum ReadingState {
41         WaitingForSyncByte,
42         ReadingHeader,
43         ReadingData
44     }
45
46     byte[] dataBuffer = new byte[ENOCEAN_MAX_DATA];
47     ReadingState state = ReadingState.WaitingForSyncByte;
48     int currentPosition = 0;
49     int dataLength = -1;
50     int optionalLength = -1;
51     byte packetType = -1;
52
53     @Override
54     protected void processMessage(byte firstByte) {
55         byte[] readingBuffer = new byte[ENOCEAN_MAX_DATA];
56         int bytesRead = -1;
57         byte _byte;
58
59         try {
60             readingBuffer[0] = firstByte;
61
62             bytesRead = this.inputStream.read(readingBuffer, 1, inputStream.available());
63             if (bytesRead == -1) {
64                 throw new IOException("could not read from inputstream");
65             }
66
67             if (readingTask == null || readingTask.isCancelled()) {
68                 return;
69             }
70
71             bytesRead++;
72             for (int p = 0; p < bytesRead; p++) {
73                 _byte = readingBuffer[p];
74
75                 switch (state) {
76                     case WaitingForSyncByte:
77                         if (_byte == ESP3Packet.ESP3_SYNC_BYTE) {
78                             state = ReadingState.ReadingHeader;
79                             logger.trace("Received Sync Byte");
80                         }
81                         break;
82                     case ReadingHeader:
83                         if (currentPosition == ESP3Packet.ESP3_HEADER_LENGTH) {
84                             if (ESP3Packet.checkCRC8(dataBuffer, ESP3Packet.ESP3_HEADER_LENGTH, _byte)
85                                     && ((dataBuffer[0] & 0xFF) << 8) + (dataBuffer[1] & 0xFF)
86                                             + (dataBuffer[2] & 0xFF) > 0) {
87                                 state = ReadingState.ReadingData;
88
89                                 dataLength = ((dataBuffer[0] & 0xFF << 8) | (dataBuffer[1] & 0xFF));
90                                 optionalLength = dataBuffer[2] & 0xFF;
91                                 packetType = dataBuffer[3];
92                                 currentPosition = 0;
93
94                                 if (packetType == 3) {
95                                     logger.trace("Received sub_msg");
96                                 }
97
98                                 logger.trace(">> Received header, data length {} optional length {} packet type {}",
99                                         dataLength, optionalLength, packetType);
100                             } else {
101                                 // check if we find a sync byte in current buffer
102                                 int copyFrom = -1;
103                                 for (int i = 0; i < ESP3Packet.ESP3_HEADER_LENGTH; i++) {
104                                     if (dataBuffer[i] == ESP3Packet.ESP3_SYNC_BYTE) {
105                                         copyFrom = i + 1;
106                                         break;
107                                     }
108                                 }
109
110                                 if (copyFrom != -1) {
111                                     System.arraycopy(dataBuffer, copyFrom, dataBuffer, 0,
112                                             ESP3Packet.ESP3_HEADER_LENGTH - copyFrom);
113                                     state = ReadingState.ReadingHeader;
114                                     currentPosition = ESP3Packet.ESP3_HEADER_LENGTH - copyFrom;
115                                     dataBuffer[currentPosition++] = _byte;
116                                 } else {
117                                     currentPosition = 0;
118                                     state = _byte == ESP3Packet.ESP3_SYNC_BYTE ? ReadingState.ReadingHeader
119                                             : ReadingState.WaitingForSyncByte;
120                                 }
121                                 logger.trace("CrC8 header check not successful");
122                             }
123                         } else {
124                             dataBuffer[currentPosition++] = _byte;
125                         }
126                         break;
127                     case ReadingData:
128                         if (currentPosition == dataLength + optionalLength) {
129                             if (ESP3Packet.checkCRC8(dataBuffer, dataLength + optionalLength, _byte)) {
130                                 state = ReadingState.WaitingForSyncByte;
131                                 BasePacket packet = ESP3PacketFactory.BuildPacket(dataLength, optionalLength,
132                                         packetType, dataBuffer);
133
134                                 if (packet != null) {
135                                     switch (packet.getPacketType()) {
136                                         case COMMON_COMMAND:
137                                             logger.debug("Common command: {}",
138                                                     HexUtils.bytesToHex(packet.getPayload()));
139                                             break;
140                                         case EVENT:
141                                             logger.debug("Event occured: {}", HexUtils.bytesToHex(packet.getPayload()));
142                                             break;
143                                         case RADIO_ERP1: {
144                                             ERP1Message msg = (ERP1Message) packet;
145                                             logger.debug("{} with RORG {} for {} payload {} received",
146                                                     packet.getPacketType().name(), msg.getRORG().name(),
147                                                     HexUtils.bytesToHex(msg.getSenderId()), HexUtils.bytesToHex(
148                                                             Arrays.copyOf(dataBuffer, dataLength + optionalLength)));
149
150                                             if (msg.getRORG() != RORG.Unknown) {
151                                                 informListeners(msg);
152                                             } else {
153                                                 logger.debug("Received unknown RORG");
154                                             }
155                                         }
156                                             break;
157                                         case RADIO_ERP2:
158                                             break;
159                                         case RADIO_MESSAGE:
160                                             break;
161                                         case RADIO_SUB_TEL:
162                                             break;
163                                         case REMOTE_MAN_COMMAND:
164                                             break;
165                                         case RESPONSE: {
166                                             Response response = (Response) packet;
167                                             logger.debug("{} with code {} payload {} received",
168                                                     packet.getPacketType().name(), response.getResponseType().name(),
169                                                     HexUtils.bytesToHex(packet.getPayload())); // Responses do not have
170                                                                                                // optional data
171                                             handleResponse(response);
172                                         }
173                                             break;
174                                         case SMART_ACK_COMMAND:
175                                             break;
176                                         default:
177                                             break;
178                                     }
179                                 } else {
180                                     logger.trace("Unknown ESP3Packet: {}", HexUtils
181                                             .bytesToHex(Arrays.copyOf(dataBuffer, dataLength + optionalLength)));
182                                 }
183                             } else {
184                                 state = _byte == ESP3Packet.ESP3_SYNC_BYTE ? ReadingState.ReadingHeader
185                                         : ReadingState.WaitingForSyncByte;
186                                 logger.trace("ESP3Packet malformed: {}",
187                                         HexUtils.bytesToHex(Arrays.copyOf(dataBuffer, dataLength + optionalLength)));
188                             }
189
190                             currentPosition = 0;
191                             dataLength = optionalLength = packetType = -1;
192                         } else {
193                             dataBuffer[currentPosition++] = _byte;
194                         }
195                         break;
196                 }
197             }
198         } catch (IOException ioexception) {
199             errorListener.ErrorOccured(ioexception);
200             return;
201         }
202     }
203
204     @Override
205     protected byte[] serializePacket(BasePacket packet) throws EnOceanException {
206         return new ESP3Packet(packet).serialize();
207     }
208 }