17c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet/* 27c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Copyright (C) 2009 Google Inc. All rights reserved. 37c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 47c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Licensed under the Apache License, Version 2.0 (the "License"); 57c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * you may not use this file except in compliance with the License. 67c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * You may obtain a copy of the License at 77c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 87c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * http://www.apache.org/licenses/LICENSE-2.0 97c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Unless required by applicable law or agreed to in writing, software 117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * distributed under the License is distributed on an "AS IS" BASIS, 127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * See the License for the specific language governing permissions and 147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * limitations under the License. 157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetpackage com.google.polo.wire.protobuf; 187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.exception.BadSecretException; 207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.exception.NoConfigurationException; 217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.exception.PoloException; 227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.exception.ProtocolErrorException; 237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.PairingContext; 247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.PoloUtil; 257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.ConfigurationAckMessage; 267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.ConfigurationMessage; 277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.EncodingOption; 287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.OptionsMessage; 297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.PairingRequestAckMessage; 307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.PairingRequestMessage; 317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.PoloMessage; 327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.SecretAckMessage; 337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.pairing.message.SecretMessage; 347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.wire.PoloWireInterface; 357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.polo.wire.protobuf.PoloProto.OuterMessage; 367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport com.google.protobuf.nano.MessageNano; 377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.IOException; 397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.InputStream; 407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetimport java.io.OutputStream; 417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet/** 437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Implementation of {@link PoloWireInterface} that uses Protocol Buffers for 447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * the data representation. 457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * <p/> 467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * The primary work of this class is to translate Protocol Buffer messages 477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * instances (derived from {@link MessageNano} to an internal message 487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * instance (derived from {@link PoloMessage}, and vice versa. 497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * <p/> 507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * The reason we are going through all this trouble, and not using protocol 517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * buffer objects directly, is that we'd like to limit the scope of protocol 527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * buffers to the wire protocol only. Some applications may prefer to use 537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * a different wire format, where the requirement of adding the protobuf library 547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * could be an impediment. 557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetpublic class ProtobufWireAdapter implements PoloWireInterface { 577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * The output coming from the peer. 607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private final InputStream mInputStream; 627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * The input going to the peer. 647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private final OutputStream mOutputStream; 667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Constructor. 697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param input the {@link InputStream} from the peer 717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param output the {@link OutputStream} to the peer 727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public ProtobufWireAdapter(InputStream input, OutputStream output) { 747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet mInputStream = input; 757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet mOutputStream = output; 767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Generates a new instance from a {@link PairingContext}. 807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param context the {@link PairingContext} 827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return the new instance 837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public static ProtobufWireAdapter fromContext(PairingContext context) { 857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new ProtobufWireAdapter(context.getPeerInputStream(), 867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet context.getPeerOutputStream()); 877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Returns the next message sent over the wire, blocking as necessary. 917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public PoloMessage getNextMessage() throws IOException, PoloException { 937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return protoToPoloMessage(readNextInnerMessage()); 947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Returns the next message read over the wire, requiring it to be a certain 987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * type. 997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 1007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param type the required message type 1017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws IOException on error during read 1027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws PoloException if the wrong message type was read, or on protocol 1037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * error 1047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 1057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public PoloMessage getNextMessage(PoloMessage.PoloMessageType type) 1067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throws IOException, PoloException { 1077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloMessage message = getNextMessage(); 1087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (message.getType() != type) { 1097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throw new PoloException("Wrong message type (wanted " + type + 1107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet ", got " + message.getType() + ")"); 1117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return message; 1137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 1167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Returns the next message seen on the input stream. 1177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 1187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return the next OuterMessage read from the wire 1197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws IOException on error during read 1207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 1217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private OuterMessage readNextOuterMessage() throws IOException, PoloException { 1227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Read the preamble (length of payload) 1237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet byte[] preambleBuffer = readBytesBlocking(4); 1247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int messageLen = (int) PoloUtil.intBigEndianBytesToLong(preambleBuffer); 1257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Read the payload (serialized PoloMessage) 1277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet byte[] messageBuffer = readBytesBlocking(messageLen); 1287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Decode and return the payload 1307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OuterMessage message = OuterMessage.parseFrom(messageBuffer); 1317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (message.status != OuterMessage.STATUS_OK) { 1337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throw new ProtocolErrorException(); 1347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return message; 1377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 1407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Reads the next inner message from the wire, decoding and handling the outer 1417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * message in the process. 1427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 1437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return a protocol buffer message 1447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws IOException on error during read 1457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws PoloException on protocol error 1467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 1477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private MessageNano readNextInnerMessage() 1487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throws IOException, PoloException { 1497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OuterMessage message = readNextOuterMessage(); 1507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet byte[] payload = message.payload; 1527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (message.type == OuterMessage.MESSAGE_TYPE_OPTIONS) { 1547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Options.parseFrom(payload); 1557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST) { 1567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.PairingRequest.parseFrom(payload); 1577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST_ACK) { 1587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.PairingRequestAck.parseFrom(payload); 1597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_CONFIGURATION) { 1607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Configuration.parseFrom(payload); 1617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_CONFIGURATION_ACK) { 1627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.ConfigurationAck.parseFrom(payload); 1637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_SECRET) { 1647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Secret.parseFrom(payload); 1657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message.type == OuterMessage.MESSAGE_TYPE_SECRET_ACK) { 1667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.SecretAck.parseFrom(payload); 1677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throw new IOException("Could not unparse message"); 1707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 1737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Convenience method to read a fixed number of bytes from the client 1747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * InputStream, blocking if necessary. 1757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 1767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param numBytes the number of bytes to read 1777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return the bytes read 1787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws IOException on error during read 1797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 1807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private byte[] readBytesBlocking(int numBytes) throws IOException { 1817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet byte[] buf = new byte[numBytes]; 1827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int bytesRead = 0; 1837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // For an SSLSocket, read() can frequently return zero bytes, 1857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // or fewer bytes than desired, due to SSL unwrapping and other 1867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // non-application-data events. 1877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet while (bytesRead < numBytes) { 1887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int inc = mInputStream.read(buf, bytesRead, numBytes - bytesRead); 1897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (inc < 0) { 1907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throw new IOException("Stream closed while reading."); 1917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet bytesRead += inc; 1937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return buf; 1957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 1967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 1977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 1987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Wraps an outer message in an inner message. 1997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 2007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param message the {@link MessageNano} to wrap 2017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws PoloException if the message was not well formed 2027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 2037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private OuterMessage wrapInnerMessage(MessageNano message) 2047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throws PoloException { 2057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int type; 2067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (message instanceof PoloProto.Options) { 2077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_OPTIONS; 2087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.PairingRequest) { 2097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST; 2107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.PairingRequestAck) { 2117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_PAIRING_REQUEST_ACK; 2127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.Configuration) { 2137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_CONFIGURATION; 2147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.ConfigurationAck) { 2157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_CONFIGURATION_ACK; 2167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.Secret) { 2177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_SECRET; 2187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (message instanceof PoloProto.SecretAck) { 2197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = OuterMessage.MESSAGE_TYPE_SECRET_ACK; 2207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 2217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throw new PoloException("Bad inner message type."); 2227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // compose outer message 2257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OuterMessage outerMessage = new OuterMessage(); 2267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.status = OuterMessage.STATUS_OK; 2277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.protocolVersion = 1; 2287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.type = type; 2297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.payload = MessageNano.toByteArray(message); 2307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return outerMessage; 2317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 2347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Writes an {@link OuterMessage} to the wire. 2357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 2367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param message the message 2377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @throws IOException on error during write 2387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 2397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private void writeMessage(OuterMessage message) throws IOException { 2407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet byte[] messageBytes = message.payload; 2417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int messageLength = messageBytes.length; 2427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet mOutputStream.write(PoloUtil.intToBigEndianIntBytes(messageLength)); 2447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet mOutputStream.write(messageBytes); 2457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 2487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Writes a new message to the wire. 2497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 2507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public void sendMessage(PoloMessage message) 2517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet throws IOException, PoloException { 2527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet MessageNano pb = poloMessageToProto(message); 2537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OuterMessage outerMessage = wrapInnerMessage(pb); 2547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet writeMessage(outerMessage); 2557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 2587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Sends a new error message to the wire. 2597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 2607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet public void sendErrorMessage(Exception e) throws IOException { 2617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OuterMessage outerMessage = new OuterMessage(); 2627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.protocolVersion = 1; 2637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (e instanceof NoConfigurationException) { 2657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.status = OuterMessage.STATUS_BAD_CONFIGURATION; 2667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (e instanceof BadSecretException) { 2677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.status = OuterMessage.STATUS_BAD_SECRET; 2687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 2697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet outerMessage.status = OuterMessage.STATUS_ERROR; 2707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet writeMessage(outerMessage); 2737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 2757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 2767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts an internal message to the corresponding protocol buffer message. 2777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 2787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param poloMessage the internal message 2797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return a new {@link MessageNano} instance 2807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 2817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private MessageNano poloMessageToProto(PoloMessage poloMessage) { 2827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (poloMessage instanceof PairingRequestMessage) { 2837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((PairingRequestMessage) poloMessage); 2847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof PairingRequestAckMessage) { 2857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((PairingRequestAckMessage) poloMessage); 2867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof OptionsMessage) { 2877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((OptionsMessage) poloMessage); 2887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof ConfigurationMessage) { 2897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((ConfigurationMessage) poloMessage); 2907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof ConfigurationAckMessage) { 2917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((ConfigurationAckMessage) poloMessage); 2927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof SecretMessage) { 2937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((SecretMessage) poloMessage); 2947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (poloMessage instanceof SecretAckMessage) { 2957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return toProto((SecretAckMessage) poloMessage); 2967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return null; 2987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 2997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PairingRequestMessage} to a 3027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PoloProto.PairingRequest}. 3037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 3047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.PairingRequest toProto(PairingRequestMessage poloMessage) { 3057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.PairingRequest pairingRequest = new PoloProto.PairingRequest(); 3067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet pairingRequest.serviceName = poloMessage.getServiceName(); 3077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (poloMessage.hasClientName()) { 3097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet pairingRequest.clientName = poloMessage.getClientName(); 3107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return pairingRequest; 3127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PairingRequestAckMessage} to a 3167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PoloProto.PairingRequestAck}. 3177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 3187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.PairingRequestAck toProto(PairingRequestAckMessage poloMessage) { 3197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.PairingRequestAck pairingRequestAck = new PoloProto.PairingRequestAck(); 3207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (poloMessage.hasServerName()) { 3217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet pairingRequestAck.serverName = poloMessage.getServerName(); 3227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return pairingRequestAck; 3247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link OptionsMessage} to a {@link PoloProto.Options}. 3287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 3297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.Options toProto(OptionsMessage poloMessage) { 3307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.Options options = new PoloProto.Options(); 3317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (poloMessage.getProtocolRolePreference()) { 3337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case DISPLAY_DEVICE: 3347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.preferredRole = PoloProto.Options.ROLE_TYPE_INPUT; 3357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case INPUT_DEVICE: 3377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.preferredRole = PoloProto.Options.ROLE_TYPE_OUTPUT; 3387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int i = 0, n = poloMessage.getOutputEncodingSet().size(); 3427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.outputEncodings = new PoloProto.Options.Encoding[n]; 3437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet for (EncodingOption enc : poloMessage.getOutputEncodingSet()) { 3447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.outputEncodings[i++] = toProto(enc); 3457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet i = 0; 3487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet n = poloMessage.getInputEncodingSet().size(); 3497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.inputEncodings = new PoloProto.Options.Encoding[n]; 3507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet for (EncodingOption enc : poloMessage.getInputEncodingSet()) { 3517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet options.inputEncodings[i++] = toProto(enc); 3527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return options; 3557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link ConfigurationMessage} to a 3597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PoloProto.Configuration}. 3607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 3617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.Configuration toProto(ConfigurationMessage poloMessage) { 3627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.Configuration configuration = new PoloProto.Configuration(); 3637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet configuration.encoding = toProto(poloMessage.getEncoding()); 3647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet configuration.clientRole = toProto(poloMessage.getClientRole()); 3657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return configuration; 3667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link EncodingOption} to a {@link PoloProto.Options.Encoding}. 3707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 3717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.Options.Encoding toProto(EncodingOption enc) { 3727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.Options.Encoding encoding = new PoloProto.Options.Encoding(); 3737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (enc.getType()) { 3757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case ENCODING_ALPHANUMERIC: 3767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_ALPHANUMERIC; 3777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case ENCODING_HEXADECIMAL: 3797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_HEXADECIMAL; 3807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case ENCODING_NUMERIC: 3827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_NUMERIC; 3837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case ENCODING_QRCODE: 3857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_QRCODE; 3867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet default: 3887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.type = PoloProto.Options.Encoding.ENCODING_TYPE_UNKNOWN; 3897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 3907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet encoding.symbolLength = enc.getSymbolLength(); 3937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return encoding; 3947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 3957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 3967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 3977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link OptionsMessage.ProtocolRole} to a 3987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PoloProto.Options}. 3997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private int toProto(OptionsMessage.ProtocolRole role) { 4017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (role) { 4027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case DISPLAY_DEVICE: 4037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Options.ROLE_TYPE_OUTPUT; 4047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case INPUT_DEVICE: 4057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Options.ROLE_TYPE_INPUT; 4067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet default: 4077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return PoloProto.Options.ROLE_TYPE_UNKNOWN; 4087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link ConfigurationAckMessage} to a 4137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PoloProto.ConfigurationAck}. 4147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.ConfigurationAck toProto(ConfigurationAckMessage poloMessage) { 4167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.ConfigurationAck configurationAck = new PoloProto.ConfigurationAck(); 4177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return configurationAck; 4187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link SecretMessage} to a {@link PoloProto.Secret}. 4227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.Secret toProto(SecretMessage poloMessage) { 4247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.Secret secret = new PoloProto.Secret(); 4257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet secret.secret = poloMessage.getSecret(); 4267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return secret; 4277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link SecretAckMessage} to a {@link PoloProto.SecretAck}. 4317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloProto.SecretAck toProto(SecretAckMessage poloMessage) { 4337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet PoloProto.SecretAck secretAck = new PoloProto.SecretAck(); 4347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet secretAck.secret = poloMessage.getSecret(); 4357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return secretAck; 4367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // 4397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // polo -> protocol buffer routines 4407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // 4417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a protocol buffer message to the corresponding internal 4447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * message. 4457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * 4467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @param protoMessage the protobuf message to convert 4477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * @return the new {@link PoloMessage} 4487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PoloMessage protoToPoloMessage(MessageNano protoMessage) { 4507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (protoMessage instanceof PoloProto.PairingRequest) { 4517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.PairingRequest) protoMessage); 4527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.PairingRequestAck) { 4537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.PairingRequestAck) protoMessage); 4547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.Options) { 4557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.Options) protoMessage); 4567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.Configuration) { 4577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.Configuration) protoMessage); 4587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.ConfigurationAck) { 4597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.ConfigurationAck) protoMessage); 4607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.Secret) { 4617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.Secret) protoMessage); 4627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else if (protoMessage instanceof PoloProto.SecretAck) { 4637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return fromProto((PoloProto.SecretAck) protoMessage); 4647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return null; 4667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.PairingRequest} to a 4707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PairingRequestMessage}. 4717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PairingRequestMessage fromProto(PoloProto.PairingRequest protoMessage) { 4737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new PairingRequestMessage(protoMessage.serviceName, protoMessage.clientName); 4747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.PairingRequestAck} to a 4787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link PairingRequestAckMessage}. 4797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private PairingRequestAckMessage fromProto(PoloProto.PairingRequestAck protoMessage) { 4817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new PairingRequestAckMessage(protoMessage.serverName); 4827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 4857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.Options} to a {@link OptionsMessage}. 4867c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 4877c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private OptionsMessage fromProto(PoloProto.Options protoMessage) { 4887c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OptionsMessage optionsMessage = new OptionsMessage(); 4897c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4907c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (protoMessage.preferredRole) { 4917c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.ROLE_TYPE_INPUT: 4927c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet optionsMessage.setProtocolRolePreference(OptionsMessage.ProtocolRole.INPUT_DEVICE); 4937c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 4947c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.ROLE_TYPE_OUTPUT: 4957c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet optionsMessage.setProtocolRolePreference(OptionsMessage.ProtocolRole.DISPLAY_DEVICE); 4967c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 4977c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 4987c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 4997c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet for (PoloProto.Options.Encoding e : protoMessage.inputEncodings) { 5007c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet optionsMessage.addInputEncoding(fromProto(e)); 5017c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5027c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5037c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet for (PoloProto.Options.Encoding e : protoMessage.outputEncodings) { 5047c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet optionsMessage.addOutputEncoding(fromProto(e)); 5057c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5067c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5077c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return optionsMessage; 5087c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5097c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 5117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.Configuration} to a 5127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link ConfigurationMessage}. 5137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 5147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private ConfigurationMessage fromProto(PoloProto.Configuration protoMessage) { 5157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet EncodingOption enc = fromProto(protoMessage.encoding); 5167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OptionsMessage.ProtocolRole role = OptionsMessage.ProtocolRole.UNKNOWN; 5177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (protoMessage.clientRole) { 5197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.ROLE_TYPE_INPUT: 5207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet role = OptionsMessage.ProtocolRole.INPUT_DEVICE; 5217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.ROLE_TYPE_OUTPUT: 5237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet role = OptionsMessage.ProtocolRole.DISPLAY_DEVICE; 5247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new ConfigurationMessage(enc, role); 5287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 5317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.ConfigurationAck} to a 5327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * {@link ConfigurationAckMessage}. 5337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 5347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private ConfigurationAckMessage fromProto(PoloProto.ConfigurationAck protoMessage) { 5357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new ConfigurationAckMessage(); 5367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 5397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.Secret} to a {@link SecretMessage}. 5407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 5417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private SecretMessage fromProto(PoloProto.Secret protoMessage) { 5427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new SecretMessage(protoMessage.secret); 5437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 5467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.SecretAck} to a {@link SecretAckMessage}. 5477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 5487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private SecretAckMessage fromProto(PoloProto.SecretAck protoMessage) { 5497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new SecretAckMessage(protoMessage.secret); 5507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet /** 5537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet * Converts a {@link PoloProto.Options.Encoding} to a {@link EncodingOption}. 5547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet */ 5557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet private EncodingOption fromProto(PoloProto.Options.Encoding enc) { 5567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet EncodingOption.EncodingType type; 5577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet switch (enc.type) { 5597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.Encoding.ENCODING_TYPE_ALPHANUMERIC: 5607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = EncodingOption.EncodingType.ENCODING_ALPHANUMERIC; 5617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.Encoding.ENCODING_TYPE_HEXADECIMAL: 5637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = EncodingOption.EncodingType.ENCODING_HEXADECIMAL; 5647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.Encoding.ENCODING_TYPE_NUMERIC: 5667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = EncodingOption.EncodingType.ENCODING_NUMERIC; 5677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet case PoloProto.Options.Encoding.ENCODING_TYPE_QRCODE: 5697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = EncodingOption.EncodingType.ENCODING_QRCODE; 5707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet break; 5717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet default: 5727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet type = EncodingOption.EncodingType.ENCODING_UNKNOWN; 5737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return new EncodingOption(type, enc.symbolLength); 5767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 5787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 5797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 580