| # 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 |