]> git.basschouten.com Git - openhab-addons.git/commitdiff
[bluetooth.bluegiga] Introduced better initialization functionality (#10148)
authorpali <pauli.anttila@gmail.com>
Mon, 15 Feb 2021 17:08:14 +0000 (19:08 +0200)
committerGitHub <noreply@github.com>
Mon, 15 Feb 2021 17:08:14 +0000 (09:08 -0800)
* [bluetooth.bluegiga] Introduced better initialization functionality

+ other improvements
* [bluetooth.bluegiga] Review change
* [bluetooth.bluegiga] Fixed typo

Signed-off-by: Pauli Anttila <pauli.anttila@gmail.com>
bundles/org.openhab.binding.bluetooth.bluegiga/src/main/java/org/openhab/binding/bluetooth/bluegiga/handler/BlueGigaBridgeHandler.java
bundles/org.openhab.binding.bluetooth.bluegiga/src/main/java/org/openhab/binding/bluetooth/bluegiga/internal/BlueGigaResponsePackets.java
bundles/org.openhab.binding.bluetooth.bluegiga/src/main/java/org/openhab/binding/bluetooth/bluegiga/internal/BlueGigaSerialHandler.java

index e57e3d56a5d40b337e9cce00e4331e1c53c71c05..7bd7cdb16823770598ddf6072de0f0826a9ac781 100644 (file)
@@ -24,6 +24,7 @@ import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
@@ -158,6 +159,7 @@ public class BlueGigaBridgeHandler extends AbstractBluetoothBridgeHandler<BlueGi
 
     private @Nullable ScheduledFuture<?> removeInactiveDevicesTask;
     private @Nullable ScheduledFuture<?> discoveryTask;
+    private @Nullable ScheduledFuture<?> initTask;
 
     private @Nullable Future<?> passiveScanIdleTimer;
 
@@ -168,15 +170,40 @@ public class BlueGigaBridgeHandler extends AbstractBluetoothBridgeHandler<BlueGi
 
     @Override
     public void initialize() {
-        logger.info("Initializing BlueGiga");
         super.initialize();
-        Optional<BlueGigaConfiguration> cfg = Optional.of(getConfigAs(BlueGigaConfiguration.class));
         updateStatus(ThingStatus.UNKNOWN);
+        if (initTask == null) {
+            initTask = scheduler.scheduleWithFixedDelay(this::checkInit, 0, 10, TimeUnit.SECONDS);
+        }
+    }
+
+    protected void checkInit() {
+        boolean init = false;
+        try {
+            if (!serialHandler.get().isAlive()) {
+                logger.debug("BLE serial handler seems to be dead, reinitilize");
+                stop();
+                init = true;
+            }
+        } catch (InterruptedException e) {
+            return;
+        } catch (ExecutionException e) {
+            init = true;
+        }
+
+        if (init) {
+            logger.debug("Initialize BlueGiga");
+            start();
+        }
+    }
+
+    private void start() {
+        Optional<BlueGigaConfiguration> cfg = Optional.of(getConfigAs(BlueGigaConfiguration.class));
         if (cfg.isPresent()) {
+            initComplete = false;
             configuration = cfg.get();
             serialPortFuture = RetryFuture.callWithRetry(() -> {
                 var localFuture = serialPortFuture;
-                logger.debug("Initialize BlueGiga");
                 logger.debug("Using configuration: {}", configuration);
 
                 String serialPortName = configuration.port;
@@ -288,13 +315,16 @@ public class BlueGigaBridgeHandler extends AbstractBluetoothBridgeHandler<BlueGi
 
     @Override
     public void dispose() {
-        logger.info("Disposing BlueGiga");
+        if (initTask != null) {
+            initTask.cancel(true);
+            initTask = null;
+        }
         stop();
-        stopScheduledTasks();
         super.dispose();
     }
 
     private void stop() {
+        logger.info("Stop BlueGiga");
         transactionManager.thenAccept(tman -> {
             tman.removeEventListener(this);
             tman.close();
@@ -309,6 +339,7 @@ public class BlueGigaBridgeHandler extends AbstractBluetoothBridgeHandler<BlueGi
 
         serialPortFuture.thenAccept(this::closeSerialPort);
         serialPortFuture.cancel(false);
+        stopScheduledTasks();
     }
 
     private void schedulePassiveScan() {
@@ -764,8 +795,7 @@ public class BlueGigaBridgeHandler extends AbstractBluetoothBridgeHandler<BlueGi
 
     @Override
     public void bluegigaClosed(Exception reason) {
-        logger.debug("BlueGiga connection closed, request reinitialization");
+        logger.debug("BlueGiga connection closed, request reinitialization, reason: {}", reason.getMessage());
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason.getMessage());
-        initComplete = false;
     }
 }
index 01f61fabf7616fe18f51e81335212a39d232d103..56fe26fc413b194ce57a2a9721d64b7740e4cb2c 100644 (file)
@@ -199,7 +199,7 @@ class BlueGigaResponsePackets {
             return bleFrame;
         } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
                 | IllegalArgumentException | InvocationTargetException e) {
-            logger.error("Error instantiating BLE class", e);
+            logger.debug("Error instantiating BLE class", e);
         }
 
         return null;
index c08d70ce3f7e2ce32aeb19fb88c6c139cbca6f44..be2fad17b61bfd1f78063ed8972047b832ffe05a 100644 (file)
@@ -67,6 +67,8 @@ public class BlueGigaSerialHandler {
         parserThread = createBlueGigaBLEHandler(uid);
         parserThread.setUncaughtExceptionHandler((t, th) -> {
             logger.warn("BluegigaSerialHandler terminating due to unhandled error", th);
+            notifyEventListeners(new BlueGigaException(
+                    "BluegigaSerialHandler terminating due to unhandled error, reason " + th.getMessage()));
         });
         parserThread.setDaemon(true);
         parserThread.start();
@@ -238,7 +240,6 @@ public class BlueGigaSerialHandler {
     private void inboundMessageHandlerLoop() {
         final int[] framecheckParams = { 0x00, 0x7F, 0xC0, 0xF8, 0xE0 };
 
-        int exceptionCnt = 0;
         logger.trace("BlueGiga BLE thread started");
         int[] inputBuffer = new int[BLE_MAX_LENGTH];
         int inputCount = 0;
@@ -260,9 +261,8 @@ public class BlueGigaSerialHandler {
                 }
 
                 if (inputCount < 4) {
-                    // The BGAPI protocol has no packet framing, and no error detection, so we do a few
-                    // sanity checks on the header to try and allow resyncronisation should there be an
-                    // error.
+                    // The BGAPI protocol has no packet framing and no error detection, so we do a few
+                    // sanity checks on the header to try and allow resynchronisation.
                     // Byte 0: Check technology type is bluetooth and high length is 0
                     // Byte 1: Check length is less than 64 bytes
                     // Byte 2: Check class ID is less than 8
@@ -278,21 +278,22 @@ public class BlueGigaSerialHandler {
                 } else if (inputCount == 4) {
                     // Process the header to get the length
                     inputLength = inputBuffer[1] + (inputBuffer[0] & 0x02 << 8) + 4;
-                    if (inputLength > 64) {
-                        logger.debug("BLE length larger than 64 bytes ({})", inputLength);
+                    if (inputLength > BLE_MAX_LENGTH) {
+                        logger.debug("Received illegal BLE packet, length larger than max {} bytes ({})",
+                                BLE_MAX_LENGTH, inputLength);
                         if (inputStream.markSupported()) {
                             inputStream.reset();
                         }
                         inputCount = 0;
+                        inputLength = 0;
                         continue;
                     }
-                }
-                if (inputCount == inputLength) {
+                } else if (inputCount == inputLength) {
+                    // End of packet reached - process
                     if (logger.isTraceEnabled()) {
                         logger.trace("BLE RX: {}", printHex(inputBuffer, inputLength));
                     }
 
-                    // End of packet reached - process
                     BlueGigaResponse responsePacket = BlueGigaResponsePackets.getPacket(inputBuffer);
 
                     if (logger.isTraceEnabled()) {
@@ -300,24 +301,16 @@ public class BlueGigaSerialHandler {
                     }
                     if (responsePacket != null) {
                         notifyEventListeners(responsePacket);
+                    } else {
+                        logger.debug("Unknown packet received: {}", printHex(inputBuffer, inputLength));
                     }
 
                     inputCount = 0;
-                    exceptionCnt = 0;
-                }
-
-            } catch (IOException e) {
-                logger.debug("BlueGiga BLE IOException: ", e);
-
-                if (exceptionCnt++ > 10) {
-                    logger.error("BlueGiga BLE exception count exceeded, closing handler");
-                    close = true;
-                    notifyEventListeners(e);
                 }
             } catch (Exception e) {
-                logger.debug("BlueGiga BLE Exception, closing handler", e);
+                logger.trace("BlueGiga BLE Exception: ", e);
                 close = true;
-                notifyEventListeners(e);
+                notifyEventListeners(new BlueGigaException("BlueGiga BLE Exception, reason " + e.getMessage(), e));
             }
         }
         logger.debug("BlueGiga BLE exited.");