
    }>                     f   S r SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSKrSSK	J
r
  SSKJr  \R                  " S5      rSrSrS	rS
rSrSrSrSrSrSr " S S\R2                  5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r \RB                  " \5      r"\RB                  " \5      r#\RB                  " \5      r$\RB                  " \5      r%\RL                  r'\RB                  " \ 5      r(\RR                  r*\RV                  r,\RZ                  r.\R^                  r0\R^                  r1\R^                  r2\R^                  r3\Rh                  r5\2r6\2r7\RB                  " \5      r8\RB                  " \5      r9\Rt                  " S\Rv                  \0\Rx                  \1\Rz                  \RB                  " \R|                  5      \,5      r?Sr@S rASrBS!rCSrDS"rESrFS#rGSrHS$rI\R                  R                  \R                  R                  S%5      5      rN\R                  R                  \R                  R                  S&5      5      rO\R                  R                  S'5      (       Gaj  \#R                  \OS(5      rSS\OR                  lU        \"\RB                  " \Rx                  5      /\OR                  lV        \#\OR                  lU        \Rx                  \Rh                  \Rz                  /\OR                  lV        \R                  \OR                  lU        \#\Rh                  \,\Rz                  /\OR                  lV        \,\OR                  lU        \#/\OR                  lV        \*\OR                  lU        \$/\OR                  lV        \*\OR                  lU        \R                  \OR                  lU        S\OR                  lU        \$/\OR                  lV        \%\OR                  lU        / \OR                  l`        \'\OR                  lU        \#\.\R                  /\OR                  lV        \2/\NR                  lV        \8\NR                  lU        \"\NR                  lU        \8/\NR                  lV        S\NR                  lU        \8\$/\NR                  lV        \$\NR                  lU        \9\#/\NR                  lV        S\NR                  lU        \9\RB                  " \R|                  5      \,\?\Rv                  /\NR                  lV        \7\NR                  lU        \3\5/\NR                  lV        \9\NR                  lU        \(\6/\NR                  lV        S\NR                  lU        \9\%\#/\NR                  lV        S\NR                  lU        \9\%\#/\NR                  lV        \0\NR                  lU        \9\1\,\RB                  " \R|                  5      \,/\NR                  lV        O\R                  S)5        S* roS+ rpS, rqS- rrS. rs\?" \s5      rtS/ ru " S0 S1\R                  5      rwg)2zDImplements HID device interface on MacOS using IOKit and HIDManager.    )queue)rangeN)errors)basezpyu2f.macosi   VendorId	ProductIDProductPrimaryUsagePrimaryUsagePageMaxInputReportSizeMaxOutputReportSizeReportIDc                       \ rS rSrSrg)_CFType-    N__name__
__module____qualname____firstlineno____static_attributes__r       *platform/bq/third_party/pyu2f/hid/macos.pyr   r   -       r   r   c                       \ rS rSrSrg)	_CFString1   r   Nr   r   r   r   r   r   1   r   r   r   c                       \ rS rSrSrg)_CFSet5   r   Nr   r   r   r   r    r    5   r   r   r    c                       \ rS rSrSrg)_IOHIDManager9   r   Nr   r   r   r   r#   r#   9   r   r   r#   c                       \ rS rSrSrg)_IOHIDDevice=   r   Nr   r   r   r   r&   r&   =   r   r   r&   c                       \ rS rSrSrg)
_CFRunLoopA   r   Nr   r   r   r   r)   r)   A   r   r   r)   c                       \ rS rSrSrg)_CFAllocatorE   r   Nr   r   r   r   r,   r,   E   r   r   r,      i  s	   IOService         IOKitCoreFoundationdarwinkCFRunLoopDefaultModezNot running on MacOSc                 L    [         R                  SU R                  5       S5      $ )zBuilds a CFString from a python string.

Args:
  s: source string

Returns:
  CFStringRef representation of the source string

