
    di1                     *   d Z ddlmZmZ ddlZddlmZmZmZmZ ddlm	Z
 ddlmZmZ ddl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mZmZmZ dd
lm Z  ddl!m"Z" ej#        eee         f         Z$de%de%de%fdZ&dede%defdZ' G d d          Z(dS )z? pySim: SIM Card commands according to ISO 7816-4 and TS 11.11
    )ListTupleN)	ConstructStructConstSelect)Optional)LVfilter_dict)rpadlpadb2hh2bh2ii2hstr_sanitizeHexstr)bertlv_encode_len)sw_match
expand_hexSwHexstrResTuple
SwMatchstr)SwMatchError)LinkBaseclalchan_nrreturnc                     |dk     r&| dz	  dv r| dz  |dz  z  S t          d| |fz            |dk     r)| dz	  dv r| d	z  |dz
  d
z  z  S t          d| |fz            t          d          )z1Embed a logical channel number into the CLA byte.   )r   
            z4Undefined how to use CLA %2X with logical channel %u      )   r$         z(logical channel outside of range 0 .. 15)
ValueError)r   r   s     </home/jenkins/workspace/simtester-sanitize/pySim/commands.pylchan_nr_to_clar,   '   s     !||!8&&$J8a<00SWZ\dVeefff	B!8v$JHqLD#899SWZ\dVeefffCDDD    cla_bytec                 h    t          |           d         }t          t          ||          g          S )zEEmbed a logical channel number into the hex-string encoded CLA value.r   )r   r   r,   )r.   r   cla_ints      r+   cla_with_lchanr1   9   s-    (mmAG223444r-   c                      e Zd ZdZdmdedefdZdedd fdZedefd            Z	dnd
e
dedefdZdod
e
dededefdZ	 dnde
de
de
de
dede
dededeeef         fdZ	 dode
de
de
de
dede
dedededeeef         fdZde
fdZdefdZdefdZde
fdZdee
         dee         fd Zdedee
         fd!Zd"e
