
    .                         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 Zd Z G d de      Zd Zd Z G d dej0                        Zy)zCImplements raw HID interface on Linux using SysFS and device files.    )divisionN)errors)base                  t         c                     t        |       } | |   }|t        k(  r0|dz   t        |       k  r
d| |dz      fS t        j                  d      |dz  }|dk  rd|fS |dk(  ryt        j                  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codes       *platform/bq/third_party/pyu2f/hid/linux.pyGetValueLengthr   $   s     }"
3# QwRC!GOO9:: :Dt|Y	((    c                     d}|dk(  rd}n%|dk(  rd}n|dk(  rd}nt        j                  d      t        j                  || |||z          \  }|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   offset
value_sizeencodingrets        r   ReadLsbBytesr%   L   s`     (1_HQHQH
//8
99	xF6J+>!?	@$#	*r   c                       e Zd Zy)NoReportCountFoundN)__name__
__module____qualname__ r   r   r'   r'   ]   s    r   r'   c                    t        |       } d}d}d}d}d}|t        |       k  r| |   }t        | |      \  }}	|t        z  t        k(  r/|r`|r]||z  dz  }
t        |j                  |
      |_        d}d}n4|t        z  t        k(  r.|r!|r||z  dz  }
t        |j                  |
      |_        d}d}n|t        z  t        k(  r|r||_
        |r||_        n|t        z  t        k(  r%t        |       |dz   |	z   k\  rt        | |dz   |	      }n|t        z  t        k(  r%t        |       |dz   |	z   k\  rzt        | |dz   |	      }ni|t        z  t        k(  r%t        |       |dz   |	z   k\  rEt        | |dz   |	      }n4|t        z  t         k(  r$t        |       |dz   |	z   k\  rt        | |dz   |	      }||	|z   z  }|t        |       k  r|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   report_countreport_sizer4   r5   r   key_sizevalue_lengthbyte_lengths              r   ParseReportDescriptorr@   a   s    }"	#,+*
%c"g
S'C ,B4Hl
'':5	+#k1a7*-++[+:'	)	)[	8	+#k1a7+.,,k,;(	)	)_	<	$	
	)	)\	9	RC!Gl*	*#Ba>	)	)[	8	RC!Gl*	*"2sQw=	)	)Z	7	RC!Gl*	*!"cAg|<
	)	)U	2	RC!Gl*	*Rq,7<(""CM 	c"gN 
+r   c                 4   | j                  d      }|D ]  }|j                         }|s|j                  d      \  }}|dk(  r|j                  d      |_        F|dk(  sL|j                  d      \  }}}t	        |d      |_        t	        |d      |_         y )N   
   =s   HID_NAMEutf8s   HID_ID   :   )splitstripdecodeproduct_stringint	vendor_id
product_id)	ueventr:   lineslinekv_vidpids	            r   ParseUeventrV      s    
,,u
%d::<D::dDAqKHHV,d	
iGGDMkac3|dnCdo r   c                   >    e Zd ZdZed        Zd Zd Zd Zd Z	d Z
y)	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               #     K   g } 	 t        j                  d      } | D ]  }t         j
                  j                  d|d      }t         j
                  j                  d|d      }t        |d      }t        |d      }t        j                         }t         j
                  j                  d|      |_        t        |j                         |       t        |j                         |       |j                          |j                          |j                           y # t        $ r t        j                  d      w xY ww)N/sys/class/hidrawzNo hidraw device is availabledevice/report_descriptorzdevice/ueventrbz/dev/)oslistdirFileNotFoundErrorr   
OsHidErrorpathjoinopenr   DeviceDescriptorr@   readrV   closeToPublicDict)hidraw_devicesdevrd_pathuevent_pathrd_fileuevent_filer:   s          r   	EnumeratezLinuxHidDevice.Enumerate   s    N?zz"56n 
'',,!3(*  GGLL!4c?KkWd#gd+k""$d'',,w,diGLLND1+""$d+mmo   ?=>>?s   D>D DD>D;;D>c                    t         j                  j                  | |       t        j                  |t        j
                        | _        t        j                         | _        || j                  _	        t	        t        j                  j                  dt        j                  j                  |      d      d      }t        |j                         | j                         |j                          y )NrZ   r[   r\   )r   	HidDevice__init__r]   rc   O_RDWRri   rd   r:   ra   rb   basenamer@   re   rf   )selfra   rl   s      r   rq   zLinuxHidDevice.__init__   s    NND$'wwtRYY'DH%%'DIDIIN277<< 3 " 0 0 6 :<=ACG ',,.$))4MMOr   c                 .    | j                   j                  S See base class.)r:   r0   rt   s    r   GetInReportDataLengthz$LinuxHidDevice.GetInReportDataLength   s    99///r   c                 .    | j                   j                  S rv   )r:   r2   rx   s    r   GetOutReportDataLengthz%LinuxHidDevice.GetOutReportDataLength   s    99000r   c                 b    t        dg|z         }t        j                  | j                  |       y)rw   r   N)r   r]   writeri   )rt   packetouts      r   WritezLinuxHidDevice.Write   s$    
QC&L
!CHHTXXsr   c                     t        j                  | j                  | j                               }t	        t        |            }|S rv   )r]   re   ri   ry   listr   )rt   raw_in
decoded_ins      r   ReadzLinuxHidDevice.Read   s4    WWTXXt99;<Fi'(Jr   N)r(   r)   r*   __doc__staticmethodrn   rq   ry   r{   r   r   r+   r   r   rX   rX      s4        0	01
r   rX   )r   
__future__r   r]   r   pyu2fr   	pyu2f.hidr   r-   r   r1   r.   r3   r6   r7   r8   r9   r   r%   	Exceptionr'   r@   rV   rp   rX   r+   r   r   <module>r      s{     J  	   !  

%)P" <~%=T^^ =r   