16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_device_filter.h" 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/values.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_descriptors.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/usb/usb_device.h" 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace device { 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace { 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kProductIdKey[] = "productId"; 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kVendorIdKey[] = "vendorId"; 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kInterfaceClassKey[] = "interfaceClass"; 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kInterfaceSubclassKey[] = "interfaceSubclass"; 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kInterfaceProtocolKey[] = "interfaceProtocol"; 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbDeviceFilter::UsbDeviceFilter() 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : vendor_id_set_(false), 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) product_id_set_(false), 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_class_set_(false), 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_subclass_set_(false), 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_protocol_set_(false) { 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)UsbDeviceFilter::~UsbDeviceFilter() { 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbDeviceFilter::SetVendorId(uint16 vendor_id) { 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) vendor_id_set_ = true; 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) vendor_id_ = vendor_id; 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbDeviceFilter::SetProductId(uint16 product_id) { 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) product_id_set_ = true; 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) product_id_ = product_id; 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbDeviceFilter::SetInterfaceClass(uint8 interface_class) { 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_class_set_ = true; 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_class_ = interface_class; 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbDeviceFilter::SetInterfaceSubclass(uint8 interface_subclass) { 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_subclass_set_ = true; 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_subclass_ = interface_subclass; 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UsbDeviceFilter::SetInterfaceProtocol(uint8 interface_protocol) { 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_protocol_set_ = true; 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) interface_protocol_ = interface_protocol; 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UsbDeviceFilter::Matches(scoped_refptr<UsbDevice> device) const { 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (vendor_id_set_) { 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (device->vendor_id() != vendor_id_) { 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (product_id_set_ && device->product_id() != product_id_) { 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (interface_class_set_) { 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool foundMatch = false; 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const UsbConfigDescriptor& config = device->GetConfiguration(); 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(reillyg): Check device configuration if the class is not defined at 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // a per-interface level. This is not really important because most devices 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // have per-interface classes. The only counter-examples I know of are hubs. 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (UsbInterfaceDescriptor::Iterator ifaceIt = config.interfaces.begin(); 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ifaceIt != config.interfaces.end() && !foundMatch; 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++ifaceIt) { 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ifaceIt->interface_class == interface_class_ && 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (!interface_subclass_set_ || 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (ifaceIt->interface_subclass == interface_subclass_ && 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (!interface_protocol_set_ || 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ifaceIt->interface_protocol == interface_protocol_)))) { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci foundMatch = true; 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!foundMatch) { 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)base::Value* UsbDeviceFilter::ToValue() const { 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<base::DictionaryValue> obj(new base::DictionaryValue()); 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (vendor_id_set_) { 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) obj->SetInteger(kVendorIdKey, vendor_id_); 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (product_id_set_) { 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) obj->SetInteger(kProductIdKey, product_id_); 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (interface_class_set_) { 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) obj->SetInteger(kInterfaceClassKey, interface_class_); 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (interface_subclass_set_) { 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) obj->SetInteger(kInterfaceSubclassKey, interface_subclass_); 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (interface_protocol_set_) { 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) obj->SetInteger(kInterfaceProtocolKey, interface_protocol_); 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return obj.release(); 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool UsbDeviceFilter::MatchesAny(scoped_refptr<UsbDevice> device, 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<UsbDeviceFilter>& filters) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<UsbDeviceFilter>::const_iterator i = filters.begin(); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci i != filters.end(); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++i) { 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (i->Matches(device)) { 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace device 135