| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |