o
    _                     @   s   d Z ddlmZ ddlZddlZddlmZ ddlmZ dZ	dZ
dZd	Zd
ZdZdZdZdZdd Zdd ZG dd deZdd Zdd ZG dd dejZdS )zCImplements raw HID interface on Linux using SysFS and device files.    )divisionN)errors)base                  t         c                 C   sp   t | } | | }|tkr!|d t| k rd| |d  fS td|d@ }|dkr-d|fS |dkr3dS td)a  Get value length for a key in rd.

  For a key at position pos in the Report Descriptor rd, return the length
  of the associated value.  This supports both short and long format
  values.

  Args:
    rd: Report Descriptor
    pos: The position of the key in rd.

  Returns:
    (key_size, data_len) where key_size is the number of bytes occupied by
    the key and data_len is the length of the value associated by the key.
        zMalformed report descriptor   )r   r   zCannot happen)	bytearrayLONG_ITEM_ENCODINGlenr   HidError)rdposkeycode r   /lib/python3.10/site-packages/pyu2f/hid/linux.pyGetValueLength#   s   

r   c                 C   sV   d}|dkr	d}n|dkrd}n|dkrd}nt dt|| |||  \}|S )	zFReads value_size bytes from rd at offset, least signifcant byte first.Nr   z<Br   z<Hr   z<LzInvalid value size specified)r   r   structunpack)r   offsetZ
value_sizeencodingretr   r   r   ReadLsbBytesK   s   
r!   c                   @   s   e Zd ZdS )NoReportCountFoundN)__name__
__module____qualname__r   r   r   r   r"   \   s    r"   c                 C   s  t | } d}d}d}d}d}|t| k r| | }t| |\}}	|t@ tkr;|r:|r:|| d }
t|j|
|_d}d}n|t@ tkrW|rV|rV|| d }
t|j|
|_d}d}nt|t@ t	krh|rb||_
|rg||_nc|t@ tkrt| |d |	 krt| |d |	}nJ|t@ tkrt| |d |	 krt| |d |	}n1|t@ tkrt| |d |	 krt| |d |	}n|t@ tkrt| |d |	 krt| |d |	}||	| 7 }|t| k s|S )a  Parse the binary report descriptor.

  Parse the binary report descriptor into a DeviceDescriptor object.

  Args:
    rd: The binary report descriptor
    desc: The DeviceDescriptor object to update with the results
        from parsing the descriptor.

  Returns:
    None
  r   Nr   r   )r   r   r   REPORT_DESCRIPTOR_KEY_MASK
INPUT_ITEMmaxinternal_max_in_report_lenOUTPUT_ITEMinternal_max_out_report_lenCOLLECTION_ITEM
usage_pageusageREPORT_COUNTr!   REPORT_SIZE
USAGE_PAGEUSAGE)r   descr   Zreport_countZreport_sizer-   r.   r   Zkey_sizeZvalue_lengthZbyte_lengthr   r   r   ParseReportDescriptor`   sf   'r4   c           	      C   sz   |  d}|D ]3}| }|sq| d\}}|dkr"|d|_q|dkr:| d\}}}t|d|_t|d|_qd S )N   
   =s   HID_NAMEutf8s   HID_ID   :   )splitstripdecodeZproduct_stringintZ	vendor_idZ
product_id)	Zueventr3   lineslinekv_Zvidpidr   r   r   ParseUevent   s   
rD   c                   @   sD   e Zd ZdZedd Zdd Zdd Zdd	 Zd
d Z	dd Z
dS )LinuxHidDevicezImplementation of HID device for linux.

  Implementation of HID device interface for linux that uses block
  devices to interact with the device and sysfs to enumerate/discover
  device metadata.
  c                  c   s    t dD ]C} t jd| d}t jd| d}t|d}t|d}t }t jd| |_t| | t	| | |
  |
  | V  qd S )N/sys/class/hidrawdevice/report_descriptorzdevice/ueventrbz/dev/)oslistdirpathjoinopenr   DeviceDescriptorr4   readrD   closeZToPublicDict)ZhidrawZrd_pathZuevent_pathrd_fileZuevent_filer3   r   r   r   	Enumerate   s$   

zLinuxHidDevice.Enumeratec                 C   sj   t j| | t|tj| _t  | _|| j_	ttj	
dtj	|dd}t| | j |  d S )NrF   rG   rH   )r   	HidDevice__init__rI   rM   O_RDWRdevrN   r3   rK   rL   basenamer4   rO   rP   )selfrK   rQ   r   r   r   rT      s   


zLinuxHidDevice.__init__c                 C      | j jS See base class.)r3   r)   rX   r   r   r   GetInReportDataLength      z$LinuxHidDevice.GetInReportDataLengthc                 C   rY   rZ   )r3   r+   r\   r   r   r   GetOutReportDataLength   r^   z%LinuxHidDevice.GetOutReportDataLengthc                 C   s    t dg| }t| j| dS )r[   r   N)r   rI   writerV   )rX   Zpacketoutr   r   r   Write   s   zLinuxHidDevice.Writec                 C   s"   t | j|  }tt|}|S rZ   )rI   rO   rV   r]   listr   )rX   Zraw_inZ
decoded_inr   r   r   Read   s   zLinuxHidDevice.ReadN)r#   r$   r%   __doc__staticmethodrR   rT   r]   r_   rb   rd   r   r   r   r   rE      s    
rE   )re   Z
__future__r   rI   r   Zpyu2fr   Z	pyu2f.hidr   r&   r   r*   r'   r,   r/   r0   r1   r2   r   r!   	Exceptionr"   r4   rD   rS   rE   r   r   r   r   <module>   s*   (?