defd#Zdefd$Zd%e
defd&Z dpd(ed)ed*edefd+Z!dmd,e"d*efd-Z#	 	 dqd(ed,e
d*ed/ed0edefd1Z$d(ed2edefd3Z%d(ed2ed,e"fd4Z&	 	 drd(ed2ed,e
d5ed/ed0ed6edefd7Z'd(edefd8Z(d(edefd9Z)d(edefd:Z*dnd;ed<edefd=Z+d(ed;edefd>Z,dnd,e
d<edefd?Z-dsd;ed@e"d/ed0edef
dAZ.dBe
defdCZ/dtdBe
dEe
dFe"defdGZ0defdHZ1defdIZ2d"e
defdJZ3dKe
defdLZ4dKe
defdMZ5d"e
defdNZ6d"e
defdOZ7d"e
defdPZ8defdQZ9dudSe"dedefdTZ:de
fdUZ;dVe"dWedXe
defdYZ<dWedZe
defd[Z=dWed\e"dXe"fd]Z>dWedXe
d^e
defd_Z?dWedXe
defd`Z@dWedXe
defdaZAdKe
defdbZBdKe
defdcZCdvdfedgedeee
ef         fdhZDdie
defdjZEdmd;edefdkZFdFedee
ef         fdlZGd'S )wSimCardCommandsaG  Class providing methods for various card-specific commands such as SELECT, READ BINARY, etc.
    Historically one instance exists below CardBase, but with the introduction of multiple logical
    channels there can be multiple instances.  The lchan number will then be patched into the CLA
    byte by the respective instance. r   	transportr   c                 L    || _         d| _        || _        d| _        d | _        d S )N0000a0)_tpsel_ctrlr   r.   scp)selfr4   r   s      r+   __init__zSimCardCommands.__init__C   s)     r-   r   c                 b    t          | j        |          }| j        |_        | j        |_        |S )zLFork a per-lchan specific SimCardCommands instance off the current instance.)r4   r   )r3   r8   r.   r9   )r;   r   rets      r+   
fork_lchanzSimCardCommands.fork_lchanK   s-    $(xHHH}}
r-   c                 2    | j         rd| j         j        z
  S dS )zYMaximum length of the command apdu data section. Depends on secure channel protocol used.   )r:   overheadr;   s    r+   max_cmd_lenzSimCardCommands.max_cmd_lenR   s#     8 	***3r-   Tpduapply_lchanc                     |r(t          |dd         | j                  |dd         z   }| j        r%| j                            | j        j        |          S | j                            |          S )a  Sends an APDU and auto fetch response data

        Args:
           pdu : string of hexadecimal characters (ex. "A0A40000023F00")
           apply_lchan : apply the currently selected lchan to the CLA byte before sending
        Returns:
           tuple(data, sw), where
                        data : string (in hex) of returned data (ex. "074F4EFFFF")
                        sw   : string (in hex) of status word (ex. "9000")
        r      N)r1   r   r:   send_apdu_wrapperr8   	send_apdu)r;   rE   rF   s      r+   rJ   zSimCardCommands.send_apduZ   sp      	D QqS4=99CGCC8 	+8--dh.@#FFF8%%c***r-   9000swc                     |r(t          |dd         | j                  |dd         z   }| j        r&| j                            | j        j        ||          S | j                            ||          S )aX  Sends an APDU and check returned SW

        Args:
           pdu : string of hexadecimal characters (ex. "A0A40000023F00")
           sw : string of 4 hexadecimal characters (ex. "9000"). The user may mask out certain
                digits using a '?' to add some ambiguity if needed.
           apply_lchan : apply the currently selected lchan to the CLA byte before sending
        Returns:
                tuple(data, sw), where
                        data : string (in hex) of returned data (ex. "074F4EFFFF")
                        sw   : string (in hex) of status word (ex. "9000")
        r   rH   N)r1   r   r:   rI   r8   send_apdu_checksw)r;   rE   rL   rF   s       r+   rN   z!SimCardCommands.send_apdu_checkswl   st      	D QqS4=99CGCC8 	78--dh.H#rRRR8--c2666r-   r   insp1p2
cmd_constrcmd_dataresp_constrc	           
      x   |r|                     |          nd}	|rt          t          |	          g          nd}
|rdnd}d                    |||||
t	          |	          |g          }|                     ||          \  }}|r0t          |                    t          |                              }nd}||fS )a  Build and sends an APDU using a 'construct' definition; parses response.

        Args:
                cla : string (in hex) ISO 7816 class byte
                ins : string (in hex) ISO 7816 instruction byte
                p1 : string (in hex) ISO 7116 Parameter 1 byte
                p2 : string (in hex) ISO 7116 Parameter 2 byte
                cmd_cosntr : defining how to generate binary APDU command data
                cmd_data : command data passed to cmd_constr
                resp_cosntr : defining how to decode binary APDU response data
                apply_lchan : apply the currently selected lchan to the CLA byte before sending
        Returns:
                Tuple of (decoded_data, sw)
        r-    00rF   N)	buildr   lenjoinr   rJ   r   parser   )r;   r   rO   rP   rQ   rR   rS   rT   rF   cmdlclerE   datarL   rsps                   r+   send_apdu_constrz SimCardCommands.send_apdu_constr   s      -5=jx(((# (0S#c((___b (TTbggsCRSXXr:;;^^C{^CC
r 	k//D		::;;CCCRyr-   sw_expc
           
          |                      ||||||||	          \  }
}t          ||          s-t          ||                                | j        j                  |
|fS )a  Build and sends an APDU using a 'construct' definition; parses response.

        Args:
                cla : string (in hex) ISO 7816 class byte
                ins : string (in hex) ISO 7816 instruction byte
                p1 : string (in hex) ISO 7116 Parameter 1 byte
                p2 : string (in hex) ISO 7116 Parameter 2 byte
                cmd_cosntr : defining how to generate binary APDU command data
                cmd_data : command data passed to cmd_constr
                resp_cosntr : defining how to decode  binary APDU response data
                exp_sw : string (in hex) of status word (ex. "9000")
        Returns:
                Tuple of (decoded_data, sw)
        rX   )rb   r   r   lowerr8   sw_interpreter)r;   r   rO   rP   rQ   rR   rS   rT   rc   rF   ra   rL   s               r+   send_apdu_constr_checkswz(SimCardCommands.send_apdu_constr_checksw   sr    " ))#sBJR]8C * E E	bF## 	Lr6<<>>483JKKKRyr-   fcpc                    ddl m}  |g d          }|                                }|dd         dk    rt          d|dd         z            t	          |dd         d          }t          |dd                    dz  |k    rd}nGt	          |dd	         d          }t          |dd                    dz  |k    rd	}t          d
          ||d          }|                    |          S )Nr   )TLV)828384a58a8b8c80abc68188rH   62z>Tag of the FCP template does not match, expected 62 but got %sr    r%   r&   z%Cannot determine length of TLV-length)	pytlv.TLVrj   re   r*   intrZ   r\   )r;   rh   rj   	tlvparserexp_tlv_lenskiptlvs          r+   __parse_fcpzSimCardCommands.__parse_fcp   s*    	"!!!!!C < < < = =	 iikkqs8tPSVWXYZWZS[[] ] ] #ac(B''s122w<<1++DDc!A#h++K3qrr7||q K//DEEE $%%js###r-   c                     | j         dk    r;|                     |d                   }|d         }t          |dd         d          S t          |d         dd         d          S )	N0004rk   r    r"   r%         r9   _SimCardCommands__parse_fcpry   )r;   r
tlv_parsedfile_descriptors       r+   __record_lenzSimCardCommands.__record_len   se    =F""))!B%00J(.Oqs+R000quRU|R(((r-   c                     | j         dk    r1|                     |d                   }t          |d         d          S t          |d         dd         d          S )Nr   r   rr   r%   r    r"   r   )r;   r   r   s      r+   __lenzSimCardCommands.__len   sW    =F""))!B%00Jz$',,,quQqSz2&&&r-   c                 4    | j                                         S )z.Return the ATR of the currently inserted card.)r8   get_atrrC   s    r+   r   zSimCardCommands.get_atr   s    x!!!r-   dir_listc                     g }t          |t                    s|g}|D ]T}|                     | j        dz   | j        z   dz   |z   dz             \  }}|                    ||f           |dk    r|c S U|S )zj Try to select a specified path

        Args:
                dir_list : list of hex-string FIDs
        a402rW   rK   )
isinstancelistrJ   r.   r9   append)r;   r   rvir`   rL   s         r+   try_select_pathzSimCardCommands.try_select_path   s     (D)) 	" zH 	 	A~~dmd&:T]&JT&QTU&UX\&\]]HD"IItRj!!!V||			 	r-   c                     g }t          |t                    s|g}|D ]/}|                     |          \  }}|                    |           0|S )zExecute SELECT for an entire list/path of FIDs.

        Args:
                dir_list: list of FIDs representing the path to select

        Returns:
                list of return values (FCP in hex encoding) for each element of the path
        )r   r   select_filer   )r;   r   r   r   r`   _sws         r+   select_pathzSimCardCommands.select_path  s^     (D)) 	" zH 	 	A((++ID#IIdOOOO	r-   fidc                 ^    |                      | j        dz   | j        z   dz   |z   dz             S )zoExecute SELECT a given file by FID.

        Args:
                fid : file identifier as hex string
        r   r   rW   )rN   r.   r9   r;   r   s     r+   r   zSimCardCommands.select_file  s7     %%dmd&:T]&JT&QTW&WZ^&^___r-   c                 <    |                      | j        dz             S )z*Execute SELECT to switch to the parent DF a40304rN   r.   rC   s    r+   select_parent_dfz SimCardCommands.select_parent_df  s    %%dmh&>???r-   aidc                     dt          t          |          dz  d          z   dd         }|                     | j        dz   dz   |z   |z   dz             S )	zzExecute SELECT a given Application ADF.

        Args:
                aid : application identifier as hex string
        0rH   xNr   0404rW   )formatrZ   rN   r.   )r;   r   aidlens      r+   
select_adfzSimCardCommands.select_adf  s[     s3xx1}c222BCC8%%dmd&:V&Cf&Ls&RUY&YZZZr-   Neflengthoffsetc                    |                      |          }t          |d                   dk    rdS ||                     |          |z
  }|dk     rdS d}d}||k     rt          | j        ||z
            }| j        d||z   |fz  z   }	 |                     |          \  }	}
n,# t          $ r}|                    d|z             |d}~ww xY w||	z  }||z  }||k     ||
fS )a   Execute READD BINARY.

        Args:
                ef : string or list of strings indicating name or path of transparent EF
                length : number of bytes to read
                offset : byte offset in file from which to start reading
        r   r   NNNrV   z
b0%04x%02xzfailed to read (offset %d))	r   rZ   _SimCardCommands__lenminrD   r.   rN   	Exceptionadd_note)r;   r   r   r   r   
total_datachunk_offset	chunk_lenrE   r`   rL   es               r+   read_binaryzSimCardCommands.read_binary)  s*    R  qu::??<>ZZ]]V+FA::<
V##D,f\.ABBI- 5yAABC11#66bb   

