a
    kÄ#dÃ  ã                   @   sd  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mZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZ d dlm  mZ d dlmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 d d	l1m2Z2 d d
l3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9m:Z:m;Z;m<Z< d dl=m>Z> d dl?m@Z@ d dlAmBZB d dlCmDZD d dlET ejF�rˆd dlGmHZH nd dlGmIZI eIddi ƒZHeddeJfdeKfdeJfdeJfdeJfgƒZLG dd„ de4eHƒZMG dd„ deMe7ƒZNG dd „ d eMe7ƒZOG d!d"„ d"eMƒZPG d#d$„ d$eMƒZQG d%d&„ d&eMƒZRG d'd(„ d(eMƒZSG d)d*„ d*eMƒZTG d+d,„ d,eBƒZUG d-d.„ d.eTƒZVG d/d0„ d0eMƒZWG d1d2„ d2eBƒZXG d3d4„ d4eMƒZYG d5d6„ d6eYe<ƒZZG d7d8„ d8eMƒZ[G d9d:„ d:e[ƒZ\G d;d<„ d<eBƒZ]G d=d>„ d>eMƒZ^G d?d@„ d@eMƒZ_G dAdB„ dBe_ƒZ`G dCdD„ dDe_ƒZaG dEdF„ dFeBƒZbG dGdH„ dHeMƒZcG dIdJ„ dJeMƒZdG dKdL„ dLeDƒZedS )Mé    N)Údefaultdict)ÚSequence)ÚDictÚOptionalÚListÚTypeÚAnyÚIterableÚcastÚUnionÚ
NamedTupleÚorbÚSet)Úlog_automotive)ÚRawÚPacket)ÚScapy_Exception)ÚUDSÚUDS_NRÚUDS_DSCÚUDS_TPÚUDS_RDBIÚUDS_WDBIÚUDS_SAÚUDS_RCÚ	UDS_IOCBIÚUDS_RMBAÚUDS_ERÚUDS_TesterPresentSenderÚUDS_CCÚ	UDS_RDBPIÚUDS_RDÚUDS_TD)ÚEcuState)ÚServiceEnumeratorÚ_AutomotiveTestCaseScanResultÚ%_AutomotiveTestCaseFilteredScanResultÚ StateGeneratingServiceEnumerator)ÚAutomotiveTestCaseABCÚ_SocketUnionÚ_TransitionTupleÚStateGenerator)Ú'AutomotiveTestCaseExecutorConfiguration)Ú_Edge)ÚStagedAutomotiveTestCase)ÚAutomotiveTestCaseExecutor)Ú*)ÚABC)ÚABCMetar1   © Ú_PointOfInterestZmemory_addressÚ	directionÚmemorySizeLenÚmemoryAddressLenZ
memorySizec                   @   s8   e Zd Zedd„ ƒZedd„ ƒZdd„ Zedd„ ƒZd	S )
ÚUDS_Enumeratorc                 C   s   | j S ©N©ÚnegativeResponseCode)Úrespr3   r3   úX/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/automotive/uds_scan.pyÚ_get_negative_response_code?   s    z*UDS_Enumerator._get_negative_response_codec                 C   s   t | d� d¡S )Nr:   z%UDS_NR.negativeResponseCode%)r   Úsprintf)Znrcr3   r3   r=   Ú_get_negative_response_descD   s    
ÿz*UDS_Enumerator._get_negative_response_descc                 C   s   |   |d d¡S )Né   zPR: Supported©Ú
_get_label©ÚselfÚtupr3   r3   r=   Ú_get_table_entry_zJ   s    z!UDS_Enumerator._get_table_entry_zc                 C   s
   |   d¡S )Nz!NR: %UDS_NR.negativeResponseCode%)r?   )Úresponser3   r3   r=   Ú_get_negative_response_labelN   s    z+UDS_Enumerator._get_negative_response_labelN)Ú__name__Ú
__module__Ú__qualname__Ústaticmethodr>   r@   rG   rI   r3   r3   r3   r=   r8   >   s   

r8   c                       sª   e Zd ZdZe ej¡Ze edd„ fe	dfdœ¡ e
eefdd„ fed< ejd Zd	d
„ Z‡ fdd„Zee_dd„ Zedd„ ƒZ‡ fdd„Zedd„ ƒZdd„ Z‡  ZS )ÚUDS_DSCEnumeratorzAvailable sessionsc                 C   s   | dkS )Nr   r3   ©Úxr3   r3   r=   Ú<lambda>X   ó    zUDS_DSCEnumerator.<lambda>N)Údelay_state_changeÚoverwrite_timeoutc                 C   s   t | ƒdk ot| ƒdkS ©Né   r   ©ÚmaxÚminrO   r3   r3   r=   rQ   \   rR   Ú
scan_rangeaë  
        :param int delay_state_change: Specifies an additional delay after
                                       after a session is modified from
                                       the transition function. In unit-test
                                       scenarios, this delay should be set to
                                       zero.
        :param bool overwrite_timeout: True by default. This enumerator
                                       overwrites the timeout argument, since
                                       most ECUs take some time until a session
                                       is changed. This ensures that more
                                       results are gathered by default. In
                                       unit-test scenarios, this value should
                                       be set to False, in order to use the
                                       timeout specified by the 'timeout'
                                       argument.c                 K   s"   |  dtddƒ¡}tƒ t|d� S )NrZ   rA   rV   )ÚdiagnosticSessionType)ÚpopÚranger   r   )rE   ÚkwargsZsession_ranger3   r3   r=   Ú_get_initial_requestsn   s    z'UDS_DSCEnumerator._get_initial_requestsc                    sB   d|d< d|d< |  dd¡r$d|d< tt| ƒj||fi |¤Ž d S )NFÚexit_if_service_not_supportedZretry_if_busy_returncoderT   Té   Útimeout)r\   ÚsuperrN   Úexecute©rE   ÚsocketÚstater^   ©Ú	__class__r3   r=   rd   s   s
    zUDS_DSCEnumerator.executec                 C   s   d|d j |d  d¡f S )Nú
0x%02x: %sé   z%UDS_DSC.diagnosticSessionType%)r[   r?   rD   r3   r3   r=   Ú_get_table_entry_yƒ   s    þz$UDS_DSCEnumerator._get_table_entry_yc                 C   sz   z|t j d }W n ty(   d}Y n0 | j||dd�}|d urr|jrbt dt|ƒt|ƒf ¡ tt	|j
ƒdkS dS d S )Nrb   ra   F©rb   Úverbosez&Try to enter session req: %s, resp: %sé   )rN   rJ   ÚKeyErrorÚsr1rn   r   ÚdebugÚreprr
   ÚintÚservice)rf   ÚconfigurationÚrequestrb   Zansr3   r3   r=   Úenter_state‰   s    
