blob: 6ef83c233b2b6b916802a6baff393b368d3a5592 [file] [log] [blame]
# Copyright 2017 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.
#
# """extract data from output of use-devices on linux box"""
# The parser takes output of "usb-devices" as rawdata, and has capablities to
# 1. Populate usb data into dictionary
# 3. Extract defined peripheral devices based on CAMERA_LIST, SPEAKER_LIST.
# 4. As of now only one type touch panel is defined here, which is Mimo.
# 5. Check usb devices's interface.
# 6. Retrieve usb device based on product and manufacture.
#
import cStringIO
from autotest_lib.client.common_lib.cros import textfsm
USB_DEVICES_TPLT = (
'Value Required Vendor ([0-9a-fA-F]+)\n'
'Value Required ProdID ([0-9A-Fa-f]+)\n'
'Value Required prev ([0-9a-fA-Z.]+)\n'
'Value Manufacturer (.+)\n'
'Value Product (.+)\n'
'Value serialnumber ([0-9a-fA-Z\:\-]+)\n'
'Value cinterfaces (\d)\n'
'Value List intindex ([0-9])\n'
'Value List intdriver ([A-Za-z-\(\)]+)\n\n'
'Start\n'
' ^USB-Device -> Continue.Record\n'
' ^P:\s+Vendor=${Vendor}\s+ProdID=${ProdID}\sRev=${prev}\n'
' ^S:\s+Manufacturer=${Manufacturer}\n'
' ^S:\s+Product=${Product}\n'
' ^S:\s+SerialNumber=${serialnumber}\n'
' ^C:\s+\#Ifs=\s+${cinterfaces}\n'
' ^I:\s+If\#=\s+${intindex}.*Driver=${intdriver}\n'
)
# As of now there are certain types of cameras, speakers and touch-panel.
# New devices can be added to these global variables.
CAMERA_LIST = ['2bd9:0011', '046d:0843', '046d:082d', '046d:0853', '064e:9405',
'046d:085f']
CAMERA_MAP = {'2bd9:0011':'Huddly GO',
'046d:0843':'Logitech Webcam C930e',
'046d:082d':'HD Pro Webcam C920',
'046d:0853':'PTZ Pro Camera',
'046d:085f':'PTZ Pro 2',
'064e:9405':'HD WebCam'}
SPEAKER_LIST = ['18d1:8001', '0b0e:0412', '2abf:0505']
SPEAKER_MAP = {'18d1:8001':'Hangouts Meet speakermic',
'0b0e:0412':'Jabra SPEAK 410',
'2abf:0505':'FLX UC 500'}
TOUCH_DISPLAY_LIST = ['17e9:016b','17e9:416d']
TOUCH_CONTROLLER_LIST = ['266e:0110']
DISPLAY_PANEL_MAP = {'17e9:016b':'DisplayLink',
'17e9:416d':'DisplayLink'}
TOUCH_PANEL_MAP = {'266e:0110':'SiS HID Touch Controller'}
INTERFACES_LIST = {'2bd9:0011':['uvcvideo', 'uvcvideo',
'uvcvideo', 'uvcvideo'],
'046d:0843':['uvcvideo', 'uvcvideo',
'snd-usb-audio', 'snd-usb-audio'],
'046d:082d':['uvcvideo', 'uvcvideo',
'snd-usb-audio', 'snd-usb-audio'],
'046d:085f': ['uvcvideo', 'uvcvideo','usbhid'],
'0b0e:0412':['snd-usb-audio', 'snd-usb-audio',
'snd-usb-audio'],
'18d1:8001':['snd-usb-audio', 'snd-usb-audio',
'snd-usb-audio', 'usbhid'],
'17e9:016b':['udl'],
'17e9:416d':['udl'],
'266e:0110':['usbhid'],
'046d:0853':['uvcvideo', 'uvcvideo','usbhid'],
'064e:9405':['uvcvideo', 'uvcvideo'],
'2abf:0505':['snd-usb-audio', 'snd-usb-audio',
'snd-usb-audio', 'usbhid']
}
def extract_usb_data(rawdata):
"""populate usb data into list dictionary
@param rawdata: The output of "usb-devices" on CfM.
@returns list of dictionary, examples:
{'Manufacturer': 'USBest Technology', 'Product': 'SiS HID Touch Controller',
'Vendor': '266e', 'intindex': ['0'], 'tport': '00', 'tcnt': '01',
'serialnumber': '', 'tlev': '03', 'tdev': '18', 'dver': '',
'intdriver': ['usbhid'], 'tbus': '01', 'prev': '03.00',
'cinterfaces': '1', 'ProdID': '0110', 'tprnt': '14'}
"""
usbdata = []
rawdata += '\n'
re_table = textfsm.TextFSM(cStringIO.StringIO(USB_DEVICES_TPLT))
fsm_results = re_table.ParseText(rawdata)
usbdata = [dict(zip(re_table.header, row)) for row in fsm_results]
return usbdata
def extract_peri_device(usbdata, vid_pid):
"""retrive the list of dictionary for certain types of VID_PID
@param usbdata: list of dictionary for usb devices
@param vid_pid: list of vid_pid combination
@returns the list of dictionary for certain types of VID_PID
"""
vid_pid_usb_list = []
for _vid_pid in vid_pid:
vid = _vid_pid.split(':')[0]
pid = _vid_pid.split(':')[1]
for _data in usbdata:
if vid == _data['Vendor'] and pid == _data['ProdID']:
vid_pid_usb_list.append(_data)
return vid_pid_usb_list
def get_list_audio_device(usbdata):
"""retrive the list of dictionary for all audio devices
@param usbdata: list of dictionary for usb devices
@returns the list of dictionary for all audio devices
"""
audio_device_list = []
for _data in usbdata:
if "snd-usb-audio" in _data['intdriver']:
audio_device_list.append(_data)
return audio_device_list
def get_list_video_device(usbdata):
"""retrive the list of dictionary for all video devices
@param usbdata: list of dictionary for usb devices
@returns the list of dictionary for all video devices
"""
video_device_list = []
for _data in usbdata:
if "uvcvideo" in _data['intdriver']:
video_device_list.append(_data)
return video_device_list
def get_list_mimo_device(usbdata):
"""retrive the list of dictionary for all touch panel devices
@param usbdata: list of dictionary for usb devices
@returns the lists of dictionary
one for displaylink, the other for touch controller
"""
displaylink_list = []
touchcontroller_list = []
for _data in usbdata:
if "udl" in _data['intdriver']:
displaylink_list.append(_data)
if "SiS HID Touch Controller" == _data['Product']:
touchcontroller_list.append(_data)
return displaylink_list, touchcontroller_list
def get_list_by_product(usbdata, product_name):
"""retrive the list of dictionary based on product_name
@param usbdata: list of dictionary for usb devices
@returns the list of dictionary
"""
usb_list_by_product = []
for _data in usbdata:
if product_name == _data['Product']:
usb_list_by_product.append(_data)
return usb_list_by_product
def get_list_by_manufacturer(usbdata, manufacturer_name):
"""retrive the list of dictionary based on manufacturer_name
@param usbdata: list of dictionary for usb devices
@returns the list of dictionary
"""
usb_list_by_manufacturer = []
for _data in usbdata:
if manufacturer_name == _data['Manufacturer']:
usb_list_by_manufacturer.append(_data)
return usb_list_by_manufacturer
def is_usb_device_ok(usbdata, vid_pid):
"""check usb device has expected usb interface
@param usbdata: list of dictionary for usb devices
@vid_pid: VID, PID combination for each type of USB device
@returns:
int: number of device
boolean: usb interfaces expected or not?
"""
number_of_device = 0
device_health = []
vid = vid_pid[0:4]
pid = vid_pid[-4:]
for _data in usbdata:
if vid == _data['Vendor'] and pid == _data['ProdID']:
number_of_device += 1
compare_list = _data['intdriver'][0:len(INTERFACES_LIST[vid_pid])]
if cmp(compare_list, INTERFACES_LIST[vid_pid]) == 0:
device_health.append('1')
else:
device_health.append('0')
return number_of_device, device_health
def get_speakers(usbdata):
"""get number of speaker for each type
@param usbdata: list of dictionary for usb devices
@returns: list of dictionary, key is VID_PID, value is number of speakers
"""
number_speaker = {}
for _speaker in SPEAKER_LIST:
vid = _speaker.split(':')[0]
pid = _speaker.split(':')[1]
_number = 0
for _data in usbdata:
if _data['Vendor'] == vid and _data['ProdID'] == pid:
_number += 1
number_speaker[_speaker] = _number
return number_speaker
def get_dual_speaker(usbdata):
"""check whether dual speakers are present
@param usbdata: list of dictionary for usb devices
@returns: True or False
"""
dual_speaker = None
speaker_dict = get_speakers(usbdata)
for _key in speaker_dict.keys():
if speaker_dict[_key] == 2:
dual_speaker = _key
break
return dual_speaker
def get_cameras(usbdata):
"""get number of camera for each type
@param usbdata: list of dictionary for usb devices
@returns: list of dictionary, key is VID_PID, value is number of cameras
"""
number_camera = {}
for _camera in CAMERA_LIST:
vid = _camera.split(':')[0]
pid = _camera.split(':')[1]
_number = 0
for _data in usbdata:
if _data['Vendor'] == vid and _data['ProdID'] == pid:
_number += 1
number_camera[_camera] = _number
return number_camera
def get_display_mimo(usbdata):
"""get number of displaylink in Mimo for each type
@param usbdata: list of dictionary for usb devices
@returns: list of dictionary, key is VID_PID, value
is number of displaylink
"""
number_display = {}
for _display in TOUCH_DISPLAY_LIST:
vid = _display.split(':')[0]
pid = _display.split(':')[1]
_number = 0
for _data in usbdata:
if _data['Vendor'] == vid and _data['ProdID'] == pid:
_number += 1
number_display[_display] = _number
return number_display
def get_controller_mimo(usbdata):
"""get number of touch controller Mimo for each type
@param usbdata: list of dictionary for usb devices
@returns: list of dictionary, key is VID_PID, value
is number of touch controller
"""
number_controller = {}
for _controller in TOUCH_CONTROLLER_LIST:
vid = _controller.split(':')[0]
pid = _controller.split(':')[1]
_number = 0
for _data in usbdata:
if _data['Vendor'] == vid and _data['ProdID'] == pid:
_number += 1
number_controller[_controller] = _number
return number_controller
def get_preferred_speaker(peripheral):
"""get string for the 1st speakers in the device list
@param peripheral: of dictionary for usb devices
@returns: string for name of preferred speake
"""
for _key in peripheral:
if _key in SPEAKER_LIST:
speaker_name = SPEAKER_MAP[_key]+' ('+_key+')'
return speaker_name
def get_preferred_camera(peripheral):
"""get string for the 1st cameras in the device list
@param peripheral: of dictionary for usb devices
@returns: string for name of preferred camera
"""
for _key in peripheral:
if _key in CAMERA_LIST:
camera_name = CAMERA_MAP[_key]+' ('+_key+')'
return camera_name
def get_device_prod(vid_pid):
"""get product for vid_pid
@param vid_pid: vid and pid combo for device
@returns: product
"""
for _key in SPEAKER_MAP.keys():
if _key == vid_pid:
return SPEAKER_MAP[_key]
for _key in CAMERA_MAP.keys():
if _key == vid_pid:
return CAMERA_MAP[_key]
for _key in DISPLAY_PANEL_MAP.keys():
if _key == vid_pid:
return DISPLAY_PANEL_MAP[_key]
for _key in TOUCH_PANEL_MAP.keys():
if _key == vid_pid:
return TOUCH_PANEL_MAP[_key]
return None