7&@AAA $JI%L V## 2~s   B! !
C
+CC
r`   c                 4   |                      |t          |          dz  |          }|d                                         |                                k    r@t          d|                                d|d                                         d          dS )a  Verify contents of transparent EF.

        Args:
                ef : string or list of strings indicating name or path of transparent EF
                data : hex string of expected data
                offset : byte offset in file from which to start verifying
        rH   r   z%Binary verification failed (expected , got )N)r   rZ   re   r*   )r;   r   r`   r   ress        r+   __verify_binaryzSimCardCommands.__verify_binaryH  s     r3t99>6::q6<<>>TZZ\\))*

c!fllnnnn. / / / *)r-   Fverifyconservec                    |                      |          }t          ||          }t          |          dz  }|r6	 |                     |||          \  }}	||k    rd|	fS n# t          $ r Y nw xY w|                     |           d}
d}||k     rt          | j        ||z
            }| j        d||z   |fz  z   ||dz  ||z   dz           z   }	 | 	                    |          \  }}n.# t          $ r!}|
                    d||fz             |d}~ww xY w|
|z  }
||z  }||k     |r|                     |||           |
|fS )aK  Execute UPDATE BINARY.

        Args:
                ef : string or list of strings indicating name or path of transparent EF
                data : hex string of data to be written
                offset : byte offset in file from which to start writing
                verify : Whether or not to verify data after write
        rH   NrV   r   z
