<p>dexter <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/pysim/+/26112">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  daniel: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">commands: complete documentation strings<br><br>Some of the methods lack an explaination of the arguments. Lets add that<br>to be complete<br><br>Change-Id: Icda245e2fd5ef4556c7736d73574dfbb48168973<br>---<br>M pySim/commands.py<br>1 file changed, 107 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/pySim/commands.py b/pySim/commands.py</span><br><span>index 1faa00f..107f0f5 100644</span><br><span>--- a/pySim/commands.py</span><br><span>+++ b/pySim/commands.py</span><br><span>@@ -90,7 +90,12 @@</span><br><span>            return self._tp.get_atr()</span><br><span> </span><br><span>        def try_select_path(self, dir_list):</span><br><span style="color: hsl(0, 100%, 40%);">-            """ Try to select a specified path given as list of hex-string FIDs"""</span><br><span style="color: hsl(120, 100%, 40%);">+          """ Try to select a specified path</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 dir_list : list of hex-string FIDs</span><br><span style="color: hsl(120, 100%, 40%);">+            """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                 rv = []</span><br><span>              if type(dir_list) is not list:</span><br><span>                       dir_list = [dir_list]</span><br><span>@@ -119,11 +124,21 @@</span><br><span>                return rv</span><br><span> </span><br><span>        def select_file(self, fid:str):</span><br><span style="color: hsl(0, 100%, 40%);">-         """Execute SELECT a given file by FID."""</span><br><span style="color: hsl(120, 100%, 40%);">+               """Execute SELECT a given file by FID.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 fid : file identifier as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+           """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                 return self._tp.send_apdu_checksw(self.cla_byte + "a4" + self.sel_ctrl + "02" + fid)</span><br><span> </span><br><span>         def select_adf(self, aid:str):</span><br><span style="color: hsl(0, 100%, 40%);">-          """Execute SELECT a given Applicaiton ADF."""</span><br><span style="color: hsl(120, 100%, 40%);">+           """Execute SELECT a given Applicaiton ADF.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 aid : application identifier as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+            """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                 aidlen = ("0" + format(len(aid) // 2, 'x'))[-2:]</span><br><span>           return self._tp.send_apdu_checksw(self.cla_byte + "a4" + "0404" + aidlen + aid)</span><br><span> </span><br><span>@@ -214,6 +229,16 @@</span><br><span> </span><br><span>   def update_record(self, ef, rec_no:int, data:str, force_len:bool=False, verify:bool=False,</span><br><span>                                     conserve:bool=False):</span><br><span style="color: hsl(120, 100%, 40%);">+               """Execute UPDATE RECORD.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 ef : string or list of strings indicating name or path of linear fixed EF</span><br><span style="color: hsl(120, 100%, 40%);">+                     rec_no : record number to read</span><br><span style="color: hsl(120, 100%, 40%);">+                        data : hex string of data to be written</span><br><span style="color: hsl(120, 100%, 40%);">+                       force_len : enforce record length by using the actual data length</span><br><span style="color: hsl(120, 100%, 40%);">+                     verify : verify data by re-reading the record</span><br><span style="color: hsl(120, 100%, 40%);">+                 conserve : read record and compare it with data, skip write on match</span><br><span style="color: hsl(120, 100%, 40%);">+          """</span><br><span>           res = self.select_path(ef)</span><br><span> </span><br><span>               if force_len:</span><br><span>@@ -243,6 +268,13 @@</span><br><span>                 return res</span><br><span> </span><br><span>       def verify_record(self, ef, rec_no:int, data:str):</span><br><span style="color: hsl(120, 100%, 40%);">+            """Verify record against given data</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 ef : string or list of strings indicating name or path of linear fixed EF</span><br><span style="color: hsl(120, 100%, 40%);">+                     rec_no : record number to read</span><br><span style="color: hsl(120, 100%, 40%);">+                        data : hex string of data to be verified</span><br><span style="color: hsl(120, 100%, 40%);">+              """</span><br><span>           res = self.read_record(ef, rec_no)</span><br><span>           if res[0].lower() != data.lower():</span><br><span>                   raise ValueError('Record verification failed (expected %s, got %s)' % (data.lower(), res[0].lower()))</span><br><span>@@ -344,14 +376,24 @@</span><br><span>                return rdata, sw</span><br><span> </span><br><span>         def run_gsm(self, rand:str):</span><br><span style="color: hsl(0, 100%, 40%);">-            """Execute RUN GSM ALGORITHM."""</span><br><span style="color: hsl(120, 100%, 40%);">+                """Execute RUN GSM ALGORITHM.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 rand : 16 byte random data as hex string (RAND)</span><br><span style="color: hsl(120, 100%, 40%);">+               """</span><br><span>           if len(rand) != 32:</span><br><span>                  raise ValueError('Invalid rand')</span><br><span>             self.select_path(['3f00', '7f20'])</span><br><span>           return self._tp.send_apdu(self.cla_byte + '88000010' + rand)</span><br><span> </span><br><span>     def authenticate(self, rand:str, autn:str, context='3g'):</span><br><span style="color: hsl(0, 100%, 40%);">-               """Execute AUTHENTICATE (USIM/ISIM)."""</span><br><span style="color: hsl(120, 100%, 40%);">+         """Execute AUTHENTICATE (USIM/ISIM).</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 rand : 16 byte random data as hex string (RAND)</span><br><span style="color: hsl(120, 100%, 40%);">+                       autn : 8 byte Autentication Token (AUTN)</span><br><span style="color: hsl(120, 100%, 40%);">+                      context : 16 byte random data ('3g' or 'gsm')</span><br><span style="color: hsl(120, 100%, 40%);">+         """</span><br><span>           # 3GPP TS 31.102 Section 7.1.2.1</span><br><span>             AuthCmd3G = Struct('rand'/LV, 'autn'/Optional(LV))</span><br><span>           AuthResp3GSyncFail = Struct(Const(b'\xDC'), 'auts'/LV)</span><br><span>@@ -379,11 +421,20 @@</span><br><span>               return self._tp.send_apdu_constr_checksw(self.cla_byte, '04', '00', '00', None, None, None)</span><br><span> </span><br><span>      def activate_file(self, fid):</span><br><span style="color: hsl(0, 100%, 40%);">-           """Execute ACTIVATE FILE command as per TS 102 221 Section 11.1.15."""</span><br><span style="color: hsl(120, 100%, 40%);">+          """Execute ACTIVATE FILE command as per TS 102 221 Section 11.1.15.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 fid : file identifier as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+           """</span><br><span>           return self._tp.send_apdu_checksw(self.cla_byte + '44000002' + fid)</span><br><span> </span><br><span>      def manage_channel(self, mode='open', lchan_nr=0):</span><br><span style="color: hsl(0, 100%, 40%);">-              """Execute MANAGE CHANNEL command as per TS 102 221 Section 11.1.17."""</span><br><span style="color: hsl(120, 100%, 40%);">+         """Execute MANAGE CHANNEL command as per TS 102 221 Section 11.1.17.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 mode : logical channel operation code ('open' or 'close')</span><br><span style="color: hsl(120, 100%, 40%);">+                     lchan_nr : logical channel number (1-19, 0=assigned by UICC)</span><br><span style="color: hsl(120, 100%, 40%);">+          """</span><br><span>           if mode == 'close':</span><br><span>                  p1 = 0x80</span><br><span>            else:</span><br><span>@@ -403,53 +454,94 @@</span><br><span>                        raise SwMatchError(sw, '9000')</span><br><span> </span><br><span>   def verify_chv(self, chv_no:int, code:str):</span><br><span style="color: hsl(0, 100%, 40%);">-             """Verify a given CHV (Card Holder Verification == PIN)"""</span><br><span style="color: hsl(120, 100%, 40%);">+              """Verify a given CHV (Card Holder Verification == PIN)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 chv_no : chv number (1=CHV1, 2=CHV2, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+                     code : chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+         """</span><br><span>           fc = rpad(b2h(code), 16)</span><br><span>             data, sw = self._tp.send_apdu(self.cla_byte + '2000' + ('%02X' % chv_no) + '08' + fc)</span><br><span>                self._chv_process_sw('verify', chv_no, code, sw)</span><br><span>             return (data, sw)</span><br><span> </span><br><span>        def unblock_chv(self, chv_no:int, puk_code:str, pin_code:str):</span><br><span style="color: hsl(0, 100%, 40%);">-          """Unblock a given CHV (Card Holder Verification == PIN)"""</span><br><span style="color: hsl(120, 100%, 40%);">+             """Unblock a given CHV (Card Holder Verification == PIN)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 chv_no : chv number (1=CHV1, 2=CHV2, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+                     puk_code : puk code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+                     pin_code : new chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+         """</span><br><span>           fc = rpad(b2h(puk_code), 16) + rpad(b2h(pin_code), 16)</span><br><span>               data, sw = self._tp.send_apdu(self.cla_byte + '2C00' + ('%02X' % chv_no) + '10' + fc)</span><br><span>                self._chv_process_sw('unblock', chv_no, pin_code, sw)</span><br><span>                return (data, sw)</span><br><span> </span><br><span>        def change_chv(self, chv_no:int, pin_code:str, new_pin_code:str):</span><br><span style="color: hsl(0, 100%, 40%);">-               """Change a given CHV (Card Holder Verification == PIN)"""</span><br><span style="color: hsl(120, 100%, 40%);">+              """Change a given CHV (Card Holder Verification == PIN)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 chv_no : chv number (1=CHV1, 2=CHV2, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+                     pin_code : current chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+                     new_pin_code : new chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+             """</span><br><span>           fc = rpad(b2h(pin_code), 16) + rpad(b2h(new_pin_code), 16)</span><br><span>           data, sw = self._tp.send_apdu(self.cla_byte + '2400' + ('%02X' % chv_no) + '10' + fc)</span><br><span>                self._chv_process_sw('change', chv_no, pin_code, sw)</span><br><span>                 return (data, sw)</span><br><span> </span><br><span>        def disable_chv(self, chv_no:int, pin_code:str):</span><br><span style="color: hsl(0, 100%, 40%);">-                """Disable a given CHV (Card Holder Verification == PIN)"""</span><br><span style="color: hsl(120, 100%, 40%);">+             """Disable a given CHV (Card Holder Verification == PIN)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 chv_no : chv number (1=CHV1, 2=CHV2, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+                     pin_code : current chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+                     new_pin_code : new chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+             """</span><br><span>           fc = rpad(b2h(pin_code), 16)</span><br><span>                 data, sw = self._tp.send_apdu(self.cla_byte + '2600' + ('%02X' % chv_no) + '08' + fc)</span><br><span>                self._chv_process_sw('disable', chv_no, pin_code, sw)</span><br><span>                return (data, sw)</span><br><span> </span><br><span>        def enable_chv(self, chv_no:int, pin_code:str):</span><br><span style="color: hsl(0, 100%, 40%);">-         """Enable a given CHV (Card Holder Verification == PIN)"""</span><br><span style="color: hsl(120, 100%, 40%);">+              """Enable a given CHV (Card Holder Verification == PIN)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 chv_no : chv number (1=CHV1, 2=CHV2, ...)</span><br><span style="color: hsl(120, 100%, 40%);">+                     pin_code : chv code as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+             """</span><br><span>           fc = rpad(b2h(pin_code), 16)</span><br><span>                 data, sw = self._tp.send_apdu(self.cla_byte + '2800' + ('%02X' % chv_no) + '08' + fc)</span><br><span>                self._chv_process_sw('enable', chv_no, pin_code, sw)</span><br><span>                 return (data, sw)</span><br><span> </span><br><span>        def envelope(self, payload:str):</span><br><span style="color: hsl(0, 100%, 40%);">-                """Send one ENVELOPE command to the SIM"""</span><br><span style="color: hsl(120, 100%, 40%);">+              """Send one ENVELOPE command to the SIM</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 payload : payload as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+               """</span><br><span>           return self._tp.send_apdu_checksw('80c20000%02x%s' % (len(payload)//2, payload))</span><br><span> </span><br><span>         def terminal_profile(self, payload:str):</span><br><span style="color: hsl(0, 100%, 40%);">-                """Send TERMINAL PROFILE to card"""</span><br><span style="color: hsl(120, 100%, 40%);">+             """Send TERMINAL PROFILE to card</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                 payload : payload as hex string</span><br><span style="color: hsl(120, 100%, 40%);">+               """</span><br><span>           data_length = len(payload) // 2</span><br><span>              data, sw = self._tp.send_apdu(('80100000%02x' % data_length) + payload)</span><br><span>              return (data, sw)</span><br><span> </span><br><span>        # ETSI TS 102 221 11.1.22</span><br><span>    def suspend_uicc(self, min_len_secs:int=60, max_len_secs:int=43200):</span><br><span style="color: hsl(0, 100%, 40%);">-            """Send SUSPEND UICC to the card."""</span><br><span style="color: hsl(120, 100%, 40%);">+            """Send SUSPEND UICC to the card.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            Args:</span><br><span style="color: hsl(120, 100%, 40%);">+                  min_len_secs : mimumum suspend time seconds</span><br><span style="color: hsl(120, 100%, 40%);">+                   max_len_secs : maximum suspend time seconds</span><br><span style="color: hsl(120, 100%, 40%);">+          """</span><br><span>           def encode_duration(secs:int) -> Hexstr:</span><br><span>                  if secs >= 10*24*60*60:</span><br><span>                           return '04%02x' % (secs // (10*24*60*60))</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/pysim/+/26112">change 26112</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/pysim/+/26112"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: pysim </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Icda245e2fd5ef4556c7736d73574dfbb48168973 </div>
<div style="display:none"> Gerrit-Change-Number: 26112 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>