ÿÿzUDS_DSCEnumerator.enter_statec                    s0   t t| ƒ ||¡}|r,|\}}d|_||fS d S ©Nrk   )rc   rN   Úget_new_edgeÚtp)rE   rf   ÚconfigÚedgerg   Ú	new_staterh   r3   r=   rz   œ   s    zUDS_DSCEnumerator.get_new_edgec                 C   sh   t  | ||¡ z|tj d }W n ty6   d}Y n0 t |¡ t | ||d ¡}|sdt  | |¡ |S )NrS   é   Úreq)	ÚUDS_TPEnumeratorÚenterrN   rJ   rp   ÚtimeÚsleeprx   Úcleanup)ÚsockÚconfr^   ÚdelayZstate_changedr3   r3   r=   Úenter_state_with_tp¨   s    


ÿz%UDS_DSCEnumerator.enter_state_with_tpc                 C   s*   t j| jd jd| jd jj dœtjfS )NéÿÿÿÿzDSC=%d)r€   Údesc)rN   r‰   Ú_resultsr€   r[   r�   r…   ©rE   rf   r}   r3   r3   r=   Úget_transition_function»   s    
þýz)UDS_DSCEnumerator.get_transition_function)rJ   rK   rL   Ú_descriptionÚcopyr$   Ú_supported_kwargsÚupdatert   ÚboolÚlistÚtupler]   Ú_supported_kwargs_docr_   rd   Ú__doc__rl   rM   rx   rz   r‰   rŽ   Ú__classcell__r3   r3   rh   r=   rN   T   s&   
þÿ


rN   c                   @   s@   e Zd ZdZdd„ Zdd„ Zedd„ ƒZedd	„ ƒZd
d„ Z	dS )r�   zTesterPresent supportedc                 K   s   t ƒ tƒ  gS r9   )r   r   ©rE   r^   r3   r3   r=   r_   Æ   s    z&UDS_TPEnumerator._get_initial_requestsc                 C   s   dS )NzTesterPresent:r3   rD   r3   r3   r=   rl   Ê   s    z#UDS_TPEnumerator._get_table_entry_yc                 C   sR   |j r*d |d< | jtƒ tƒ  ddd� dS t | |¡ t| ƒ|d< |d  ¡  dS )NÚtpsgš™™™™™¹?Frm   T)Úunittestrq   r   r   r�   r…   r   Ústart)rf   rv   Ú_r3   r3   r=   r‚   Î   s    zUDS_TPEnumerator.enterc              
   C   sR   z|d   ¡  d |d< W n4 ttfyL } zt d|¡ W Y d }~n
d }~0 0 dS )Nrš   zCleanup TP-Sender Error: %sT)ÚstopÚAttributeErrorrp   r   rr   )r�   rv   Úer3   r3   r=   r…   Ý   s    "zUDS_TPEnumerator.cleanupc                 C   s   | j ddi| jfS )Nr‹   ZTP)r‚   r…   r�   r3   r3   r=   rŽ   ç   s    z(UDS_TPEnumerator.get_transition_functionN)
rJ   rK   rL   r�   r_   rl   rM   r‚   r…   rŽ   r3   r3   r3   r=   r�   Ã   s   

	r�   c                   @   sB   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	S )
ÚUDS_EREnumeratorzECUReset supportedc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ   ð   rR   zUDS_EREnumerator.<lambda>rZ   c                 K   s*   |  dtdƒ¡}ttt tƒ t|d� ƒS )NrZ   rV   )Ú	resetType)r\   r]   r
   r	   r   r   r   )rE   r^   Z
reset_typer3   r3   r=   r_   ò   s    z&UDS_EREnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nrj   rk   z%UDS_ER.resetType%)r¢   r?   rD   r3   r3   r=   rl   ÷   s    ÿz#UDS_EREnumerator._get_table_entry_yN©rJ   rK   rL   r�   r�   r$   r‘   r”   r•   r]   r_   rl   r3   r3   r3   r=   r¡   ì   s   ÿr¡   c                   @   sB   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	S )
ÚUDS_CCEnumeratorzCommunicationControl supportedc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ     rR   zUDS_CCEnumerator.<lambda>rZ   c                 K   s.   |  dtdƒ¡}ttt tƒ t|ddd� ƒS )NrZ   rV   rk   é   )ÚcontrolTypeZcommunicationType0ZcommunicationType2)r\   r]   r
   r	   r   r   r   )rE   r^   Zcontrol_typer3   r3   r=   r_     s
    þz&UDS_CCEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nrj   rk   z%UDS_CC.controlType%)r¦   r?   rD   r3   r3   r=   rl   
  s    ÿz#UDS_CCEnumerator._get_table_entry_yNr£   r3   r3   r3   r=   r¤   ý   s   ÿr¤   c                   @   sB   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	S )
ÚUDS_RDBPIEnumeratorz&ReadDataByPeriodicIdentifier supportedc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ     rR   zUDS_RDBPIEnumerator.<lambda>rZ   c                 K   s,   |  dtdƒ¡}ttt tƒ td|d� ƒS )NrZ   rV   rk   )ZtransmissionModeÚperiodicDataIdentifier)r\   r]   r
   r	   r   r   r    )rE   r^   Zpdidr3   r3   r=   r_     s    ÿz)UDS_RDBPIEnumerator._get_initial_requestsc                 C   sP   |d }|d ur0d|d j |d  d¡|jf S d|d j |d  d¡f S d S )NrA   z0x%02x %s: %srk   z"%UDS_RDBPI.periodicDataIdentifier%z0x%02x %s: No response)r¨   r?   Ú
