1// Copyright 2012 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "polo/pairing/clientpairingsession.h"
16
17#include <glog/logging.h>
18#include <string>
19
20#include "polo/encoding/hexadecimalencoder.h"
21#include "polo/pairing/polochallengeresponse.h"
22
23namespace polo {
24namespace pairing {
25
26ClientPairingSession::ClientPairingSession(wire::PoloWireAdapter *wire,
27                                           PairingContext *context,
28                                           PoloChallengeResponse* challenge,
29                                           const std::string &service_name,
30                                           const std::string &client_name)
31    : PairingSession(wire, context, challenge),
32      service_name_(service_name),
33      client_name_(client_name) {
34}
35
36ClientPairingSession::~ClientPairingSession() {
37}
38
39void ClientPairingSession::DoInitializationPhase() {
40  if (!client_name_.empty()) {
41    message::PairingRequestMessage message(service_name_, client_name_);
42    wire()->SendPairingRequestMessage(message);
43  } else {
44    message::PairingRequestMessage message(service_name_);
45    wire()->SendPairingRequestMessage(message);
46  }
47
48  LOG(INFO) << "Waiting for PairingRequestAck...";
49  wire()->GetNextMessage();
50}
51
52void ClientPairingSession::DoConfigurationPhase() {
53  const message::ConfigurationMessage* config = configuration();
54  if (!config) {
55    LOG(ERROR) << "No configuration";
56    listener()->OnError(kErrorBadConfiguration);
57    return;
58  }
59
60  wire()->SendConfigurationMessage(*config);
61  wire()->GetNextMessage();
62
63  LOG(INFO) << "Waiting for ConfigurationAck...";
64}
65
66void ClientPairingSession::OnPairingRequestAckMessage(
67    const message::PairingRequestAckMessage& message) {
68  LOG(INFO) << "Handle PairingRequestAckMessage " << message.ToString();
69
70  if (message.has_server_name()) {
71    set_peer_name(message.server_name());
72  }
73
74  wire()->SendOptionsMessage(local_options());
75  wire()->GetNextMessage();
76}
77
78void ClientPairingSession::OnOptionsMessage(
79    const message::OptionsMessage& message) {
80  LOG(INFO) << "HandleOptionsMessage " << message.ToString();
81
82  message::ConfigurationMessage* configuration =
83      message::ConfigurationMessage::GetBestConfiguration(local_options(),
84                                                          message);
85
86  if (!configuration) {
87    LOG(ERROR) << "No compatible configuration: "
88        << local_options().ToString() << ", " << message.ToString();
89    wire()->SendErrorMessage(kErrorBadConfiguration);
90    listener()->OnError(kErrorBadConfiguration);
91    return;
92  }
93
94  bool valid_configuration = SetConfiguration(*configuration);
95  delete configuration;
96
97  if (valid_configuration) {
98    DoConfigurationPhase();
99  } else {
100    wire()->SendErrorMessage(kErrorBadConfiguration);
101    listener()->OnError(kErrorBadConfiguration);
102  }
103}
104
105void ClientPairingSession::OnConfigurationAckMessage(
106    const message::ConfigurationAckMessage& message) {
107  LOG(INFO) << "HandleConfigurationAckMessage " << message.ToString();
108
109  DoPairingPhase();
110}
111
112void ClientPairingSession::OnConfigurationMessage(
113    const message::ConfigurationMessage& message) {
114  LOG(ERROR) << "Received unexpected ConfigurationMessage";
115  wire()->SendErrorMessage(kErrorProtocol);
116  listener()->OnError(kErrorProtocol);
117}
118
119void ClientPairingSession::OnPairingRequestMessage(
120    const message::PairingRequestMessage& message) {
121  LOG(ERROR) << "Received unexpected PairingRequestMessage";
122  wire()->SendErrorMessage(kErrorProtocol);
123  listener()->OnError(kErrorProtocol);
124}
125
126}  // namespace pairing
127}  // namespace polo
128