*/
@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";
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;
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());
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;
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);
}
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
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(
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);
} 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());
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;
} 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.
}
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);
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);
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.
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 {
}
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();
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;
* 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();
} 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);
}
}
* 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;
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;
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);
}
}
}
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 = "";
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);
}
}
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)));
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) {
<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>