dataRecord©rE   rF   r<   r3   r3   r=   rl     s    ýþz&UDS_RDBPIEnumerator._get_table_entry_yNr£   r3   r3   r3   r=   r§     s   ÿr§   c                       sR   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
‡ fdd„Zd	d
„ Z‡  ZS )ÚUDS_ServiceEnumeratorz2Available services and negative response per statec                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ   .  rR   zUDS_ServiceEnumerator.<lambda>rZ   c                 K   s(   |  ddd„ tdƒD ƒ¡}dd„ |D ƒS )NrZ   c                 s   s   | ]}|d @ s|V  qdS )é@   Nr3   ©Ú.0rP   r3   r3   r=   Ú	<genexpr>5  rR   z>UDS_ServiceEnumerator._get_initial_requests.<locals>.<genexpr>rV   c                 s   s   | ]}t |d �V  qdS ))ru   N)r   r­   r3   r3   r=   r¯   6  rR   ©r\   r]   ©rE   r^   rZ   r3   r3   r=   r_   0  s    ÿz+UDS_ServiceEnumerator._get_initial_requestsc                    s<   |r|j dkrt d¡ d|d< tt| ƒj|||fi |¤ŽS )NéQ   z[ECUResetPositiveResponse detected! This might have changed the state of the ECU under test.Fr`   )ru   r   Úwarningrc   r«   Ú_evaluate_response©rE   rg   rw   rH   r^   rh   r3   r=   r´   8  s    ÿ
ÿÿz(UDS_ServiceEnumerator._evaluate_responsec                 C   s   d|d j |d  d¡f S )Nrj   rk   z%UDS.service%)ru   r?   rD   r3   r3   r=   rl   I  s    z(UDS_ServiceEnumerator._get_table_entry_y)rJ   rK   rL   r�   r�   r$   r‘   r”   r•   r]   r_   r´   rl   r˜   r3   r3   rh   r=   r«   *  s   ÿr«   c                   @   sV   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
edd„ ƒZd	d
„ Zdd„ ZdS )ÚUDS_RDBIEnumeratorz"Readable data identifier per statec                 C   s   t | ƒdk ot| ƒdkS ©Né   r   rW   rO   r3   r3   r=   rQ   R  rR   zUDS_RDBIEnumerator.<lambda>rZ   c                 K   s   |  dtdƒ¡}dd„ |D ƒS )NrZ   r¸   c                 s   s    | ]}t ƒ t|gd � V  qdS ©)ÚidentifiersN©r   r   r­   r3   r3   r=   r¯   W  rR   z;UDS_RDBIEnumerator._get_initial_requests.<locals>.<genexpr>r°   r±   r3   r3   r=   r_   T  s    z(UDS_RDBIEnumerator._get_initial_requestsc                 C   s(   t | ƒdkrt| ƒdd … nd}d| S )Nra   zNo data availableúPR: %s)ÚlenÚbytes)r<   Úloadr3   r3   r=   Úprint_informationY  s     z$UDS_RDBIEnumerator.print_informationc                 C   s(   d|d j d |d  d¡dd… f S )Nú
0x%04x: %srk   r   z%UDS_RDBI.identifiers%rŠ   )rº   r?   rD   r3   r3   r=   rl   _  s    ÿz%UDS_RDBIEnumerator._get_table_entry_yc                 C   s   |   |d | j¡S )NrA   )rC   rÀ   rD   r3   r3   r=   rG   d  s    z%UDS_RDBIEnumerator._get_table_entry_zN)rJ   rK   rL   r�   r�   r$   r‘   r”   r•   r]   r_   rM   rÀ   rl   rG   r3   r3   r3   r=   r¶   N  s   ÿ
r¶   c                       s4   e Zd Zedd„ ƒZedd„ ƒZ‡ fdd„Z‡  ZS )ÚUDS_RDBISelectiveEnumeratorc                 C   s,   t t| ƒ} dd„ | jD ƒ}t |¡}d|iS )Nc                 S   s   g | ]}|j j‘qS r3   ©r<   ÚdataIdentifier)r®   Úpr3   r3   r=   Ú
<listcomp>p  s   ÿzFUDS_RDBISelectiveEnumerator.__connector_rnd_to_seq.<locals>.<listcomp>rZ   )r
   r8   Úresults_with_positive_responserÂ   Úpoints_to_blocks)Zrdbi_randomr�   Z"identifiers_with_positive_responserZ   r3   r3   r=   Z__connector_rnd_to_seqj  s    
ÿÿÿz2UDS_RDBISelectiveEnumerator.__connector_rnd_to_seqc                    st   t | ƒdkrg S tj}g }tdd|ƒD ]8‰ˆ| ‰ t‡ ‡fdd„| D ƒƒ}|r&| tˆˆ ƒ¡ q&ttj 	|¡ƒ}|S )Nr   r¸   c                 3   s&   | ]}ˆ|  koˆ k n  V  qd S r9   r3   )r®   Ú
identifier©Úendrœ   r3   r=   r¯   ƒ  s   ÿz?UDS_RDBISelectiveEnumerator.points_to_blocks.<locals>.<genexpr>)
r½   ÚUDS_RDBIRandomEnumeratorÚ
block_sizer]   ÚanyÚappendr”   Ú	itertoolsÚchainÚfrom_iterable)ÚpoisrÍ   Ú
generatorsZpr_in_blockrZ   r3   rÊ   r=   rÈ   w  s    ÿz,UDS_RDBISelectiveEnumerator.points_to_blocksc                    s$   t t| ƒ tƒ tƒ gd | jg¡ d S r9   )rc   rÂ   Ú__init__rÌ   r¶   Ú2_UDS_RDBISelectiveEnumerator__connector_rnd_to_seq©rE   rh   r3   r=   rÕ   Š  s    

þz$UDS_RDBISelectiveEnumerator.__init__)rJ   rK   rL   rM   rÖ   rÈ   rÕ   r˜   r3   r3   rh   r=   rÂ   i  s
   

rÂ   c                       sd   e Zd Ze ej¡Ze edd„ fedd„ fdœ¡ dZej	d Z	‡ fdd„Z
e	e
_d	d
„ Z‡  ZS )rÌ   c                 C   s   d|   kodkS   S ©Nr   éÿÿ  r3   rO   r3   r3   r=   rQ   ”  rR   z!UDS_RDBIRandomEnumerator.<lambda>c                 C   s   d|   kodkS   S rØ   r3   rO   r3   r3   r=   rQ   •  rR   )Úprobe_startÚ	probe_endr¬   z”
        :param int probe_start: Specifies the start identifier for probing.
        :param int probe_end: Specifies the end identifier for probing.c                    s   t t| ƒj||fi |¤Ž d S r9   )rc   rÌ   rd   re   rh   r3   r=   rd   �  s    z UDS_RDBIRandomEnumerator.executec              n   K   s‚  dddddddddd	d
ddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd ddddddd!œm}g }t j}| d"d#¡}| d$d%¡}t|||ƒ}t|ƒD ]4\}}	|	| }
| |d&¡}|t t|	|
ƒ|¡7 }�qd'd(„ | jD ƒ}||7 }t	t
t|ƒƒƒ}d)d*„ |D ƒS )+Né   é   é   é   é   é   é   é   é   é   é   r   é1   é6   é	   é
   é   é   ra   rA   é#   é   é   é   é   é)   r¥   é   é   é   é   é"   )mrã   r   rì   rë   ré   rê   rß   rö   rà   rá   rð   é   é   rÞ   ræ   é   rÝ   rô   rî   rõ   rï   rÜ   é    é$   é%   é(   rò   é*   é,   é/   é0   rç   é4   r¬   éB   éD   éE   éF   éG   éH   éI   éJ   éK   éL   éM   éN   r²   éX   éZ   é\   éa   éb   éd   ée   éf   ég   éj   él   é|   é€   éˆ   é‰   éŠ   é‹   é”   é–   é˜   é¨   é©   éª   é«   é¬   é°   é±   é²   é»   éè   éë   éð   éü   rV   i  i  i"  i<  i?  iC  iD  iF  iG  iJ  iK  iL  iN  iR  i@  iA  i„  i¼  i¾  iÄ  iÅ  iÆ  iÇ  iÌ  éè  iô  iõ  iö  rÚ   r   rÛ   r¸   rk   c                 S   s   g | ]}|j j‘qS r3   rÃ   ©r®   Útr3   r3   r=   rÆ   Å  rR   zBUDS_RDBIRandomEnumerator._get_initial_requests.<locals>.<listcomp>c                 s   s    | ]}t ƒ t|gd � V  qdS r¹   r»   r­   r3   r3   r=   r¯   Ì  rR   zAUDS_RDBIRandomEnumerator._get_initial_requests.<locals>.<genexpr>)rÌ   rÍ   r\   r]   Ú	enumerateÚgetÚrandomÚsamplerÇ   Úsortedr”   Úset)rE   r^   Zsamples_per_blockZto_scanrÍ   rÚ   rÛ   Zprobe_rangeZblock_indexrœ   rË   Zcount_samplesZpositive_identifiersr3   r3   r=   r_   £  s<    òÿz.UDS_RDBIRandomEnumerator._get_initial_requests)rJ   rK   rL   r�   r¶   r‘   r’   rt   rÍ   r–   rd   r—   r_   r˜   r3   r3   rh   r=   rÌ   ‘  s   

þ
rÌ   c                       s|   e Zd ZdZe ej¡Ze dedfi¡ e	e
efdd„ fed< ejd Z‡ fdd	„Zee_d
d„ Zdd„ Zdd„ Z‡  ZS )ÚUDS_WDBIEnumeratorz#Writeable data identifier per stateÚrdbi_enumeratorNc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ   Ö  rR   zUDS_WDBIEnumerator.<lambda>rZ   zõ
        :param rdbi_enumerator: Specifies an instance of an UDS_RDBIEnumerator
                                which is used to extract possible data
                                identifiers.
        :type rdbi_enumerator: UDS_RDBIEnumeratorc                    s   t t| ƒj||fi |¤Ž d S r9   )rc   r:  rd   re   rh   r3   r=   rd   Þ  s    zUDS_WDBIEnumerator.executec                 K   sl   |  dtdƒ¡}|  dd ¡}|d u r<t d¡ dd„ |D ƒS t|tƒr`t d¡ dd„ |jD ƒS td	ƒ‚d S )
