
    |e"                        d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZmZ dd	lmZmZmZmZ  ej        e          Zd
edefdZdedefdZdede fdZ!dede fdZ" G d de          Z#dS )a   This registry can read data from LAN devices and send commands to them.
For non DIY devices data will be encrypted with devicekey. The registry cannot
decode such messages by itself because it does not manage the list of known
devices and their devicekey.
    N)AES)MD5)get_random_bytes)ZeroconfServiceStateChange)AsyncServiceBrowserAsyncServiceInfo   )SIGNAL_CONNECTEDSIGNAL_UPDATEXDeviceXRegistryBasedata_to_pad
block_sizec                 \    |t          |           |z  z
  }t          |g          |z  }| |z   S N)lenbytes)r   r   padding_lenpaddings       6/config/custom_components/sonoff/core/ewelink/local.pypadr      s8    s;//*<<K[M""[0G      padded_datac                 (    | d         }| d |          S )N )r   r   r   s      r   unpadr   #   s    b/K}}%%r   payload	devicekeyc                 r   |                     d          }t          j                    }|                    |           |                                }t          d          }t          j        | d                                        d          }t          j        |t          j	        |          }t          |t          j                  }|                    |          }d| d<   t          j        |                              d          | d<   t          j        |                              d          | d<   | S )Nutf-8   dataivTencryptr&   )encoder   newupdatedigestr   jsondumpsr   MODE_CBCr   r   r'   base64	b64encodedecode)	r   r    hash_keyr&   	plaintextcipherpadded
ciphertexts	            r   r'   r'   (   s      ))IGIIE	LL
,,..C	"		B
76?++227;;IWS#,2...FCN++F''JGI&z2299'BBGFO$R((//88GDMNr   c                    |                     d          }t          j                    }|                    |           |                                }t          j        |t
          j        t          j        | d                             }t          j        | d                   }|	                    |          }t          |t
          j                  S )Nr"   r&   r%   r$   )r(   r   r)   r*   r+   r   r.   r/   	b64decodedecryptr   r   )r   r    r2   r3   r5   r7   r6   s          r   r:   r:   =   s      ))IGIIE	LL
,,..CWS#,6+;GDM+J+JKKKF!'&/22J^^J''F(((r   c                       e Zd ZU dZeed<   dZeed<   defdZ	d Z
deded	ed
efdZdeded	efdZdededefdZ	 	 	 	 ddededededef
dZeddededefd            ZdS )XRegistryLocalNbrowserFonlinezeroconfc                     t          |d| j        g          | _        d| _        |                     t
                     d S )Nz_ewelink._tcp.local.T)r   	_handler1r=   r>   dispatcher_sendr   )selfr?   s     r   startzXRegistryLocal.startN   sD    *,t~.>
 
 -.....r   c                 h   K   | j         sd S d| _         | j                                         d {V  d S )NF)r>   r=   async_cancel)rC   s    r   stopzXRegistryLocal.stopU   sH      { 	Fl'')))))))))))r   service_typenamestate_changec                 |    |t           j        k    rdS t          j        |                     |||                     dS )z+Step 1. Receive change event from zeroconf.N)r   Removedasynciocreate_task	_handler2)rC   r?   rH   rI   rJ   s        r   rA   zXRegistryLocal._handler1[   s?     -555FDNN8\4HHIIIIIr   c                 l  K   |dd         }	 t          ||          }|                    |d           d{V r|j        st                              | d           dS |j        D ]9}t          j        |          }|j        r| d|j         nt          |          } n"|j
        r|j        r|j
         d|j         }nd}d |j                                        D             }|                     |||           dS # t          $ r*}	t                              | d|		           Y d}	~	dS d}	~	ww xY w)
zGStep 2. Request additional info about add and update event from device.      i  Nz$ <= Local0 | Can't get zeroconf info:c                     i | ]C\  }}|                                 t          |t                    r|                                 n|DS r   )r1   
isinstancer   ).0kvs      r   
<dictcomp>z,XRegistryLocal._handler2.<locals>.<dictcomp>}   sQ       Aq 

*Q*>*>EAHHJJJA  r   z <= Local0 | Zeroconf errorexc_info)r	   async_request
properties_LOGGERdebug	addresses	ipaddressIPv4Addressportstrserveritems	_handler3	Exception)
rC   r?   rH   rI   deviceidinfoaddrhostr$   es
             r   rO   zXRegistryLocal._handler2h   s     ":	P#L$77D++Hd;;;;;;;; 4? OOOPPP  	  	  ,T2204	H$,,,,,s4yy;  49  "k77DI77DDD  O1133  D
 NN8T400000 	P 	P 	PMMXBBBQMOOOOOOOOO	Ps   AC?  BC? ?
