Ui dZddlZddlZddlZddlZddlZddlmZddlm Z m Z m Z m Z m Z mZmZddlTddlmZmZedeZedeZe eefZd efd Zd ed e efd Zd ed efdZded efdZdeeefd efdZdeded efdZded e fdZ!ded efdZ"ded efdZ#ded efdZ$ded efdZ%ded e efdZ&ded e ee ffdZ'ded e fd Z(d!ed"ed efd#Z)d efd$Z*d%efd&Z+d ed e efd'Z,dVd ed)e-d e efd*Z.d+ed,ed-ed efd.Z/dWd+ed,ed-ed efd0Z0dXd efd1Z1d2Z2d3ed4ed e-fd5Z3 dYd:ed;edZ4d?Z5d@ed efdAZ6dZdCZ7dDe8d efdEZ9dFZ:dGZ;GdHdIej<Z=GdJdKe=Z>GdLdMZ?GdNdOe?Z@GdPdQZAGdRdSZBGdTdUZCdS)[z pySim: various utilities N)BytesIO)OptionalListDictAnyTupleNewTypeUnion)*)bertlv_encode_tagbertlv_encode_lenSwHexstr SwMatchstrimsic tt|dz}t|dz}d|ztd|dzdzt|dfzz}|S)z7Converts a string IMSI into the encoded value of the EF%02xz%01x%s) half_round_uplen swap_nibblesrpad)rloeeis ;/home/jenkins/workspace/simtester-sanitize/./pySim/utils.pyenc_imsir5sb D A   A TQB !l8a1}d4nn.M#MNN NB Iefreturncvt|dkrdSt|ddddz}|dz }t|ddd}t|dkrdSt|ddz dz}|s|dz }|t|dz krdS|dd}|S) z6Converts an EF value to the IMSI string representationNrrfr)rintrrstrip)r rswappedrrs rdec_imsir*>s 2ww{{t BqsGR1A AA2abb6""))#..G 7||at gaj//Q ! #B  aCCLL1 t 122;D KrcFt|dS)Nr&)rstrip)r s r dec_iccidr-Qs    ! !# & &&riccidc<tt|dS)N)rrr.s r enc_iccidr2Us UB ( ((rct|}t|dkrtdt|dkrtdt|dkr|tt|z }t|dkrt |t|dkr@ t |n/#t$r"|tt|z }YnwxYw|S)Nz,ICCID input value must be at least 18 digitsr0z+ICCID input value must be at most 20 digits)strr ValueErrorcalculate_luhn verify_luhnr1s rsanitize_iccidr:Xs JJE 5zzBGHHH 5zzBFGGG 5zzR ^E**+++ 5zzR E 5zzR 0      0 0 0 S..// /EEE 0 Ls<C )C87C8mccmncc|}|}t|dkrd}n4t|dkr d|zdz}nt|dkr|dz }t|dkrd}n1t|dkrd|z}nt|dkrd|z}|d|dz|d|dzz|d|dzzS)z,Converts integer MCC/MNC into 3 bytes for EFrFFFr0Fr$00)r,rr;r<s renc_plmnrCqs ))++C ))++C 3xx1}} SQCi#o SQ s  3xx1}} SQSj SQCi FSVOAQ 0CFSVO DDr threehexbytescvddd}t|t||d<t||d<|S)Nr?rBr;r<dec_mcc_from_plmn_strdec_mnc_from_plmn_str)rDress rdec_plmnrJsDc " "C-(((&}55CJ&}55CJ Jrplmnct|}|ddz}|ddzdz }|ddz}|dkr|dkr|dkrdSt|||S)Nrrr#r)h2i derive_mccrKiadigit1digit2digit3s rdec_mcc_from_plmnrVsi TB UT\Fedlq F UT\F }}36S==u fff - --rc|d}|d}|d}||z|z}|dS)Nrrrr@upperr,rKrSrTrUrIs rrGrGG !WF !WF !WF 6/F "C 99;;  S ! !!rct|}|ddz}|ddzdz }|ddzdz }|dkr|dkr|dkrdSt|||S)Nr$rrMr#rrN)rO derive_mncrQs rdec_mnc_from_plmnr^sn TB UT\Fedlq Fedlq F }}36S==u fff - --rc|d}|d}|d}||z|z}|dS)Nr#r$r@rXrZs rrHrHr[r twohexbytescddddddddddd dd d dg}t|}|d d z|dz}t}|D]+}|d|dzzr||d,|dz}|dvr+|d|dn7|dkr|dn|dkr|d|dz}|dvr+|d|dn=|dzdkr|dn|dzdkr|dtt |S)NrUTRAN)bitname zNG-RANz GSM COMPACTr`z cdma2000 HRPDr#zcdma2000 1xRTTrrrdrep)i@riz E-UTRAN WB-S1z E-UTRAN NB-S1iPi`)rjGSMz EC-GSM-IoT)rOsetaddsortedlist)raact_listrRu16tsela eutran_bitsgsm_bitss rdec_actrysG$$H%%M**O,,,-- H [  B qEQJ"Q% D %%C  1%= !  GGAfI   -K&&&                      f}H###    &   &    $s))  r fivehexbytescddgd}d}d}|d|}||||z}t||d<t||d<t||d<|S)Nr?r;r<actrgr#r;r<r})rGrHry)rzrI plmn_chars act_charsplmn_stract_strs rdec_xplmn_w_actrsuc" - -CJIKZK(H:j9&<<=G&x00CJ&x00CJ!!CJ Jrcrddgd}d}|d|}t||d<t||d<|S)Nrr|rgr;r<rF)rDrIr~rs r dec_xplmnrsKAb ) )CJ[j[)H&x00CJ&x00CJ Jrki_hexop_hexcddlm}ddlm}t t |}t t |}|||j}||}t|||S)zD Run the milenage algorithm to calculate OPC from Ki and OP r)AES)strxor) Cryptodome.CipherrCryptodome.Util.strxorrbytesh2bnewMODE_ECBencryptb2h)rrrrki_bytesop_bytesaes opc_bytess rderive_milenage_opcrs&%%%%%------S[[!!HS[[!!H ''(CL ) )C H%%I vvi** + ++rc tttt|}dt |dddd|dddDzdzz }|dkrdn|S)z= Calculate Luhn checksum used in e.g. ICCID and IMEI NcNg|]"}tt|dzd#S)r$r)sumdivmod).0ds r z"calculate_luhn.. s>*/*/*/ +.fQUB.?.?*@*@*/*/*/rr)rrmapr'r6r)ccnum check_digits rr8r8s s3B  ! !Cs3rv2v;*/*/$'"I*/*/*//002455Kr!!11{2rdigitsct|dd}t||dkr(tdt|d|ddS)zBVerify the Luhn check digit; raises ValueError if it is incorrect.Nz%Luhn check digit mismatch: should be z but is )r8r6r7)rcds rr9r9sc ss $ $B 2ww&*jPSTVPWPWPWPWY_`bYcYcdeeercH|dSt|dkr |ddSdS)zU Derive the MCC (Mobile Country Code) from the first three digits of an IMSI Nrr)rs r mcc_from_imsirs/ |t 4yy1}}BQBxtrFlongc`|dSt|dkr|r |ddS|ddSdS)zS Derive the MNC (Mobile Country Code) from the 4th to 6th digit of an IMSI Nrrgr`r)rrs r mnc_from_imsir#sF |t 4yy1}}  !9 !9 trrSrTrUcXd}|dkr||dzz }|dkr||dzz }|dkr||z }|S)ze Derive decimal representation of the MCC (Mobile Country Code) from three given digits. rrdr)rSrTrUr;s rrPrP3sN C ~~ v| ~~ v{ ~~ v  Jrrcjd}|dkrt|||S|dkr||dzz }|dkr||z }|S)zy Derive decimal representation of the MNC (Mobile Network Code) from two or (optionally) three given digits. rrr)rP)rSrTrUr<s rr]r]EsT C~~&&&111 ~~ v{ ~~ v  Jrc`|Rt|dkr0dd|D}t|d}ntd|Wt|dkr5|} t |}n1#t$r}td|d}~wwxYwtd|S) a The ADM pin can be supplied either in its hexadecimal form or as ascii string. This function checks the supplied opts parameter and returns the pin_adm as hex encoded string, regardless in which form it was originally supplied by the user Nrhc2g|]}dt|zS)r)ordrxs rrz$sanitize_pin_adm..cs#BBBQvQ0BBBrr%z&PIN-ADM needs to be <=8 digits (ascii)z1PIN-ADM needs to be hex encoded using this optionz3PIN-ADM needs to be exactly 16 digits (hex encoded))rjoinrr7r)pin_adm pin_adm_hex try_encodeexcs rsanitize_pin_admrYs w<<1  ggBB'BBBCCG7B''GGEFF F {  r ! !!G _ \\  _ _ _ !TUU[^^ _RSS S Ns-A== BBBct|dkrdS|d} ddl}||}|jdkrdS|jdkrdSn:#t $r-d}|D] }ddl}|d |sd }n!|rYdSYnwxYwd}|D] }ddl}|d |sd }n!|rdSdS) z Validates the given address and returns it's type (FQDN or IPv4 or IPv6) Return: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), None (Bad address argument given) TODO: Handle IPv6 rN.r#rrgr$Tz ^[0-9_]+$Fz ^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)?$)rsplit ipaddress ip_addressversion Exceptionrematch)addr addr_listripa invalid_ipv4ir fqdn_flags r get_addr_typerwsG 4yyA~~t 3I""4(( ;!  4 [A  4       A III88K++ $    44   I  xx:A>> I E  t 4s$A  A 1BBswpatternc|}d}tddD]1}||dkr|dz}||dkr|dz}&|||z}2||kS)z%Match given SW against given pattern.rrr#?r)lowerrange)rrsw_lower sw_maskedrs rsw_matchrs|xxzzHI 1a[[00 1:  !CII QZ3  !CII!HQK/II  rOr$rTwidthhspacelspace align_leftc|dSt|dkrdSt|t}t||z}||z}t|dz |zdz}g} tt|D]V} || d|} |rd} nd} | |zt| z} d|z| z} | | t | zWd | S) aZPretty print a list of strings into a tabulated form. Args: width : total width in characters per line space : horizontal space between cells lspace : number of spaces before row align_lef : Align text to the left side Returns: multi-line string containing formatted table Nrr)keyrz%%-%dsz%%%ds  )rmaxiterrappendtupler)str_listrrrr longest_strcellwithcolsrowstabler str_list_rowformat_str_cellformat_str_rows rtabulate_str_listrs r 8}}rhC(((K;&(H H D MMA $ & *D E %++  ;;4(  &&OO%O)H4L8I8II,.8 ^eL&9&99:::: 99U  rc`|ddkrk|d}|dkr ||dz }n ||dz}|dzt|dz z }|dkr|S|d||zS|ddkrt|dzr|S|d}|dzr|S|dkr||dz |}n||dz|dz}|dzt|dz z }|dkr|S|d||dzzS|S)apExpand a given hexstring to a specified length by replacing "." or ".." with a filler that is derived from the neighboring nibbles respective bytes. Usually this will be the nibble respective byte before "." or "..", except when the string begins with "." or "..", then the nibble respective byte after "." or ".." is used.". In case the string cannot be expanded for some reason, the input string is returned unmodified. Args: hexstring : hexstring to expand length : desired length of the resulting hexstring. Returns: expanded hexstring rrrr$z..r#)countindexrreplace) hexstringlengthposfillermissings r expand_hexrsm sq  ooc"" 77sQw'FFsQw'F1*I 23 a<<   fw&6777   ! # # y>>A   ood## 7   77sQws{+FFsQws1u}-F1*I 23 a<<   vA'>??? r num_nibblesc$|dz}|dzr|dz }|S)zHcompute the number of bytes needed to store the given number of nibbles.r$rr)rn_bytess rbytes_for_nibblesrs&QGQ1  NrPct||dz krt|dz}d|z}dt|dz zdz}|||zz }|d|zz }|S)z0Generate a string that contains a boxed heading.r##z # %-zs # )rr6)headingrrIfstrs rboxed_heading_strrsm 7||eaiG q  +C c%!)nn $w .D47 C3;C Jrapduc Ht|dkr d}d}d}d|||fSt|dkrd}|d}|dkrd}d}d|||fSt|dkr|d}|dkrd}|d|dz}t|d|zkrd}d|||fSt|d|zdzkr|d|z}|dkrd}d|||fStd t|||t|dd fztd t|z) a*Parse a given command APDU and return case (see also ISO/IEC 7816-3, Table 12 and Figure 26), lc, le and the data field. Args: apdu : hexstring that contains the command APDU Returns: tuple containing case, lc and le values of the APDU (case, lc, le, data) r#rrrr`r$rzRinvalid APDU (%s), Lc=0x%02x (%d) does not match the length (%d) of the data fieldNzinvalid APDU (%s), too short!)rr7r)rlcledatas rparse_command_apdur&sm 4yyA~~  2r4  Ta  !W 77B2r4  TQ !W 77BAbdF| t99B  Br2t$ $ YY!b&1* $ $a"fBQwwr2t$ $q #D 2r3tABBx==ABCC C83t99DEEErcb|dd}|dd}g}t|dkr<|dd|dd}}||t|dk>> normalize("3B:A7:00:40:18:80:65:A2:08:01:01:52") [59, 167, 0, 64, 24, 128, 101, 162, 8, 1, 1, 82] :rrr$Nrz"warning: odd string, remainder: %rc.g|]}t|dS)r%)r'rs rrz normalizeATR..ms # # #!3q":: # # #r)rrrr7)atrrIbytes r normalizeATRrUs ++c2  C ++c2  C C c((a--GSWc 4 c((a-- 3xx!||=CDDD # #s # # #C Jrcd}t|}i}||d<d|di|d<|d}d|i|d<|dz}d}d}|dz|d<|t|kr|d zd kr!|dz }d |vri|d <d||i|d |<|d zd kr!|dz }d |vri|d <d||i|d |<|dzd kr!|dz }d|vri|d<d||i|d|<|dzd kr7|dz }d|vri|d<||}d|i|d|<|dz|krd|d<|dz }nn|t|kd||dz|dz|zi|d<|dz|z}d|vr+ d||i|d<n#t$r ddi|d<YnwxYw|dz }t||kr ||d|d<t|dd|kr:|t|ddz }|dkrd\} } nd\} } d|| | fz|d<|S)aDecompose the ATR in elementary fields Args: atr_txt: ATR as a hex bytes string Returns: dictionary of field and values >>> decomposeATR("3B A7 00 40 18 80 65 A2 08 01 01 52") { 'T0': {'value': 167}, 'TB': {1: {'value': 0}}, 'TC': {2: {'value': 24}}, 'TD': {1: {'value': 64}}, 'TS': {'value': 59}, 'atr': [59, 167, 0, 64, 24, 128, 101, 162, 8, 1, 1, 82], 'hb': {'value': [128, 101, 162, 8, 1, 1, 82]}, 'hbn': 7} rr valueTSrT0rhbnTATBTCTDTTCKhbrNextra)sare)risz&ATR is truncated: %d byte%s %s missingwarning)rr IndexError) atr_txtATR_PROTOCOL_TYPE_T0r TDi hb_lengthpointerpnlastrt1t2s r decomposeATRr.rs$7##G CCJ'!*%CI !*C#CIbIG BsCJ CLL $J4   qLG3D $gg&67CIbM $J4   qLG3D $gg&67CIbM $J4   qLG3D $gg&67CIbM $J4   qLG3D '"C$cNCIbMd 333!E !GBB C CLL H''A+! i0G"GHICI Q; "D || '!74=1CJJ ' ' '!2CJJJ '   7||dtuu~G  3t9W **c#d)G"4555 Q;;#HR!HRAWbRTDUUI Js EE21E2ceZdZdZddedeedeefdZdZdefd Z dd Z dd Z defdZ de fdZejdefdZejdefdZdedefdZdefdZdedee effdZdefdZdS) DataObjecta`A DataObject (DO) in the sense of ISO 7816-4. Contrary to 'normal' TLVs where one simply has any number of different TLVs that may occur in any order at any point, ISO 7816 has the habit of specifying TLV data but with very specific ordering, or specific choices of tags at specific points in a stream. This class tries to represent this.NredesctagcL||_||_||_d|_d|_dS)z Args: name: A brief, all-lowercase, underscore separated string identifier desc: A human-readable description of what this DO represents tag : The tag associated with this DO N)rer1r2decodedencoded)selfrer1r2s r__init__zDataObject.__init__s+    rc|jSNrer6s r__str__zDataObject.__str__ yrr!c&|jd|jdS)N()) __class__rer;s r__repr__zDataObject.__repr__s>>>499955rDataObjectChoicec`t|trtd||gSt)z7OR-ing DataObjects together renders a DataObjectChoice.Nmembers) isinstancer0rC TypeErrorr6others r__or__zDataObject.__or__s0 eZ ( ( #D4-@@@ @OrDataObjectCollectionc`t|trtd||gSt)zCompute the tag (sometimes the tag encodes part of the value).r2r;s r _compute_tagzDataObject._compute_tags xrc|j|jiS)z,Return a dict in form "name: decoded_value" )rer4r;s rto_dictzDataObject.to_dicts 4<((rdocdS)zParse the value part of the DO into the internal state of this instance. Args: do : binary encoded bytes Nr)r6rTs r from_byteszDataObject.from_bytesrcdS)zEncode the internal state of this instance into the TLV value part. Returns: binary bytes encoding the internal state Nrr;s rto_byteszDataObject.to_bytes rWrc|d|jkrtd||jfz|d}|dd|z}|||d|zdS)aSParse binary TLV representation into internal state. The resulting decoded representation is _not_ returned, but just internalized in the object instance! Args: do : input bytes containing TLV-encoded representation Returns: bytes remaining at end of 'do' after parsing one TLV/DO. rz%s: Can only decode tag 0x%02xrr$N)r2r7rV)r6rTrvals rfrom_tlvzDataObject.from_tlvsw a5DH  ="DH-.// /A1V8n !F())}rc|}t|tt |z|zS)zpEncode internal representation to binary TLV. Returns: bytes encoded in TLV format. )rYr rQr r)r6r[s rto_tlvzDataObject.to_tlv$sE mmoo !2!2!4!4558I#c((8S8SSVYYYrbinaryc|d}||jkrtd||||jfz||}||fS)zDecode a single DOs from the input data. Args: binary : binary bytes of encoded data Returns: tuple of (decoded_result, binary_remainder) rz-%s: Unknown Tag 0x%02x in %s; expected 0x%02x)r2r7r\rS)r6r_r2 remainders rdecodezDataObject.decode-sdQi $(??L"C:;<< <MM&))   **rc*|Sr9)r^r;s rencodezDataObject.encode<s{{}}rNNr!rCr!rL)__name__ __module__ __qualname____doc__r6rr'r7r<rBrKrNrQdictrSabcabstractmethodrrVrYr\r^rrbrdrrrr0r0sQQ  S  8C=    6#6666c)))))  U      %    5U"ZZZZZ +U +uT5['9 + + + +rr0cJeZdZdZd dededeffd ZdefdZd efd Z xZ S) TL0_DataObjectz2Data Object that has Tag, Len=0 and no Value part.Nrer1r2c\t|||||_dSr9)superr7r[)r6rer1r2r[rAs rr7zTL0_DataObject.__init__Cs* tS)))rr_cRt|dkrt|j|_dSNr)rr7r[r4)r6r_s rrVzTL0_DataObject.from_bytesGs& v;;!   x rr!cdS)Nrrr;s rrYzTL0_DataObject.to_bytesLssrr9) rhrirjrkr6r'r7rrVrY __classcell__)rAs@rrprp@s<<S#     %rrpc|eZdZdZd dedeefdZdefdZdefdZdd Z d e de e e ffd Z de fd ZdS)rLzA DataObjectCollection consists of multiple Data Objects identified by their tags. A given encoded DO may contain any of them in any order, and may contain multiple instances of each DO.Nrer1c||_||_|pg|_i|_i|_d|D|_d|D|_dS)Nci|] }|j| SrrPrms r z1DataObjectCollection.__init__..[s999Aqua999rci|] }|j| Srr:rzs rr|z1DataObjectCollection.__init__..\s;;;a;;;r)rer1rFmembers_by_tagmembers_by_name)r6rer1rFs rr7zDataObjectCollection.__init__Us]  }"  !99999;;7;;;rr!cdd|jD}|jdd|dS)Nc,g|]}t|Srr6rs rrz0DataObjectCollection.__str__.._s444!s1vv444rr?,r@)rFrerr6 member_strss rr<zDataObjectCollection.__str__^s:44t|444 999chh{&;&;&;&;<.cs5551tAww555rr?rr@)rFrArrs rrBzDataObjectCollection.__repr__bs:55 555 >>>388K+@+@+@+@AArct|tr*|j|jz}t|j|j|St|t r$t|j|j|j|gzSt )zDExtending DataCollections with other DataCollections or DataObjects.)rGrLrFrer1r0rHr6rJrFs rrNzDataObjectCollection.__add__fso e1 2 2 lU]2G' 49gFF F z * * ' 49dleW>TUU UOrr_cpg}|}t|r|d}|dkr||fS||jvr-td||||jfz|j|}||}||t|||fS)aDecode any number of DOs from the collection until the end of the input data, or uninitialized memory (0xFF) is found. Args: binary : binary bytes of encoded data Returns: tuple of (decoded_result, binary_remainder) rr)%s: Unknown Tag 0x%02x in %s; expected %s)rr~r7keysr\rrS)r6r_rIrar2objs rrbzDataObjectCollection.decodess )nn &A,Cd{{Y''$--- !L"&Y8K8P8P8R8R!S"TUUU%c*C Y//I JJs{{}} % % %)nn &Yrct}|D]D}||d}||E|Srt) bytearrayrrr^)r6r4rIrrs rrdzDataObjectCollection.encodesSkk % %A&&qt,,C JJszz|| $ $ $ $ rrerg)rhrirjrkr6rr7r<rBrNrrrrbrdrrrrLrLPs< !d)))H"C1D1I1I1K1KLMNN N!#&LL((  y))rc|jt|d}t|d|_|Srt)rrrvaluesr4r^)r6r4rs rrdzDataObjectChoice.encodesF"4==#347>>++,,Q/ zz||rNrf) rhrirjrkrNrKrrrlrbrdrrrrCrCs    *U*uT5['9****$rrCceZdZdZddedeefdZdefdZdefdZdd Z d e de e e ffd Z d e de e e ffd Zde fdZde fdZdS)DataObjectSequenceaDA sequence of DataObjects or DataObjectChoices. This allows us to express a certain ordered sequence of DOs or choices of DOs that have to appear as per the specification. By wrapping them into this formal DataObjectSequence, we can offer convenience methods for encoding or decoding an entire sequence.Nrer1c4|pg|_||_||_dSr9)sequencerer1)r6rer1rs rr7zDataObjectSequence.__init__s B   rr!cdd|jD}|jdd|dS)Nc,g|]}t|Srrrs rrz.DataObjectSequence.__str__..s555!s1vv555rr?rr@)rrerrs rr<zDataObjectSequence.__str__s:55t}555 999chh{&;&;&;&;<.s6661tAww666rr?rr@)rrArrs rrBzDataObjectSequence.__repr__s:66 666 >>>388K+@+@+@+@AArcFt|dr$t|j|j|j|gzSt|dr$t|j|j|j|gzSt|dr(t|j|j|j|jzSdS)z>Add (append) a DataObject or DataObjectChoice to the sequence.r0rCrN)rGrrer1rrIs rrNzDataObjectSequence.__add__s e\ * * \%diDMUG."s :::q:::r)reinscla_listr1)r6rerrr1s rr7zCardCommand.__init__s=  B ::DM:::  rc|jSr9r:r;s rr<zCardCommand.__str__%r=rc0d|j|j|jfzS)Nz%s(INS=%02x,CLA=%s))rerrr;s rrBzCardCommand.__repr__(s$ 48T]'KKKrct|tsd|z}|}|jD]=}d}t ddD]}||dkr|dz }|||z } ||krdS>dS)z6Does the given CLA match the CLA list of the command?.z%02urrr$rTF)rGr6rrr)r6cla cla_match cla_maskedrs r match_clazCardCommand.match_cla+s#s## 3,Ciikk  IJ1a[[ ) )Q<3&&#%JJ#a&(JJY&&tt'urre)rhrirjrkr7r<rBrrrrrrs^..LLLrrc6eZdZdZgfdZdZdZdZddZdS) CardCommandSetz@A set of card instructions, typically specified within one spec.c6||_d|D|_dS)Nci|] }|j| Sr)r)rcs rr|z+CardCommandSet.__init__..As,,,!QUA,,,r)recmds)r6rers rr7zCardCommandSet.__init__?s" ,,t,,, rc|jSr9r:r;s rr<zCardCommandSet.__str__Cr=rc|j|Sr9)r)r6idxs r __getitem__zCardCommandSet.__getitem__Fsy~rcvt|trI|j|jvr*t d||j|j|jfz||j|j<dSt|t r3|jD]}|j||j|<dSt |d|)Nz"%s: INS 0x%02x already defined: %sz$: Unsupported type to add operator: )rGrrrr7rr)r6rJrs rrNzCardCommandSet.__add__Is e[ ) ) LyDI%% !E"& 49UY3G!H"IJJJ#(DIei ~ . . LZ__&& - -$z!} !  - ->BddEEJLL LrNct|}||jvrdS|j|}|r||sdS|S)z*look-up the command within the CommandSet.N)r'rr)r6rrcmds rlookupzCardCommandSet.lookupVsO#hhdi4in  s}}S)) 4 rr9) rhrirjrkr7r<rrNrrrrrr<suJJ"$---- L L Lrr)F)rr9)rr$rT)r)Drkjsonrmstringdatetimeargparseiortypingrrrrrr r osmocom.utils osmocom.tlvr r r6rrHexstrResTuplerr*r-r2r'r:rCrlrJrVrGr^rHryrrrr8r9rboolrrPr]rrrrrrrrrrr.ABCr0rprLrCrrrrrrrsv CCCCCCCCCCCCCCCCCC<<<<<<<