NrZ   r¸   r;  zUse entire scan rangec                 s   s   | ]}t ƒ t|d � V  qdS ©©rÄ   N)r   r   r­   r3   r3   r=   r¯   ë  rR   z;UDS_WDBIEnumerator._get_initial_requests.<locals>.<genexpr>z$Selective scan based on RDBI resultsc                 s   sL   | ]D}t t|jƒƒd krtƒ t|jjd� tt|jƒd d… d� V  qdS )ra   r=  N)r¿   )r½   r¾   r<   r   r   rÄ   r   r2  r3   r3   r=   r¯   î  s
   ýÿz;rdbi_enumerator has to be an instance of UDS_RDBIEnumerator)r\   r]   r   rr   Ú
isinstancer¶   rÇ   r   )rE   r^   rZ   r;  r3   r3   r=   r_   ä  s    


þz(UDS_WDBIEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )NrÁ   rk   z%UDS_WDBI.dataIdentifier%)rÄ   r?   rD   r3   r3   r=   rl   ö  s    
ÿz%UDS_WDBIEnumerator._get_table_entry_yc                 C   s   |   |d d¡S )NrA   zPR: WriteablerB   rD   r3   r3   r=   rG   û  s    z%UDS_WDBIEnumerator._get_table_entry_z)rJ   rK   rL   r�   r�   r$   r‘   r’   r¶   r”   r•   r]   r–   rd   r—   r_   rl   rG   r˜   r3   r3   rh   r=   r:  Ï  s   ÿÿ
r:  c                       s(   e Zd Zedd„ ƒZ‡ fdd„Z‡  ZS )ÚUDS_WDBISelectiveEnumeratorc                 C   s   d| iS )Nr;  r3   )Zrdbir�   r3   r3   r=   Z__connector_rdbi_to_wdbi  s    z4UDS_WDBISelectiveEnumerator.__connector_rdbi_to_wdbic                    s$   t t| ƒ tƒ tƒ gd | jg¡ d S r9   )rc   r?  rÕ   r¶   r:  Ú4_UDS_WDBISelectiveEnumerator__connector_rdbi_to_wdbir×   rh   r3   r=   rÕ     s    

þz$UDS_WDBISelectiveEnumerator.__init__)rJ   rK   rL   rM   r@  rÕ   r˜   r3   r3   rh   r=   r?     s   
r?  c                       sˆ   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	d
„ Zdd„ Z‡ fdd„Z‡ fdd„Zeddd„ƒZedd„ ƒZ‡  ZS )ÚUDS_SAEnumeratorz3Available security seeds with access type and statec                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ     rR   zUDS_SAEnumerator.<lambda>rZ   c                 K   s"   |  dtdddƒ¡}dd„ |D ƒS )NrZ   rk   rV   rA   c                 s   s   | ]}t ƒ t|d � V  qdS )©ÚsecurityAccessTypeN)r   r   r­   r3   r3   r=   r¯     rR   z9UDS_SAEnumerator._get_initial_requests.<locals>.<genexpr>r°   r±   r3   r3   r=   r_     s    z&UDS_SAEnumerator._get_initial_requestsc                 C   s
   |d j S ry   rB  rD   r3   r3   r=   rl     s    z#UDS_SAEnumerator._get_table_entry_yc                 C   s   |   |d dd„ ¡S )NrA   c                 S   s
   d| j  S ©Nr¼   )ÚsecuritySeed©Úrr3   r3   r=   rQ     rR   z5UDS_SAEnumerator._get_table_entry_z.<locals>.<lambda>rB   rD   r3   r3   r=   rG     s    z#UDS_SAEnumerator._get_table_entry_zc                 C   s$   t t| ƒj| r |js t d¡ d S )Nrß   )r
   r$   Z
_retry_pktr›   rƒ   r„   )rE   rf   rg   Úglobal_configurationr3   r3   r=   Úpre_execute!  s    zUDS_SAEnumerator.pre_executec                    s^   t t| ƒj|||fi |¤Žr dS |jdkrZ|  |¡dv rZt dt|ƒ¡ t t| ƒ ||¡S dS )NTro   )rü   é7   zMRetry %s because requiredTimeDelayNotExpired or requestSequenceError receivedF)	rc   rA  Ú_evaluate_retryru   r>   r   rr   rs   Ú_populate_retryrµ   rh   r3   r=   rK  *  s"    
ÿÿ
ÿý
ÿz UDS_SAEnumerator._evaluate_retryc                    sR   t t| ƒj|||fi |¤Žr dS |d urN|jdkrN|jd dkrNt d¡ dS dS )NTr  rA   rk   z&Seed received. Leave scan to try a keyF)rc   rA  r´   ru   rC  r   rr   rµ   rh   r3   r=   r´   ?  s    
ÿÿÿþ
z#UDS_SAEnumerator._evaluate_responserk   rR   c                 C   s¤   t ƒ t||d� }tdƒD ]„}| j|ddd�}|d u r< d S |jdkrjt |¡dkrjt dt	|ƒ¡  d S |jdkr–|j
dkr–t d	¡ t d¡ qq|  S qd S )
N)rC  ZsecurityAccessDataRecordrê   r   Frm   ro   rJ  zSecurity access no seed! NR: %sz!Security access retry to get seed)r   r   r]   rq   ru   r8   r>   r   Úinfors   r;   rƒ   r„   )r†   ÚlevelÚrecordr€   r�   Úseedr3   r3   r=   Úget_seed_pktP  s(    ÿ
ÿÿ


zUDS_SAEnumerator.get_seed_pktc                 C   s\   | d u s| j dkrJt t|ƒ¡ t t|ƒ¡ t t| ƒ¡ t d¡ dS t d¡ dS d S )Nro   zSecurity access error!FzSecurity access granted!T)ru   r   rM  rs   )ÚresrP  Úkeyr3   r3   r=   Ú!evaluate_security_access_responseg  s    