D3	D..D3ri   rl   r$   c                 r   d                     fdt          ddd          D                       }|d         d                             d          d}|r||d	<                       d
          r||d<   d         |d<   nt          j        |          |d<   |                     t          |           dS )z%Step 3. Process new data from device. c                 4    g | ]}d | v 	d |          S )r$   r   )rV   ir$   s     r   
<listcomp>z,XRegistryLocal._handler3.<locals>.<listcomp>   s5    VVVA:!::QUCUCUtJ1JJ'CUCUCUr   r
      idtypeseq)ri   subdevid	localtyperv   rl   r'   r$   r&   paramsN)joinrangegetr,   loadsrB   r   )rC   ri   rl   r$   rawmsgs      `  r   rg   zXRegistryLocal._handler3   s     ggVVVVq!QVVVWW !T
f88E??	
 
  	CK88I 	,CKT
CII JsOOCM]C00000r   rs   devicery   commandsequencetimeoutc                 b  K   | |dS t          t          |                    }|p|                                 |d         d|pi d}d|v rt          ||d                   }|d          d|                    dd           d	| }	 |d         }d
|vr|dz  }| j                            d| d| |ddi|           d {V }		 |	                                 d {V }
|
d         dk    rt          	                    | d|
            d|
v rc|d         |d         |
d         |
d         |
d         d}|r |                    d          r|d         |d<   | 
                    t          |           dS t          	                    | d|
            dS # t          $ r*}t          	                    | d|            Y d }~dS d }~ww xY w# t          j        $ r# t          	                    | d|            Y dS t          j        $ r*}t          	                    | d|            Y d }~d S d }~wt          j        t          j        t          j        f$ r'}t          	                    ||!           Y d }~d"S d }~wt          $ r'}t                              ||!           Y d }~d#S d }~ww xY w)$Nnoqueryri   123)r   ri   
selfApikeyr$   r    z => Local4 | rl   ro   z | rS   z:8081zhttp://z
/zeroconf/
Connectionclose)r,   headersr   errorr   z <= r&   rx   rv   r$   )ri   rx   rv   r$   r&   subDevIdrw   r>   z !! Can't read JSON z !! Timeout r   z !! Can't connect: zE#CONrZ   zE#COSzE#???)nextiterr   r'   r|   sessionpostr,   r^   r_   rB   r   rh   rM   TimeoutErroraiohttpClientConnectorErrorClientOSErrorServerDisconnectedErrorCancelledErrorr   )rC   r   ry   r   r   r   r   logrl   rrespr   rm   s                r   sendzXRegistryLocal.send   s      ?~ y4<<((G !3DMMOOz*Lb	
 
 &  gvk':;;G
#UU&**VR2H2HUUVUU:	&>D$ l''3$33'33%w/	 (        A#$6688^^^^^^=A%%MMS"4"4d"4"4555t||(.z(:)/)<#';$(L"&t*  " Afjj&<&< A.4Z.@C
O,,]C@@@#8 MMS"4"4d"4"4555"7   ==!==>>>wwwww # 	 	 	MMS77g7788899+ 	 	 	MMS88Q8899977777 !+"
 	 	 	
 MM#M***77777 	 	 	MM#M***77777	sa   =G B,F 3F 
GG=G GG .J.<J.
H//)J.I::J.J))J.r   r    returnc                     t          | |          }|r+|                    d          r|                    dd          }t          j        |          S )Ns   {"rfs   "="s   ":")r:   
startswithreplacer,   r}   )r   r    r$   s      r   decrypt_msgzXRegistryLocal.decrypt_msg   sO    sI&& 	0DOOG,, 	0<<//Dz$r   )NNNrs   r   )__name__
__module____qualname__r=   r   __annotations__r>   boolr   rD   rG   rd   r   rA   rO   dictrg   r   intr   staticmethodr   r   r   r   r<   r<   J   s        #'G '''FD/h / / / /* * *JJ J 	J
 )J J J JP P P3 P P P P>1# 1S 1 1 1 1 14 V VV V 	V
 V V V V Vp      #         \     r   r<   )$__doc__rM   r/   ra   r,   loggingr   Crypto.Cipherr   Crypto.Hashr   Crypto.Randomr   r?   r   r   zeroconf.asyncior   r	   baser   r   r   r   	getLoggerr   r^   r   r   r   r   r   rd   r'   r:   r<   r   r   r   <module>r      s   
                      * * * * * * 1 1 1 1 1 1 1 1 B B B B B B B B I I I I I I I I I I I I
'
H
%
%!U ! ! ! ! !&u &# & & & &
T c    *
)T 
)c 
) 
) 
) 
)r  r  r  r  r ] r  r  r  r  r r   