103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef DEVICE_SERIAL_DATA_SENDER_H_
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define DEVICE_SERIAL_DATA_SENDER_H_
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <queue>
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/linked_ptr.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/string_piece.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/buffer.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/data_stream.mojom.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/public/cpp/system/data_pipe.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace device {
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class AsyncWaiter;
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// A DataSender sends data to a DataSink.
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class DataSender : public serial::DataSinkClient, public mojo::ErrorHandler {
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void(uint32_t bytes_sent)> DataSentCallback;
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void(uint32_t bytes_sent, int32_t error)>
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      SendErrorCallback;
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void()> CancelCallback;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Constructs a DataSender to send data to |sink|, using a data pipe with a
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // buffer size of |buffer_size|, with connection errors reported as
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |fatal_error_value|.
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DataSender(mojo::InterfacePtr<serial::DataSink> sink,
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)             uint32_t buffer_size,
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)             int32_t fatal_error_value);
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~DataSender();
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Starts an asynchronous send of |data|. If the send completes successfully,
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |callback| will be called. Otherwise, |error_callback| will be called with
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // the error. If there is a cancel in progress or there has been a connection
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // error, this will not start a send and returns false. It is the caller's
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // responsibility to ensure |data| remains valid until one of |callback| and
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |error_callback| is called.
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool Send(const base::StringPiece& data,
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            const DataSentCallback& callback,
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            const SendErrorCallback& error_callback);
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Requests the cancellation of any in-progress sends. Calls to Send() will
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // fail until |callback| is called.
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool Cancel(int32_t error, const CancelCallback& callback);
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  class PendingSend;
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // serial::DataSinkClient overrides.
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void ReportBytesSent(uint32_t bytes_sent) OVERRIDE;
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void ReportBytesSentAndError(
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint32_t bytes_sent,
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      int32_t error,
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const mojo::Callback<void(uint32_t)>& callback) OVERRIDE;
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // mojo::ErrorHandler override.
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnConnectionError() OVERRIDE;
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Copies data from |pending_sends_| into the data pipe and starts |waiter_|
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // waiting if the pipe is full. When a PendingSend in |pending_sends_| has
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // been fully copied into the data pipe, it moves to |sends_awaiting_ack_|.
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void SendInternal();
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Invoked when |handle_| is ready for writes. Calls SendInternal().
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void OnDoneWaiting(MojoResult result);
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Dispatches a cancel callback if one is pending.
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void RunCancelCallback();
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Shuts down this DataSender and dispatches fatal errors to all pending
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // operations.
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ShutDown();
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The control connection to the data sink.
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::InterfacePtr<serial::DataSink> sink_;
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The data connection to the data sink.
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  mojo::ScopedDataPipeProducerHandle handle_;
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The error value to report in the event of a fatal error.
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const int32_t fatal_error_value_;
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // A waiter used to wait until |handle_| is writable if we are waiting.
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<AsyncWaiter> waiter_;
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // A queue of PendingSend that have not yet been fully written to the data
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // pipe.
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::queue<linked_ptr<PendingSend> > pending_sends_;
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // A queue of PendingSend that have been written to the data pipe, but have
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // not yet been acked by the DataSink.
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::queue<linked_ptr<PendingSend> > sends_awaiting_ack_;
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The callback to report cancel completion if a cancel operation is in
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // progress.
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CancelCallback pending_cancel_;
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Whether we have encountered a fatal error and shut down.
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool shut_down_;
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DataSender);
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace device
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // DEVICE_SERIAL_DATA_SENDER_H_
113