]> git.basschouten.com Git - openhab-addons.git/commitdiff
[androidtv] Fixes Bugs and Prepares for PhilipsTV (#16191)
authormorph166955 <53797132+morph166955@users.noreply.github.com>
Fri, 12 Jan 2024 17:53:35 +0000 (11:53 -0600)
committerGitHub <noreply@github.com>
Fri, 12 Jan 2024 17:53:35 +0000 (18:53 +0100)
Signed-off-by: Ben Rosenblum <rosenblumb@gmail.com>
15 files changed:
bundles/org.openhab.binding.androidtv/README.md
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVBindingConstants.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/AndroidTVHandler.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/GoogleTVDiscoveryParticipant.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/discovery/ShieldTVDiscoveryParticipant.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConfiguration.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConnectionManager.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVConstants.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/googletv/GoogleTVMessageParser.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConfiguration.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConnectionManager.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVConstants.java
bundles/org.openhab.binding.androidtv/src/main/java/org/openhab/binding/androidtv/internal/protocol/shieldtv/ShieldTVMessageParser.java
bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/i18n/androidtv.properties
bundles/org.openhab.binding.androidtv/src/main/resources/OH-INF/thing/thing-types.xml

index 229a0af58456168a94e5fa9446ced6c260f61025..1fce2128de78bdf28035851a51905bcfda396966 100644 (file)
@@ -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       |
index 01f322fd9ac621bea2c4c8aecfb7587549d5b52d..776122e5f8669d1981d7f85263cc8253dd7ac1d3 100644 (file)
@@ -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";
index a1d0fe7247bd362875563540ce1b7b9d56acfd61..dd2660b3cc123f54a63bd1e14eeeced90589d841 100644 (file)
@@ -128,6 +128,10 @@ public class AndroidTVHandler extends BaseThingHandler {
                 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 class AndroidTVHandler extends BaseThingHandler {
                 if (!shieldtvConnectionManager.getLoggedIn()) {
                     failed = true;
                 }
-                statusMessage = statusMessage + " | ShieldTV: " + shieldtvConnectionManager.getStatusMessage();
+                statusMessage = statusMessage + "ShieldTV: " + shieldtvConnectionManager.getStatusMessage();
             }
         }
 
@@ -159,13 +163,13 @@ public class AndroidTVHandler extends BaseThingHandler {
         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 class AndroidTVHandler extends BaseThingHandler {
                 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);
index aef8f3012e933f8068de9683c315a1aeeea8facb..eae5b03aa0870e9a631360ec4df65b388fa345ee 100644 (file)
@@ -79,7 +79,7 @@ public class GoogleTVDiscoveryParticipant implements MDNSDiscoveryParticipant {
             if (uid != null) {
                 final String id = uid.getId();
                 final String label = service.getName() + " (" + id + ")";
-                final Map<String, Object> properties = Map.of(PROPERTY_IP_ADDRESS, ipAddress);
+                final Map<String, Object> properties = Map.of(PARAMETER_IP_ADDRESS, ipAddress);
 
                 return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build();
             } else {
index d408ef1960f0fe27cfd32f4d814ac37dba5ba2a5..428367fbc98deb8c900375eaaaaa075a5155b82c 100644 (file)
@@ -81,7 +81,7 @@ public class ShieldTVDiscoveryParticipant implements MDNSDiscoveryParticipant {
             if (uid != null) {
                 final String id = uid.getId();
                 final String label = service.getName() + " (" + id + ")";
-                final Map<String, Object> properties = Map.of(PROPERTY_IP_ADDRESS, ipAddress);
+                final Map<String, Object> properties = Map.of(PARAMETER_IP_ADDRESS, ipAddress);
 
                 return DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label).build();
             } else {
index e782a81fb10fcaf9e30ea561586dff7f4eb83b20..fd0da51795e71aacd15053b3a4a8951d21af5d00 100644 (file)
@@ -23,7 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 public class GoogleTVConfiguration {
 
     public String ipAddress = "";
-    public int port = 6466;
+    public int googletvPort = 6466;
     public int reconnect;
     public int heartbeat;
     public String keystoreFileName = "";
index ef54f8ba79e5a912578f1f75e1be8d43167db67d..1ba30cb807472a6cca42f84a8295a692673cb0e0 100644 (file)
@@ -80,8 +80,6 @@ import org.slf4j.LoggerFactory;
  */
 @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 class GoogleTVConnectionManager {
     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 @@ public class GoogleTVConnectionManager {
     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 @@ public class GoogleTVConnectionManager {
     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 @@ public class GoogleTVConnectionManager {
         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 @@ public class GoogleTVConnectionManager {
             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 class GoogleTVConnectionManager {
             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 class GoogleTVConnectionManager {
                     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 class GoogleTVConnectionManager {
                 } 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 class GoogleTVConnectionManager {
                         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 class GoogleTVConnectionManager {
                     } 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 class GoogleTVConnectionManager {
                 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 class GoogleTVConnectionManager {
                 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 class GoogleTVConnectionManager {
                 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 class GoogleTVConnectionManager {
                 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 class GoogleTVConnectionManager {
                 }
 
                 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 class GoogleTVConnectionManager {
                         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 @@ public class GoogleTVConnectionManager {
      * 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 @@ public class GoogleTVConnectionManager {
         } 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 @@ public class GoogleTVConnectionManager {
      * 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 @@ public class GoogleTVConnectionManager {
                 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 @@ public class GoogleTVConnectionManager {
             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 @@ public class GoogleTVConnectionManager {
     }
 
     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 @@ public class GoogleTVConnectionManager {
             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 class GoogleTVConnectionManager {
                         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 class GoogleTVConnectionManager {
                             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) {
index 70642913fcaa7bb1e44fbbb32b5422958b0c8b74..b6038fd8ef5fa0909eba091d0f1e238f62a73e9b 100644 (file)
@@ -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";
 }
index 51613b2de1be41ce8fb0ca27fee3f26489cfec1b..0c63d40b36ed2f77d3010fda8e72cab05735b7e9 100644 (file)
@@ -57,6 +57,8 @@ public class GoogleTVMessageParser {
             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
                 //
index db3af7efa41d118ca60b1de64eb8805d05b1a7b2..71f2f631b6b12585b71a15ca087095d6463989c9 100644 (file)
@@ -23,7 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 public class ShieldTVConfiguration {
 
     public String ipAddress = "";
-    public int port = 8987;
+    public int shieldtvPort = 8987;
     public int reconnect;
     public int heartbeat;
     public String keystoreFileName = "";
index 66e505db80768d26ab44f65c3d9ef3179c425b71..0c79a8f04c558fe633f78ea50f4af05ad0c0aa76 100644 (file)
@@ -76,8 +76,6 @@ import org.slf4j.LoggerFactory;
  */
 @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 class ShieldTVConnectionManager {
     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 @@ public class ShieldTVConnectionManager {
             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 class ShieldTVConnectionManager {
             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 class ShieldTVConnectionManager {
                 } 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 class ShieldTVConnectionManager {
                 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());
index 4ea4961fc1d2408585b4f21848a68f995e5c1856..4501da752d2102f62c7ce07eda031baff1301ed5 100644 (file)
@@ -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";
index 9a14f3f8ba6df6f17f16d32eb500cf120445ed95..002191e92c8d06bfb3606cbdf4bbde01600aca2b 100644 (file)
@@ -204,13 +204,10 @@ public class ShieldTVMessageParser {
             } 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<String, String> appNameDB = new HashMap<>();
                 Map<String, String> appURLDB = new HashMap<>();
                 int appCount = 0;
@@ -353,6 +350,8 @@ public class ShieldTVMessageParser {
                     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);
index 3b6b485f42a0ddc50ee63fe69dad0f1d91e6438d..3e644d9af3fd56246140222b2a774ade27e44c0d 100644 (file)
@@ -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
 
index e7e383fdaeddb9b2ea12f385d412a90ca0f571cf..8e5c032c0dadd23ed35ce3dff71db30261bad5c6 100644 (file)
                                <label>Hostname</label>
                                <description>Hostname or IP address of the device</description>
                        </parameter>
-                       <parameter name="port" type="integer">
-                               <label>Port</label>
+                       <parameter name="googletvPort" type="integer">
+                               <label>GoogleTV Port</label>
                                <description>Port to connect to</description>
+                               <default>6466</default>
+                               <advanced>true</advanced>
+                       </parameter>
+                       <parameter name="shieldtvPort" type="integer">
+                               <label>ShieldTV Port</label>
+                               <description>Port to connect to</description>
+                               <default>8987</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="keystoreFileName" type="text">
                                <label>Keystore File Name</label>
                                <description>Java keystore containing key and certs</description>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="keystorePassword" type="text">
                                <context>password</context>
                                <label>Keystore Password</label>
                                <description>Password for the keystore file</description>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="reconnect" type="integer" min="0">
                                <label>Reconnect Delay</label>
                                <description>Delay between reconnection attempts</description>
                                <default>60</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="heartbeat" type="integer" min="0">
                                <label>Heartbeat Frequency</label>
                                <description>Frequency of heartbeats</description>
                                <default>5</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="delay" type="integer" min="0">
                                <label>Delay</label>
                                <description>Delay between messages</description>
                                <default>0</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="gtvEnabled" type="boolean">
                                <label>Enable GoogleTV</label>
                                <description>Enable the GoogleTV Protocol</description>
                                <default>true</default>
+                               <advanced>true</advanced>
                        </parameter>
                </config-description>
 
                                <label>Hostname</label>
                                <description>Hostname or IP address of the device</description>
                        </parameter>
-                       <parameter name="port" type="integer">
-                               <label>Port</label>
+                       <parameter name="googletvPort" type="integer">
+                               <label>GoogleTV Port</label>
                                <description>Port to connect to</description>
+                               <default>6466</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="keystoreFileName" type="text">
                                <label>Keystore File Name</label>
                                <description>Java keystore containing key and certs</description>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="keystorePassword" type="text">
                                <context>password</context>
                                <label>Keystore Password</label>
                                <description>Password for the keystore file</description>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="reconnect" type="integer" min="0">
                                <label>Reconnect Delay</label>
                                <description>Delay between reconnection attempts</description>
                                <default>60</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="heartbeat" type="integer" min="0">
                                <label>Heartbeat Frequency</label>
                                <description>Frequency of heartbeats</description>
                                <default>5</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="delay" type="integer" min="0">
                                <label>Delay</label>
                                <description>Delay between messages</description>
                                <default>0</default>
+                               <advanced>true</advanced>
                        </parameter>
                        <parameter name="gtvEnabled" type="boolean">
                                <label>Enable GoogleTV</label>
                                <description>Enable the GoogleTV Protocol</description>
                                <default>true</default>
+                               <advanced>true</advanced>
                        </parameter>
                </config-description>