d6%04x%02xz5failed to write chunk (chunk_offset %d, chunk_len %d))binary_sizer   rZ   r   r   r   r   rD   r.   rN   r   _SimCardCommands__verify_binary)r;   r   r`   r   r   r   file_lendata_lengthdata_currentrL   r   r   r   rE   
chunk_datachunk_swr   s                    r+   update_binaryzSimCardCommands.update_binaryU  s    ##B''$))$ii1n  
		#'#3#3BV#L#L b4''8O (   
  	
[((D,kL.HIII- 5yAAB\!^l9&<a%??@AC'+'='=c'B'B$
HH   

RVbdmUnnooo $JI%L [((  	3  T62228##s)   #A   
A-,A-C' '
D1DDrec_noc                     |                      |          }|                     |          }| j        d||fz  z   }|                     |          S )zExecute READ RECORD.

        Args:
                ef : string or list of strings indicating name or path of linear fixed EF
                rec_no : record number to read
        zb2%02x04%02x)r   _SimCardCommands__record_lenr.   rN   )r;   r   r   r   
rec_lengthrE   s         r+   read_recordzSimCardCommands.read_record  sT     R  &&q))
mn
/CCC%%c***r-   c                    |                      ||          }|d                                         |                                k    r@t          d|                                d|d                                         d          dS )zVerify record against given data

        Args:
                ef : string or list of strings indicating name or path of linear fixed EF
                rec_no : record number to read
                data : hex string of data to be verified
        r   z%Record verification failed (expected r   r   N)r   re   r*   )r;   r   r   r`   r   s        r+   __verify_recordzSimCardCommands.__verify_record  sz     r6**q6<<>>TZZ\\))*

