1 // Copyright 2013 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.
5 #ifndef GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_
6 #define GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_
8 #include "base/memory/weak_ptr.h"
9 #include "base/time/time.h"
10 #include "base/timer/timer.h"
11 #include "google_apis/gcm/engine/connection_handler.h"
15 } // namespace mcs_proto
19 class GCM_EXPORT ConnectionHandlerImpl
: public ConnectionHandler
{
21 // |read_callback| will be invoked with the contents of any received protobuf
23 // |write_callback| will be invoked anytime a message has been successfully
24 // sent. Note: this just means the data was sent to the wire, not that the
25 // other end received it.
26 // |connection_callback| will be invoked with any fatal read/write errors
28 ConnectionHandlerImpl(
29 base::TimeDelta read_timeout
,
30 const ProtoReceivedCallback
& read_callback
,
31 const ProtoSentCallback
& write_callback
,
32 const ConnectionChangedCallback
& connection_callback
);
33 virtual ~ConnectionHandlerImpl();
35 // ConnectionHandler implementation.
36 virtual void Init(const mcs_proto::LoginRequest
& login_request
,
37 net::StreamSocket
* socket
) OVERRIDE
;
38 virtual bool CanSendMessage() const OVERRIDE
;
39 virtual void SendMessage(const google::protobuf::MessageLite
& message
)
43 // State machine for handling incoming data. See WaitForData(..) for usage.
44 enum ProcessingState
{
45 // Processing the version, tag, and size packets (assuming minimum length
46 // size packet). Only used during the login handshake.
47 MCS_VERSION_TAG_AND_SIZE
= 0,
48 // Processing the tag and size packets (assuming minimum length size
49 // packet). Used for normal messages.
51 // Processing a maximum length size packet (for messages with length > 128).
52 // Used when a normal size packet was not sufficient to read the message
55 // Processing the protocol buffer bytes (for those messages with non-zero
60 // Sends the protocol version and login request. First step in the MCS
61 // connection handshake.
62 void Login(const google::protobuf::MessageLite
& login_request
);
64 // SendMessage continuation. Invoked when Socket::Write completes.
67 // Starts the message processing process, which is comprised of the tag,
68 // message size, and bytes packet types.
69 void GetNextMessage();
71 // Performs any necessary SocketInputStream refreshing until the data
72 // associated with |packet_type| is fully ready, then calls the appropriate
73 // OnGot* message to process the packet data. If the read times out,
74 // will close the stream and invoke the connection callback.
75 void WaitForData(ProcessingState state
);
77 // Incoming data helper methods.
79 void OnGotMessageTag();
80 void OnGotMessageSize();
81 void OnGotMessageBytes();
86 // Closes the current connection.
87 void CloseConnection();
89 // Timeout policy: the timeout is only enforced while waiting on the
90 // handshake (version and/or LoginResponse) or once at least a tag packet has
91 // been received. It is reset every time new data is received, and is
92 // only stopped when a full message is processed.
93 // TODO(zea): consider enforcing a separate timeout when waiting for
95 const base::TimeDelta read_timeout_
;
96 base::OneShotTimer
<ConnectionHandlerImpl
> read_timeout_timer_
;
98 // This connection's socket and the input/output streams attached to it.
99 net::StreamSocket
* socket_
;
100 scoped_ptr
<SocketInputStream
> input_stream_
;
101 scoped_ptr
<SocketOutputStream
> output_stream_
;
103 // Whether the MCS login handshake has successfully completed. See Init(..)
104 // description for more info on what the handshake involves.
105 bool handshake_complete_
;
107 // State for the message currently being processed, if there is one.
109 uint32 message_size_
;
111 ProtoReceivedCallback read_callback_
;
112 ProtoSentCallback write_callback_
;
113 ConnectionChangedCallback connection_callback_
;
115 base::WeakPtrFactory
<ConnectionHandlerImpl
> weak_ptr_factory_
;
117 DISALLOW_COPY_AND_ASSIGN(ConnectionHandlerImpl
);
122 #endif // GOOGLE_APIS_GCM_ENGINE_CONNECTION_HANDLER_IMPL_H_