blob: 01655565f4c286d2a11fe60aa67c5066b1325d29 [file] [log] [blame]
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
from cros.factory.probe.functions import sysfs
from cros.factory.probe.lib import cached_probe_function
REQUIRED_FIELDS = ['idVendor', 'idProduct']
OPTIONAL_FIELDS = ['manufacturer', 'product', 'bcdDevice']
def ReadUSBSysfs(dir_path):
result = sysfs.ReadSysfs(
dir_path, REQUIRED_FIELDS, optional_keys=OPTIONAL_FIELDS)
if result:
result['bus_type'] = 'usb'
return result
class USBFunction(cached_probe_function.GlobPathCachedProbeFunction):
"""Probes all usb devices listed in the sysfs ``/sys/bus/usb/devices/``.
Description
-----------
This function goes through ``/sys/bus/usb/devices/`` to read attributes of
each usb device (also includes usb root hub) listed there. Each result
should contain these fields:
- ``device_path``: Pathname of the sysfs directory.
- ``idVendor``
- ``idProduct``
The result might also contain these optional fields if they are exported in
the sysfs entry:
- ``manufacturer``
- ``product``
- ``bcdDevice``
Examples
--------
Let's say the Chromebook has two usb devices. One of which
(at ``/sys/bus/usb/devices/1-1``) has the attributes:
- ``idVendor=0x0123``
- ``idProduct=0x4567``
- ``manufacturer=Google``
- ``product=Google Fancy Camera``
- ``bcdDevice=0x8901``
And the other one (at ``/sys/bus/usb/devices/1-2``) has the attributes:
- ``idVendor=0x0246``
- ``idProduct=0x1357``
- ``product=Goofy Bluetooth``
Then the probe statement::
{
"eval": "usb"
}
will have the corresponding probed result::
[
{
"bus_type": "usb",
"idVendor": "0123",
"idProduct": "4567",
"manufacturer": "Google",
"product": "Google Fancy Camera",
"bcdDevice": "8901"
},
{
"bus_type": "usb",
"idVendor": "0246",
"idProduct": "1357",
"product": "Goofy Bluetooth"
}
]
To verify if the Chromebook has Google Fancy Camera or not, you can write
a probe statement like::
{
"eval": "usb",
"expect": {
"idVendor": "0123",
"idProduct": "4567"
}
}
and verify if the ``camera`` field of the probed result dict contains
elements or not.
You can also specify ``dir_path`` argument directly to ask the function
to probe that sysfs USB entry. For example, the probe statement ::
{
"eval": "usb:/sys/bus/usb/devices/1-1"
}
will have the corresponding probed results::
[
{
"bus_type": "usb",
"idVendor": "0123",
...
}
]
"""
GLOB_PATH = '/sys/bus/usb/devices/*'
@classmethod
def ProbeDevice(cls, dir_path):
# A valid usb device name is <roothub_num>-<addr>[.<addr2>[.<addr3>...]] or
# usb[0-9]+ for usb root hub.
name = os.path.basename(dir_path)
if (not re.match(r'^[0-9]+-[0-9]+(\.[0-9]+)*$', name) and
not re.match(r'^usb[0-9]+$', name)):
return None
return ReadUSBSysfs(dir_path)