c!fllnnnn. / / / *)r-   	force_lenleftpadc                    |                      |          }|                     |          }	t          ||	          }|rt          |          dz  }	nyt          |          dz  |	k    r$t	          d|	t          |          dz  fz            t          |          dz  |	k     r)|rt          ||	dz            }nt          ||	dz            }|rB	 |                     ||          \  }
}|
d|	dz           }
|
|k    rd|fS n# t          $ r Y nw xY w| j	        d||	fz  z   |z   }| 
                    |          }|r|                     |||           |S )a,  Execute UPDATE RECORD.

        Args:
                ef : string or list of strings indicating name or path of linear fixed EF
                rec_no : record number to read
                data : hex string of data to be written
                force_len : enforce record length by using the actual data length
                verify : verify data by re-reading the record
                conserve : read record and compare it with data, skip write on match
                leftpad : apply 0xff padding from the left instead from the right side.
        rH   z;Data length exceeds record length (expected max %d, got %d)r   Nzdc%02x04%02x)r   r   r   rZ   r*   r   r   r   r   r.   rN   _SimCardCommands__verify_record)r;   r   r   r`   r   r   r   r   r   r   r   rL   rE   s                r+   update_recordzSimCardCommands.update_record  s    r""&&s++
$
++ 	6TaJJ 4yyA~
** !^D		Qb0 "0 1 1 1Ta*,, 6j1n55DDj1n55D  	
#'#3#3B#?#? b+AjlN;4''8O (   
  }~0DDDL$$S)) 	3  VT222
s   /C= =
D
	D
c                 V    |                      |          }|                     |          S )zDetermine the record size of given file.

        Args:
                ef : string or list of strings indicating name or path of linear fixed EF
        )r   r   r;   r   r   s      r+   record_sizezSimCardCommands.record_size  s+     R    ###r-   c                     |                      |          }|                     |          |                     |          z  S )zDetermine the number of records in given file.

        Args:
                ef : string or list of strings indicating name or path of linear fixed EF
        )r   r   r   r   s      r+   record_countzSimCardCommands.record_count  s:     R  zz!}} 1 1! 4 444r-   c                 V    |                      |          }|                     |          S )zDetermine the size of given transparent file.

        Args:
                ef : string or list of strings indicating name or path of transparent EF
        )r   r   r   s      r+   r   zSimCardCommands.binary_size  s'     R  zz!}}r-   tagfirstc                 @    |rd|z  }nd}|                      |          S )Nz80cb008001%02x0080cb0000rN   )r;   r   r   rE   s       r+   _retrieve_datazSimCardCommands._retrieve_data  s/     	$,CCC%%c***r-   c                     |                      |          }t          |d                   dk    rdS d}|                     |d          \  }}||z  }|dv r#|                     |d          \  }}||z  }|dv #||fS )	zExecute RETRIEVE DATA, see also TS 102 221 Section 11.3.1.

        Args
                ef : string or list of strings indicating name or path of transparent EF
                tag : BER-TLV Tag of value to be retrieved
        r   r   r   rV   Tr   )62f162f2F)r   rZ   r   )r;   r   r   r   r   r`   rL   s          r+   retrieve_datazSimCardCommands.retrieve_data  s     R  qu::??<
&&s$&77bd
$$$**3e*<<HD"$J $$$ 2~r-   c                     |rd}nd}t          |t          t          f          rt          |          }d|t	          |          dz  |fz  }|                     |          S )N   r   z80db00%02x%02x%srH   )r   bytes	bytearrayr   rZ   rN   )r;   r`   r   rP   rE   s        r+   	_set_datazSimCardCommands._set_data  sg     	BBBdUI.// 	t99D BD		1d#;;%%c***r-   valuec           	         |                      |          }t          |d                   dk    rdS |s|                     d|z  d          S d|t          t	          t          |          dz                      fz  }||z   }t          |          }	d}
t          |	          }|	}t          |          dk    rM|d	| j                 }|                     ||
          \  }}d
}
|| j        d	         }t          |          dk    M||fS )zExecute SET DATA.

        Args
                ef : string or list of strings indicating name or path of transparent EF
                tag : BER-TLV Tag of value to be stored
                value : BER-TLV value to be stored
        r   r   r   z%02xTr   z%02x%srH   NF)r   rZ   r   r   r   r   rD   )r;   r   r   r   r   r   r   tlr}   tlv_binr   	total_len	remainingfragmentrdatarL   s                   r+   set_datazSimCardCommands.set_data  s    R  qu::??<  	<>>&3,d>;;; c"3CJJM"B"BCCDD5jc((LL		)nnq   !2$"2!23Hxu==IE2E!$"2"3"34I	 )nnq  
 byr-   randc                     t          |          dk    rt          d          |                     ddg           |                     d|z   dz   d          S )	zrExecute RUN GSM ALGORITHM.

        Args:
                rand : 16 byte random data as hex string (RAND)
            zInvalid rand3f007f20
a088000010rW   rK   )rL   )rZ   r*   r   rN   )r;   r   s     r+   run_gsmzSimCardCommands.run_gsm4  s]     t99??^,,,&&)***%%lT&9D&@V%LLLr-   3gautncontextc           
         t          dt          z  dt          t                    z            }t          t          d          dt          z            }t          t          d          dt          z  dt          z  dt          z  d	t          t                    z            }t	          ||          }||d
}|dk    rd}	n|dk    rd}	nt          d|z            |                     | j        dd|	|||          \  }
}d|
v rd|
i}nd|
i}||fS )zExecute AUTHENTICATE (USIM/ISIM).

        Args:
                rand : 16 byte random data as hex string (RAND)
                autn : 8 byte Authentication Token (AUTN)
                context : 16 byte random data ('3g' or 'gsm')
        r   r      auts   r   ckikkc)r   r   r   ru   gsmrr   zUnsupported context '%s'rv   rW   synchronisation_failuresuccessful_3g_authentication)r   r
   	COptionalr   r   r*   rg   r.   )r;   r   r   r   	AuthCmd3GAuthResp3GSyncFailAuthResp3GSuccess
