Make it possible to override tags
Replace the "= object()" with a proper class and explanation git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@93 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
68960b8c8b
commit
54c53d262c
36
TLV_utils.py
36
TLV_utils.py
|
@ -1,12 +1,28 @@
|
|||
import binascii, utils, sre
|
||||
import binascii, utils, sre, sys
|
||||
|
||||
context_FCP = object()
|
||||
context_FMD = object()
|
||||
context_FCI = object()
|
||||
recurse = object()
|
||||
binary = object()
|
||||
number = object()
|
||||
ascii = object()
|
||||
class identifier:
|
||||
"""An identifier, because I'm too lazy to use quotes all over the place.
|
||||
Instantiating an object of this type registers a name in the current scope, essentially
|
||||
making each instantiation of this class equal to
|
||||
foo = identifier("foo")
|
||||
even when you only write
|
||||
identifier("foo")
|
||||
"""
|
||||
def __init__(self,name):
|
||||
self.name = name
|
||||
sys._getframe(1).f_locals[name] = self
|
||||
def __str__(self):
|
||||
return self.name
|
||||
def __repr__(self):
|
||||
return "identifier(%r)" % self.name
|
||||
|
||||
identifier("context_FCP")
|
||||
identifier("context_FMD")
|
||||
identifier("context_FCI")
|
||||
identifier("recurse")
|
||||
identifier("binary")
|
||||
identifier("number")
|
||||
identifier("ascii")
|
||||
|
||||
file_descriptor_byte_descriptions = [
|
||||
#mask byte no match match
|
||||
|
@ -241,7 +257,7 @@ def tlv_unpack(data):
|
|||
|
||||
return ber_class, constructed, tag, length, value, rest
|
||||
|
||||
def decode(data, context = None, level = 0):
|
||||
def decode(data, context = None, level = 0, tags=tags):
|
||||
result = []
|
||||
while len(data) > 0:
|
||||
if ord(data[0]) in (0x00, 0xFF):
|
||||
|
@ -263,7 +279,7 @@ def decode(data, context = None, level = 0):
|
|||
|
||||
if interpretation[0] is recurse:
|
||||
current.append("\n")
|
||||
current.append( decode(value, interpretation[2], level+1) )
|
||||
current.append( decode(value, interpretation[2], level+1, tags=tags) )
|
||||
elif interpretation[0] is number:
|
||||
num = 0
|
||||
for i in value:
|
||||
|
|
|
@ -55,6 +55,7 @@ class Cardmultiplexer:
|
|||
of the participating classes instead of overriding them."""
|
||||
|
||||
MERGE_DICTS = ("APPLICATIONS", "COMMANDS", "STATUS_WORDS")
|
||||
MERGE_DICTS_RECURSIVE = ("TLV_OBJECTS", )
|
||||
MERGE_LISTS = ()
|
||||
|
||||
def __init__(self, classes, *args, **kwargs):
|
||||
|
@ -143,12 +144,29 @@ class Cardmultiplexer:
|
|||
def _merge_attributes(self):
|
||||
"""Update the local copy of merged attributes."""
|
||||
|
||||
for attr in self.MERGE_DICTS:
|
||||
for attr in self.MERGE_DICTS + self.MERGE_DICTS_RECURSIVE:
|
||||
tmpdict = {}
|
||||
have_one = False
|
||||
for cls in self._classes:
|
||||
if hasattr(cls, attr):
|
||||
tmpdict.update( getattr(cls, attr) )
|
||||
if not attr in self.MERGE_DICTS_RECURSIVE:
|
||||
tmpdict.update( getattr(cls, attr) )
|
||||
else:
|
||||
def recurse(target, source):
|
||||
for (key, value) in source.items():
|
||||
if target.has_key(key):
|
||||
if isinstance(value, dict) and isinstance(target[key], dict):
|
||||
recurse( target[key], value )
|
||||
elif isinstance(value, dict):
|
||||
target[key] = dict(value)
|
||||
else:
|
||||
target[key] = value
|
||||
else:
|
||||
if isinstance(value, dict):
|
||||
target[key] = dict(value)
|
||||
else:
|
||||
target[key] = value
|
||||
recurse( tmpdict, getattr(cls, attr) )
|
||||
have_one = True
|
||||
if have_one:
|
||||
setattr(self, attr, tmpdict)
|
||||
|
|
|
@ -27,6 +27,8 @@ class Card:
|
|||
'6C??': "Bad value for LE, 0x%(SW2)02x is the correct value.",
|
||||
'63C?': lambda SW1,SW2: "The counter has reached the value '%i'" % (SW2%16)
|
||||
}
|
||||
## For the format of this dictionary of dictionaries see TLV_utils.tags
|
||||
TLV_OBJECTS = {}
|
||||
|
||||
def __init__(self, card = None, reader = None):
|
||||
if card is None:
|
||||
|
@ -61,7 +63,7 @@ class Card:
|
|||
|
||||
def cmd_parsetlv(self):
|
||||
"Decode the TLV data in the last response"
|
||||
print TLV_utils.decode(self.last_result.data)
|
||||
print TLV_utils.decode(self.last_result.data, tags=self.TLV_OBJECTS)
|
||||
|
||||
COMMANDS = {
|
||||
"reset": cmd_reset,
|
||||
|
|
|
@ -36,7 +36,7 @@ class ISO_7816_4_Card(Card):
|
|||
|
||||
if len(result.data) > 0:
|
||||
print utils.hexdump(result.data)
|
||||
print TLV_utils.decode(result.data)
|
||||
print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS)
|
||||
|
||||
def open_file(self, fid):
|
||||
"Open an EF under the current DF"
|
||||
|
@ -49,7 +49,7 @@ class ISO_7816_4_Card(Card):
|
|||
result = self.open_file(fid)
|
||||
if len(result.data) > 0:
|
||||
print utils.hexdump(result.data)
|
||||
print TLV_utils.decode(result.data)
|
||||
print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS)
|
||||
|
||||
def read_binary_file(self, offset = 0):
|
||||
"""Read from the currently selected EF.
|
||||
|
@ -93,7 +93,7 @@ class ISO_7816_4_Card(Card):
|
|||
result = self.select_file(p1, p2, fid)
|
||||
if len(result.data) > 0:
|
||||
print utils.hexdump(result.data)
|
||||
print TLV_utils.decode(result.data)
|
||||
print TLV_utils.decode(result.data,tags=self.TLV_OBJECTS)
|
||||
|
||||
ATRS = list(Card.ATRS)
|
||||
ATRS.extend( [
|
||||
|
@ -162,3 +162,5 @@ class ISO_7816_4_Card(Card):
|
|||
"6A87": "Wrong parameter(s) P1-P2, Lc inconsistent with P1-P2",
|
||||
"6A88": "Wrong parameter(s) P1-P2, Referenced data not found",
|
||||
} )
|
||||
|
||||
TLV_OBJECTS = TLV_utils.tags
|
||||
|
|
Loading…
Reference in New Issue