<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/pysim/+/23539">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">commands: conserve write cycles<br><br>When a record or a binary file is written the card goes throth a full<br>flash/eeprom write cycle at this location, even when the data does not<br>change. This can be optimized by reading before writing in order to<br>compere if the data we are about to write is actually different.<br><br>Change-Id: Ifd1b80d3ede15a7caa29077a37ac7cf58c9053f1<br>Related: OS#4963<br>---<br>M pySim-shell.py<br>M pySim/commands.py<br>M pySim/filesystem.py<br>3 files changed, 28 insertions(+), 5 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/39/23539/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/pySim-shell.py b/pySim-shell.py</span><br><span>index 3f26ac5..fa24e7b 100755</span><br><span>--- a/pySim-shell.py</span><br><span>+++ b/pySim-shell.py</span><br><span>@@ -67,11 +67,17 @@</span><br><span>               self.numeric_path = False</span><br><span>            self.add_settable(cmd2.Settable('numeric_path', bool, 'Print File IDs instead of names',</span><br><span>                                               onchange_cb=self._onchange_numeric_path))</span><br><span style="color: hsl(120, 100%, 40%);">+           self.conserve_write = True</span><br><span style="color: hsl(120, 100%, 40%);">+            self.add_settable(cmd2.Settable('conserve_write', bool, 'Read and compare before write',</span><br><span style="color: hsl(120, 100%, 40%);">+                                                onchange_cb=self._onchange_conserve_write))</span><br><span>                self.update_prompt()</span><br><span> </span><br><span>     def _onchange_numeric_path(self, param_name, old, new):</span><br><span>              self.update_prompt()</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      def _onchange_conserve_write(self, param_name, old, new):</span><br><span style="color: hsl(120, 100%, 40%);">+             self.rs.conserve_write = new</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       def update_prompt(self):</span><br><span>             path_list = self.rs.selected_file.fully_qualified_path(not self.numeric_path)</span><br><span>                self.prompt = 'pySIM-shell (%s)> ' % ('/'.join(path_list))</span><br><span>diff --git a/pySim/commands.py b/pySim/commands.py</span><br><span>index 9aed588..65c3891 100644</span><br><span>--- a/pySim/commands.py</span><br><span>+++ b/pySim/commands.py</span><br><span>@@ -144,9 +144,17 @@</span><br><span>                                raise ValueError('Failed to read (offset %d)' % (offset))</span><br><span>            return total_data, sw</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       def update_binary(self, ef, data, offset=0, verify=False):</span><br><span style="color: hsl(120, 100%, 40%);">+    def update_binary(self, ef, data, offset=0, verify=False, conserve=False):</span><br><span style="color: hsl(120, 100%, 40%);">+            data_length = len(data) // 2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                # Save write cycles by reading+comparing before write</span><br><span style="color: hsl(120, 100%, 40%);">+         if conserve:</span><br><span style="color: hsl(120, 100%, 40%);">+                  data_current, sw = self.read_binary(ef, data_length, offset)</span><br><span style="color: hsl(120, 100%, 40%);">+                  if data_current == data:</span><br><span style="color: hsl(120, 100%, 40%);">+                              return None, sw</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            self.select_path(ef)</span><br><span style="color: hsl(0, 100%, 40%);">-            pdu = self.cla_byte + 'd6%04x%02x' % (offset, len(data) // 2) + data</span><br><span style="color: hsl(120, 100%, 40%);">+          pdu = self.cla_byte + 'd6%04x%02x' % (offset, data_length) + data</span><br><span>            res = self._tp.send_apdu_checksw(pdu)</span><br><span>                if verify:</span><br><span>                   self.verify_binary(ef, data, offset)</span><br><span>@@ -163,7 +171,7 @@</span><br><span>           pdu = self.cla_byte + 'b2%02x04%02x' % (rec_no, rec_length)</span><br><span>          return self._tp.send_apdu(pdu)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      def update_record(self, ef, rec_no, data, force_len=False, verify=False):</span><br><span style="color: hsl(120, 100%, 40%);">+     def update_record(self, ef, rec_no, data, force_len=False, verify=False, conserve=False):</span><br><span>            r = self.select_path(ef)</span><br><span>             if not force_len:</span><br><span>                    rec_length = self.__record_len(r)</span><br><span>@@ -171,6 +179,14 @@</span><br><span>                             raise ValueError('Invalid data length (expected %d, got %d)' % (rec_length, len(data) // 2))</span><br><span>                 else:</span><br><span>                        rec_length = len(data) // 2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         # Save write cycles by reading+comparing before write</span><br><span style="color: hsl(120, 100%, 40%);">+         if conserve:</span><br><span style="color: hsl(120, 100%, 40%);">+                  data_current, sw = self.read_record(ef, rec_no)</span><br><span style="color: hsl(120, 100%, 40%);">+                       data_current = data_current[0:rec_length*2]</span><br><span style="color: hsl(120, 100%, 40%);">+                   if data_current == data:</span><br><span style="color: hsl(120, 100%, 40%);">+                              return None, sw</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            pdu = (self.cla_byte + 'dc%02x04%02x' % (rec_no, rec_length)) + data</span><br><span>                 res = self._tp.send_apdu_checksw(pdu)</span><br><span>                if verify:</span><br><span>diff --git a/pySim/filesystem.py b/pySim/filesystem.py</span><br><span>index 6adffd9..f2b1677 100644</span><br><span>--- a/pySim/filesystem.py</span><br><span>+++ b/pySim/filesystem.py</span><br><span>@@ -590,6 +590,7 @@</span><br><span>             self.mf.add_application(a)</span><br><span>         for f in self.profile.files_in_mf:</span><br><span>             self.mf.add_file(f)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.conserve_write = True</span><br><span> </span><br><span>     def _match_applications(self):</span><br><span>         """match the applications from the profile with applications on the card"""</span><br><span>@@ -690,7 +691,7 @@</span><br><span>     def update_binary(self, data_hex, offset=0):</span><br><span>         if not isinstance(self.selected_file, TransparentEF):</span><br><span>             raise TypeError("Only works with TransparentEF")</span><br><span style="color: hsl(0, 100%, 40%);">-        return self.card._scc.update_binary(self.selected_file.fid, data_hex, offset)</span><br><span style="color: hsl(120, 100%, 40%);">+        return self.card._scc.update_binary(self.selected_file.fid, data_hex, offset, conserve=self.conserve_write)</span><br><span> </span><br><span>     def update_binary_dec(self, data):</span><br><span>         data_hex = self.selected_file.encode_hex(data)</span><br><span>@@ -710,7 +711,7 @@</span><br><span>     def update_record(self, rec_nr, data_hex):</span><br><span>         if not isinstance(self.selected_file, LinFixedEF):</span><br><span>             raise TypeError("Only works with Linear Fixed EF")</span><br><span style="color: hsl(0, 100%, 40%);">-        return self.card._scc.update_record(self.selected_file.fid, rec_nr, data_hex)</span><br><span style="color: hsl(120, 100%, 40%);">+        return self.card._scc.update_record(self.selected_file.fid, rec_nr, data_hex, conserve=self.conserve_write)</span><br><span> </span><br><span>     def update_record_dec(self, rec_nr, data):</span><br><span>         hex_data = self.selected_file.encode_record_hex(data)</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/pysim/+/23539">change 23539</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/+/23539"/><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: Ifd1b80d3ede15a7caa29077a37ac7cf58c9053f1 </div>
<div style="display:none"> Gerrit-Change-Number: 23539 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>