2 * Copyright (c) 2010-2021 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.bluetooth.daikinmadoka.internal;
15 import java.io.ByteArrayOutputStream;
16 import java.util.Comparator;
17 import java.util.concurrent.ConcurrentSkipListSet;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.bluetooth.daikinmadoka.internal.model.commands.ResponseListener;
23 * As the protocol emutes an UART communication over BLE (characteristics write/notify), this class takes care of BLE
26 * @author Benjamin Lafois - Initial contribution
29 public class BRC1HUartProcessor {
32 * Maximum number of bytes per message chunk, including headers
34 public static final int MAX_CHUNK_SIZE = 20;
37 * In the unlikely event of messages arrive in wrong order, this comparator will sort the queue
39 private Comparator<byte[]> chunkSorter = (byte[] m1, byte[] m2) -> m1[0] - m2[0];
41 private ConcurrentSkipListSet<byte[]> uartMessages = new ConcurrentSkipListSet<>(chunkSorter);
43 private ResponseListener responseListener;
45 public BRC1HUartProcessor(ResponseListener responseListener) {
46 this.responseListener = responseListener;
49 private boolean isMessageComplete() {
50 int messagesInQueue = this.uartMessages.size();
52 if (messagesInQueue <= 0) {
56 byte[] firstMessageInQueue = uartMessages.first();
57 if (firstMessageInQueue.length < 2) {
61 int expectedChunks = (int) Math.ceil(firstMessageInQueue[1] / (MAX_CHUNK_SIZE - 1.0));
62 if (expectedChunks != messagesInQueue) {
66 // Check that we have every single ID
68 for (byte[] m : this.uartMessages) {
73 if (m[0] != expected++) {
80 public void chunkReceived(byte[] byteValue) {
81 this.uartMessages.add(byteValue);
82 if (isMessageComplete()) {
84 // Beyond this point, full message received
85 ByteArrayOutputStream bos = new ByteArrayOutputStream();
87 for (byte[] msg : uartMessages) {
89 bos.write(msg, 1, msg.length - 1);
93 this.uartMessages.clear();
95 this.responseListener.receivedResponse(bos.toByteArray());
99 public void abandon() {
100 this.uartMessages.clear();