1/*
2 * Copyright (C) 2009 Google Inc.  All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.polo.pairing;
18
19import com.google.polo.exception.PoloException;
20import com.google.polo.pairing.message.ConfigurationAckMessage;
21import com.google.polo.pairing.message.OptionsMessage;
22import com.google.polo.pairing.message.PairingRequestAckMessage;
23import com.google.polo.pairing.message.PairingRequestMessage;
24import com.google.polo.pairing.message.PoloMessage.PoloMessageType;
25import com.google.polo.wire.PoloWireInterface;
26
27import java.io.IOException;
28
29/**
30 * Pairing session implementation for a client.
31 */
32public class ClientPairingSession extends PairingSession {
33
34  /**
35   * Client name;
36   */
37  private final String mClientName;
38
39  /**
40   * Constructor.
41   *
42   * @param protocol     the wire interface for the session
43   * @param context      the pairing context for the session
44   * @param serviceName  the string service name, used in the pairing request
45   */
46  public ClientPairingSession(PoloWireInterface protocol,
47      PairingContext context, String serviceName) {
48    this(protocol, context, serviceName, null);
49  }
50
51  /**
52   * Constructor.
53   *
54   * @param protocol     the wire interface for the session
55   * @param context      the pairing context for the session
56   * @param serviceName  the string service name, used in the pairing request
57   * @param clientName   the string client name, used in the pairing request
58   */
59  public ClientPairingSession(PoloWireInterface protocol,
60      PairingContext context, String serviceName, String clientName) {
61    super(protocol, context);
62    mServiceName = serviceName;
63    mClientName = clientName;
64  }
65
66  @Override
67  protected void doInitializationPhase()
68      throws PoloException, IOException {
69    logDebug("Sending PairingRequest... " + mServiceName + " " + mClientName);
70    PairingRequestMessage msg = new PairingRequestMessage(mServiceName, mClientName);
71    sendMessage(msg);
72
73    logDebug("Waiting for PairingRequestAck ...");
74    PairingRequestAckMessage ack = (PairingRequestAckMessage) getNextMessage(
75        PoloMessageType.PAIRING_REQUEST_ACK);
76
77    if (ack.hasServerName()) {
78      mPeerName = ack.getServerName();
79      logDebug("Got PairingRequestAck with server name = " + mPeerName);
80    } else {
81      mPeerName = null;
82    }
83
84    logDebug("Sending Options ...");
85    sendMessage(mLocalOptions);
86
87    logDebug("Waiting for Options...");
88    OptionsMessage serverOptions = (OptionsMessage) getNextMessage(
89        PoloMessageType.OPTIONS);
90
91    // Compare compatibility with server options, and save config.
92    logDebug("Local config = " + mLocalOptions);
93    logDebug("Server options = " + serverOptions);
94    setConfiguration(mLocalOptions.getBestConfiguration(serverOptions));
95  }
96
97  @Override
98  protected void doConfigurationPhase() throws PoloException, IOException {
99    logDebug("Sending Configuration...");
100    sendMessage(mSessionConfig);
101    logDebug("Waiting for ConfigurationAck...");
102    ConfigurationAckMessage ack = (ConfigurationAckMessage)
103        getNextMessage(PoloMessageType.CONFIGURATION_ACK);
104  }
105
106  /**
107   * Returns {@code true} if client name is set.
108   */
109  public boolean hasClientName() {
110    return mClientName != null;
111  }
112
113  /**
114   * Returns {@code true} if server name is set.
115   */
116  public boolean hasServerName() {
117    return hasPeerName();
118  }
119
120  /**
121   * Returns client name, or {@code null} if not set.
122   */
123  public String getClientName() {
124    return mClientName;
125  }
126
127  /**
128   * Returns server name, or {@code null} if not set.
129   */
130  public String getServerName() {
131    return getPeerName();
132  }
133}
134