AuthResp3GrS   rQ   r`   rL   r>   s                r+   authenticatezSimCardCommands.authenticate?  s    6"9fYr]]&:;;	#E'NNF2I>>"5>>58T"Wd2gtT]^`TaTaOabb.0ABB
 $//d??BBBB7'ABBB22M4r9h
L L
rT>>,d3CC148CRyr-   c                 ,    |                      d          S )z:Execute a STATUS command as per TS 102 221 Section 11.1.2.80F20000r   rC   s    r+   statuszSimCardCommands.status\  s    %%j111r-   c           	      B    |                      | j        dddddd          S )zBExecute DECATIVATE FILE command as per TS 102 221 Section 11.1.14.04rW   N)rg   r.   rC   s    r+   deactivate_filezSimCardCommands.deactivate_file`  s&    ,,T]D$dTXZ^___r-   c                 B    |                      | j        dz   |z             S )zExecute ACTIVATE FILE command as per TS 102 221 Section 11.1.15.

        Args:
                fid : file identifier as hex string
        44000002r   r   s     r+   activate_filezSimCardCommands.activate_filed  s$     %%dmj&@3&FGGGr-   payloadc                 f    |                      | j        dt          |          dz  |fz  z             S )z9Execute CREATE FILE command as per TS 102 222 Section 6.3ze00000%02x%srH   )rN   r.   rZ   r;   r  s     r+   create_filezSimCardCommands.create_filel  s3    %%dmnGVWY`Ga6a&abbbr-   c                 V    |                      dt          |          dz  |fz            S )z:Execute RESIZE FILE command as per TS 102 222 Section 6.10z80d40000%02x%srH   rN   rZ   r  s     r+   resize_filezSimCardCommands.resize_filep  s+    %%&6#g,,/79S&STTTr-   c                 B    |                      | j        dz   |z             S )z9Execute DELETE FILE command as per TS 102 222 Section 6.4e4000002r   r   s     r+   delete_filezSimCardCommands.delete_filet  "    %%dmj&@3&FGGGr-   c                 B    |                      | j        dz   |z             S )z:Execute TERMINATE DF command as per TS 102 222 Section 6.7e6000002r   r   s     r+   terminate_dfzSimCardCommands.terminate_dfx  r"  r-   c                 B    |                      | j        dz   |z             S )z:Execute TERMINATE EF command as per TS 102 222 Section 6.8e8000002r   r   s     r+   terminate_efzSimCardCommands.terminate_ef|  r"  r-   c                 <    |                      | j        dz             S )zBExecute TERMINATE CARD USAGE command as per TS 102 222 Section 6.9fe000000r   rC   s    r+   terminate_card_usagez$SimCardCommands.terminate_card_usage  s    %%dmj&@AAAr-   openmodec                 `    |dk    rd}nd}| j         d||fz  z   }|                     |          S )zExecute MANAGE CHANNEL command as per TS 102 221 Section 11.1.17.

        Args:
                mode : logical channel operation code ('open' or 'close')
                lchan_nr : logical channel number (1-19, 0=assigned by UICC)
        closer   r   z
70%02x%02x)r.   rN   )r;   r-  r   rP   rE   s        r+   manage_channelzSimCardCommands.manage_channel  sB     7??BBBmlb(^;;%%c***r-   c                 4    | j                                         S )zPhysically reset the card)r8   
reset_cardrC   s    r+   r2  zSimCardCommands.reset_card  s    x""$$$r-   op_namechv_nopin_codec           
          t          |d          rHt          d||t          |                                          t	          |d                   fz            |dk    rt          |d| j        j                  d S )N63cxz9Failed to %s chv_no 0x%02X with code 0x%s, %i tries left.r$   rK   )r   RuntimeErrorr   upperry   r   r8   rf   )r;   r3  r4  r5  rL   s        r+   _chv_process_swzSimCardCommands._chv_process_sw  s    B 	UZ 'X1D1D1F1FBqE

