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

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

Issue 2000743002: [battor agent] Add 'read more bytes' logic in the BattOr connection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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
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/command_line.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 data.push_back(BATTOR_CONTROL_BYTE_END); 141 data.push_back(BATTOR_CONTROL_BYTE_END);
142 142
143 LogSerial(StringPrintf("Bytes sent: %s.", CharVectorToString(data).c_str())); 143 LogSerial(StringPrintf("Bytes sent: %s.", CharVectorToString(data).c_str()));
144 144
145 pending_write_length_ = data.size(); 145 pending_write_length_ = data.size();
146 io_handler_->Write(base::WrapUnique(new device::SendBuffer( 146 io_handler_->Write(base::WrapUnique(new device::SendBuffer(
147 data, base::Bind(&BattOrConnectionImpl::OnBytesSent, AsWeakPtr())))); 147 data, base::Bind(&BattOrConnectionImpl::OnBytesSent, AsWeakPtr()))));
148 } 148 }
149 149
150 void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) { 150 void BattOrConnectionImpl::ReadMessage(BattOrMessageType type) {
151 LogSerial("Read requested.");
152
151 pending_read_message_type_ = type; 153 pending_read_message_type_ = type;
152 size_t max_bytes_to_read = GetMaxBytesForMessageType(type); 154 size_t message_max_bytes = GetMaxBytesForMessageType(type);
153 155
154 // Check the left-over bytes from the last read to make sure that we don't 156 LogSerial(
155 // already have a full message. 157 "Before doing a serial read, checking to see if we already have a "
158 "complete message in the 'already read' buffer.");
159
156 BattOrMessageType parsed_type; 160 BattOrMessageType parsed_type;
157 std::unique_ptr<vector<char>> bytes(new vector<char>()); 161 std::unique_ptr<vector<char>> bytes(new vector<char>());
158 bytes->reserve(max_bytes_to_read); 162 bytes->reserve(message_max_bytes);
159 163 ParseMessageError parse_message_error =
160 LogSerial("Checking if a complete message is in the 'already read' buffer."); 164 ParseMessage(&parsed_type, bytes.get());
161 if (ParseMessage(&parsed_type, bytes.get())) { 165 if (parse_message_error == ParseMessageError::NONE) {
162 LogSerial("Complete message found."); 166 LogSerial("Complete message found.");
163 base::ThreadTaskRunnerHandle::Get()->PostTask( 167 EndReadBytes(true, parsed_type, std::move(bytes));
164 FROM_HERE,
165 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), true,
166 parsed_type, base::Passed(std::move(bytes))));
167 return; 168 return;
168 } 169 }
169 170
170 LogSerial("No complete message found."); 171 if (parse_message_error != ParseMessageError::NOT_ENOUGH_BYTES) {
171 BeginReadBytes(max_bytes_to_read - already_read_buffer_.size()); 172 LogSerial(StringPrintf(
173 "Read failed because, before performing a serial read, the message in "
174 "the 'already read' buffer had an irrecoverable error with code: %d.",
175 parse_message_error));
176 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
177 return;
178 }
179
180 LogSerial("No complete message found in the 'already read' buffer.");
181 BeginReadBytes(message_max_bytes - already_read_buffer_.size());
172 } 182 }
173 183
174 void BattOrConnectionImpl::Flush() { 184 void BattOrConnectionImpl::Flush() {
175 io_handler_->Flush(); 185 io_handler_->Flush();
176 already_read_buffer_.clear(); 186 already_read_buffer_.clear();
177 } 187 }
178 188
179 scoped_refptr<device::SerialIoHandler> BattOrConnectionImpl::CreateIoHandler() { 189 scoped_refptr<device::SerialIoHandler> BattOrConnectionImpl::CreateIoHandler() {
180 return device::SerialIoHandler::Create(file_thread_task_runner_, 190 return device::SerialIoHandler::Create(file_thread_task_runner_,
181 ui_thread_task_runner_); 191 ui_thread_task_runner_);
(...skipping 10 matching lines...) Expand all
192 base::Bind(&BattOrConnectionImpl::OnBytesRead, AsWeakPtr()); 202 base::Bind(&BattOrConnectionImpl::OnBytesRead, AsWeakPtr());
193 203
194 io_handler_->Read(base::WrapUnique(new device::ReceiveBuffer( 204 io_handler_->Read(base::WrapUnique(new device::ReceiveBuffer(
195 pending_read_buffer_, static_cast<uint32_t>(max_bytes_to_read), 205 pending_read_buffer_, static_cast<uint32_t>(max_bytes_to_read),
196 on_receive_buffer_filled))); 206 on_receive_buffer_filled)));
197 } 207 }
198 208
199 void BattOrConnectionImpl::OnBytesRead(int bytes_read, 209 void BattOrConnectionImpl::OnBytesRead(int bytes_read,
200 device::serial::ReceiveError error) { 210 device::serial::ReceiveError error) {
201 if (error != device::serial::ReceiveError::NONE) { 211 if (error != device::serial::ReceiveError::NONE) {
202 LogSerial(StringPrintf("Read failed with error code: %d.", 212 LogSerial(StringPrintf(
203 static_cast<int>(error))); 213 "Read failed due to serial read failure with error code: %d.",
214 static_cast<int>(error)));
204 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 215 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
205 return; 216 return;
206 } 217 }
207 218
208 if (bytes_read == 0) { 219 if (bytes_read == 0) {
209 // If we didn't have a message before, and we weren't able to read any 220 // If we didn't have a message before, and we weren't able to read any
210 // additional bytes, then there's no valid message available. 221 // additional bytes, then there's no valid message available.
211 LogSerial("Read failed due to no bytes being read."); 222 LogSerial("Read failed due to no bytes being read.");
212 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 223 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
213 return; 224 return;
214 } 225 }
215 226
216 LogSerial(StringPrintf( 227 LogSerial(StringPrintf(
217 "%d more bytes read: %s.", bytes_read, 228 "%d more bytes read: %s.", bytes_read,
218 CharArrayToString(pending_read_buffer_->data(), bytes_read).c_str())); 229 CharArrayToString(pending_read_buffer_->data(), bytes_read).c_str()));
219 230
220 already_read_buffer_.insert(already_read_buffer_.end(), 231 already_read_buffer_.insert(already_read_buffer_.end(),
221 pending_read_buffer_->data(), 232 pending_read_buffer_->data(),
222 pending_read_buffer_->data() + bytes_read); 233 pending_read_buffer_->data() + bytes_read);
223 234
224 BattOrMessageType type; 235 BattOrMessageType type;
236 size_t message_max_bytes =
237 GetMaxBytesForMessageType(pending_read_message_type_);
225 std::unique_ptr<vector<char>> bytes(new vector<char>()); 238 std::unique_ptr<vector<char>> bytes(new vector<char>());
226 bytes->reserve(GetMaxBytesForMessageType(pending_read_message_type_)); 239 bytes->reserve(message_max_bytes);
227 240
228 if (!ParseMessage(&type, bytes.get())) { 241 ParseMessageError parse_message_error = ParseMessage(&type, bytes.get());
229 LogSerial( 242 if (parse_message_error == ParseMessageError::NOT_ENOUGH_BYTES) {
230 "Read failed due to having no complete message after max read length."); 243 if (already_read_buffer_.size() >= message_max_bytes) {
244 LogSerial(
245 "Read failed due to no complete message after max read length.");
246 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
247 return;
248 }
249
250 LogSerial("(Message still incomplete: reading more bytes.)");
251 BeginReadBytes(message_max_bytes - already_read_buffer_.size());
252 return;
253 }
254
255 if (parse_message_error != ParseMessageError::NONE) {
256 LogSerial(StringPrintf(
257 "Read failed due to the message containing an irrecoverable error: %d.",
258 parse_message_error));
231 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 259 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
232 return; 260 return;
233 } 261 }
234 262
235 if (type != pending_read_message_type_) { 263 if (type != pending_read_message_type_) {
236 LogSerial("Read failed due to receiving a message of the wrong type."); 264 LogSerial("Read failed due to receiving a message of the wrong type.");
237 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr); 265 EndReadBytes(false, BATTOR_MESSAGE_TYPE_CONTROL, nullptr);
238 return; 266 return;
239 } 267 }
240 268
241 EndReadBytes(true, type, std::move(bytes)); 269 EndReadBytes(true, type, std::move(bytes));
242 } 270 }
243 271
244 void BattOrConnectionImpl::EndReadBytes(bool success, 272 void BattOrConnectionImpl::EndReadBytes(bool success,
245 BattOrMessageType type, 273 BattOrMessageType type,
246 std::unique_ptr<vector<char>> bytes) { 274 std::unique_ptr<vector<char>> bytes) {
247 LogSerial(StringPrintf("Read finished with success: %d.", success)); 275 LogSerial(StringPrintf("Read finished with success: %d.", success));
248 276
249 pending_read_buffer_ = nullptr; 277 pending_read_buffer_ = nullptr;
250 base::ThreadTaskRunnerHandle::Get()->PostTask( 278 base::ThreadTaskRunnerHandle::Get()->PostTask(
251 FROM_HERE, 279 FROM_HERE,
252 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), success, 280 base::Bind(&Listener::OnMessageRead, base::Unretained(listener_), success,
253 type, base::Passed(std::move(bytes)))); 281 type, base::Passed(std::move(bytes))));
254 } 282 }
255 283
256 bool BattOrConnectionImpl::ParseMessage(BattOrMessageType* type, 284 BattOrConnectionImpl::ParseMessageError BattOrConnectionImpl::ParseMessage(
257 vector<char>* bytes) { 285 BattOrMessageType* type,
286 vector<char>* bytes) {
258 if (already_read_buffer_.size() <= 3) 287 if (already_read_buffer_.size() <= 3)
259 return false; 288 return ParseMessageError::NOT_ENOUGH_BYTES;
260 289
261 // The first byte is the start byte. 290 // The first byte is the start byte.
262 if (already_read_buffer_[0] != BATTOR_CONTROL_BYTE_START) { 291 if (already_read_buffer_[0] != BATTOR_CONTROL_BYTE_START)
263 return false; 292 return ParseMessageError::MISSING_START_BYTE;
264 }
265 293
266 // The second byte specifies the message type. 294 // The second byte specifies the message type.
267 *type = static_cast<BattOrMessageType>(already_read_buffer_[1]); 295 *type = static_cast<BattOrMessageType>(already_read_buffer_[1]);
268 296
269 if (*type < static_cast<uint8_t>(BATTOR_MESSAGE_TYPE_CONTROL) || 297 if (*type < static_cast<uint8_t>(BATTOR_MESSAGE_TYPE_CONTROL) ||
270 *type > static_cast<uint8_t>(BATTOR_MESSAGE_TYPE_PRINT)) { 298 *type > static_cast<uint8_t>(BATTOR_MESSAGE_TYPE_PRINT))
271 return false; 299 return ParseMessageError::INVALID_MESSAGE_TYPE;
272 }
273 300
274 // After that comes the message bytes. 301 // After that comes the message bytes.
275 bool escape_next_byte = false; 302 bool escape_next_byte = false;
276 for (size_t i = 2; i < already_read_buffer_.size(); i++) { 303 for (size_t i = 2; i < already_read_buffer_.size(); i++) {
277 char next_byte = already_read_buffer_[i]; 304 char next_byte = already_read_buffer_[i];
278 305
279 if (escape_next_byte) { 306 if (escape_next_byte) {
280 bytes->push_back(next_byte); 307 bytes->push_back(next_byte);
281 escape_next_byte = false; 308 escape_next_byte = false;
282 continue; 309 continue;
283 } 310 }
284 311
285 switch (next_byte) { 312 switch (next_byte) {
286 case BATTOR_CONTROL_BYTE_START: 313 case BATTOR_CONTROL_BYTE_START:
287 // Two start bytes in a message is invalid. 314 // Two start bytes in a message is invalid.
288 return false; 315 return ParseMessageError::TOO_MANY_START_BYTES;
289 316
290 case BATTOR_CONTROL_BYTE_END: 317 case BATTOR_CONTROL_BYTE_END:
291 already_read_buffer_.erase(already_read_buffer_.begin(), 318 already_read_buffer_.erase(already_read_buffer_.begin(),
292 already_read_buffer_.begin() + i + 1); 319 already_read_buffer_.begin() + i + 1);
293 return true; 320 return ParseMessageError::NONE;
294 321
295 case BATTOR_CONTROL_BYTE_ESCAPE: 322 case BATTOR_CONTROL_BYTE_ESCAPE:
296 escape_next_byte = true; 323 escape_next_byte = true;
297 continue; 324 continue;
298 325
299 default: 326 default:
300 bytes->push_back(next_byte); 327 bytes->push_back(next_byte);
301 } 328 }
302 } 329 }
303 330
304 // If we made it to the end of the read buffer and no end byte was seen, then 331 // If we made it to the end of the read buffer and no end byte was seen, then
305 // we don't have a complete message. 332 // we don't have a complete message.
306 return false; 333 return ParseMessageError::NOT_ENOUGH_BYTES;
307 } 334 }
308 335
309 void BattOrConnectionImpl::OnBytesSent(int bytes_sent, 336 void BattOrConnectionImpl::OnBytesSent(int bytes_sent,
310 device::serial::SendError error) { 337 device::serial::SendError error) {
311 bool success = (error == device::serial::SendError::NONE) && 338 bool success = (error == device::serial::SendError::NONE) &&
312 (pending_write_length_ == static_cast<size_t>(bytes_sent)); 339 (pending_write_length_ == static_cast<size_t>(bytes_sent));
313 base::ThreadTaskRunnerHandle::Get()->PostTask( 340 base::ThreadTaskRunnerHandle::Get()->PostTask(
314 FROM_HERE, 341 FROM_HERE,
315 base::Bind(&Listener::OnBytesSent, base::Unretained(listener_), success)); 342 base::Bind(&Listener::OnBytesSent, base::Unretained(listener_), success));
316 } 343 }
317 344
318 void BattOrConnectionImpl::LogSerial(const std::string& str) { 345 void BattOrConnectionImpl::LogSerial(const std::string& str) {
319 serial_log_ << str << std::endl << std::endl; 346 serial_log_ << str << std::endl << std::endl;
320 } 347 }
321 348
322 } // namespace battor 349 } // namespace battor
OLDNEW
« no previous file with comments | « tools/battor_agent/battor_connection_impl.h ('k') | tools/battor_agent/battor_connection_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698