z2UDS_SAEnumerator.evaluate_security_access_response)rk   rR   )rJ   rK   rL   r�   r�   r$   r‘   r”   r•   r]   r_   rl   rG   rI  rK  r´   rM   rQ  rT  r˜   r3   r3   rh   r=   rA    s   ÿ	rA  c                   @   sF   e Zd ZdZeƒ Zeddd„ƒZddd„Zdd	„ Z	d
d„ Z
dd„ ZdS )ÚUDS_SA_XOR_EnumeratorzXOR SecurityAccess supportedrk   c                 C   s°   dd„ }dd„ }z
| j }W n ty.   Y d S 0 d }d }t|ƒdkrLd}|}t|ƒdkr`d}|}|d ur¨|d ur¨t ||t ||¡d	 ƒ¡}tttƒ t	|d
 |d� ƒS d S d S )Nc                 S   s
   d|  @ S )Nì   ÿÿ r3   ©Úsr3   r3   r=   Úkey_function_int}  s    z;UDS_SA_XOR_Enumerator.get_key_pkt.<locals>.key_function_intc                 S   s
   d|  @ S )NrÙ   r3   rW  r3   r3   r=   Úkey_function_short�  s    z=UDS_SA_XOR_Enumerator.get_key_pkt.<locals>.key_function_shortrA   ÚHrã   ÚIr   rk   )rC  ZsecurityKey)
rE  rŸ   r½   ÚstructÚpackÚunpackr
   r   r   r   )rP  rN  rY  rZ  rX  ÚfmtZkey_functionrS  r3   r3   r=   Úget_key_pkty  s(    
ÿ
z!UDS_SA_XOR_Enumerator.get_key_pktNc           	      C   s  t  d| ¡ |d u r*|  ||¡}|s*dS t|jƒsFt  d| ¡ dS |  ||¡}|d u r^dS z,|j|ddd�}|jrˆt  d¡ t	dƒ‚W n€ t
tt	f�y
 } z`z2| jd	 j}| jd	 j}|  ||¡sÒt  d
¡ W n tyð   t  d¡ Y n0 |‚W Y d }~n
d }~0 0 |  |||¡S )Nz+Try bootloader security access for level %dFz-Security access for level %d already granted!Tr   rm   zSocket closed during scan.zSocket closed during scanrŠ   z#Exception during retry. This is badzCouldn't populate retry.)r   rM  rQ  rÎ   rE  ra  rq   ÚclosedÚcriticalr   ÚOSErrorÚ
ValueErrorrŒ   r€   rg   rL  Ú	exceptionÚ
IndexErrorr³   rT  )	rE   r†   rN  Zseed_pktZkey_pktrR  r    Zlast_seed_reqÚ
last_stater3   r3   r=   Úget_security_accessœ  sD    ÿ
ÿ
ÿÿz)UDS_SA_XOR_Enumerator.get_security_accessc                    sF   t jrt | j¡}nt | j¡}‡ fdd„|jD ƒ}| j|fi |¤ŽS )Nc                    s"   i | ]}|ˆ   ¡ v r|ˆ | “qS r3   )Úkeys)r®   Úk©r^   r3   r=   Ú
<dictcomp>È  rR   z=UDS_SA_XOR_Enumerator.transition_function.<locals>.<dictcomp>)ÚsixÚPY3ÚinspectÚgetfullargspecri  Ú
getargspecÚargs)rE   r†   r�   r^   ÚspecZfunc_kwargsr3   rl  r=   Útransition_functionÁ  s
    z)UDS_SA_XOR_Enumerator.transition_functionc           	      C   sÐ   | j d j}| j d j}|d u s*|jdkr.d S zŠ|jdksH|jd dkrNW d S |}|j}|  |||¡r¶t d¡ t |¡}|jd |_	||kr”W d S ||f}|d| dœ| j
|< |W S W n tyÊ   Y n0 d S )	NrŠ   ro   r  rA   rk   zSecurity Access found.zSA=%d)rN  r‹   )rŒ   r<   rg   ru   rC  ri  r   rr   r�   Zsecurity_levelÚ_transition_function_argsrŸ   )	rE   rf   r|   Z	last_resprh  rP  Zsec_lvlr~   r}   r3   r3   r=   rz   Ë  s0    
ÿ

ÿ
z"UDS_SA_XOR_Enumerator.get_new_edgec                 C   s   | j | j| d fS r9   )ru  rv  r�   r3   r3   r=   rŽ   ë  s    
ÿz-UDS_SA_XOR_Enumerator.get_transition_function)rk   )rk   N)rJ   rK   rL   r�   Údictrv  rM   ra  ri  ru  rz   rŽ   r3   r3   r3   r=   rU  u  s   "
%
 rU  c                   @   sb   e Zd ZdZe ej¡Ze dedd„ fi¡ ee	e
fdd„ fed< ejd Zdd	„ Zd
d„ ZdS )ÚUDS_RCEnumeratorú9Available RoutineControls and negative response per stateÚ	type_listc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ   õ  rR   zUDS_RCEnumerator.<lambda>c                 C   s   t | ƒdk ot| ƒdkS r·   rW   rO   r3   r3   r=   rQ   ø  rR   rZ   zµ
        :param list type_list: A list of RoutineControlTypes which should
                               be enumerated. Possible values = [1, 2, 3].
                               c                 K   s6   |  dg d¢¡}|  dtdƒ¡}dd„ t ||¡D ƒS )Nrz  )rk   rA   ra   rZ   r¸   c                 s   s$   | ]\}}t ƒ t||d � V  qdS ))ÚroutineControlTypeÚroutineIdentifierN)r   r   )r®   Zrc_typeZdata_idr3   r3   r=   r¯     s   þÿz9UDS_RCEnumerator._get_initial_requests.<locals>.<genexpr>)r\   r]   rÐ   Úproduct)rE   r^   rz  rZ   r3   r3   r=   r_   ÿ  s
    