S T U U U<<r648+BCCC <r-   codec                     t          t          |          d          }|                     | j        dz   d|z  z   dz   |z             \  }}|                     d|||           ||fS )zVerify a given CHV (Card Holder Verification == PIN)

        Args:
                chv_no : chv number (1=CHV1, 2=CHV2, ...)
                code : chv code as hex string
        r%   2000%02X08r   r   r   rJ   r.   r:  )r;   r4  r;  fcr`   rL   s         r+   
verify_chvzSimCardCommands.verify_chv  sm     #d))R  >>$-&"8FVO"Lt"SVX"XYYbXvtR888bzr-   puk_codec                    t          t          |          d          t          t          |          d          z   }|                     | j        dz   d|z  z   dz   |z             \  }}|                     d|||           ||fS )zUnblock a given CHV (Card Holder Verification == PIN)

        Args:
                chv_no : chv number (1=CHV1, 2=CHV2, ...)
                puk_code : puk code as hex string
                pin_code : new chv code as hex string
        r%   2C00r>  10unblockr@  )r;   r4  rC  r5  rA  r`   rL   s          r+   unblock_chvzSimCardCommands.unblock_chv  s     #h--$$tCMM2'>'>>>>$-&"8FVO"Lt"SVX"XYYbY"===bzr-   new_pin_codec                    t          t          |          d          t          t          |          d          z   }|                     | j        dz   d|z  z   dz   |z             \  }}|                     d|||           ||fS )zChange a given CHV (Card Holder Verification == PIN)

        Args:
                chv_no : chv number (1=CHV1, 2=CHV2, ...)
                pin_code : current chv code as hex string
                new_pin_code : new chv code as hex string
        r%   2400r>  rF  changer@  )r;   r4  r5  rI  rA  r`   rL   s          r+   
change_chvzSimCardCommands.change_chv  s     #h--$$tC,=,=r'B'BB>>$-&"8FVO"Lt"SVX"XYYbXvx<<<bzr-   c                     t          t          |          d          }|                     | j        dz   d|z  z   dz   |z             \  }}|                     d|||           ||fS )zDisable a given CHV (Card Holder Verification == PIN)

        Args:
                chv_no : chv number (1=CHV1, 2=CHV2, ...)
                pin_code : current chv code as hex string
                new_pin_code : new chv code as hex string
        r%   2600r>  r?  disabler@  r;   r4  r5  rA  r`   rL   s         r+   disable_chvzSimCardCommands.disable_chv  sm     #h--$$>>$-&"8FVO"Lt"SVX"XYYbY"===bzr-   c                     t          t          |          d          }|                     | j        dz   d|z  z   dz   |z             \  }}|                     d|||           ||fS )zEnable a given CHV (Card Holder Verification == PIN)

        Args:
                chv_no : chv number (1=CHV1, 2=CHV2, ...)
                pin_code : chv code as hex string
        r%   2800r>  r?  enabler@  rQ  s         r+   
