blob: 1e893de29ef51a9d2c5e9dbb3ee52f7f66072ee1 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Modified by FRC Team 971.
//
// Wrapper for libusb.
#ifndef _GLIBUSB_GLIBUSB_H_
#define _GLIBUSB_GLIBUSB_H_
#include <stdint.h>
#include <iosfwd>
#include <string>
#include <vector>
#include "glibusb_endpoint.h"
extern "C" {
struct libusb_context;
}
namespace glibusb {
// Structure to hold the physical location on the USB bus of the device.
struct DeviceLocation {
DeviceLocation() : bus_number(0), device_address(0) {}
DeviceLocation(uint8_t new_bus_number, uint8_t new_device_address)
: bus_number(new_bus_number), device_address(new_device_address) {}
bool operator==(const struct DeviceLocation &rhs) const {
return ((bus_number == rhs.bus_number) &&
(device_address == rhs.device_address));
}
std::string ToString() const;
uint8_t bus_number;
uint8_t device_address;
};
// Returns a string representing the DeviceLocation.
std::string DeviceLocationToString(const DeviceLocation &location);
std::ostream &operator <<(std::ostream &out,
const DeviceLocation &location);
// Structure to hold the USB vendor and product ids for a device.
struct VendorProductId {
constexpr VendorProductId() : vendor_id(0), product_id(0) {}
constexpr VendorProductId(uint16_t new_vendor_id, uint16_t new_product_id)
: vendor_id(new_vendor_id), product_id(new_product_id) {}
bool operator==(const struct VendorProductId &rhs) const {
return ((vendor_id == rhs.vendor_id) &&
(product_id == rhs.product_id));
}
std::string ToString() const;
uint16_t vendor_id;
uint16_t product_id;
};
// Returns a string representing the VendorProductId.
std::string VendorProductIdToString(const VendorProductId &vendor_product_id);
// Structure to hold the location and id of a device. This is enough to
// uniquely identify the device redundantly.
struct DeviceLocationAndId {
DeviceLocationAndId() {}
DeviceLocationAndId(const DeviceLocation &new_location,
const VendorProductId &new_id)
: location(new_location), id(new_id)
{}
bool operator==(const struct DeviceLocationAndId &rhs) const {
return ((location == rhs.location) &&
(id == rhs.id));
}
std::string ToString() const;
DeviceLocation location;
VendorProductId id;
};
// Returns a string representing the DeviceLocation and provides a stream
// operator for logging.
std::string DeviceLocationAndIdToString(const DeviceLocationAndId &location_and_id);
std::ostream &operator <<(std::ostream &out,
const DeviceLocationAndId &location_and_id);
// Provides an interface to an individual USB device.
class UsbDevice {
public:
explicit UsbDevice(VendorProductId vendor_product_id)
: vendor_product_id_(vendor_product_id) {}
virtual ~UsbDevice() {}
// Activates an alternate setting; returns true on success.
bool SetAlternateSetting(int setting) {
return DoSetAlternateSetting(setting);
}
// Returns the first endpoint to match the direction and transfer types.
// Caller is responsible for freeing the endpoint.
UsbInEndpoint *FindInEndpoint(UsbEndpoint::TransferType endpoint) {
return DoFindInEndpoint(endpoint);
}
UsbOutEndpoint *FindOutEndpoint(UsbEndpoint::TransferType endpoint) {
return DoFindOutEndpoint(endpoint);
}
// Returns the endpoint at the specified address.
// Caller is responsible for freeing the endpoint.
// Virtual for testing.
UsbInEndpoint *InEndpoint(int number) { return DoInEndpoint(number); }
UsbOutEndpoint *OutEndpoint(int number) { return DoOutEndpoint(number); }
// Returns the vendor and product ids.
VendorProductId GetVendorAndProductId() { return vendor_product_id_; }
struct DeviceLocationAndId Id() { return DoDeviceLocationAndId(); }
protected:
VendorProductId vendor_product_id_;
private:
friend class Libusb; // For private constructor.
virtual bool DoSetAlternateSetting(int setting) = 0;
virtual UsbInEndpoint *DoFindInEndpoint(
UsbEndpoint::TransferType endpoint) = 0;
virtual UsbOutEndpoint *DoFindOutEndpoint(
UsbEndpoint::TransferType endpoint) = 0;
virtual UsbInEndpoint *DoInEndpoint(int number) = 0;
virtual UsbOutEndpoint *DoOutEndpoint(int number) = 0;
virtual struct DeviceLocationAndId DoDeviceLocationAndId() = 0;
UsbDevice(const UsbDevice &) = delete;
void operator=(const UsbDevice &) = delete;
};
// Provides RAII-style libusb initialization.
class Libusb {
public:
Libusb();
~Libusb();
// Sets the debug level.
void SetDebug(int level);
// Returns the locations, vendor ids, and product ids of all attached devices.
void FindDeviceLocationAndId(std::vector<DeviceLocationAndId> *result);
// Finds and returns exactly one device with the matching vendor and
// product ID or CHECKs.
UsbDevice *FindSingleMatchingDeviceOrLose(const VendorProductId &id);
// Does the same, but returns NULL on failure rather than CHECKing.
UsbDevice *FindSingleMatchingDevice(const VendorProductId &id);
// Finds and returns exactly one device with the matching vendor and
// product ID, at the specified bus number and device address, or CHECKs.
UsbDevice *FindSingleMatchingDeviceAtLocationOrLose(
const DeviceLocationAndId &dev_location_id);
// Does the same, but returns NULL on failure rather than CHECKing.
UsbDevice *FindSingleMatchingDeviceAtLocation(
const DeviceLocationAndId &dev_location_id);
// Finds exactly one device that matches whatever parameters were specified,
// or CHECKs.
//
// Args:
// target_vendor_product_id: a vendor/product ID pair to search for,
// or empty string.
// target_device_location: a device location to search for, or empty string.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindDeviceBySpecification(
const std::string &target_vendor_product_id,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Finds exactly one device matching the specified parameters or checks.
//
// Args:
// target_ids: a list of product and vendor ids that match.
// target_device_location: a string with the device location, or an empty
// string to search all locations.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindSingleDeviceMatchingTargetId(
const VendorProductId &target_id,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Finds exactly one device matching the specified parameters or checks.
//
// Args:
// target_ids: a list of product and vendor ids that match.
// target_device_location: a string with the device location, or an empty
// string to search all locations.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindSingleDeviceMatchingTargetIds(
const std::vector<VendorProductId> &target_ids,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Parses a vendor id and product id string, and appends the result on
// target_ids.
// The string must be in the form VVVV:PPPP, where VVVV is a 4-digit hex
// vendor id and PPPP is a 4-digit hex product id.
static void ParseProductVendorString(const std::string &target_vendor_product_id,
std::vector<VendorProductId> *target_ids);
static void ParseDeviceLocationString(const std::string &target_device_location,
DeviceLocation *location);
// TODO(charliehotel): add richer ways to retrieve device handles.
private:
// Libusb handle
struct libusb_context *libusb_context_;
Libusb(const Libusb &) = delete;
void operator=(const Libusb &) = delete;
};
} // namespace glibusb
#endif // _GLIBUSB_GLIBUSB_H_