ýz&UDS_RCEnumerator._get_initial_requestsc                 C   s$   d|d j |d j|d  d¡f S )Nz0x%04x-%d: %srk   z%UDS_RC.routineIdentifier%)r|  r{  r?   rD   r3   r3   r=   rl   
  s    þz#UDS_RCEnumerator._get_table_entry_yN)rJ   rK   rL   r�   r�   r$   r‘   r’   r”   r•   r]   r–   r_   rl   r3   r3   r3   r=   rx  ñ  s   ÿÿ
rx  c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚUDS_RCStartEnumeratorry  c                    s0   d|v rt dƒ‚dg|d< tt| ƒjf i |¤ŽS )Nrz  z"'type_list' already set in kwargs.rk   )rp   rc   r~  r_   r™   rh   r3   r=   r_     s    
ÿz+UDS_RCStartEnumerator._get_initial_requests)rJ   rK   rL   r�   r_   r˜   r3   r3   rh   r=   r~    s   r~  c                       s8   e Zd ZdZedd„ ƒZedd„ ƒZ‡ fdd„Z‡  ZS )ÚUDS_RCSelectiveEnumeratoréý   c                 C   s\   t j}g }| D ]4}t|| dƒ}t|| d dƒ}| t||ƒ¡ qtj |¡}t	t
|ƒƒS )Nr   rk   r¸   )r  Úexpansion_widthrX   rY   rÏ   r]   rÐ   rÑ   rÒ   r8  r9  )rÓ   r�  rÔ   rÉ   rœ   rË   Zranges_with_overlapsr3   r3   r=   Úpoints_to_ranges"  s    z*UDS_RCSelectiveEnumerator.points_to_rangesc                 C   s2   t t| ƒ} dd„ | jD ƒ}t |¡}ddg|dœS )Nc                 S   s   g | ]\}}}}}|j ‘qS r3   )r|  )r®   r�   r<   r3   r3   r=   rÆ   2  rR   zGUDS_RCSelectiveEnumerator.__connector_start_to_rest.<locals>.<listcomp>rA   ra   )rz  rZ   )r
   r8   rÇ   r  r‚  )Zrc_startZ_rc_stopZidentifiers_with_prrZ   r3   r3   r=   Z__connector_start_to_rest.  s    
ÿÿÿz3UDS_RCSelectiveEnumerator.__connector_start_to_restc                    s$   t t| ƒ tƒ tƒ gd | jg¡ d S r9   )rc   r  rÕ   r~  rx  Ú3_UDS_RCSelectiveEnumerator__connector_start_to_restr×   rh   r3   r=   rÕ   :  s    

þz"UDS_RCSelectiveEnumerator.__init__)	rJ   rK   rL   r�  rM   r‚  rƒ  rÕ   r˜   r3   r3   rh   r=   r    s   

r  c                   @   sB   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	S )
ÚUDS_IOCBIEnumeratorzMAvailable Input Output Controls By Identifier and negative response per statec                 C   s   t | ƒdk ot| ƒdkS r·   rW   rO   r3   r3   r=   rQ   F  rR   zUDS_IOCBIEnumerator.<lambda>rZ   c                 K   s   |  dtdƒ¡}dd„ |D ƒS )NrZ   r¸   c                 s   s   | ]}t ƒ t|d � V  qdS r<  )r   r   r­   r3   r3   r=   r¯   K  rR   z<UDS_IOCBIEnumerator._get_initial_requests.<locals>.<genexpr>r°   r±   r3   r3   r=   r_   H  s    z)UDS_IOCBIEnumerator._get_initial_requestsc                 C   s6   |d }|d ur$d|d j |jf S d|d j  S d S )NrA   rÁ   rk   z0x%04x: No response)rÄ   ZcontrolStatusRecordrª   r3   r3   r=   rl   M  s    ÿÿz&UDS_IOCBIEnumerator._get_table_entry_yNr£   r3   r3   r3   r=   r„  A  s   ÿr„  c                   @   sP   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZedd	„ ƒZd
d„ Z	dd„ Z
dS )ÚUDS_RMBAEnumeratorABCz9Readable Memory Addresses and negative response per statec                 C   s   t | d| j ƒS )z¥
        Helper function to get the memoryAddress from a UDS_RMBA packet
        :param pkt: UDS_RMBA request
        :return: memory address of the request
        úmemoryAddress%d)Úgetattrr7   ©Úpktr3   r3   r=   Úget_addr\  s    zUDS_RMBAEnumeratorABC.get_addrc                 C   s   t | d| j |ƒ dS )z¢
        Helper function to set the memoryAddress of a UDS_RMBA packet
        :param pkt: UDS_RMBA request
        :param addr: memory address to be set
        r†  N)Úsetattrr7   )r‰  Úaddrr3   r3   r=   Úset_addrf  s    zUDS_RMBAEnumeratorABC.set_addrc                 C   s   t | d| j ƒS )zr
        Helper function to gets the memorySize of a UDS_RMBA packet
        :param pkt: UDS_RMBA request
        úmemorySize%d)r‡  r6   rˆ  r3   r3   r=   Úget_sizep  s    zUDS_RMBAEnumeratorABC.get_sizec                 C   s.   t d| jd  d |ƒ}t| d| j |ƒ dS )zœ
        Helper function to set the memorySize of a UDS_RMBA packet
        :param pkt: UDS_RMBA request
        :param size: memory size to be set
        rA   rë   rk   rŽ  N)rY   r6   r‹  )r‰  ÚsizeÚset_sizer3   r3   r=   r‘  y  s    zUDS_RMBAEnumeratorABC.set_sizec                 C   s   d|   |d ¡ S ©Nz0x%04xrk   )rŠ  rD   r3   r3   r=   rl   „  s    z(UDS_RMBAEnumeratorABC._get_table_entry_yc                 C   s   |   |d dd„ ¡S )NrA   c                 S   s
   d| j  S rD  )r©   rF  r3   r3   r=   rQ   Š  rR   z:UDS_RMBAEnumeratorABC._get_table_entry_z.<locals>.<lambda>rB   rD   r3   r3   r=   rG   ˆ  s    z(UDS_RMBAEnumeratorABC._get_table_entry_zN)rJ   rK   rL   r�   rM   rŠ  r�  r�  r‘  rl   rG   r3   r3   r3   r=   r…  X  s   
	
	


r…  c                       sf   e Zd Ze ej¡Ze dedfi¡ ed= ejd Z‡ fdd„Z	ee	_
eddd„ƒZd	d
„ Z‡  ZS )ÚUDS_RMBARandomEnumeratorr›   NrZ   z�
        :param bool unittest: Enables smaller search space for unit-test
                              scenarios. This saves execution time.c                    s   t t| ƒj||fi |¤Ž d S r9   )rc   r“  rd   re   rh   r3   r=   rd   ˜  s    z UDS_RMBARandomEnumerator.executec              	   C   sj   t ƒ tƒ  }|pt dd¡|_| p,t dd¡|_t ||p<d¡ t |t ddd|j  d ¡d@ ¡ |S )Nrk   rã   r   rA   rë   l   ðÿ )	r   r   r6  Úrandintr6   r7   r“  r‘  r�  )Úaddr_lenÚsize_lenr�  r‰  r3   r3   r=   Ú_random_memory_addr_pktž  s    ÿÿÿz0UDS_RMBARandomEnumerator._random_memory_addr_pktc                    s¨   |  dd¡rPt ‡ fdd„tdƒD ƒ‡ fdd„tdƒD ƒ‡ fdd„tdƒD ƒ¡S t ‡ fd	d„tdƒD ƒ‡ fd
