16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifndef DEVICE_SERIAL_DATA_RECEIVER_H_ 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define DEVICE_SERIAL_DATA_RECEIVER_H_ 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/callback.h" 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/ref_counted.h" 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/weak_ptr.h" 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "device/serial/buffer.h" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "device/serial/data_stream.mojom.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/cpp/system/data_pipe.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace device { 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class AsyncWaiter; 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// A DataReceiver receives data from a DataSource. 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class DataReceiver : public base::RefCounted<DataReceiver>, 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public serial::DataSourceClient, 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public mojo::ErrorHandler { 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public: 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) typedef base::Callback<void(scoped_ptr<ReadOnlyBuffer>)> ReceiveDataCallback; 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) typedef base::Callback<void(int32_t error)> ReceiveErrorCallback; 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Constructs a DataReceiver to receive data from |source|, using a data 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // pipe with a buffer size of |buffer_size|, with connection errors reported 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // as |fatal_error_value|. 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DataReceiver(mojo::InterfacePtr<serial::DataSource> source, 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) uint32_t buffer_size, 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int32_t fatal_error_value); 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Begins a receive operation. If this returns true, exactly one of |callback| 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // and |error_callback| will eventually be called. If there is already a 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // receive in progress or there has been a connection error, this will have no 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // effect and return false. 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool Receive(const ReceiveDataCallback& callback, 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const ReceiveErrorCallback& error_callback); 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private: 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) class PendingReceive; 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) struct PendingError; 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) friend class base::RefCounted<DataReceiver>; 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual ~DataReceiver(); 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // serial::DataSourceClient override. Invoked by the DataSource to report 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // errors. 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void OnError(uint32_t bytes_since_last_error, int32_t error) OVERRIDE; 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // mojo::ErrorHandler override. Calls ShutDown(). 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void OnConnectionError() OVERRIDE; 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Invoked by the PendingReceive to report that the user is done with the 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // receive buffer, having read |bytes_read| bytes from it. 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void Done(uint32_t bytes_read); 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Invoked when |handle_| is ready to read. Unless an error has occurred, this 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // calls ReceiveInternal(). 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void OnDoneWaiting(MojoResult result); 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The implementation of Receive(). If a |pending_error_| is ready to 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // dispatch, it does so. Otherwise, this attempts to read from |handle_| and 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // dispatches the contents to |pending_receive_|. If |handle_| is not ready, 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |waiter_| is used to wait until it is ready. If an error occurs in reading 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |handle_|, ShutDown() is called. 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void ReceiveInternal(); 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // We may have been notified of an error that occurred at some future point in 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // the stream. We should never be able to read past the point at which the 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // error occurred until we have dealt with the error and called Resume() on 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // the DataSource. If this has occurred, something bad has happened on the 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // service side, so we shut down. 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool CheckErrorNotInReadRange(uint32_t num_bytes); 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Called when we encounter a fatal error. If a receive is in progress, 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |fatal_error_value_| will be reported to the user. 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void ShutDown(); 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The control connection to the data source. 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mojo::InterfacePtr<serial::DataSource> source_; 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The data connection to the data source. 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mojo::ScopedDataPipeConsumerHandle handle_; 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The error value to report in the event of a fatal error. 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const int32_t fatal_error_value_; 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The number of bytes received from the data source. 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) uint32_t bytes_received_; 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Whether we have encountered a fatal error and shut down. 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool shut_down_; 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // A waiter used to wait until |handle_| is readable if we are waiting. 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<AsyncWaiter> waiter_; 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The current pending receive operation if there is one. 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<PendingReceive> pending_receive_; 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The current pending error if there is one. 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<PendingError> pending_error_; 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::WeakPtrFactory<DataReceiver> weak_factory_; 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DataReceiver); 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}; 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace device 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif // DEVICE_SERIAL_DATA_RECEIVER_H_ 113