enable_chvzSimCardCommands.enable_chv  sm     #h--$$>>$-&"8FVO"Lt"SVX"XYYbXvx<<<bzr-   c                 `    |                      dt          |          dz  |fz  dz   d          S )zlSend one ENVELOPE command to the SIM

        Args:
                payload : payload as hex string
        z80c20000%02x%srH   rW   FrX   r  r  s     r+   envelopezSimCardCommands.envelope  s9     %%&6#g,,/79S&SVZ&Zjo%pppr-   c                 n    t          |          dz  }|                     d|z  |z   d          \  }}||fS )zeSend TERMINAL PROFILE to card

        Args:
                payload : payload as hex string
        rH   z80100000%02xFrX   )rZ   rN   )r;   r  r   r`   rL   s        r+   terminal_profilez SimCardCommands.terminal_profile  sE     'lla'))>K+G7*Rbg)hhbbzr-   <     min_len_secsmax_len_secsc                     dt           dt          fd}dt          dt           fd} ||          } ||          }|                     d|z   |z   d          \  }} ||d	d
                   }	|d
d	         }
|	|
|fS )zSend SUSPEND UICC to the card.

        Args:
                 min_len_secs : mimumum suspend time seconds
                 max_len_secs : maximum suspend time seconds
        secsr   c                 |    | dk    rd| dz  z  S | dk    rd| dz  z  S | dk    rd| dz  z  S | dk    rd| dz  z  S d	| z  S )
Ni / z04%02xiQ z03%02xi  z02%02xr[  z01%02xz00%02x )r`  s    r+   encode_durationz5SimCardCommands.suspend_uicc.<locals>.encode_duration  sr    {""4K#899x4H#566u}}4E?33rzz42:..d?"r-   encc                     | d d         }t          | dd                   d         }|dk    r|dz  dz  dz  dz  S |dk    r|dz  dz  dz  S |d	k    r|dz  dz  S |d
k    r|dz  S |dk    r|S t          d          )NrH   r    r   r  r!      r[  03r   01rW   zTime unit must be 0x00..0x04)r   r*   )rd  	time_unitr   s      r+   decode_durationz5SimCardCommands.suspend_uicc.<locals>.decode_duration  s    BQBIQqS]]1%FD  {2~b(++D  {2~b((D  {2~%D  {"D  ;<<<r-   
8076000004FrX   Nr    )ry   r   rN   )r;   r]  r^  rc  rj  min_dur_encmax_dur_encr`   rL   negotiated_duration_secsresume_tokens              r+   suspend_uicczSimCardCommands.suspend_uicc  s    		## 		#& 		# 		# 		# 		#	= 	=C 	= 	= 	= 	= &ol33%ol33)),*D{*Rbg)hhb#2?48#<#< ABBx(,;;r-   tokenc                     t          t          |                    dk    rt          d          |                     d|z   d          \  }}||fS )z'Send SUSPEND UICC (resume) to the card.r"   zToken must be 8 bytes long
8076010008FrX   )rZ   r   r*   rN   )r;   rq  r`   rL   s       r+   resume_uicczSimCardCommands.resume_uicc  sS    s5zz??a9:::)),*>e)TTbbzr-   c                 D    |                      d||fz            \  }}||fS )Nz%02xca%04x00r   )r;   r   r   r`   rL   s        r+   get_datazSimCardCommands.get_data  s,    )).C:*EFFbbzr-   c                 @    |                      d|z            \  }}||fS )Nz807800%02x00r   )r;   r   r`   rL   s       r+   get_identityzSimCardCommands.get_identity$  s(    )).G*DEEbbzr-   )r   )T)rK   T)Nr   )r   FF)FFFF)FF)r   )r,  r   )r[  r\  )H__name__
__module____qualname____doc__r   ry   r<   r?   propertyrD   r   boolr   rJ   r   rN   r   r   dictr   rb   rg   r   r   r   r   r   r   Pathr   r   r   r   r   strr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r!  r%  r(  r+  r0  r2  r:  rB  rH  rM  rR  rV  rX  rZ  rp  rt  rv  rx  rb  r-   r+   r3   r3   >   s	       ) ) ( c    3 +<     S    X+ +V + + + + + +$7 7V 7 7RV 7bj 7 7 7 7* W[ F  V  ]f #)8AOS_deikses_t   < PT F  V QW -6BHW`)3HLX]^bdl^lXm   0$v $ $ $ $L) ) ) ) )'# ' ' ' '" " " " "V h    "D T&\    "`v `( ` ` ` `@( @ @ @ @[f [ [ [ [ [ d C  H    >/ / /S / / / / UZ',/$ /$ /$F /$C /$T /$ $/$19/$ /$ /$ /$b
+d 
+C 
+H 
+ 
+ 
+ 
+/$ / /3 / / / / TYTY3 3 3c 3 3D 3"36:3MQ3^f3 3 3 3j$d $s $ $ $ $5t 5 5 5 5 5d s    + +# +d +h + + + + 3 8    (+ +f +T +X + + + +  C  QU bj    >	MF 	Mx 	M 	M 	M 	M  v  x    :2 2 2 2 2` ` ` ` `H HH H H H Hc6 ch c c c cU6 Uh U U U UHv H( H H H HH H8 H H H HH H8 H H H HBh B B B B+ +3 +3 +h + + + +%F % % % %Ds DC D6 Dx D D D D
 
F 
x 
 
 
 
#        f QY    #  H    
 
 
8 
 
 
 
q q8 q q q q 8    %< %< %< %<QVWZ\bdlWlQm %< %< %< %<P H     C c    
C E&(2B,C      r-   r3   ))r|  typingr   r   	constructr   r   r   r   r	   r	  osmocom.constructr
   r   osmocom.utilsr   r   r   r   r   r   r   r   osmocom.tlvr   pySim.utilsr   r   r   r   r   pySim.exceptionsr   pySim.transportr   Unionr  ry   r,   r1   r3   rb  r-   r+   <module>r     s   *          6 6 6 6 6 6 6 6 6 6 6 6 + + + + + + - - - - - - - - N N N N N N N N N N N N N N N N N N N N ) ) ) ) ) ) L L L L L L L L L L L L L L ) ) ) ) ) ) $ $ $ $ $ $ |FDL()E E E E E E E$5V 5s 5v 5 5 5 5
h h h h h h h h h hr-   