y>C OO;L! 6 60145555 6 KK3 4 4 4L))C OO;EEE  A !I77>> r$%!<<HHH!&&&!%%8999%%a((( -0    s?A.F..GGNr ct|jD](}d|j|j_|dkr |j|=)d|_|j}|r|jd|_|jdd|d|jd_ ||j d<|S)zPerform physical card reset and obtain ATR. Args: cmd_app : Command Application State (for unregistering old file commands) NrFr#ATR) listr'keyssccscpr*rr7r,rNr))r8cmd_applchan_nratrs rr7zRuntimeState.resets TZ__..// % %H+/DJx $ (1}} 8$$!ioo  * JqMGM 1 T7+++%) 1 "" e rr_r(c||jvrtd|zt|||j|<|j|S)zAdd a logical channel to the runtime state. You shouldn't call this directly but always go through RuntimeLchan.add_lchan().z'Cannot create already-existing lchan %d)r'r[rr(r8r_s r add_lchanzRuntimeState.add_lchansR tz(( ( (FQRR R+Hd;; 8z(##rcP||jvr |j|=dSdS)NTF)r'r[rbs r del_lchanzRuntimeState.del_lchans- tz(( ( ( 8$45rctt|}||jvr |j|SdSN)rr'r[)r8r r_s rget_lchan_by_clazRuntimeState.get_lchan_by_clas8$S)) tz(( ( (:h' '4r)rrrr rg) __name__ __module__ __qualname____doc__r>r3rr7intrcrerrhrrrr*s??////b,,,\V,$#$.$$$$#x'?rrcXeZdZdZdedefdZdeddfdZdefdZ de fdZ de fd Z de fd Zdeefd Zdeefd Zdeefd ZdeefdZdeefdZdefdZdeefdZde defdZde fdZd6de fdZd7deefdZd6defdZd6de fdZdZ de fdZ!de fdZ"d8d!ed"efd#Z#de$ee ffd$Z%d%Z&d&Z'd9d'e d"efd(Z(d)efd*Z)d9d+efd,Z*d9d+ede$ee ffd-Z+d+ed'e fd.Z,d+ed)efd/Z-d9d0efd1Z.d2Z/d0ed'e fd3Z0d6d4Z1d6d5Z2dS):r(z=Represent the runtime state of a logical channel with a card.r_rsc||_||_|jjj||_|jj|_d|_d|_ d|_ dSrg) r_rpr_scc fork_lchanr\r& selected_filerNselected_file_fcpselected_file_fcp_hex)r8r_rps rr>zRuntimeLchan.__init__sX  7<$//99"WZ !%%)"""rr c|j|}|jdkr%||_|j|_|S)zAdd a new logical channel from the current logical channel. Just affects internal state, doesn't actually open a channel with the UICC.r)rprcr_get_cwdrtrN)r8r_ new_lchans rrczRuntimeLchan.add_lchansGG%%h// =A  &*llnnI #%)%6I "rc(|jddS)Nfile_descriptorfile_descriptor_byte)rur8s rselected_file_descriptor_bytez*RuntimeLchan.selected_file_descriptor_bytes%&789OPPrc6|dS)N shareabler~r}s rselected_file_shareablez$RuntimeLchan.selected_file_shareable1133K@@rc6|dS)N structurerr}s rselected_file_structurez$RuntimeLchan.selected_file_structurerrc6|dS)N file_typerr}s rselected_file_typezRuntimeLchan.selected_file_typerrcB|jddS)Nr{ num_of_recrugetr}s rselected_file_num_of_recz%RuntimeLchan.selected_file_num_of_rec%&78<<\JJJrcB|jddS)Nr{ record_lenrr}s rselected_file_record_lenz%RuntimeLchan.selected_file_record_lenrrc6|jdS)N file_sizerr}s rselected_file_sizezRuntimeLchan.selected_file_sizes%))+666rcB|jddS)Nproprietary_informationreserved_file_sizerr}s r selected_file_reserved_file_sizez-RuntimeLchan.selected_file_reserved_file_sizes %&?@DDEYZZZrcB|jddS)Nrmaximum_file_sizerr}s rselected_file_maximum_file_sizez,RuntimeLchan.selected_file_maximum_file_sizes %&?@DDEXYYYrc\t|jtr|jS|jjS)z\Obtain the current working directory. Returns: CardDF instance ) isinstancertCardDFparentr}s rrxzRuntimeLchan.get_cwds. d(& 1 1 -% %%, ,rc||j}|j|kr)t|tr|S|j}|j|k)dS)zoObtain the currently selected application DF (if any). Returns: CardADF() instance or NoneN)rtrrCardADF)r8nodes rget_application_dfzRuntimeLchan.get_application_dfsM !kT!!$((  ;DkT!!trrGcd|vr'|d}|ddkrd|d<n|g}|}|D]2}|}d}|D]}||kr ||}n|dS3|S)zObtain the file object from the file system tree by its name without actually selecting the file. Returns: CardFile() instance or None/rr#N)splitrxget_selectables)r8rGpathlistfilep selectables selectables rget_file_by_namezRuntimeLchan.get_file_by_names $;;zz#H{b  " vH ||~~  A..00KD)   ??&z2DE# |tt rrWcd}|}|r.|j}|r%t|dr||}|p|jj|S)zInterpret a given status word relative to the currently selected application or the underlying card profile. Args: sw : Status word as string of 4 hex digits Returns: Tuple of two strings N interpret_sw)r applicationhasattrrrpr)r8rWresr4apps rrzRuntimeLchan.interpret_sw(st%%''  +/C +wsN33 +&&r**6dgo222666rNfidc t|ddstd|z|| |j|\}}nn#t $ra}||||j}|s|t|jd|dd|d|d}~wwxYw|j |}|dd d d kr6t|dd t|zd }n|dd ddkr6t|ddt|zd}n5t!|ddt|zd}|j |g||||dS)zqBlindly try to select a file and automatically add a matching file object if the file actually exists.rzNCannot select unknown file by name %s, only hexadecimal 4 digit FID is allowedrArz - Nr{r|rdfzDF.z)dedicated file, manually added at runtime)rsfidrGdescr transparentzEF.z*elementary file, manually added at runtime)rrunregister_cmdsr\ select_filerO _select_postr sw_actual RuntimeErrorrtdecode_select_responserrLupper TransparentEF LinFixedEF add_files) r8rr^data_swswmk select_respr;s r probe_filezRuntimeLchan.probe_file=s'c1a   h`cffhh h W%%% U(..s33KT33 U U U   g & & &!!#-00A   qtttQqTTJKKQT T  U(??EE ( )*@ A+ NRV V V3TC8H8H0HGIIIAA,-.DEkRVccc!c53s88>>CSCS;S'SUUU3TC@P@P8P$PRRR $$aS))) '1d+++++sA C"AB>>Crc|rZ||_t|tr||_|r'||_|j||_nd|_d|_||dSrg)rtrrrNrvrru register_cmds)r8r^rselect_resp_datas rrzRuntimeLchan._select_postfs  .!%D $(( )$(! .-=*)-);)R)RSc)d)d&&-1*)-& 7#####rctt|ts|jr|jjdkr|jjD]Q}t|dtr4|djdkr#||dj |nR|j |}|std|j d|| ||j }|j}|D]} t|tr/|jj|j|j\}}n"|j|j\}}|}l#t*$r} ||||| d} ~ wwxYw||||dS)zSelect a file (EF, DF, ADF, MF, ...). Args: file : CardFile [or derived class] instance cmd_app : Command Application State (for unregistering old file commands) FrTzCannot determine path from z to )r\N)rrrNhas_fsrpr&ritemsr,rGrtbuild_select_path_torrrvrrMrFr\rrrOr) r8rr^r inter_pathrtrr;rrs rrzRuntimeLchan.select_filews$(( T-> 4CTC[_dCdCd#gj88::@@BB   jmW55*Q-:NRV:V:VKK 1 2G<<<E'<"&',"@"@DH"@"U"UKT33"&("6"6qu"="=KT3 !    !!'=$???   '1d+++++s A(E66 FFFcJ|j}d|vrs|d}|ddkrd|d< |D]}||||jS#t$r}||||d}~wwxYw|j}t|r|} ||vr||||n| ||n*#t$r}||||d}~wwxYw|jS)zSelect a file (EF, DF, ADF, MF, ...). Args: name : Name of file to select cmd_app : Command Application State (for unregistering old file commands) rrrr#N) rtrr,ru Exceptionrrrlowerr)r8rGr^ prev_sel_filerreselss rr,zRuntimeLchan.selectsb*  $;;zz#H{b  "  !,,AKK7++++--     888 !1133 $<< ::<DDcn|j\}}|j|S)z5Request STATUS (current selected file FCP) from card.)r\statusrtr)r8rrs rrzRuntimeLchan.statuss.hoo'' s!88>>>rct|r|}|j}||S)z9Get the related CardFile object for a specified filename.)rrrtr)r8rGrs rget_file_for_filenamez"RuntimeLchan.get_file_for_filenames; $<< ::<>>T\C\^lmn o o o o o' &rdata_hexc<t|jts)td|jd|jjj|t|dz|z|j |jj |||j j S)zUpdate transparent EF binary data. Args: data_hex : hex string of data to be written offset : Offset into the file from which to write 'data_hex' rrconserve) rrtrrrr#_RuntimeLchan__check_writeable_sizelenr\ update_binaryrrpr6)r8rrs rrzRuntimeLchan.update_binary3s$,m<< t)TM_M_M_MQM_MiMqMqstt t ##CMMQ$6$?@@@x%%d&8&rcdictr~boolrrLrrrrrrrrrrxrrCardFilerrrrrr,rrrrrrrrrrrr rrrrrrrrnrrr(r(sGG * *, * * * *#.QtQQQQAAAAAAAAAAACAAAAK(3-KKKKK(3-KKKK7HSM7777[(3-[[[[Z#ZZZZ - - - - - HW$5    "S"X""""H7s7777*',',c',',',',R$$();$$$$"7,7,7,7,7,7,r(&(&3(&(&(&(&T??? ## L L# Lc L L L L tSy!1    (ooo* q qc q3 q q q q,d,,,, D D# D D D D H Hc H%c 2B H H H H 0C 03 0 0 0 0 4 44 4 4 4 4 C C C C C C    iC i3 i i i i0000 222222rr(N)rltypingrr osmocom.utilsrrrr osmocom.tlvr pySim.exceptionspySim.filesystem pySim.logr rrir/rmrrr(rnrrr0s/$#"""""""222222222222((((((!!!!!!koh N3 N3 N N N NLLLLLLLL^t2t2t2t2t2t2t2t2t2t2r