From c5b66c12aa94561f7d7fa03584c30357c457554f Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Thu, 5 Oct 2023 23:13:13 +0200 Subject: [PATCH 1/2] [ipcamera] Handle empty snapshotUrls and XML encoded characters Signed-off-by: Kai Kreuzer --- .../internal/onvif/OnvifConnection.java | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java index 70b830ab394b2..a31d32c9718aa 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java @@ -70,6 +70,7 @@ * * * @author Matthew Skinner - Initial contribution + * @author Kai Kreuzer - Improve handling for certain cameras */ @NonNullByDefault @@ -360,21 +361,46 @@ public void processReply(String message) { } else if (message.contains("GetDeviceInformationResponse")) { logger.debug("GetDeviceInformationResponse recieved"); } else if (message.contains("GetSnapshotUriResponse")) { - snapshotUri = removeIPfromUrl(Helper.fetchXML(message, ":MediaUri", ":Uri")); - logger.debug("GetSnapshotUri:{}", snapshotUri); - if (ipCameraHandler.snapshotUri.isEmpty() - && !"ffmpeg".equals(ipCameraHandler.cameraConfig.getSnapshotUrl())) { - ipCameraHandler.snapshotUri = snapshotUri; + String url = Helper.fetchXML(message, ":MediaUri", ":Uri"); + if (!url.isBlank()) { + snapshotUri = removeIPfromUrl(url); + logger.debug("GetSnapshotUri: {}", snapshotUri); + if (ipCameraHandler.snapshotUri.isEmpty() + && !"ffmpeg".equals(ipCameraHandler.cameraConfig.getSnapshotUrl())) { + ipCameraHandler.snapshotUri = snapshotUri; + } } } else if (message.contains("GetStreamUriResponse")) { - rtspUri = Helper.fetchXML(message, ":MediaUri", ":Uri>"); - logger.debug("GetStreamUri:{}", rtspUri); + rtspUri = unEscapeXml(Helper.fetchXML(message, ":MediaUri", ":Uri>")); + logger.debug("GetStreamUri: {}", rtspUri); if (ipCameraHandler.cameraConfig.getFfmpegInput().isEmpty()) { ipCameraHandler.rtspUri = rtspUri; } } } + /** + * Simple method to unescape XML special characters in String. + * There are five XML Special characters which needs to be escaped: + * + *
+     * & => &
+     * < => <
+     * > => >
+     * " => "
+     * ' => '
+     * 
+ * + * @todo This method can be removed once https://github.com/openhab/openhab-core/pull/3738 is merged. + * + * @param input the input xml as String to unescape, may be null + * @return the unescaped xml as String, may be null + */ + public static String unEscapeXml(String str) { + return str.replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"") + .replace("'", "'"); + } + /** * The {@link removeIPfromUrl} Will throw away all text before the cameras IP, also removes the IP and the PORT * leaving just the URL. From d6636c22d3589eea78a1aedd2c5108804039bef3 Mon Sep 17 00:00:00 2001 From: Kai Kreuzer Date: Sun, 15 Oct 2023 21:03:21 +0200 Subject: [PATCH 2/2] use unescape method from StringUtils Signed-off-by: Kai Kreuzer --- .../internal/onvif/OnvifConnection.java | 46 ++++++------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java index a31d32c9718aa..f1ecfd0fdb44c 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/onvif/OnvifConnection.java @@ -40,6 +40,7 @@ import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.ChannelUID; import org.openhab.core.types.StateOption; +import org.openhab.core.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -371,36 +372,17 @@ public void processReply(String message) { } } } else if (message.contains("GetStreamUriResponse")) { - rtspUri = unEscapeXml(Helper.fetchXML(message, ":MediaUri", ":Uri>")); - logger.debug("GetStreamUri: {}", rtspUri); - if (ipCameraHandler.cameraConfig.getFfmpegInput().isEmpty()) { - ipCameraHandler.rtspUri = rtspUri; + String xml = StringUtils.unEscapeXml(Helper.fetchXML(message, ":MediaUri", ":Uri>")); + if (xml != null) { + rtspUri = xml; + logger.debug("GetStreamUri: {}", rtspUri); + if (ipCameraHandler.cameraConfig.getFfmpegInput().isEmpty()) { + ipCameraHandler.rtspUri = rtspUri; + } } } } - /** - * Simple method to unescape XML special characters in String. - * There are five XML Special characters which needs to be escaped: - * - *
-     * & => &
-     * < => <
-     * > => >
-     * " => "
-     * ' => '
-     * 
- * - * @todo This method can be removed once https://github.com/openhab/openhab-core/pull/3738 is merged. - * - * @param input the input xml as String to unescape, may be null - * @return the unescaped xml as String, may be null - */ - public static String unEscapeXml(String str) { - return str.replace("&", "&").replace("<", "<").replace(">", ">").replace(""", "\"") - .replace("'", "'"); - } - /** * The {@link removeIPfromUrl} Will throw away all text before the cameras IP, also removes the IP and the PORT * leaving just the URL. @@ -590,7 +572,7 @@ public void initChannel(SocketChannel socketChannel) throws Exception { }); bootstrap = localBootstap; } - if (!mainEventLoopGroup.isShuttingDown()) { + if (!mainEventLoopGroup.isShuttingDown() && bootstrap != null) { bootstrap.connect(new InetSocketAddress(ipAddress, onvifPort)).addListener(new ChannelFutureListener() { @Override @@ -609,10 +591,12 @@ public void operationComplete(@Nullable ChannelFuture future) { if (cause instanceof ConnectTimeoutException) { logger.debug("Camera is not reachable on IP {}", ipAddress); connectError = true; - } else if ((cause instanceof ConnectException) - && cause.getMessage().contains("Connection refused")) { - logger.debug("Camera ONVIF port {} is refused.", onvifPort); - refusedError = true; + } else if (cause instanceof ConnectException) { + String msg = cause.getMessage(); + if (msg != null && msg.contains("Connection refused")) { + logger.debug("Camera ONVIF port {} is refused.", onvifPort); + refusedError = true; + } } } if (isConnected) {