Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: tools/battor_agent/battor_connection_impl.cc

Issue 1970243002: [battor agent] Add option to log serial communication (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@char_array_to_str
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/battor_agent/battor_connection_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/battor_agent/battor_connection_impl.h" 5 #include "tools/battor_agent/battor_connection_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
9 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
10 #include "base/thread_task_runner_handle.h" 11 #include "base/thread_task_runner_handle.h"
11 #include "device/serial/buffer.h" 12 #include "device/serial/buffer.h"
12 #include "device/serial/serial_io_handler.h" 13 #include "device/serial/serial_io_handler.h"
13 #include "net/base/io_buffer.h" 14 #include "net/base/io_buffer.h"
15 #include "tools/battor_agent/serial_utils.h"
14 16
17 using std::endl;
15 using std::vector; 18 using std::vector;
16 19
17 namespace battor { 20 namespace battor {
18 21
19 namespace { 22 namespace {
20 23
24 // The command line switch used to specify a file to which serial communication
25 // is logged.
26 const char kSerialLogPathSwitch[] = "battor-serial-log";
27
21 // Serial configuration parameters for the BattOr. 28 // Serial configuration parameters for the BattOr.
22 const uint32_t kBattOrBitrate = 2000000; 29 const uint32_t kBattOrBitrate = 2000000;
23 const device::serial::DataBits kBattOrDataBits = 30 const device::serial::DataBits kBattOrDataBits =
24 device::serial::DataBits::EIGHT; 31 device::serial::DataBits::EIGHT;
25 const device::serial::ParityBit kBattOrParityBit = 32 const device::serial::ParityBit kBattOrParityBit =
26 device::serial::ParityBit::NONE; 33 device::serial::ParityBit::NONE;
27 const device::serial::StopBits kBattOrStopBit = device::serial::StopBits::ONE; 34 const device::serial::StopBits kBattOrStopBit = device::serial::StopBits::ONE;
28 const bool kBattOrCtsFlowControl = true; 35 const bool kBattOrCtsFlowControl = true;
29 const bool kBattOrHasCtsFlowControl = true; 36 const bool kBattOrHasCtsFlowControl = true;
30 // The maximum BattOr message is 50kB long. 37 // The maximum BattOr message is 50kB long.
(...skipping 20 matching lines...) Expand all
51 } // namespace 58 } // namespace
52 59
53 BattOrConnectionImpl::BattOrConnectionImpl( 60 BattOrConnectionImpl::BattOrConnectionImpl(
54 const std::string& path, 61 const std::string& path,
55 BattOrConnection::Listener* listener, 62 BattOrConnection::Listener* listener,
56 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, 63 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner,
57 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) 64 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
58 : BattOrConnection(listener), 65 : BattOrConnection(listener),
59 path_(path), 66 path_(path),
60 file_thread_task_runner_(file_thread_task_runner), 67 file_thread_task_runner_(file_thread_task_runner),
61 ui_thread_task_runner_(ui_thread_task_runner) {} 68 ui_thread_task_runner_(ui_thread_task_runner) {
69 std::string serial_log_path =
70 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
71 kSerialLogPathSwitch);
72 if (!serial_log_path.empty()) {
73 serial_log_.open(serial_log_path.c_str(),
74 std::fstream::out | std::fstream::trunc);
75 serial_log_ << std::boolalpha;
76 }
77 }
62 78
63 BattOrConnectionImpl::~BattOrConnectionImpl() {} 79 BattOrConnectionImpl::~BattOrConnectionImpl() {}
64 80
65 void BattOrConnectionImpl::Open() { 81 void BattOrConnectionImpl::Open() {
66 if (io_handler_) { 82 if (io_handler_) {
67 OnOpened(true); 83 OnOpened(true);
68 return; 84 return;
69 } 85 }
70 86
71 io_handler_ = CreateIoHandler(); 87 io_handler_ = CreateIoHandler();
72 88
73 device::serial::ConnectionOptions options; 89 device::serial::ConnectionOptions options;
74 options.bitrate = kBattOrBitrate; 90 options.bitrate = kBattOrBitrate;
75 options.data_bits = kBattOrDataBits; 91 options.data_bits = kBattOrDataBits;
76 options.parity_bit = kBattOrParityBit; 92 options.parity_bit = kBattOrParityBit;
77 options.stop_bits = kBattOrStopBit; 93 options.stop_bits = kBattOrStopBit;
78 options.cts_flow_control = kBattOrCtsFlowControl; 94 options.cts_flow_control = kBattOrCtsFlowControl;
79 options.has_cts_flow_control = kBattOrHasCtsFlowControl; 95 options.has_cts_flow_control = kBattOrHasCtsFlowControl;
80 96
97 serial_log_ << "Opening serial connection." << endl << endl;
81 io_handler_->Open(path_, options, 98 io_handler_->Open(path_, options,
82 base::Bind(&BattOrConnectionImpl::OnOpened, AsWeakPtr())); 99 base::Bind(&BattOrConnectionImpl::OnOpened, AsWeakPtr()));
83 } 100 }
84 101
85 void BattOrConnectionImpl::OnOpened(bool success) { 102 void BattOrConnectionImpl::OnOpened(bool success) {
103 serial_log_ << "Serial connection open finished with success: " << success
104 << "." << endl
105 << endl;
106
86 if (!success) 107 if (!success)
87 Close(); 108 Close();
88 109
89 base::ThreadTaskRunnerHandle::Get()->PostTask( 110 base::ThreadTaskRunnerHandle::Get()->PostTask(
90 FROM_HERE, base::Bind(&Listener::OnConnectionOpened, 111 FROM_HERE, base::Bind(&Listener::OnConnectionOpened,
91 base::Unretained(listener_), success)); 112 base::Unretained(listener_), success));
92 } 113 }
93 114
94 void BattOrConnectionImpl::Close() { 115 void BattOrConnectionImpl::Close() {
116 serial_log_ << "Serial connection closed." << endl << endl;
95 io_handler_ = nullptr; 117 io_handler_ = nullptr;
96 } 118 }
97 119
98 void BattOrConnectionImpl::SendBytes(BattOrMessageType type, 120 void BattOrConnectionImpl::SendBytes(BattOrMessageType type,
99 const void* buffer, 121 const void* buffer,
100 size_t bytes_to_send) { 122 size_t bytes_to_send) {
101 const char* bytes = reinterpret_cast<const char*>(buffer); 123 const char* bytes = reinterpret_cast<const char*>(buffer);
102 124
103 // Reserve a send buffer with enough extra bytes for the start, type, end, and 125 // Reserve a send buffer with enough extra bytes for the start, type, end, and
104 // escape bytes. 126 // escape bytes.
105 vector<char> data; 127 vector<char> data;
106 data.reserve(2 * bytes_to_send + 3); 128 data.reserve(2 * bytes_to_send + 3);
107 129
108 data.push_back(BATTOR_CONTROL_BYTE_START); 130 data.push_back(BATTOR_CONTROL_BYTE_START);
109 data.push_back(type); 131 data.push_back(type);
110 132
111 for (size_t i = 0; i < bytes_to_send; i++) { 133 for (size_t i = 0; i < bytes_to_send; i++) {
112 if (bytes[i] == BATTOR_CONTROL_BYTE_START || 134 if (bytes[i] == BATTOR_CONTROL_BYTE_START ||
113 bytes[i] == BATTOR_CONTROL_BYTE_END) { 135 bytes[i] == BATTOR_CONTROL_BYTE_END) {
114 data.push_back(BATTOR_CONTROL_BYTE_ESCAPE); 136 data.push_back(BATTOR_CONTROL_BYTE_ESCAPE);
115 } 137 }
116 138
117 data.push_back(bytes[i]); 139 data.push_back(bytes[i]);
118 } 140 }
119 141
120 data.push_back(BATTOR_CONTROL_BYTE_END); 142 data.push_back(BATTOR_CONTROL_BYTE_END);
121 143
144 serial_log_ << "Bytes sent: " << CharVectorToString(data) << "." << endl
145 << endl;
146
122 pending_write_length_ = data.size(); 147 pending_write_length_ = data.size();
123 io_handler_->Write(base::WrapUnique(new device::SendBuffer( 148 io_handler_->Write(base::WrapUnique(new device::SendBuffer(
124 data, base::Bind(&BattOrConnectionImpl::OnBytesSent, AsWeakPtr())))); 149 data, base::Bind(&BattOrConnectionImpl::OnBytesSent, AsWeakPtr()))));
125 } 150 }
126 151
127 void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) { 152 void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) {
128 pending_read_message_type_ = type; 153 pending_read_message_type_ = type;
129 size_t max_bytes_to_read = GetMaxBytesForMessageType(type); 154 size_t max_bytes_to_read = GetMaxBytesForMessageType(type);
130 155
131 // Check the left-over bytes from the last read to make sure that we don't 156 // Check the left-over bytes from the last read to make sure that we don't
132 // already have a full message. 157 // already have a full message.
133 BattOrMessageType parsed_type; 158 BattOrMessageType parsed_type;
134 std::unique_ptr<vector<char>> bytes(new vector<char>()); 159 std::unique_ptr<vector<char>> bytes(new vector<char>());
135 bytes->reserve(max_bytes_to_read); 160 bytes->reserve(max_bytes_to_read);
136 161
162 serial_log_
163 << "Checking if a complete message is in the 'already read' buffer."
164 << endl
165 << endl;
166
137 if (ParseMessage(&parsed_type, bytes.get())) { 167 if (ParseMessage(&parsed_type, bytes.get())) {
168 serial_log_ << "Complete message found." << endl << endl;
138 base::ThreadTaskRunnerHandle::Get()->PostTask( 169 base::ThreadTaskRunnerHandle::Get()->PostTask(
139 FROM_HERE, 170 FROM_HERE,
140 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), true, 171 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), true,
141 parsed_type, base::Passed(std::move(bytes)))); 172 parsed_type, base::Passed(std::move(bytes))));
142 return; 173 return;
143 } 174 }
144 175
176 serial_log_ << "No complete message found." << endl << endl;
145 BeginReadBytes(max_bytes_to_read - already_read_buffer_.size()); 177 BeginReadBytes(max_bytes_to_read - already_read_buffer_.size());
146 } 178 }
147 179
148 void BattOrConnectionImpl::Flush() { 180 void BattOrConnectionImpl::Flush() {
149 io_handler_->Flush(); 181 io_handler_->Flush();
150 already_read_buffer_.clear(); 182 already_read_buffer_.clear();
151 } 183 }
152 184
153 scoped_refptr<device::SerialIoHandler> BattOrConnectionImpl::CreateIoHandler() { 185 scoped_refptr<device::SerialIoHandler> BattOrConnectionImpl::CreateIoHandler() {
154 return device::SerialIoHandler::Create(file_thread_task_runner_, 186 return device::SerialIoHandler::Create(file_thread_task_runner_,
155 ui_thread_task_runner_); 187 ui_thread_task_runner_);
156 } 188 }
157 189
158 void BattOrConnectionImpl::BeginReadBytes(size_t max_bytes_to_read) { 190 void BattOrConnectionImpl::BeginReadBytes(size_t max_bytes_to_read) {
191 serial_log_ << "Starting read of up to " << max_bytes_to_read << " bytes."
192 << endl
193 << endl;
194
159 pending_read_buffer_ = 195 pending_read_buffer_ =
160 make_scoped_refptr(new net::IOBuffer(max_bytes_to_read)); 196 make_scoped_refptr(new net::IOBuffer(max_bytes_to_read));
161 197
162 auto on_receive_buffer_filled = 198 auto on_receive_buffer_filled =
163 base::Bind(&BattOrConnectionImpl::OnBytesRead, AsWeakPtr()); 199 base::Bind(&BattOrConnectionImpl::OnBytesRead, AsWeakPtr());
164 200
165 io_handler_->Read(base::WrapUnique(new device::ReceiveBuffer( 201 io_handler_->Read(base::WrapUnique(new device::ReceiveBuffer(
166 pending_read_buffer_, static_cast<uint32_t>(max_bytes_to_read), 202 pending_read_buffer_, static_cast<uint32_t>(max_bytes_to_read),
167 on_receive_buffer_filled))); 203 on_receive_buffer_filled)));
168 } 204 }
169 205
170 void BattOrConnectionImpl::OnBytesRead(int bytes_read, 206 void BattOrConnectionImpl::OnBytesRead(int bytes_read,
171 device::serial::ReceiveError error) { 207 device::serial::ReceiveError error) {
172 if (bytes_read == 0 || error != device::serial::ReceiveError::NONE) { 208 if (error != device::serial::ReceiveError::NONE) {
173 // If we didn't have a message before, and we weren't able to read any 209 serial_log_ << "Read failed with error: " << error << "." << endl << endl;
174 // additional bytes, then there's no valid message available.
175 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 210 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
176 return; 211 return;
177 } 212 }
178 213
214 if (bytes_read == 0) {
215 // If we didn't have a message before, and we weren't able to read any
216 // additional bytes, then there's no valid message available.
217 serial_log_ << "Read failed due to no bytes being read." << endl << endl;
218 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
219 return;
220 }
221
222 serial_log_ << bytes_read << " more bytes read: "
223 << CharVectorToString(
224 vector<char>(pending_read_buffer_->data(),
225 pending_read_buffer_->data() + bytes_read))
226 << "." << endl
227 << endl;
228
179 already_read_buffer_.insert(already_read_buffer_.end(), 229 already_read_buffer_.insert(already_read_buffer_.end(),
180 pending_read_buffer_->data(), 230 pending_read_buffer_->data(),
181 pending_read_buffer_->data() + bytes_read); 231 pending_read_buffer_->data() + bytes_read);
182 232
183 BattOrMessageType type; 233 BattOrMessageType type;
184 std::unique_ptr<vector<char>> bytes(new vector<char>()); 234 std::unique_ptr<vector<char>> bytes(new vector<char>());
185 bytes->reserve(GetMaxBytesForMessageType(pending_read_message_type_)); 235 bytes->reserve(GetMaxBytesForMessageType(pending_read_message_type_));
186 236
187 if (!ParseMessage(&type, bytes.get())) { 237 if (!ParseMessage(&type, bytes.get())) {
188 // Even after reading the max number of bytes, we still don't have a valid 238 serial_log_ << "Read failed due to having no complete message after max "
189 // message. 239 "read length."
240 << endl
241 << endl;
nednguyen 2016/05/12 15:44:29 Let create a Log(const string& message) method ins
190 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 242 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
191 return; 243 return;
192 } 244 }
193 245
194 if (type != pending_read_message_type_) { 246 if (type != pending_read_message_type_) {
195 // We received a complete message, but it wasn't the type we were expecting. 247 serial_log_ << "Read failed due to receiving a message of the wrong type."
248 << endl
249 << endl;
196 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 250 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
197 return; 251 return;
198 } 252 }
199 253
200 EndReadBytes(true, type, std::move(bytes)); 254 EndReadBytes(true, type, std::move(bytes));
201 } 255 }
202 256
203 void BattOrConnectionImpl::EndReadBytes( 257 void BattOrConnectionImpl::EndReadBytes(bool success,
204 bool success, 258 BattOrMessageType type,
205 BattOrMessageType type, 259 std::unique_ptr<vector<char>> bytes) {
206 std::unique_ptr<std::vector<char>> bytes) { 260 serial_log_ << "Read finished with success: " << success << "." << endl
261 << endl;
262
207 pending_read_buffer_ = nullptr; 263 pending_read_buffer_ = nullptr;
208 base::ThreadTaskRunnerHandle::Get()->PostTask( 264 base::ThreadTaskRunnerHandle::Get()->PostTask(
209 FROM_HERE, 265 FROM_HERE,
210 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), success, 266 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), success,
211 type, base::Passed(std::move(bytes)))); 267 type, base::Passed(std::move(bytes))));
212 } 268 }
213 269
214 bool BattOrConnectionImpl::ParseMessage(BattOrMessageType* type, 270 bool BattOrConnectionImpl::ParseMessage(BattOrMessageType* type,
215 vector<char>* bytes) { 271 vector<char>* bytes) {
216 if (already_read_buffer_.size() <= 3) 272 if (already_read_buffer_.size() <= 3)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 void BattOrConnectionImpl::OnBytesSent(int bytes_sent, 323 void BattOrConnectionImpl::OnBytesSent(int bytes_sent,
268 device::serial::SendError error) { 324 device::serial::SendError error) {
269 bool success = (error == device::serial::SendError::NONE) && 325 bool success = (error == device::serial::SendError::NONE) &&
270 (pending_write_length_ == static_cast<size_t>(bytes_sent)); 326 (pending_write_length_ == static_cast<size_t>(bytes_sent));
271 base::ThreadTaskRunnerHandle::Get()->PostTask( 327 base::ThreadTaskRunnerHandle::Get()->PostTask(
272 FROM_HERE, 328 FROM_HERE,
273 base::Bind(&Listener::OnBytesSent, base::Unretained(listener_), success)); 329 base::Bind(&Listener::OnBytesSent, base::Unretained(listener_), success));
274 } 330 }
275 331
276 } // namespace battor 332 } // namespace battor
OLDNEW
« no previous file with comments | « tools/battor_agent/battor_connection_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698