Resulting CFString must be CFReleased when no longer needed.
Nr   )cfCFStringCreateWithCStringencode)ss    r   CFStrr;      s     
	%	%dAHHJ	::r   c                    [        U5      n[        R                  X5      n[        R	                  U5        U(       d  g[        R                  U5      [        R                  5       :w  a8  [        R                  " SR                  [        R                  U5      5      5      e[        R                  " 5       n[        R                  U[        [        R                  " U5      5      nU(       d  gUR                  $ )z'Reads int property from the HID device.NzExpected number type, got {})r;   iokitIOHIDDeviceGetPropertyr7   	CFReleaseCFGetTypeIDCFNumberGetTypeIDr   
OsHidErrorformatctypesc_int32CFNumberGetValueK_CF_NUMBER_SINT32_TYPEbyrefvaluedev_refkeycf_keytype_refoutrets         r   GetDeviceIntPropertyrQ      s    :&))':(,,v	^^H!5!5!77


:AA
x " # # 	#
H&="LL-	/#		r   c                 0   [        U5      n[        R                  X5      n[        R	                  U5        U(       d  g[        R                  U5      [        R                  5       :w  a8  [        R                  " SR                  [        R                  U5      5      5      e[        R                  " U[        5      n[        R                  " [        5      n[        R                  X4[        [         5      nU(       d  gUR"                  R%                  S5      $ )z*Reads string property from the HID device.NzExpected string type, got {}utf8)r;   r=   r>   r7   r?   r@   CFStringGetTypeIDr   rB   rC   rD   castCF_STRING_REFcreate_string_buffer"DEVICE_STRING_PROPERTY_BUFFER_SIZECFStringGetCStringK_CF_STRING_ENCODING_UTF8rI   decoderJ   s         r   GetDeviceStringPropertyr\      s    :&))':(,,v	^^H!5!5!77


:AA
x " # # [[=1(##$FG#
h-O7	9#				&	!!r   c                     [         R                  U 5      n[        R                  " [        5      n[         R                  U[        U5        UR                  $ )zObtains the unique path for the device.

Args:
  device_handle: reference to the device

Returns:
  A unique path for the device, obtained from the IO Registry

)r=   IOHIDDeviceGetServicerD   rW   DEVICE_PATH_BUFFER_SIZEIORegistryEntryGetPathK_IO_SERVICE_PLANErI   )device_handleio_service_obj
str_buffers      r   GetDevicePathre      sD     ..}=.**+BC*~/A:N			r   c                 r    AAAA[        U5       Vs/ s H  ouU   PM	     nnU R                  U5        gs  snf )z+Handles incoming IN report from HID device.N)r   put)	
read_queueresultsenderreport_type	report_idreportreport_lengthiincoming_bytess	            r   HidReadCallbackrq      s;     fk9',]';<';!1I';.<..  =s   4c                    [         R                  5       U l        U R                  (       d  [        R	                  S5        g[
        R                  U R                  U R                  [        5        [        nU[        :X  d
  U[        :X  a3  [         R                  [        SS5      nU[        :X  a  M'  U[        :X  a  M3  U[        :w  a  [        R	                  SU5        [
        R                  U R                  U R                  [        5        g)zBinds a device to the thread's run loop, then starts the run loop.

Args:
  hid_device: The MacOsHidDevice object

The HID manager requires a run loop to handle Report reads. This thread
function serves that purpose.
zFailed to get current run loopNi  Fz!Unexpected run loop exit code: %d)r7   CFRunLoopGetCurrentrun_loop_refloggererrorr=   IOHIDDeviceScheduleWithRunLooprb   K_CF_RUNLOOP_DEFAULT_MODEK_CF_RUN_LOOP_RUN_TIMED_OUT K_CF_RUN_LOOP_RUN_HANDLED_SOURCECFRunLoopRunInModeK_CF_RUN_LOOP_RUN_STOPPED IOHIDDeviceUnscheduleFromRunLoop)
hid_devicerun_loop_run_results     r   DeviceReadThreadr     s     224*		 	 
LL12
&&z'?'?'1'>'>'@B
 4	 ;	;	 @	@//! 
 ;	;	 @	@ 55
LL46IJ (()A)A)3)@)@)BDr   c                   L    \ rS rSrSr\S 5       rS rS rS r	S r
S rS	 rS
rg)MacOsHidDevicei4  z]Implementation of HID device for MacOS.

Uses IOKit HID Manager to interact with the device.
c                  Z   [         R                  SS5      n U (       d  [        R                  " S5      e[         R	                  U S5        [         R                  U 5      nU(       d  [        R                  " S5      e[         R                  U5      n[        U-  " 5       n[         R                  X5        / nU H  n[        R                  " 5       n[        U[        5      Ul        [        U[        5      Ul        [!        U["        5      Ul        [        U[&        5      Ul        [        U[*        5      Ul        [        U[.        5      Ul        [3        U5      Ul        UR7                  UR9                  5       5        M     [:        R=                  U5        [:        R=                  U 5        U$ )See base class.Nz&Unable to obtain HID manager referencez)Failed to obtain devices from HID manager)r=   IOHIDManagerCreater   rB   IOHIDManagerSetDeviceMatchingIOHIDManagerCopyDevicesCFSetGetCountIO_HID_DEVICE_REFCFSetGetValuesr   DeviceDescriptorrQ   HID_DEVICE_PROPERTY_VENDOR_ID	vendor_idHID_DEVICE_PROPERTY_PRODUCT_ID
product_idr\   HID_DEVICE_PROPERTY_PRODUCTproduct_string!HID_DEVICE_PROPERTY_PRIMARY_USAGEusage&HID_DEVICE_PROPERTY_PRIMARY_USAGE_PAGE
usage_pageHID_DEVICE_PROPERTY_REPORT_IDrl   re   pathappendToPublicDictr7   r?   )hid_mgrdevice_set_refnumdevicesdescriptorsdevds          r   	EnumerateMacOsHidDevice.Enumerate:  sN    &&tT2GFGG	''6 227;NIJJ


n
-C 3&)G	1 K



!a(.KLak)#/MNal01LNa$S*KLag)
57al(.KLakS!af)*  LL LLr   c           	         [         R                  [        U5      nU(       d  [        R                  " S5      e[         R                  [        U5      U l        U R                  (       d  [        R                  " S5      e[         R                  U5        Xl	        [         R                  U R                  S5      nU[        :w  a%  [        R                  " SR                  U5      5      e[        R                  " 5       U l        S U l        ["        R$                  " [&        U 4S9U l        SU R(                  l        U R(                  R-                  5         [/        U R                  [0        5      U l        U R2                  (       d  [        R                  " S5      e[/        U R                  [4        5      U l        U R6                  (       d  [        R                  " S5      e[8        R:                  U R2                  -  " 5       U l        [         R?                  U R                  U R<                  U R2                  [@        [8        RB                  " U R                  5      5        g )	Nz7Device path does not match any HID device on the systemz2Failed to obtain device handle from registry entryr   z+Failed to open device for communication: {})targetargsTz#Unable to obtain max in report sizez$Unable to obtain max out report size)"r=   IORegistryEntryFromPathK_IO_MASTER_PORT_DEFAULTr   rB   IOHIDDeviceCreateK_CF_ALLOCATOR_DEFAULTrb   IOObjectReleasedevice_pathIOHIDDeviceOpenK_IO_RETURN_SUCCESSrC   r   Queuerh   rt   	threadingThreadr   read_threaddaemonstartrQ   )HID_DEVICE_PROPERTY_MAX_INPUT_REPORT_SIZEinternal_max_in_report_len*HID_DEVICE_PROPERTY_MAX_OUTPUT_REPORT_SIZEinternal_max_out_report_lenrD   c_uint8in_report_buffer&IOHIDDeviceRegisterInputReportCallbackREGISTERED_READ_CALLBACK	py_object)selfr   device_entryri   s       r   __init__MacOsHidDevice.__init__a  s   001I4PL + , , 001G1=?D & ' '	,' ""4#5#5q9F$$K%vf~/ / kkmDO D ''/?.2W6D"D ';1'3D# **CDD';2(4D$ ++DEE $^^d.M.MMPD	00'' )+r   c                     U R                   $ r   )r   r   s    r   GetInReportDataLength$MacOsHidDevice.GetInReportDataLength  s    ***r   c                     U R                   $ r   )r   r   s    r   GetOutReportDataLength%MacOsHidDevice.GetOutReportDataLength  s    +++r   c                     Sn[         R                  U R                  -  " 5       nUSS USS& [        R	                  U R
                  [        UUU R                  5      nU[        :w  a  [        R                  " S5      eg)r   r   Nz Failed to write report to device)
rD   r   r   r=   IOHIDDeviceSetReportrb   K_IO_HID_REPORT_TYPE_OUTPUTr   r   rB   )r   packetrl   out_report_bufferri   s        r   WriteMacOsHidDevice.Write  s{    I$*J*JJM!!9a''(:(:(C(1(9(,(H(H	JF $$@AA %r   c                     SnUc   U R                   R                  SS9nUc  M  U$ ! [        R                   a     M;  f = f)r   N<   )timeout)rh   getr   Empty)r   ri   s     r   ReadMacOsHidDevice.Read  sP     F
.	__(((4F . M {{ 		s   ' ??c                 L   [        U S5      (       a7  [        R                  U R                  U R                  U R
                  S S 5        [        U S5      (       a  [        R                  U R                  5        [        U S5      (       a  U R                  R                  5         g g )Nr   rt   r   )hasattrr=   r   rb   r   r   r7   CFRunLoopStoprt   r   joinr   s    r   __del__MacOsHidDevice.__del__  s    t'((44!!++	 t^$$
**+ t]## $r   )rb   r   r   r   r   rh   r   rt   N)r   r   r   r   __doc__staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r   4  s<    
 $ $L4+l+,B 
 r   r   )xr   	six.movesr   r   rD   ctypes.utilloggingsysr   pyu2fr   	pyu2f.hidr   	getLoggerru   r_   rX   r   r   r   r   r   r   r   r   	Structurer   r   r    r#   r&   r)   r,   POINTER
CF_SET_REFrV   CF_TYPE_REFCF_RUN_LOOP_REFrE   CF_RUN_LOOP_RUN_RESULTCF_ALLOCATOR_REFc_ulong
CF_TYPE_IDc_longCF_INDEXc_doubleCF_TIME_INTERVALc_uint	IO_RETURNIO_HID_REPORT_TYPEIO_OBJECT_TMACH_PORT_Tc_char_pIO_STRING_TIO_SERVICE_TIO_REGISTRY_ENTRY_TIO_HID_MANAGER_REFr   	CFUNCTYPEr   c_void_pc_uint32r   IO_HID_REPORT_CALLBACKrG   rZ   r   ra   r   r   r   r|   ry   rz   cdllLoadLibraryutilfind_libraryr=   r7   platform
startswithin_dllrx   r   restypeargtypesr8   c_intrY   CFStringGetLengthr@   rA   rF   r?   rs   argTypesr{   c_boolr   r   r   r   r>   r   r   r   rw   r}   r   warningr;   rQ   r\   re   rq   r   r   	HidDevicer   r   r   r   <module>r     s    K      
   			=	)  %( " * !, ' $2 !); &,@ )-B * * f  W G 7  7 
 ^^F#
y)nnW%.., >>,/ ^^
==?? MM	]] mmmmoo! ^^M2 NN<0 ))$0@0@)*0//;M*0//*0..*H*2	4   &  !      #$   	 8 8 AB[[V[[556FGH <<8$$+2227NO #" *FNN6??,KL")6"&+1??FOO+1??+<"'"(,,"$16??H$*OO$5" !)"#0/"%"..(M"..!+" &"",,&-",,#2" $&"!"8"$13C$*MM$3"  %0=% %7%"*4%',>+?%(04%%%-2D2=2?%%%.)4%&+<m*L%'9=%..67f..;0%..7 +>%',7+E%($5%!&6%E%"15%&&.3D3B3@3B%&&/ 48%((05F5D5B5D%((1 (1%$):<N)1)/)G)1)3%%
 	..'(;*",$! 2/B $DNW T^^ W r   