d„tdƒD ƒ‡ fdd„tdƒD ƒ‡ fdd„tdƒD ƒ¡S )Nr›   Fc                 3   s   | ]}ˆ j d d d�V  qdS )rA   )r•  r–  N©r—  ©r®   r�   r×   r3   r=   r¯   ®  rR   zAUDS_RMBARandomEnumerator._get_initial_requests.<locals>.<genexpr>r  c                 3   s   | ]}ˆ j d d�V  qdS ©ra   ©r•  Nr˜  r™  r×   r3   r=   r¯   ¯  rR   rA   c                 3   s   | ]}ˆ j d d�V  qdS ©rã   r›  Nr˜  r™  r×   r3   r=   r¯   °  rR   c                 3   s   | ]}ˆ j d d�V  qdS ©rk   r›  Nr˜  r™  r×   r3   r=   r¯   ³  rR   c                 3   s   | ]}ˆ j d d�V  qdS ©rA   r›  Nr˜  r™  r×   r3   r=   r¯   ´  rR   éô  c                 3   s   | ]}ˆ j d d�V  qdS rš  r˜  r™  r×   r3   r=   r¯   µ  rR   r1  c                 3   s   | ]}ˆ j d d�V  qdS rœ  r˜  r™  r×   r3   r=   r¯   ¶  rR   éˆ  ©r5  rÐ   rÑ   r]   r™   r3   r×   r=   r_   ª  s    ýüz.UDS_RMBARandomEnumerator._get_initial_requests)NNN)rJ   rK   rL   r�   r$   r‘   r’   r“   r–   rd   r—   rM   r—  r_   r˜   r3   r3   rh   r=   r“  �  s   ÿ
r“  c                       s˜   e Zd Ze ej¡Ze dedfi¡ ejd Z‡ fdd„Z	ee	_
‡ fdd„Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Z‡ fdd„Zd‡ fdd„	Z‡  ZS )ÚUDS_RMBASequentialEnumeratorÚpoints_of_interestNzÆ
        :param list points_of_interest: A list of _PointOfInterest objects as
                                        starting points for sequential search.
                                        c                    s   t t| ƒj||fi |¤Ž d S r9   )rc   r¢  rd   re   rh   r3   r=   rd   Ä  s
    
ÿÿz$UDS_RMBASequentialEnumerator.executec                    s"   t t| ƒ ¡  ttƒ| _d | _d S r9   )rc   r¢  rÕ   r   r”   Ú1_UDS_RMBASequentialEnumerator__points_of_interestÚ9_UDS_RMBASequentialEnumerator__initial_points_of_interestr×   rh   r3   r=   rÕ   Ë  s
    ÿz%UDS_RMBASequentialEnumerator.__init__c                 C   sŒ   t ƒ }|D ]l}|j}|d urR|jdkrR|t|  |j¡|  |j¡t|jƒ ƒg7 }q
|t|  |j¡|  |j¡d ƒg7 }q
tt t	j
 |¡ƒƒS )Nrí   rð   )r”   r<   ru   r]   rŠ  r€   r½   r©   r9  rÐ   rÑ   rÒ   )rE   ÚresultsZ	mem_areasrF   r<   r3   r3   r=   Ú"_get_memory_addresses_from_resultsÒ  s    ÿÿÿz?UDS_RMBASequentialEnumerator._get_memory_addresses_from_resultsc                 C   sÊ   |   | j¡}tƒ }tƒ }|D ]¨\}}}}}	td|	d |	ƒD ]ˆ}
|r^t||
 dd|  d ƒ}nt||
 dƒ}||vr:||	f|vr:tƒ t||d� }|  	||	¡ |  
||¡ | |¡ | ||	f¡ q:q|S )Nr   é2   rA   rë   rk   )r6   r7   )r§  Zresults_with_responser9  r”   r]   rY   rX   r   r   r‘  r�  rÏ   Úadd)rE   rÓ   Ztested_addrsZtesting_addrsÚnew_requestsrŒ  ZupwardZmem_size_lenZmem_addr_lenZmem_sizeÚir‰  r3   r3   r=   Z__pois_to_requestsá  s*    ÿ
ÿÿ
z/UDS_RMBASequentialEnumerator.__pois_to_requestsc                 C   s    |   |¡}|  |¡}|j}|j}|d u s2|jdkrb|dkrb|d }t|d|||ƒt|d|||ƒgS |d urœ|jdkrœt|| d|||ƒt|| d|||ƒgS g S )Nro   rk   rA   TFrí   )rŠ  r�  r6   r7   ru   r4   )rE   r€   r<   rŒ  r�  ZmslZmalr3   r3   r=   Z__request_to_poisú  s    

þþz.UDS_RMBASequentialEnumerator.__request_to_poisc                 K   s   t ‚d S r9   )ÚNotImplementedErrorr™   r3   r3   r=   r_     s    z2UDS_RMBASequentialEnumerator._get_initial_requestsc                 C   s‚   | j d u r"|| jj  dtƒ ¡| _ | j| s8| j | j|< |  | j| ¡}t|ƒrrd| j|< || j	|< tƒ | j|< ntƒ | j	|< d S )Nr£  F)
r¥  ri   rJ   r5  r”   r¤  Ú/_UDS_RMBASequentialEnumerator__pois_to_requestsr½   Z_state_completedZ_request_iterators)rE   rf   rg   rH  rª  r3   r3   r=   rI    s     
ÿÿ
ÿÿ

z(UDS_RMBASequentialEnumerator.pre_executec                    s6   | j |  |  ||¡7  < tt| ƒj|||fi |¤ŽS r9   )r¤  Ú._UDS_RMBASequentialEnumerator__request_to_poisrc   r¢  r´   rµ   rh   r3   r=   r´   +  s    

ÿ
ÿÿz/UDS_RMBASequentialEnumerator._evaluate_responseFTc                    sì   t t| ƒ |||¡pd}zbddlm} |ƒ }| jD ]6}t|jjƒD ]$\}}	|  	|j
¡}
t|	ƒ||
| < qBq2|jddd� W nT tyÎ   d}t |¡ tddƒ�}| |¡ W d   ƒ n1 sÀ0    Y  Y n0 |rÜ|d	 S t|ƒ d S d S )
NÚ r   )ÚIntelHexzRMBA_dump.hexÚhex)Úformatz5Install 'intelhex' to create a hex file of the memoryÚwÚ
)rc   r¢  ÚshowZintelhexr°  rÇ   r4  r<   r©   rŠ  r€   r   ÚtofileÚImportErrorr   rf  ÚopenÚwriteÚprint)rE   ÚdumpÚfilteredrn   rX  r°  ZihrF   r«  ÚbrŒ  Úerr_msgÚfilerh   r3   r=   rµ  6  s,    
ÿÿ

.z!UDS_RMBASequentialEnumerator.show)FTF)rJ   rK   rL   r�   r$   r‘   r’   r”   r–   rd   r—   rÕ   r§  r­  r®  r_   rI  r´   rµ  r˜   r3   r3   rh   r=   r¢  ¹  s   ÿ
r¢  c                       s(   e Zd Zedd„ ƒZ‡ fdd„Z‡  ZS )ÚUDS_RMBAEnumeratorc              	   C   sh   t ƒ }tt| ƒ} | jD ]H}|tt |j¡d|jj|jj	dƒtt |j¡d|jj|jj	dƒg7 }qd|iS )NTr  Fr£  )
r”   r
   r“  rÇ   r4   r…  rŠ  r€   r6   r7   )Zrandr�   r£  rF   r3   r3   r=   Z__connector_rand_to_seqS  s    

