OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/proximity_auth/connection.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "components/proximity_auth/connection_observer.h" | |
9 #include "components/proximity_auth/permit_message.h" | |
10 | |
11 namespace proximity_auth { | |
12 namespace { | |
13 | |
14 // Most EasyUnlock messages fit easily into 128 bytes. | |
15 const int kInitialBufferCapacity = 128; | |
16 | |
17 } // namespace | |
18 | |
19 Connection::Connection(const RemoteDevice& remote_device) | |
20 : remote_device_(remote_device), | |
21 status_(DISCONNECTED), | |
22 is_sending_message_(false) { | |
23 } | |
24 | |
25 Connection::~Connection() { | |
26 } | |
27 | |
28 bool Connection::IsConnected() const { | |
29 return status_ == CONNECTED; | |
30 } | |
31 | |
32 void Connection::SendMessage(scoped_ptr<PermitMessage> message) { | |
33 if (!IsConnected()) { | |
34 VLOG(1) << "Cannot send message when disconnected."; | |
35 return; | |
36 } | |
37 | |
38 if (is_sending_message_) { | |
39 VLOG(1) << "Another message is currently in progress."; | |
40 return; | |
41 } | |
42 | |
43 is_sending_message_ = true; | |
44 SendMessageImpl(message.Pass()); | |
45 } | |
46 | |
47 void Connection::AddObserver(ConnectionObserver* observer) { | |
48 observers_.AddObserver(observer); | |
49 } | |
50 | |
51 void Connection::RemoveObserver(ConnectionObserver* observer) { | |
52 observers_.RemoveObserver(observer); | |
53 } | |
54 | |
55 void Connection::SetStatus(Status status) { | |
56 if (status_ == status) | |
57 return; | |
58 | |
59 received_bytes_ = NULL; | |
60 | |
61 Status old_status = status_; | |
62 status_ = status; | |
63 FOR_EACH_OBSERVER(ConnectionObserver, observers_, | |
64 OnConnectionStatusChanged(*this, old_status, status_)); | |
65 } | |
66 | |
67 void Connection::OnDidSendMessage(const PermitMessage& message, | |
68 bool success) { | |
69 if (!is_sending_message_) { | |
70 VLOG(1) << "Send completed, but no message in progress."; | |
71 return; | |
72 } | |
73 | |
74 FOR_EACH_OBSERVER( | |
75 ConnectionObserver, observers_, OnSendCompleted(*this, message, success)); | |
76 is_sending_message_ = false; | |
Tim Song
2014/09/05 00:30:33
move this line up in case an observer wants to sen
Ilya Sherman
2014/09/05 01:02:11
Done, though that seems a little fragile, since ob
Tim Song
2014/09/05 03:10:33
Alternative, expose a is_sending_message() functio
| |
77 } | |
78 | |
79 void Connection::OnBytesReceived(scoped_refptr<net::IOBuffer> io_buffer, | |
80 int bytes_received) { | |
81 if (!IsConnected()) { | |
82 VLOG(1) << "Received bytes, but not connected."; | |
83 return; | |
84 } | |
85 | |
86 // Allocate an initial buffer if one does not already exist. | |
87 if (!received_bytes_) { | |
88 received_bytes_ = new net::GrowableIOBuffer; | |
89 received_bytes_->SetCapacity(kInitialBufferCapacity); | |
90 } | |
91 | |
92 // Grow the buffer if necessary. | |
93 if (received_bytes_->RemainingCapacity() < bytes_received) | |
94 received_bytes_->SetCapacity(received_bytes_->capacity() + bytes_received); | |
95 | |
96 // TODO(tengs): Clear buffer after a timeout as a guard. | |
Tim Song
2014/09/05 00:30:33
We can remove this TODO. If the phone sends garbag
Ilya Sherman
2014/09/05 01:02:11
Done.
| |
97 memcpy(received_bytes_->data(), io_buffer->data(), bytes_received); | |
98 received_bytes_->set_offset(received_bytes_->offset() + bytes_received); | |
99 | |
100 if (HasReceivedCompleteMessage()) { | |
101 scoped_ptr<PermitMessage> message = DeserializePermitMessage(); | |
102 if (message) { | |
103 FOR_EACH_OBSERVER(ConnectionObserver, observers_, | |
104 OnMessageReceived(*this, *message)); | |
105 } | |
106 | |
107 // Whether the message was parsed successfully or not, clear the | |
108 // |received_bytes_| buffer. | |
109 received_bytes_ = NULL; | |
110 } | |
111 } | |
112 | |
113 bool Connection::HasReceivedCompleteMessage() { | |
114 return PermitMessage::IsCompleteMessage( | |
115 received_bytes_->StartOfBuffer(), received_bytes_->offset()); | |
116 } | |
117 | |
118 scoped_ptr<PermitMessage> Connection::DeserializePermitMessage() { | |
119 return PermitMessage::FromBytes( | |
120 received_bytes_->StartOfBuffer(), received_bytes_->offset()); | |
121 } | |
122 | |
123 } // namespace proximity_auth | |
OLD | NEW |