Skip to content

Commit

Permalink
Retry connection when initial attempt fails. Close #90
Browse files Browse the repository at this point in the history
Retry connection when initial attempt fails. Close #90

When connecting to a reader fails, we retry connecting later.
This is done by showing another Bus number for the device.
We need to fake Bus numbers anyway as chrome.usb does not let us retrieve them.
PCSC then views it as a different device from the previous one and attempts
to connect to it once a smartcard reader needs to be accessed.
  • Loading branch information
Fabian-Sommer authored Dec 18, 2019
1 parent 3b033af commit d48f773
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
29 changes: 24 additions & 5 deletions third_party/libusb/naclport/src/libusb_over_chrome_usb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@
#include <google_smart_card_common/pp_var_utils/construction.h>
#include <google_smart_card_common/pp_var_utils/extraction.h>

// This arbitrary chosen constant is used as a stub for the device bus number
// (as the chrome.usb API does not provide means of retrieving this).
const uint8_t kFakeDeviceBusNumber = 42;
//
// We use stubs for the device bus number (as the chrome.usb API does not
// provide means of retrieving it). We modify this for a device when opening
// the device fails. This makes PCSC recognize it as a new device which causes
// PCSC to retry opening it. The number of reconnection attempts is limited
// by kMaximumBusNumber - kDefaultBusNumber.
//

const uint8_t kDefaultBusNumber = 1;
const uint8_t kMaximumBusNumber = 64;

//
// Bit mask values for the bmAttributes field of the libusb_config_descriptor
Expand Down Expand Up @@ -498,8 +505,13 @@ int LibusbOverChromeUsb::LibusbGetDeviceDescriptor(
return LIBUSB_SUCCESS;
}

uint8_t LibusbOverChromeUsb::LibusbGetBusNumber(libusb_device* /*dev*/) {
return kFakeDeviceBusNumber;
uint8_t LibusbOverChromeUsb::LibusbGetBusNumber(libusb_device* dev) {
auto bus_numbers_iterator =
bus_numbers_.find(dev->chrome_usb_device().device);
if (bus_numbers_iterator != bus_numbers_.end()) {
return bus_numbers_iterator->second;
}
return kDefaultBusNumber;
}

uint8_t LibusbOverChromeUsb::LibusbGetDeviceAddress(libusb_device* dev) {
Expand All @@ -523,6 +535,13 @@ int LibusbOverChromeUsb::LibusbOpen(
if (!result.is_successful()) {
GOOGLE_SMART_CARD_LOG_WARNING << "LibusbOverChromeUsb::LibusbOpen " <<
"request failed: " << result.error_message();
// Modify the devices (fake) bus number that we report so that PCSC will
// retry to connect to the device once it updates the device list.
uint32_t new_bus_number =
static_cast<uint32_t>(LibusbGetBusNumber(dev)) + 1;
if (new_bus_number <= kMaximumBusNumber) {
bus_numbers_[dev->chrome_usb_device().device] = new_bus_number;
}
return LIBUSB_ERROR_OTHER;
}
const chrome_usb::ConnectionHandle chrome_usb_connection_handle =
Expand Down
6 changes: 6 additions & 0 deletions third_party/libusb/naclport/src/libusb_over_chrome_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <stdint.h>

#include <memory>
#include <unordered_map>

#include <libusb.h>

Expand Down Expand Up @@ -139,6 +140,11 @@ class LibusbOverChromeUsb final : public LibusbInterface {
int LibusbHandleEventsWithTimeout(
libusb_context* context, int timeout_seconds);

// map that holds the (fake) bus number for each device
// keys are libusb_device->chrome_usb_device().device
// if a device is not found, we return kDefaultBusNumber
std::unordered_map<int64_t, uint8_t> bus_numbers_;

chrome_usb::ApiBridgeInterface* const chrome_usb_api_bridge_;
LibusbContextsStorage contexts_storage_;
const std::shared_ptr<libusb_context> default_context_;
Expand Down

0 comments on commit d48f773

Please sign in to comment.