isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 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 | |
khorimoto | f7a6aff | 2017-01-19 22:50:47 | [diff] [blame] | 5 | #ifndef COMPONENTS_CRYPTAUTH_CONNECTION_H_ |
| 6 | #define COMPONENTS_CRYPTAUTH_CONNECTION_H_ |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 7 | |
dcheng | 2f01269 | 2016-04-21 00:19:34 | [diff] [blame] | 8 | #include <memory> |
| 9 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 10 | #include "base/macros.h" |
| 11 | #include "base/memory/ref_counted.h" |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 12 | #include "base/observer_list.h" |
khorimoto | de98b9e | 2016-12-07 22:28:55 | [diff] [blame] | 13 | #include "components/cryptauth/remote_device.h" |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 14 | |
hansberry | e7ad389 | 2016-12-19 22:19:21 | [diff] [blame] | 15 | namespace cryptauth { |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 16 | |
| 17 | class ConnectionObserver; |
| 18 | class WireMessage; |
| 19 | |
| 20 | // Base class representing a connection with a remote device, which is a |
| 21 | // persistent bidirectional channel for sending and receiving wire messages. |
| 22 | class Connection { |
| 23 | public: |
| 24 | enum Status { |
| 25 | DISCONNECTED, |
| 26 | IN_PROGRESS, |
| 27 | CONNECTED, |
| 28 | }; |
| 29 | |
| 30 | // Constructs a connection to the given |remote_device|. |
khorimoto | f7a6aff | 2017-01-19 22:50:47 | [diff] [blame] | 31 | explicit Connection(const RemoteDevice& remote_device); |
isherman | 83d08a29 | 2014-09-26 03:32:44 | [diff] [blame] | 32 | virtual ~Connection(); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 33 | |
| 34 | // Returns true iff the connection's status is CONNECTED. |
| 35 | bool IsConnected() const; |
| 36 | |
isherman | 40e54e0 | 2014-10-15 02:20:07 | [diff] [blame] | 37 | // Returns true iff the connection is currently sending a message. |
| 38 | bool is_sending_message() const { return is_sending_message_; } |
| 39 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 40 | // Sends a message to the remote device. |
| 41 | // |OnSendCompleted()| will be called for all observers upon completion with |
| 42 | // either success or failure. |
dcheng | 2f01269 | 2016-04-21 00:19:34 | [diff] [blame] | 43 | void SendMessage(std::unique_ptr<WireMessage> message); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 44 | |
khorimoto | f1ec431 | 2017-01-31 01:04:45 | [diff] [blame] | 45 | virtual void AddObserver(ConnectionObserver* observer); |
| 46 | virtual void RemoveObserver(ConnectionObserver* observer); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 47 | |
khorimoto | f7a6aff | 2017-01-19 22:50:47 | [diff] [blame] | 48 | const RemoteDevice& remote_device() const { |
khorimoto | de98b9e | 2016-12-07 22:28:55 | [diff] [blame] | 49 | return remote_device_; |
| 50 | } |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 51 | |
| 52 | // Abstract methods that subclasses should implement: |
| 53 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 54 | // Attempts to connect to the remote device if not already connected. |
| 55 | virtual void Connect() = 0; |
| 56 | |
| 57 | // Disconnects from the remote device. |
| 58 | virtual void Disconnect() = 0; |
| 59 | |
sacomoto | e4ca7e26 | 2015-09-30 14:27:56 | [diff] [blame] | 60 | // The bluetooth address of the connected device. |
| 61 | virtual std::string GetDeviceAddress(); |
| 62 | |
tengs | da506c8 | 2015-08-03 22:49:08 | [diff] [blame] | 63 | Status status() const { return status_; } |
| 64 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 65 | protected: |
| 66 | // Sets the connection's status to |status|. If this is different from the |
| 67 | // previous status, notifies observers of the change in status. |
isherman | 83d08a29 | 2014-09-26 03:32:44 | [diff] [blame] | 68 | // Virtual for testing. |
| 69 | virtual void SetStatus(Status status); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 70 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 71 | // Called after attempting to send bytes over the connection, whether the |
| 72 | // message was successfully sent or not. |
isherman | 83d08a29 | 2014-09-26 03:32:44 | [diff] [blame] | 73 | // Virtual for testing. |
| 74 | virtual void OnDidSendMessage(const WireMessage& message, bool success); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 75 | |
| 76 | // Called when bytes are read from the connection. There should not be a send |
| 77 | // in progress when this function is called. |
isherman | 83d08a29 | 2014-09-26 03:32:44 | [diff] [blame] | 78 | // Virtual for testing. |
| 79 | virtual void OnBytesReceived(const std::string& bytes); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 80 | |
| 81 | // Sends bytes over the connection. The implementing class should call |
tengs | 51902a3 | 2015-07-27 22:01:29 | [diff] [blame] | 82 | // OnDidSendMessage() once the send succeeds or fails. At most one send will |
| 83 | // be |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 84 | // in progress. |
dcheng | 2f01269 | 2016-04-21 00:19:34 | [diff] [blame] | 85 | virtual void SendMessageImpl(std::unique_ptr<WireMessage> message) = 0; |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 86 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 87 | // Deserializes the |recieved_bytes_| and returns the resulting WireMessage, |
isherman | 3ca088e1 | 2014-09-16 00:21:03 | [diff] [blame] | 88 | // or NULL if the message is malformed. Sets |is_incomplete_message| to true |
| 89 | // if the |serialized_message| does not have enough data to parse the header, |
| 90 | // or if the message length encoded in the message header exceeds the size of |
| 91 | // the |serialized_message|. Exposed for testing. |
dcheng | 2f01269 | 2016-04-21 00:19:34 | [diff] [blame] | 92 | virtual std::unique_ptr<WireMessage> DeserializeWireMessage( |
isherman | 3ca088e1 | 2014-09-16 00:21:03 | [diff] [blame] | 93 | bool* is_incomplete_message); |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 94 | |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 95 | private: |
| 96 | // The remote device corresponding to this connection. |
khorimoto | f7a6aff | 2017-01-19 22:50:47 | [diff] [blame] | 97 | const RemoteDevice remote_device_; |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 98 | |
| 99 | // The current status of the connection. |
| 100 | Status status_; |
| 101 | |
| 102 | // The registered observers of the connection. |
brettw | 236d317 | 2015-06-03 16:31:43 | [diff] [blame] | 103 | base::ObserverList<ConnectionObserver> observers_; |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 104 | |
| 105 | // A temporary buffer storing bytes received before a received message can be |
| 106 | // fully constructed. |
| 107 | std::string received_bytes_; |
| 108 | |
| 109 | // Whether a message is currently in the process of being sent. |
| 110 | bool is_sending_message_; |
| 111 | |
| 112 | DISALLOW_COPY_AND_ASSIGN(Connection); |
| 113 | }; |
| 114 | |
hansberry | e7ad389 | 2016-12-19 22:19:21 | [diff] [blame] | 115 | } // namespace cryptauth |
isherman | 06c6a9a7 | 2014-09-10 05:48:21 | [diff] [blame] | 116 | |
khorimoto | f7a6aff | 2017-01-19 22:50:47 | [diff] [blame] | 117 | #endif // COMPONENTS_CRYPTAUTH_CONNECTION_H_ |