þþýÿz*UDS_RMBAEnumerator.__connector_rand_to_seqc                    s$   t t| ƒ tƒ tƒ gd | jg¡ d S r9   )rc   rÀ  rÕ   r“  r¢  Ú*_UDS_RMBAEnumerator__connector_rand_to_seqr×   rh   r3   r=   rÕ   c  s    

þzUDS_RMBAEnumerator.__init__)rJ   rK   rL   rM   rÁ  rÕ   r˜   r3   r3   rh   r=   rÀ  R  s   
rÀ  c                       sl   e Zd ZdZe ej¡Ze dedfi¡ ej	d Z	‡ fdd„Z
e	e
_eddd„ƒZd	d
„ Zdd„ Z‡  ZS )ÚUDS_RDEnumeratorzRequestDownload supportedr›   Nz�
        :param bool unittest: Enables smaller search space for unit-test
                              scenarios. This safes execution time.c                    s   t t| ƒj||fi |¤Ž d S r9   )rc   rÂ  rd   re   rh   r3   r=   rd   u  s    zUDS_RDEnumerator.executec                 C   s~   t ƒ tƒ  }t dd¡|_t dd¡|_| p6t dd¡|_t |d¡ t ddd|j  d ¡dd|j > @ }t 	||¡ |S )Nr   rð   rk   rã   rA   rë   rV  )
r   r!   r6  r”  ZdataFormatIdentifiersr6   r7   r“  r‘  r�  )r•  r‰  rŒ  r3   r3   r=   r—  {  s    ÿz(UDS_RDEnumerator._random_memory_addr_pktc                    s”   |  dd¡r<t ‡ fdd„tdƒD ƒ‡ fdd„tdƒD ƒ¡S t ‡ fdd„tdƒD ƒ‡ fd	d„tdƒD ƒ‡ fd
d„tdƒD ƒ‡ fdd„tdƒD ƒ¡S )Nr›   Fc                 3   s   | ]}ˆ j d d�V  qdS r�  r˜  r™  r×   r3   r=   r¯   Œ  rR   z9UDS_RDEnumerator._get_initial_requests.<locals>.<genexpr>r  c                 3   s   | ]}ˆ j d d�V  qdS rž  r˜  r™  r×   r3   r=   r¯   �  rR   rŸ  c                 3   s   | ]}ˆ j d d�V  qdS r�  r˜  r™  r×   r3   r=   r¯   �  rR   c                 3   s   | ]}ˆ j d d�V  qdS rž  r˜  r™  r×   r3   r=   r¯   ‘  rR   c                 3   s   | ]}ˆ j d d�V  qdS rš  r˜  r™  r×   r3   r=   r¯   ’  rR   r1  c                 3   s   | ]}ˆ j d d�V  qdS rœ  r˜  r™  r×   r3   r=   r¯   “  rR   r   r¡  r™   r3   r×   r=   r_   ˆ  s    þüz&UDS_RDEnumerator._get_initial_requestsc                 C   s   dt  |d ¡ S r’  )r…  rŠ  rD   r3   r3   r=   rl   •  s    z#UDS_RDEnumerator._get_table_entry_y)N)rJ   rK   rL   r�   r�   r$   r‘   r’   r“   r–   rd   r—   rM   r—  r_   rl   r˜   r3   r3   rh   r=   rÂ  j  s   ÿ
rÂ  c                   @   sB   e Zd ZdZe ej¡Zeee	fdd„ fed< dd„ Z
dd„ Zd	S )
ÚUDS_TDEnumeratorzTransferData supportedc                 C   s   t | ƒdk ot| ƒdkS rU   rW   rO   r3   r3   r=   rQ   ž  rR   zUDS_TDEnumerator.<lambda>rZ   c                 K   s*   |  dtdƒ¡}ttt tƒ t|d� ƒS )NrZ   rV   )ÚblockSequenceCounter)r\   r]   r
   r	   r   r   r"   )rE   r^   Zcntr3   r3   r=   r_      s    z&UDS_TDEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nrj   rk   z%UDS_TD.blockSequenceCounter%)rÄ  r?   rD   r3   r3   r=   rl   ¥  s    þz#UDS_TDEnumerator._get_table_entry_yNr£   r3   r3   r3   r=   rÃ  š  s   ÿrÃ  c                   @   s   e Zd ZdZedd„ ƒZdS )ÚUDS_Scannera�  
    Example:
        >>> def reconnect():
        >>>     return UDS_DoIPSocket("169.254.186.237")
        >>>
        >>> es = [UDS_ServiceEnumerator, UDS_DSCEnumerator]
        >>>
        >>> def reset():
        >>>     reconnect().sr1(UDS()/UDS_ER(resetType="hardReset"),
        >>>                     verbose=False, timeout=1)
        >>>
        >>> s = UDS_Scanner(reconnect(), reconnect_handler=reconnect,
        >>>                 reset_handler=reset, test_cases=es,
        >>>                 UDS_DSCEnumerator_kwargs={
        >>>                     "timeout": 20,
        >>>                     "overwrite_timeout": False,
        >>>                     "scan_range": [1, 3]})
        >>>
        >>> try:
        >>>     s.scan()
        >>> except KeyboardInterrupt:
        >>>     pass
        >>>
        >>> s.show_testcases_status()
        >>> s.show_testcases()
    c                 C   s   t tttttttgS r9   )r«   rN   r�   rA  r?  rÀ  rx  r„  r×   r3   r3   r=   Údefault_test_case_clssÈ  s    þz"UDS_Scanner.default_test_case_clssN)rJ   rK   rL   r—   ÚpropertyrÆ  r3   r3   r3   r=   rÅ  ¬  s   rÅ  )fr]  r6  rƒ   rÐ   r�   rp  Úcollectionsr   Útypingr   Zscapy.compatr   r   r   r   r   r	   r
   r   r   r   r   Zscapy.contrib.automotiver   Zscapy.packetr   r   Zscapy.libs.sixZlibsrn  Zscapy.errorr   Zscapy.contrib.automotive.udsr   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   Zscapy.contrib.automotive.ecur#   Z+scapy.contrib.automotive.scanner.enumeratorr$   r%   r&   r'   Z*scapy.contrib.automotive.scanner.test_caser(   r)   r*   r+   Z.scapy.contrib.automotive.scanner.configurationr,   Z&scapy.contrib.automotive.scanner.graphr-   Z1scapy.contrib.automotive.scanner.staged_test_caser.   Z)scapy.contrib.automotive.scanner.executorr/   Z'scapy.contrib.automotive.uds_ecu_statesÚPY34Úabcr1   r2   rt   r“   r4   r8   rN   r�   r¡   r¤   r§   r«   r¶   rÂ   rÌ   r:  r?  rA  rU  rx  r~  r  r„  r…  r“  r¢  rÀ  rÂ  rÃ  rÅ  r3   r3   r3   r=   Ú<module>	   st   4Hú	o)$(>1g| $5, 0