<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/pysim/+/24036">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">utils: Introduce CommandSet abstraction<br><br>This will allow us to match INS -> name and add more related<br>bits in the future (e.g. for decoding APDU traces)<br><br>Change-Id: I314ff15186dc05778ea12363cac0a310b6c7713c<br>---<br>M pySim/utils.py<br>1 file changed, 67 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/36/24036/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/pySim/utils.py b/pySim/utils.py</span><br><span>index de41dfb..f0e1b40 100644</span><br><span>--- a/pySim/utils.py</span><br><span>+++ b/pySim/utils.py</span><br><span>@@ -1160,3 +1160,70 @@</span><br><span>             encoded += e.encode(decoded[i])</span><br><span>             i += 1</span><br><span>         return encoded</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class CardCommand:</span><br><span style="color: hsl(120, 100%, 40%);">+    """A single card command / instruction."""</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, name, ins, cla_list=None, desc=None):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.name = name</span><br><span style="color: hsl(120, 100%, 40%);">+        self.ins = ins</span><br><span style="color: hsl(120, 100%, 40%);">+        self.cla_list = [x.lower() for x in cla_list]</span><br><span style="color: hsl(120, 100%, 40%);">+        self.desc = desc</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __str__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        return self.name</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __repr__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        return '%s(INS=%02x,CLA=%s)' % (self.name, self.ins, self.cla_list)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def match_cla(self, cla):</span><br><span style="color: hsl(120, 100%, 40%);">+        """Does the given CLA match the CLA list of the command?."""</span><br><span style="color: hsl(120, 100%, 40%);">+        if not isinstance(cla, str):</span><br><span style="color: hsl(120, 100%, 40%);">+            cla = '%02u' % cla</span><br><span style="color: hsl(120, 100%, 40%);">+        cla = cla.lower()</span><br><span style="color: hsl(120, 100%, 40%);">+        for cla_match in self.cla_list:</span><br><span style="color: hsl(120, 100%, 40%);">+            cla_masked = ""</span><br><span style="color: hsl(120, 100%, 40%);">+            for i in range(0, 2):</span><br><span style="color: hsl(120, 100%, 40%);">+                if cla_match[i] == 'x':</span><br><span style="color: hsl(120, 100%, 40%);">+                    cla_masked += 'x'</span><br><span style="color: hsl(120, 100%, 40%);">+                else:</span><br><span style="color: hsl(120, 100%, 40%);">+                    cla_masked += cla[i]</span><br><span style="color: hsl(120, 100%, 40%);">+            if cla_masked == cla_match:</span><br><span style="color: hsl(120, 100%, 40%);">+                return True</span><br><span style="color: hsl(120, 100%, 40%);">+        return False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class CardCommandSet:</span><br><span style="color: hsl(120, 100%, 40%);">+    """A set of card instructions, typically specified within one spec."""</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, name, cmds=[]):</span><br><span style="color: hsl(120, 100%, 40%);">+        self.name = name</span><br><span style="color: hsl(120, 100%, 40%);">+        self.cmds = {}</span><br><span style="color: hsl(120, 100%, 40%);">+        for c in cmds:</span><br><span style="color: hsl(120, 100%, 40%);">+            self.cmds[c.ins] = c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __str__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+        return self.name</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __getitem__(self, idx):</span><br><span style="color: hsl(120, 100%, 40%);">+        return self.cmds[idx]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __add__(self, other):</span><br><span style="color: hsl(120, 100%, 40%);">+        if isinstance(other, CardCommand):</span><br><span style="color: hsl(120, 100%, 40%);">+            if other.ins in self.cmds:</span><br><span style="color: hsl(120, 100%, 40%);">+                raise ValueError('%s: INS 0x%02x already defined: %s' %</span><br><span style="color: hsl(120, 100%, 40%);">+                                 (self, other.ins, self.cmds[other.ins]))</span><br><span style="color: hsl(120, 100%, 40%);">+            self.cmds[other.ins] = other</span><br><span style="color: hsl(120, 100%, 40%);">+        elif isinstance(other, CardCommandSet):</span><br><span style="color: hsl(120, 100%, 40%);">+            for c in other.cmds.keys():</span><br><span style="color: hsl(120, 100%, 40%);">+                self.cmds[c] = other.cmds[c]</span><br><span style="color: hsl(120, 100%, 40%);">+        else:</span><br><span style="color: hsl(120, 100%, 40%);">+            raise ValueError('%s: Unsupported type to add operator: %s' % (self, other))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def lookup(self, ins, cla=None):</span><br><span style="color: hsl(120, 100%, 40%);">+        """look-up the command within the CommandSet."""</span><br><span style="color: hsl(120, 100%, 40%);">+        ins = int(ins)</span><br><span style="color: hsl(120, 100%, 40%);">+        if not ins in self.cmds:</span><br><span style="color: hsl(120, 100%, 40%);">+            return None</span><br><span style="color: hsl(120, 100%, 40%);">+        cmd = self.cmds[ins]</span><br><span style="color: hsl(120, 100%, 40%);">+        if cla and not cmd.match_cla(cla):</span><br><span style="color: hsl(120, 100%, 40%);">+            return None</span><br><span style="color: hsl(120, 100%, 40%);">+        return cmd</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/pysim/+/24036">change 24036</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/+/24036"/><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: I314ff15186dc05778ea12363cac0a310b6c7713c </div>
<div style="display:none"> Gerrit-Change-Number: 24036 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>