1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/weak_ptr.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/serial/serial_io_handler.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource_manager.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/api/serial.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/io_buffer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Encapsulates an open serial port.
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// NOTE: Instances of this object should only be constructed on the IO thread,
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// and all methods should only be called on the IO thread unless otherwise
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// noted.
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SerialConnection : public ApiResource,
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         public base::SupportsWeakPtr<SerialConnection> {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef device::SerialIoHandler::OpenCompleteCallback OpenCompleteCallback;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This is the callback type expected by Receive. Note that an error result
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // does not necessarily imply an empty |data| string, since a receive may
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // complete partially before being interrupted by an error condition.
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef base::Callback<
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      void(const std::string& data, core_api::serial::ReceiveError error)>
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ReceiveCompleteCallback;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This is the callback type expected by Send. Note that an error result
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // does not necessarily imply 0 bytes sent, since a send may complete
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // partially before being interrupted by an error condition.
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef base::Callback<
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      void(int bytes_sent, core_api::serial::SendError error)>
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendCompleteCallback;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SerialConnection(const std::string& port,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const std::string& owner_extension_id);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SerialConnection();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ApiResource override.
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual bool IsPersistent() const OVERRIDE;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_persistent(bool persistent) { persistent_ = persistent; }
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool persistent() const { return persistent_; }
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_name(const std::string& name) { name_ = name; }
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string& name() const { return name_; }
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_buffer_size(int buffer_size);
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int buffer_size() const { return buffer_size_; }
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_receive_timeout(int receive_timeout);
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int receive_timeout() const { return receive_timeout_; }
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_send_timeout(int send_timeout);
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int send_timeout() const { return send_timeout_; }
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_paused(bool paused);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool paused() const { return paused_; }
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Initiates an asynchronous Open of the device. It is the caller's
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // responsibility to ensure that this SerialConnection stays alive
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // until |callback| is run.
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Open(const OpenCompleteCallback& callback);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Begins an asynchronous receive operation. Calling this while a Receive
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is already pending is a no-op and returns |false| without calling
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |callback|.
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool Receive(const ReceiveCompleteCallback& callback);
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Begins an asynchronous send operation. Calling this while a Send
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is already pending is a no-op and returns |false| without calling
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |callback|.
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool Send(const std::string& data, const SendCompleteCallback& callback);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flushes input and output buffers.
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool Flush() const;
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Configures some subset of port options for this connection.
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Omitted options are unchanged. Returns |true| iff the configuration
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // changes were successful.
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool Configure(const core_api::serial::ConnectionOptions& options);
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Connection configuration query. Fills values in an existing
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ConnectionInfo. Returns |true| iff the connection's information
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // was successfully retrieved.
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool GetInfo(core_api::serial::ConnectionInfo* info) const;
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Reads current control signals (DCD, CTS, etc.) into an existing
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // DeviceControlSignals structure. Returns |true| iff the signals were
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // successfully read.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool GetControlSignals(
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      core_api::serial::DeviceControlSignals* control_signals) const;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sets one or more control signals (DTR and/or RTS). Returns |true| iff
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the signals were successfully set. Unininitialized flags in the
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // HostControlSignals structure are left unchanged.
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool SetControlSignals(
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const core_api::serial::HostControlSignals& control_signals);
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overrides |io_handler_| for testing.
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetIoHandlerForTest(scoped_refptr<device::SerialIoHandler> handler);
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const BrowserThread::ID kThreadId = BrowserThread::IO;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend class ApiResourceManager<SerialConnection>;
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static const char* service_name() { return "SerialConnectionManager"; }
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Encapsulates a cancelable, delayed timeout task. Posts a delayed
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // task upon construction and implicitly cancels the task upon
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // destruction if it hasn't run yet.
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  class TimeoutTask {
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   public:
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TimeoutTask(const base::Closure& closure, const base::TimeDelta& delay);
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ~TimeoutTask();
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   private:
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    void Run() const;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::WeakPtrFactory<TimeoutTask> weak_factory_;
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Closure closure_;
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta delay_;
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Handles a receive timeout.
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnReceiveTimeout();
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Handles a send timeout.
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnSendTimeout();
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Receives read completion notification from the |io_handler_|.
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnAsyncReadComplete(int bytes_read, device::serial::ReceiveError error);
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Receives write completion notification from the |io_handler_|.
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnAsyncWriteComplete(int bytes_sent, device::serial::SendError error);
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The pathname of the serial device.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string port_;
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flag indicating whether or not the connection should persist when
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // its host app is suspended.
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool persistent_;
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // User-specified connection name.
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string name_;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Size of the receive buffer.
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int buffer_size_;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Amount of time (in ms) to wait for a Read to succeed before triggering a
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // timeout response via onReceiveError.
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int receive_timeout_;
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Amount of time (in ms) to wait for a Write to succeed before triggering
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a timeout response.
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int send_timeout_;
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Flag indicating that the connection is paused. A paused connection will not
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // raise new onReceive events.
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool paused_;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Callback to handle the completion of a pending Receive() request.
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ReceiveCompleteCallback receive_complete_;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Callback to handle the completion of a pending Send() request.
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendCompleteCallback send_complete_;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Closure which will trigger a receive timeout unless cancelled. Reset on
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // initialization and after every successful Receive().
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<TimeoutTask> receive_timeout_task_;
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Write timeout closure. Reset on initialization and after every successful
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Send().
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<TimeoutTask> send_timeout_task_;
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<net::IOBuffer> receive_buffer_;
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Asynchronous I/O handler.
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<device::SerialIoHandler> io_handler_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace mojo {
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <>
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct TypeConverter<device::serial::HostControlSignalsPtr,
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     extensions::core_api::serial::HostControlSignals> {
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static device::serial::HostControlSignalsPtr Convert(
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const extensions::core_api::serial::HostControlSignals& input);
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <>
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct TypeConverter<device::serial::ConnectionOptionsPtr,
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     extensions::core_api::serial::ConnectionOptions> {
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static device::serial::ConnectionOptionsPtr Convert(
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const extensions::core_api::serial::ConnectionOptions& input);
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace mojo
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // EXTENSIONS_BROWSER_API_SERIAL_SERIAL_CONNECTION_H_
215