diff --git a/bundles/org.openhab.binding.androidtv/README.md b/bundles/org.openhab.binding.androidtv/README.md index 229a0af584561..1fce2128de78b 100644 --- a/bundles/org.openhab.binding.androidtv/README.md +++ b/bundles/org.openhab.binding.androidtv/README.md @@ -35,6 +35,8 @@ There are three required fields to connect successfully to a ShieldTV. | Name | Type | Description | Default | Required | Advanced | |------------------|---------|---------------------------------------|---------|----------|----------| | ipAddress | text | IP address of the device | N/A | yes | no | +| googletvPort | text | TCP Port for GoogleTV | 6466 | no | no | +| shieldtvPort | text | TCP Port for ShieldTV | 8987 | no | no | | keystore | text | Location of the Java Keystore | N/A | no | no | | keystorePassword | text | Password of the Java Keystore | N/A | no | no | | gtvEnabled | boolean | Enable/Disable the GoogleTV protocol | true | no | no | diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVBindingConstants.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVBindingConstants.java index 01f322fd9ac62..776122e5f8669 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVBindingConstants.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVBindingConstants.java @@ -49,8 +49,10 @@ public class AndroidTVBindingConstants { public static final String CHANNEL_PLAYER = "player"; // List of all config properties - public static final String PROPERTY_IP_ADDRESS = "ipAddress"; - public static final String PROPERTY_GTV_ENABLED = "gtvEnabled"; + public static final String PARAMETER_IP_ADDRESS = "ipAddress"; + public static final String PARAMETER_GOOGLETV_PORT = "googletvPort"; + public static final String PARAMETER_SHIELDTV_PORT = "shieldtvPort"; + public static final String PARAMETER_GTV_ENABLED = "gtvEnabled"; // List of all static String literals public static final String PIN_REQUEST = "REQUEST"; diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVHandler.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVHandler.java index a1d0fe7247bd3..dd2660b3cc123 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVHandler.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVHandler.java @@ -128,6 +128,10 @@ public void checkThingStatus() { failed = true; } statusMessage = "GoogleTV: " + googletvConnectionManager.getStatusMessage(); + + if (!THING_TYPE_GOOGLETV.equals(thingTypeUID)) { + statusMessage = statusMessage + " | "; + } } if (THING_TYPE_SHIELDTV.equals(thingTypeUID)) { @@ -135,7 +139,7 @@ public void checkThingStatus() { if (!shieldtvConnectionManager.getLoggedIn()) { failed = true; } - statusMessage = statusMessage + " | ShieldTV: " + shieldtvConnectionManager.getStatusMessage(); + statusMessage = statusMessage + "ShieldTV: " + shieldtvConnectionManager.getStatusMessage(); } } @@ -159,13 +163,13 @@ public void initialize() { String ipAddress = googletvConfig.ipAddress; boolean gtvEnabled = googletvConfig.gtvEnabled; - if (ipAddress.isBlank()) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "@text/offline.googletv-address-not-specified"); - return; - } - if (THING_TYPE_GOOGLETV.equals(thingTypeUID) || gtvEnabled) { + if (ipAddress.isBlank()) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "@text/offline.googletv-address-not-specified"); + return; + } + googletvConnectionManager = new GoogleTVConnectionManager(this, googletvConfig); } @@ -186,6 +190,13 @@ public void initialize() { TimeUnit.MILLISECONDS); } + public void sendCommandToProtocol(ChannelUID channelUID, Command command) { + ShieldTVConnectionManager shieldtvConnectionManager = this.shieldtvConnectionManager; + if (THING_TYPE_SHIELDTV.equals(thingTypeUID) && (shieldtvConnectionManager != null)) { + shieldtvConnectionManager.handleCommand(channelUID, command); + } + } + @Override public void handleCommand(ChannelUID channelUID, Command command) { logger.trace("{} - Command received at handler: {} {}", this.thingID, channelUID.getId(), command); diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/GoogleTVDiscoveryParticipant.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/GoogleTVDiscoveryParticipant.java index aef8f3012e933..eae5b03aa0870 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/GoogleTVDiscoveryParticipant.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/GoogleTVDiscoveryParticipant.java @@ -79,7 +79,7 @@ public String getServiceType() { if (uid != null) { final String id = uid.getId(); final String label = service.getName() + " (" + id + ")"; - final Map properties = Map.of(PROPERTY_IP_ADDRESS, ipAddress); + final Map properties = Map.of(PARAMETER_IP_ADDRESS, ipAddress); return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build(); } else { diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/ShieldTVDiscoveryParticipant.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/ShieldTVDiscoveryParticipant.java index d408ef1960f0f..428367fbc98de 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/ShieldTVDiscoveryParticipant.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/ShieldTVDiscoveryParticipant.java @@ -81,7 +81,7 @@ public String getServiceType() { if (uid != null) { final String id = uid.getId(); final String label = service.getName() + " (" + id + ")"; - final Map properties = Map.of(PROPERTY_IP_ADDRESS, ipAddress); + final Map properties = Map.of(PARAMETER_IP_ADDRESS, ipAddress); return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build(); } else { diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConfiguration.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConfiguration.java index e782a81fb10fc..fd0da51795e71 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConfiguration.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConfiguration.java @@ -23,7 +23,7 @@ public class GoogleTVConfiguration { public String ipAddress = ""; - public int port = 6466; + public int googletvPort = 6466; public int reconnect; public int heartbeat; public String keystoreFileName = ""; diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConnectionManager.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConnectionManager.java index ef54f8ba79e5a..1ba30cb807472 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConnectionManager.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConnectionManager.java @@ -80,8 +80,6 @@ */ @NonNullByDefault public class GoogleTVConnectionManager { - private static final int DEFAULT_RECONNECT_SECONDS = 60; - private static final int DEFAULT_HEARTBEAT_SECONDS = 5; private static final long KEEPALIVE_TIMEOUT_SECONDS = 30; private static final String DEFAULT_KEYSTORE_PASSWORD = "secret"; private static final String DEFAULT_MODE = "NORMAL"; @@ -335,7 +333,7 @@ public boolean getLoggedIn() { private boolean servicePing() { int timeout = 500; - SocketAddress socketAddress = new InetSocketAddress(config.ipAddress, config.port); + SocketAddress socketAddress = new InetSocketAddress(config.ipAddress, config.googletvPort); try (Socket socket = new Socket()) { socket.connect(socketAddress, timeout); return true; @@ -369,7 +367,7 @@ private void checkHealth() { private void setShimX509ClientChain(X509Certificate @Nullable [] shimX509ClientChain) { try { this.shimX509ClientChain = shimX509ClientChain; - logger.trace("Setting shimX509ClientChain {}", config.port); + logger.trace("Setting shimX509ClientChain {}", config.googletvPort); if (shimX509ClientChain != null) { if (logger.isTraceEnabled()) { logger.trace("Subject DN: {}", shimX509ClientChain[0].getSubjectX500Principal()); @@ -389,7 +387,7 @@ private void setShimX509ClientChain(X509Certificate @Nullable [] shimX509ClientC private void startChildConnectionManager(int port, String mode) { GoogleTVConfiguration childConfig = new GoogleTVConfiguration(); childConfig.ipAddress = config.ipAddress; - childConfig.port = port; + childConfig.googletvPort = port; childConfig.reconnect = config.reconnect; childConfig.heartbeat = config.heartbeat; childConfig.keystoreFileName = config.keystoreFileName; @@ -397,10 +395,10 @@ private void startChildConnectionManager(int port, String mode) { childConfig.delay = config.delay; childConfig.shim = config.shim; childConfig.mode = mode; - logger.debug("{} - startChildConnectionManager parent config: {} {} {}", handler.getThingID(), config.port, - config.mode, config.shim); - logger.debug("{} - startChildConnectionManager child config: {} {} {}", handler.getThingID(), childConfig.port, - childConfig.mode, childConfig.shim); + logger.debug("{} - startChildConnectionManager parent config: {} {} {}", handler.getThingID(), + config.googletvPort, config.mode, config.shim); + logger.debug("{} - startChildConnectionManager child config: {} {} {}", handler.getThingID(), + childConfig.googletvPort, childConfig.mode, childConfig.shim); childConnectionManager = new GoogleTVConnectionManager(this.handler, childConfig, this); } @@ -460,7 +458,7 @@ private void initialize() { folder.mkdirs(); } - config.port = (config.port > 0) ? config.port : DEFAULT_PORT; + config.googletvPort = (config.googletvPort > 0) ? config.googletvPort : DEFAULT_PORT; config.mode = (!config.mode.equals("")) ? config.mode : DEFAULT_MODE; config.keystoreFileName = (!config.keystoreFileName.equals("")) ? config.keystoreFileName @@ -520,8 +518,9 @@ public void connect() { if (isOnline || config.mode.equals(PIN_MODE)) { try { logger.debug("{} - Opening GoogleTV SSL connection to {}:{} {}", handler.getThingID(), - config.ipAddress, config.port, config.mode); - SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(config.ipAddress, config.port); + config.ipAddress, config.googletvPort, config.mode); + SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(config.ipAddress, + config.googletvPort); sslSocket.startHandshake(); this.shimServerChain = ((SSLSocket) sslSocket).getSession().getPeerCertificates(); writer = new BufferedWriter( @@ -531,7 +530,7 @@ public void connect() { this.sslSocket = sslSocket; this.sendQueue.clear(); logger.debug("{} - Connection to {}:{} {} successful", handler.getThingID(), config.ipAddress, - config.port, config.mode); + config.googletvPort, config.mode); } catch (UnknownHostException e) { setStatus(false, "offline.unknown-host"); logger.debug("{} - Unknown host {}", handler.getThingID(), config.ipAddress); @@ -539,7 +538,8 @@ public void connect() { } catch (IllegalArgumentException e) { // port out of valid range setStatus(false, "offline.invalid-port-number"); - logger.debug("{} - Invalid port number {}:{}", handler.getThingID(), config.ipAddress, config.port); + logger.debug("{} - Invalid port number {}:{}", handler.getThingID(), config.ipAddress, + config.googletvPort); return; } catch (InterruptedIOException e) { logger.debug("{} - Interrupted while establishing GoogleTV connection", handler.getThingID()); @@ -552,7 +552,7 @@ public void connect() { setStatus(false, "offline.pin-process-incomplete"); logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID()); reconnectTaskCancel(true); - startChildConnectionManager(this.config.port + 1, PIN_MODE); + startChildConnectionManager(this.config.googletvPort + 1, PIN_MODE); } else if ((message != null) && (message.contains("certificate_unknown")) && (config.shim)) { logger.debug("Shim cert_unknown I/O error while connecting: {}", e.getMessage()); Socket shimServerSocket = this.shimServerSocket; @@ -567,7 +567,7 @@ public void connect() { } else { setStatus(false, "offline.error-opening-ssl-connection-check-log"); logger.info("{} - Error opening SSL connection to {}:{} {}", handler.getThingID(), - config.ipAddress, config.port, e.getMessage()); + config.ipAddress, config.googletvPort, e.getMessage()); disconnect(false); scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later. } @@ -577,7 +577,7 @@ public void connect() { setStatus(false, "offline.initializing"); logger.trace("{} - Starting Reader Thread for {}:{}", handler.getThingID(), config.ipAddress, - config.port); + config.googletvPort); Thread readerThread = new Thread(this::readerThreadJob, "GoogleTV reader " + handler.getThingID()); readerThread.setDaemon(true); @@ -585,7 +585,7 @@ public void connect() { this.readerThread = readerThread; logger.trace("{} - Starting Sender Thread for {}:{}", handler.getThingID(), config.ipAddress, - config.port); + config.googletvPort); Thread senderThread = new Thread(this::senderThreadJob, "GoogleTV sender " + handler.getThingID()); senderThread.setDaemon(true); @@ -593,19 +593,19 @@ public void connect() { this.senderThread = senderThread; logger.trace("{} - Checking for PIN MODE for {}:{} {}", handler.getThingID(), config.ipAddress, - config.port, config.mode); + config.googletvPort, config.mode); if (config.mode.equals(PIN_MODE)) { logger.trace("{} - Sending PIN Login to {}:{}", handler.getThingID(), config.ipAddress, - config.port); + config.googletvPort); // Send app name and device name sendCommand(new GoogleTVCommand(GoogleTVRequest.encodeMessage(GoogleTVRequest.loginRequest(1)))); // Unknown but required sendCommand(new GoogleTVCommand(GoogleTVRequest.encodeMessage(GoogleTVRequest.loginRequest(2)))); // Don't send pin request yet, let user send REQUEST via PINCODE channel } else { - logger.trace("{} - Not PIN Mode {}:{} {}", handler.getThingID(), config.ipAddress, config.port, - config.mode); + logger.trace("{} - Not PIN Mode {}:{} {}", handler.getThingID(), config.ipAddress, + config.googletvPort, config.mode); } } else { scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later. @@ -628,9 +628,9 @@ public void shimInitialize() { sslContext.init(kmf.getKeyManagers(), trustManagers, null); this.sslServerSocketFactory = sslContext.getServerSocketFactory(); - logger.trace("Opening GoogleTV shim on port {}", config.port); + logger.trace("Opening GoogleTV shim on port {}", config.googletvPort); SSLServerSocket sslServerSocket = (SSLServerSocket) this.sslServerSocketFactory - .createServerSocket(config.port); + .createServerSocket(config.googletvPort); if (this.config.mode.equals(DEFAULT_MODE)) { sslServerSocket.setNeedClientAuth(true); } else { @@ -638,18 +638,18 @@ public void shimInitialize() { } while (true) { - logger.trace("Waiting for shim connection... {}", config.port); + logger.trace("Waiting for shim connection... {}", config.googletvPort); if (this.config.mode.equals(DEFAULT_MODE) && (childConnectionManager == null)) { - logger.trace("Starting childConnectionManager {}", config.port); - startChildConnectionManager(this.config.port + 1, PIN_MODE); + logger.trace("Starting childConnectionManager {}", config.googletvPort); + startChildConnectionManager(this.config.googletvPort + 1, PIN_MODE); } SSLSocket serverSocket = (SSLSocket) sslServerSocket.accept(); - logger.trace("shimInitialize accepted {}", config.port); + logger.trace("shimInitialize accepted {}", config.googletvPort); try { serverSocket.startHandshake(); - logger.trace("shimInitialize startHandshake {}", config.port); + logger.trace("shimInitialize startHandshake {}", config.googletvPort); connect(); - logger.trace("shimInitialize connected {}", config.port); + logger.trace("shimInitialize connected {}", config.googletvPort); SSLSession session = serverSocket.getSession(); Certificate[] cchain2 = session.getPeerCertificates(); @@ -708,12 +708,12 @@ public void shimInitialize() { senderThread.start(); this.shimSenderThread = senderThread; } catch (Exception e) { - logger.trace("Shim initalization exception {}", config.port); + logger.trace("Shim initalization exception {}", config.googletvPort); logger.trace("Shim initalization exception", e); } } } catch (Exception e) { - logger.trace("Shim initalization exception {}", config.port); + logger.trace("Shim initalization exception {}", config.googletvPort); logger.trace("Shim initalization exception", e); return; @@ -838,7 +838,7 @@ private void reconnect() { * Method executed by the message sender thread (senderThread) */ private void senderThreadJob() { - logger.debug("{} - Command sender thread started {}", handler.getThingID(), config.port); + logger.debug("{} - Command sender thread started {}", handler.getThingID(), config.googletvPort); try { while (!Thread.currentThread().isInterrupted() && writer != null) { GoogleTVCommand command = sendQueue.take(); @@ -871,7 +871,7 @@ private void senderThreadJob() { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { - logger.debug("{} - Command sender thread exiting {}", handler.getThingID(), config.port); + logger.debug("{} - Command sender thread exiting {}", handler.getThingID(), config.googletvPort); } } @@ -908,7 +908,7 @@ private void shimSenderThreadJob() { * Method executed by the message reader thread (readerThread) */ private void readerThreadJob() { - logger.debug("{} - Message reader thread started {}", handler.getThingID(), config.port); + logger.debug("{} - Message reader thread started {}", handler.getThingID(), config.googletvPort); try { BufferedReader reader = this.reader; int length = 0; @@ -953,7 +953,7 @@ private void readerThreadJob() { setStatus(false, "offline.pin-process-incomplete"); logger.debug("{} - GoogleTV PIN Process Incomplete", handler.getThingID()); reconnectTaskCancel(true); - startChildConnectionManager(this.config.port + 1, PIN_MODE); + startChildConnectionManager(this.config.googletvPort + 1, PIN_MODE); } else if ((message != null) && (message.contains("certificate_unknown")) && (config.shim)) { logger.debug("Shim cert_unknown I/O error while reading from stream: {}", e.getMessage()); Socket shimServerSocket = this.shimServerSocket; @@ -973,7 +973,7 @@ private void readerThreadJob() { logger.warn("Runtime exception in reader thread", e); setStatus(false, "offline.runtime-exception"); } finally { - logger.debug("{} - Message reader thread exiting {}", handler.getThingID(), config.port); + logger.debug("{} - Message reader thread exiting {}", handler.getThingID(), config.googletvPort); } } @@ -1007,7 +1007,7 @@ private String interceptMessages(String message) { } private void shimReaderThreadJob() { - logger.debug("Shim reader thread started {}", config.port); + logger.debug("Shim reader thread started {}", config.googletvPort); try { BufferedReader reader = this.shimReader; String thisShimMsg = ""; @@ -1047,7 +1047,7 @@ private void shimReaderThreadJob() { logger.warn("Runtime exception in reader thread", e); setStatus(false, "offline.runtime-exception"); } finally { - logger.debug("Shim message reader thread exiting {}", config.port); + logger.debug("Shim message reader thread exiting {}", config.googletvPort); } } @@ -1215,7 +1215,8 @@ public void handleCommand(ChannelUID channelUID, Command command) { message = "5204085b" + suffix; break; default: - logger.debug("Unknown Key {}", command); + logger.debug("Unknown Key {} - sending to vendor protocol", command); + handler.sendCommandToProtocol(channelUID, command); return; } sendCommand(new GoogleTVCommand(GoogleTVRequest.encodeMessage(message))); @@ -1267,7 +1268,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { setStatus(false, "offline.user-forced-pin-process"); logger.debug("{} - User Forced PIN Process", handler.getThingID()); disconnect(true); - startChildConnectionManager(config.port + 1, PIN_MODE); + startChildConnectionManager(config.googletvPort + 1, PIN_MODE); try { Thread.sleep(PIN_DELAY); } catch (InterruptedException e) { diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConstants.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConstants.java index 70642913fcaa7..b6038fd8ef5fa 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConstants.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConstants.java @@ -41,4 +41,5 @@ public class GoogleTVConstants { public static final String MESSAGE_POWERON = "c202020801"; public static final String MESSAGE_PINSUCCESS = "080210c801ca02"; public static final String HARD_DROP = "ffffffff"; + public static final String VERSION_01 = "7b2270726f746f636f6c5f76657273696f6e223a312c22737461747573223a3430307d"; } diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVMessageParser.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVMessageParser.java index 51613b2de1be4..0c63d40b36ed2 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVMessageParser.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVMessageParser.java @@ -57,6 +57,8 @@ public void handleMessage(String msg) { if (msg.startsWith(DELIMITER_1A)) { logger.warn("{} - GoogleTV Error Message: {}", thingId, msg); callback.getHandler().dispose(); + } else if (msg.equals(VERSION_01)) { + logger.warn("{} - GoogleTV version on device needs to be updated", thingId); } else if (msg.startsWith(DELIMITER_0A)) { // First message on connection from GTV // diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConfiguration.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConfiguration.java index db3af7efa41d1..71f2f631b6b12 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConfiguration.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConfiguration.java @@ -23,7 +23,7 @@ public class ShieldTVConfiguration { public String ipAddress = ""; - public int port = 8987; + public int shieldtvPort = 8987; public int reconnect; public int heartbeat; public String keystoreFileName = ""; diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConnectionManager.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConnectionManager.java index 66e505db80768..0c79a8f04c558 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConnectionManager.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConnectionManager.java @@ -76,8 +76,6 @@ */ @NonNullByDefault public class ShieldTVConnectionManager { - private static final int DEFAULT_RECONNECT_SECONDS = 60; - private static final int DEFAULT_HEARTBEAT_SECONDS = 5; private static final long KEEPALIVE_TIMEOUT_SECONDS = 30; private static final String DEFAULT_KEYSTORE_PASSWORD = "secret"; private static final int DEFAULT_PORT = 8987; @@ -261,7 +259,7 @@ public boolean getLoggedIn() { private boolean servicePing() { int timeout = 500; - SocketAddress socketAddress = new InetSocketAddress(config.ipAddress, config.port); + SocketAddress socketAddress = new InetSocketAddress(config.ipAddress, config.shieldtvPort); try (Socket socket = new Socket()) { socket.connect(socketAddress, timeout); return true; @@ -357,7 +355,7 @@ private void initialize() { folder.mkdirs(); } - config.port = (config.port > 0) ? config.port : DEFAULT_PORT; + config.shieldtvPort = (config.shieldtvPort > 0) ? config.shieldtvPort : DEFAULT_PORT; config.keystoreFileName = (!config.keystoreFileName.equals("")) ? config.keystoreFileName : folderName + "/shieldtv." + ((config.shim) ? "shim." : "") + handler.getThing().getUID().getId() @@ -414,8 +412,9 @@ public void connect() { if (isOnline) { try { logger.debug("{} - Opening ShieldTV SSL connection to {}:{}", handler.getThingID(), - config.ipAddress, config.port); - SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(config.ipAddress, config.port); + config.ipAddress, config.shieldtvPort); + SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(config.ipAddress, + config.shieldtvPort); sslSocket.startHandshake(); writer = new BufferedWriter( new OutputStreamWriter(sslSocket.getOutputStream(), StandardCharsets.ISO_8859_1)); @@ -436,7 +435,7 @@ public void connect() { } catch (IOException e) { setStatus(false, "offline.error-opening-ssl-connection-check-log"); logger.info("{} - Error opening SSL connection to {}:{} {}", handler.getThingID(), config.ipAddress, - config.port, e.getMessage()); + config.shieldtvPort, e.getMessage()); disconnect(false); scheduleConnectRetry(config.reconnect); // Possibly a temporary problem. Try again later. return; @@ -486,8 +485,8 @@ public void shimInitialize() { sslContext.init(kmf.getKeyManagers(), trustManagers, null); this.sslServerSocketFactory = sslContext.getServerSocketFactory(); - logger.debug("{} - Opening ShieldTV shim on port {}", handler.getThingID(), config.port); - ServerSocket sslServerSocket = this.sslServerSocketFactory.createServerSocket(config.port); + logger.debug("{} - Opening ShieldTV shim on port {}", handler.getThingID(), config.shieldtvPort); + ServerSocket sslServerSocket = this.sslServerSocketFactory.createServerSocket(config.shieldtvPort); while (true) { logger.debug("{} - Waiting for shim connection...", handler.getThingID()); diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConstants.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConstants.java index 4ea4961fc1d24..4501da752d210 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConstants.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConstants.java @@ -48,6 +48,7 @@ public class ShieldTVConstants { public static final String MESSAGE_LOWPRIV = "080a12"; public static final String MESSAGE_HOSTNAME = "080b12"; public static final String MESSAGE_APPDB = "08f10712"; + public static final String MESSAGE_APPDB_FULL = "080112"; public static final String MESSAGE_GOOD_COMMAND = "08f30712"; public static final String MESSAGE_PINSTART = "0308cf08"; public static final String MESSAGE_CERT_COMING = "20"; diff --git a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVMessageParser.java b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVMessageParser.java index 9a14f3f8ba6df..002191e92c8d0 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVMessageParser.java +++ b/bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVMessageParser.java @@ -204,13 +204,10 @@ public void handleMessage(String msg) { } else if (APP_START_FAILED.equals(msg)) { // App failed to start logger.debug("{} - App failed to start", thingId); - } else if (msg.startsWith(MESSAGE_APPDB) && msg.startsWith(DELIMITER_0A, 18)) { - // Individual update? - // 08f10712 5808061254 0a LEN app.name 12 LEN app.real.name 22 LEN URL 2801 300118f107 - logger.info("{} - Individual App Update - Please Report This: {}", thingId, msg); - } else if (msg.startsWith(MESSAGE_APPDB) && (msg.length() > 30)) { + } else if (msg.startsWith(MESSAGE_APPDB) && msg.startsWith(MESSAGE_APPDB_FULL, 12)) { // Massive dump of currently installed apps - // 08f10712 d81f080112 d31f0a540a LEN app.name 12 LEN app.real.name 22 LEN URL 2801 30010a650a LEN + // 08f10712 d81f 080112 d31f0a540a LEN app.name 12 LEN app.real.name 22 LEN URL 2801 30010a650a LEN + // --------------08XX12 where XX is not 01 are individual updates and should be ignored Map appNameDB = new HashMap<>(); Map appURLDB = new HashMap<>(); int appCount = 0; @@ -353,6 +350,8 @@ public void handleMessage(String msg) { logger.warn("{} - MP empty msg: {} appDB appNameDB: {} appURLDB: {}", thingId, msg, appNameDB.toString(), appURLDB.toString()); } + } else if (msg.startsWith(MESSAGE_APPDB)) { + logger.debug("{} - Individual app update ignored {}", thingId, msg); } else if (msg.startsWith(MESSAGE_GOOD_COMMAND)) { // This has something to do with successful command response, maybe. logger.trace("{} - Good Command Response", thingId); diff --git a/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/i18n/androidtv.properties b/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/i18n/androidtv.properties index 3b6b485f42a0d..3e644d9af3fd5 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/i18n/androidtv.properties +++ b/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/i18n/androidtv.properties @@ -24,8 +24,8 @@ thing-type.config.androidtv.googletv.keystoreFileName.label = Keystore File Name thing-type.config.androidtv.googletv.keystoreFileName.description = Java keystore containing key and certs thing-type.config.androidtv.googletv.keystorePassword.label = Keystore Password thing-type.config.androidtv.googletv.keystorePassword.description = Password for the keystore file -thing-type.config.androidtv.googletv.port.label = Port -thing-type.config.androidtv.googletv.port.description = Port to connect to +thing-type.config.androidtv.googletv.googletvPort.label = GoogleTV Port +thing-type.config.androidtv.googletv.googletvPort.description = Port to connect to thing-type.config.androidtv.googletv.reconnect.label = Reconnect Delay thing-type.config.androidtv.googletv.reconnect.description = Delay between reconnection attempts thing-type.config.androidtv.shieldtv.delay.label = Delay @@ -40,8 +40,10 @@ thing-type.config.androidtv.shieldtv.keystoreFileName.label = Keystore File Name thing-type.config.androidtv.shieldtv.keystoreFileName.description = Java keystore containing key and certs thing-type.config.androidtv.shieldtv.keystorePassword.label = Keystore Password thing-type.config.androidtv.shieldtv.keystorePassword.description = Password for the keystore file -thing-type.config.androidtv.shieldtv.port.label = Port -thing-type.config.androidtv.shieldtv.port.description = Port to connect to +thing-type.config.androidtv.shieldtv.googletvPort.label = GoogleTV Port +thing-type.config.androidtv.shieldtv.googletvPort.description = Port to connect to +thing-type.config.androidtv.shieldtv.shieldtvPort.label = ShieldTV Port +thing-type.config.androidtv.shieldtv.shieldtvPort.description = Port to connect to thing-type.config.androidtv.shieldtv.reconnect.label = Reconnect Delay thing-type.config.androidtv.shieldtv.reconnect.description = Delay between reconnection attempts diff --git a/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/thing/thing-types.xml index e7e383fdaeddb..8e5c032c0dadd 100644 --- a/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/thing/thing-types.xml @@ -43,38 +43,52 @@ Hostname or IP address of the device - - + + Port to connect to + 6466 + true + + + + Port to connect to + 8987 + true Java keystore containing key and certs + true password Password for the keystore file + true Delay between reconnection attempts 60 + true Frequency of heartbeats 5 + true Delay between messages 0 + true Enable the GoogleTV Protocol true + true @@ -114,38 +128,46 @@ Hostname or IP address of the device - - + + Port to connect to + 6466 + true Java keystore containing key and certs + true password Password for the keystore file + true Delay between reconnection attempts 60 + true Frequency of heartbeats 5 + true Delay between messages 0 + true Enable the GoogleTV Protocol true + true