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

Unified Diff: device/u2f/u2f_hid_device.cc

Issue 2824803003: Add timeout task to U2F HID state machine (Closed)
Patch Set: Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
« device/u2f/u2f_hid_device.h ('K') | « device/u2f/u2f_hid_device.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/u2f/u2f_hid_device.cc
diff --git a/device/u2f/u2f_hid_device.cc b/device/u2f/u2f_hid_device.cc
index c313b96e4c165aab270e68e616c552fa4401d62c..1c50f877797ea59a64d1f360f2e2cea79f3fdece 100644
--- a/device/u2f/u2f_hid_device.cc
+++ b/device/u2f/u2f_hid_device.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "crypto/random.h"
#include "device/base/device_client.h"
#include "device/hid/hid_connection.h"
@@ -29,7 +30,7 @@ U2fHidDevice::U2fHidDevice(scoped_refptr<HidDeviceInfo> device_info)
U2fHidDevice::~U2fHidDevice() {
// Cleanup connection
- if (connection_)
+ if (connection_ && !connection_->closed())
connection_->Close();
}
@@ -41,22 +42,54 @@ void U2fHidDevice::DeviceTransact(std::unique_ptr<U2fApduCommand> command,
void U2fHidDevice::Transition(std::unique_ptr<U2fApduCommand> command,
const DeviceCallback& callback) {
switch (state_) {
- case State::INIT:
+ case State::INIT: {
state_ = State::BUSY;
+ timeout_callback_.Reset(base::Bind(&U2fHidDevice::OnTimeout,
+ weak_factory_.GetWeakPtr(), callback));
+ auto self = weak_factory_.GetWeakPtr();
Connect(base::Bind(&U2fHidDevice::OnConnect, weak_factory_.GetWeakPtr(),
base::Passed(&command), callback));
+ if (self && !timeout_callback_.IsCancelled()) {
+ // Setup timeout task for 3 seconds
Reilly Grant (use Gerrit) 2017/04/17 22:25:17 Set up the timeout task before calling Connect to
Casey Piper 2017/04/17 23:02:38 Done. Did you mean DCHECK(timeout_callback.IsCance
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, timeout_callback_.callback(),
+ base::TimeDelta::FromMilliseconds(3000));
+ }
break;
- case State::CONNECTED:
+ }
+ case State::CONNECTED: {
state_ = State::BUSY;
+ timeout_callback_.Reset(base::Bind(&U2fHidDevice::OnTimeout,
+ weak_factory_.GetWeakPtr(), callback));
+ auto self = weak_factory_.GetWeakPtr();
AllocateChannel(std::move(command), callback);
+ if (self && !timeout_callback_.IsCancelled()) {
+ // Setup timeout task for 3 seconds
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, timeout_callback_.callback(),
+ base::TimeDelta::FromMilliseconds(3000));
+ }
break;
+ }
case State::IDLE: {
state_ = State::BUSY;
std::unique_ptr<U2fMessage> msg = U2fMessage::Create(
channel_id_, U2fMessage::Type::CMD_MSG, command->GetEncodedCommand());
+
+ timeout_callback_.Reset(base::Bind(&U2fHidDevice::OnTimeout,
+ weak_factory_.GetWeakPtr(), callback));
+ auto self = weak_factory_.GetWeakPtr();
+ // Write message to the device
WriteMessage(std::move(msg), true,
base::Bind(&U2fHidDevice::MessageReceived,
weak_factory_.GetWeakPtr(), callback));
+
+ if (self && !timeout_callback_.IsCancelled()) {
+ // Setup timeout task for 3 seconds
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, timeout_callback_.callback(),
+ base::TimeDelta::FromMilliseconds(3000));
+ }
break;
}
case State::BUSY:
@@ -86,6 +119,11 @@ void U2fHidDevice::Connect(const HidService::ConnectCallback& callback) {
void U2fHidDevice::OnConnect(std::unique_ptr<U2fApduCommand> command,
const DeviceCallback& callback,
scoped_refptr<HidConnection> connection) {
+ if (timeout_callback_.IsCancelled()) {
+ return;
+ }
Reilly Grant (use Gerrit) 2017/04/17 22:25:17 nit: no braces around single-line if. The state m
Casey Piper 2017/04/17 23:02:38 Done.
+ timeout_callback_.Cancel();
+
if (connection) {
connection_ = connection;
state_ = State::CONNECTED;
@@ -114,6 +152,11 @@ void U2fHidDevice::OnAllocateChannel(std::vector<uint8_t> nonce,
const DeviceCallback& callback,
bool success,
std::unique_ptr<U2fMessage> message) {
+ if (timeout_callback_.IsCancelled()) {
+ return;
+ }
Reilly Grant (use Gerrit) 2017/04/17 22:25:17 nit: no braces around single-line if.
Casey Piper 2017/04/17 23:02:38 Done.
+ timeout_callback_.Cancel();
+
if (!success || !message) {
state_ = State::DEVICE_ERROR;
Transition(nullptr, callback);
@@ -213,9 +256,10 @@ void U2fHidDevice::OnRead(U2fHidMessageCallback callback,
// Received a message from a different channel, so try again
if (channel_id_ != read_message->channel_id()) {
- connection_->Read(base::Bind(&U2fHidDevice::OnRead,
- weak_factory_.GetWeakPtr(),
- base::Passed(&callback)));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&U2fHidDevice::ReadMessage, weak_factory_.GetWeakPtr(),
+ base::Passed(&callback)));
return;
}
@@ -251,14 +295,20 @@ void U2fHidDevice::OnReadContinuation(std::unique_ptr<U2fMessage> message,
base::Passed(&message), base::Passed(&callback)));
}
-void U2fHidDevice::MessageReceived(const DeviceCallback& callback,
+void U2fHidDevice::MessageReceived(DeviceCallback callback,
bool success,
std::unique_ptr<U2fMessage> message) {
+ if (timeout_callback_.IsCancelled()) {
+ return;
+ }
Reilly Grant (use Gerrit) 2017/04/17 22:25:17 nit: no braces around single-line if.
Casey Piper 2017/04/17 23:02:38 Done.
+ timeout_callback_.Cancel();
+
if (!success) {
state_ = State::DEVICE_ERROR;
Transition(nullptr, callback);
return;
}
+
std::unique_ptr<U2fApduResponse> response = nullptr;
if (message)
response = U2fApduResponse::CreateFromMessage(message->GetMessagePayload());
@@ -297,8 +347,14 @@ void U2fHidDevice::OnWink(const WinkCallback& callback,
callback.Run();
}
+void U2fHidDevice::OnTimeout(DeviceCallback callback) {
+ timeout_callback_.Cancel();
Reilly Grant (use Gerrit) 2017/04/17 22:25:17 Since timeout_callback_ can only fire once it shou
Casey Piper 2017/04/17 23:02:38 Done.
+ state_ = State::DEVICE_ERROR;
+ Transition(nullptr, callback);
+}
+
std::string U2fHidDevice::GetId() {
- std::ostringstream id("hid:");
+ std::ostringstream id("hid:", std::ios::ate);
id << device_info_->device_id();
return id.str();
}
« device/u2f/u2f_hid_device.h ('K') | « device/u2f/u2f_hid_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698