laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38017?usp=email )
Change subject: transport: define TERMINAL RESPONSE content within ProactiveHandler
......................................................................
transport: define TERMINAL RESPONSE content within ProactiveHandler
So far the core proactive handling code would always generate a positive
response, with no way for the ProactiveHandler call-back to influence
that or to include additional IEs/TLVs.
Let's change that.
Change-Id: Ic772b3383533f845689ac97ad03fcf67cf59c208
---
M pySim/transport/__init__.py
1 file changed, 18 insertions(+), 15 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/17/38017/1
diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py
index 47f6547..97022ce 100644
--- a/pySim/transport/__init__.py
+++ b/pySim/transport/__init__.py
@@ -57,7 +57,18 @@
"""Default handler for not otherwise handled proactive commands."""
raise NotImplementedError('No handler method for %s' % pcmd.decoded)
-
+ def prepare_response(self, pcmd: ProactiveCommand, general_result: str = 'performed_successfully'):
+ # The Command Details are echoed from the command that has been processed.
+ (command_details,) = [c for c in pcmd.children if isinstance(c, CommandDetails)]
+ # invert the device identities
+ (command_dev_ids,) = [c for c in pcmd.children if isinstance(c, DeviceIdentities)]
+ rsp_dev_ids = DeviceIdentities()
+ rsp_dev_ids.from_dict({'device_identities': {
+ 'dest_dev_id': command_dev_ids.decoded['source_dev_id'],
+ 'source_dev_id': command_dev_ids.decoded['dest_dev_id']}})
+ result = Result()
+ result.from_dict({'result': {'general_result': general_result, 'additional_information': ''}})
+ return [command_details, rsp_dev_ids, result]
class LinkBase(abc.ABC):
"""Base class for link/transport to card."""
@@ -185,34 +196,26 @@
pcmd = ProactiveCommand()
parsed = pcmd.from_tlv(h2b(fetch_rv[0]))
print("FETCH: %s (%s)" % (fetch_rv[0], type(parsed).__name__))
- result = Result()
if self.proactive_handler:
# Extension point: If this does return a list of TLV objects,
# they could be appended after the Result; if the first is a
# Result, that cuold replace the one built here.
- self.proactive_handler.receive_fetch_raw(pcmd, parsed)
- result.from_dict({'result': {'general_result': 'performed_successfully',
- 'additional_information': ''}})
+ ti_list = self.proactive_handler.receive_fetch_raw(pcmd, parsed)
+ if not ti_list:
+ ti_list = self.proactive_handler.prepare_response(pcmd, 'FIXME')
else:
- result.from_dict({'result': {'general_result': 'command_beyond_terminal_capability',
- 'additional_information': ''}})
+ ti_list = self.proactive_handler.prepare_response(pcmd, 'command_beyond_terminal_capability')
# Send response immediately, thus also flushing out any further
# proactive commands that the card already wants to send
#
# Structure as per TS 102 223 V4.4.0 Section 6.8
- # The Command Details are echoed from the command that has been processed.
- (command_details,) = [c for c in pcmd.decoded.children if isinstance(c, CommandDetails)]
- # The Device Identities are fixed. (TS 102 223 V4.0.0 Section 6.8.2)
- device_identities = DeviceIdentities()
- device_identities.from_dict({'device_identities': {'source_dev_id': 'terminal', 'dest_dev_id':
- 'uicc'}})
-
# Testing hint: The value of tail does not influence the behavior
# of an SJA2 that sent ans SMS, so this is implemented only
# following TS 102 223, and not fully tested.
- tail = command_details.to_tlv() + device_identities.to_tlv() + result.to_tlv()
+ ti_list_bin = [x.to_tlv() for x in ti_list]
+ tail = b''.join(ti_list_bin)
# Testing hint: In contrast to the above, this part is positively
# essential to get the SJA2 to provide the later parts of a
# multipart SMS in response to an OTA RFM command.
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/38017?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ic772b3383533f845689ac97ad03fcf67cf59c208
Gerrit-Change-Number: 38017
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38009?usp=email )
Change subject: pySim.esim.saip: Fix weird DF names
......................................................................
pySim.esim.saip: Fix weird DF names
Sometimes the struct member is called like df-telecom, but in other
cases it's called df-df-saip with a double 'df' in front. That makes
no sense, but we have to deal with it from our constructors...
Change-Id: If5e670441f03a47fa34e97a326909b24927c12f7
---
M pySim/esim/saip/__init__.py
1 file changed, 3 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/09/38009/1
diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py
index 47e67e8..bf39025 100644
--- a/pySim/esim/saip/__init__.py
+++ b/pySim/esim/saip/__init__.py
@@ -817,7 +817,7 @@
return
# provide some reasonable defaults
self.decoded['templateID'] = str(oid.DF_5GS_v3)
- for fname in ['df-5gs']:
+ for fname in ['df-df-5gs']:
self.decoded[fname] = []
class ProfileElementEAP(FsProfileElement):
@@ -841,7 +841,7 @@
return
# provide some reasonable defaults
self.decoded['templateID'] = str(oid.DF_SAIP)
- for fname in ['df-saip']:
+ for fname in ['df-df-saip']:
self.decoded[fname] = []
class ProfileElementDfSNPN(FsProfileElement):
@@ -853,7 +853,7 @@
return
# provide some reasonable defaults
self.decoded['templateID'] = str(oid.DF_SNPN)
- for fname in ['df-snpn']:
+ for fname in ['df-df-snpn']:
self.decoded[fname] = []
class ProfileElementDf5GProSe(FsProfileElement):
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/38009?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: If5e670441f03a47fa34e97a326909b24927c12f7
Gerrit-Change-Number: 38009
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Attention is currently required from: laforge.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/pysim/+/37967?usp=email
to look at the new patch set (#2).
The following approvals got outdated and were removed:
Verified-1 by Jenkins Builder
Change subject: remove pySim.gsmtap as it has moved to osmopython.gsmtap
......................................................................
remove pySim.gsmtap as it has moved to osmopython.gsmtap
Change-Id: I631bb85bc6e76b089004d9f2e2082d70cbccf200
---
M pySim/apdu_source/gsmtap.py
M pySim/apdu_source/pyshark_gsmtap.py
M pySim/apdu_source/tca_loader_log.py
D pySim/gsmtap.py
M requirements.txt
M setup.py
6 files changed, 5 insertions(+), 221 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/67/37967/2
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/37967?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I631bb85bc6e76b089004d9f2e2082d70cbccf200
Gerrit-Change-Number: 37967
Gerrit-PatchSet: 2
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Attention is currently required from: laforge.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/pysim/+/37965?usp=email
to look at the new patch set (#5).
The following approvals got outdated and were removed:
Verified-1 by Jenkins Builder
Change subject: Migrate over to using pyosmocom
......................................................................
Migrate over to using pyosmocom
We're creating a 'pyosmocom' pypi module which contains a number of core
Osmocom libraries / interfaces that are not specific to SIM card stuff
contained here.
The main modules moved in this initial step are pySim.tlv, pySim.utils
and pySim.construct. utils is split, not all of the contents is
unrelated to SIM Cards. The other two are moved completely.
Change-Id: I4b63e45bcb0c9ba2424dacf85e0222aee735f411
---
M README.md
M contrib/csv-encrypt-columns.py
M contrib/es9p_client.py
M contrib/saip-tool.py
M contrib/unber.py
M osmo-smdpp.py
M pySim-prog.py
M pySim-read.py
M pySim-shell.py
M pySim-trace.py
M pySim/apdu/__init__.py
M pySim/apdu/global_platform.py
M pySim/apdu/ts_102_221.py
M pySim/apdu/ts_102_222.py
M pySim/apdu/ts_31_102.py
M pySim/ara_m.py
M pySim/card_key_provider.py
M pySim/cards.py
M pySim/cat.py
M pySim/cdma_ruim.py
M pySim/commands.py
D pySim/construct.py
M pySim/esim/bsp.py
M pySim/esim/es8p.py
M pySim/esim/rsp.py
M pySim/esim/saip/__init__.py
M pySim/esim/saip/personalization.py
M pySim/euicc.py
M pySim/filesystem.py
M pySim/global_platform/__init__.py
M pySim/global_platform/http.py
M pySim/global_platform/scp.py
M pySim/global_platform/uicc.py
M pySim/gsm_r.py
M pySim/gsmtap.py
M pySim/iso7816_4.py
M pySim/ota.py
M pySim/runtime.py
M pySim/secure_channel.py
M pySim/sms.py
M pySim/sysmocom_sja2.py
D pySim/tlv.py
M pySim/transport/__init__.py
M pySim/transport/calypso.py
M pySim/transport/modem_atcmd.py
M pySim/transport/pcsc.py
M pySim/transport/serial.py
M pySim/ts_102_221.py
M pySim/ts_102_222.py
M pySim/ts_102_310.py
M pySim/ts_31_102.py
M pySim/ts_31_102_telecom.py
M pySim/ts_31_103.py
M pySim/ts_31_103_shared.py
M pySim/ts_31_104.py
M pySim/ts_51_011.py
M pySim/utils.py
M requirements.txt
M setup.py
M tests/unittests/test_apdu.py
D tests/unittests/test_construct.py
M tests/unittests/test_esim.py
M tests/unittests/test_esim_bsp.py
M tests/unittests/test_esim_saip.py
M tests/unittests/test_files.py
M tests/unittests/test_globalplatform.py
M tests/unittests/test_ota.py
M tests/unittests/test_sms.py
D tests/unittests/test_tlv.py
M tests/unittests/test_tlvs.py
M tests/unittests/test_utils.py
71 files changed, 157 insertions(+), 2,057 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/65/37965/5
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/37965?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I4b63e45bcb0c9ba2424dacf85e0222aee735f411
Gerrit-Change-Number: 37965
Gerrit-PatchSet: 5
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Attention: laforge <laforge(a)osmocom.org>
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38014?usp=email )
Change subject: pySim.esim.saip: Implement optimized file content encoding
......................................................................
pySim.esim.saip: Implement optimized file content encoding
Make sure we make use of the fill pattern when encoding file contents:
Only encode the differences to the fill pattern of the file, in order
to reduce the profile download size.
Change-Id: I61e4a5e04beba5c9092979fc546292d5ef3d7aad
---
M pySim/esim/saip/__init__.py
M tests/unittests/test_esim_saip.py
2 files changed, 81 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/14/38014/1
diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py
index 658810a..505ea30 100644
--- a/pySim/esim/saip/__init__.py
+++ b/pySim/esim/saip/__init__.py
@@ -20,6 +20,8 @@
import io
from typing import Tuple, List, Optional, Dict, Union
from collections import OrderedDict
+from difflib import SequenceMatcher, Match
+
import asn1tools
from osmocom.utils import b2h, h2b, Hexstr
from osmocom.tlv import BER_TLV_IE, bertlv_parse_tag, bertlv_parse_len
@@ -40,6 +42,29 @@
logger = logging.getLogger(__name__)
+class NonMatch(Match):
+ """Representing a contiguous non-matching block of data; the opposite of difflib.Match"""
+ @classmethod
+ def from_matchlist(cls, l: List[Match], size:int) -> List['NonMatch']:
+ """Build a list of non-matching blocks of data from its inverse (list of matching blocks).
+ The caller must ensure that the input list is ordered, non-overlapping and only contains
+ matches at equal offsets in a and b."""
+ res = []
+ cur = 0
+ for match in l:
+ if match.a != match.b:
+ return ValueError('only works for equal-offset matches')
+ assert match.a >= cur
+ nm_len = match.a - cur
+ if nm_len > 0:
+ # there's no point in generating zero-lenth non-matching sections
+ res.append(cls(a=cur, b=cur, size=nm_len))
+ cur = match.a + match.size
+ if size > cur:
+ res.append(cls(a=cur, b=cur, size=size-cur))
+
+ return res
+
class Naa:
"""A class defining a Network Access Application (NAA)."""
name = None
@@ -359,12 +384,33 @@
return ValueError("Unknown key '%s' in tuple list" % k)
return stream.getvalue()
- def file_content_to_tuples(self) -> List[Tuple]:
- # FIXME: simplistic approach. needs optimization. We should first check if the content
- # matches the expanded default value from the template. If it does, return empty list.
- # Next, we should compute the diff between the default value and self.body, and encode
- # that as a sequence of fillFileOffset and fillFileContent tuples.
- return [('fillFileContent', self.body)]
+ def file_content_to_tuples(self, optimize:bool = True) -> List[Tuple]:
+ if not optimize:
+ # simplistic approach: encode the full file, ignoring the template/default
+ return [('fillFileContent', self.body)]
+ # Try to 'compress' the file body, based on the default file contents.
+ if self.template:
+ default = self.template.expand_default_value_pattern(length=len(self.body))
+ if not default:
+ sm = SequenceMatcher(a=b'\xff'*len(self.body), b=self.body)
+ else:
+ if default == self.body:
+ # 100% match: retrun an empty tuple list to make eUICC use the default
+ return []
+ sm = SequenceMatcher(a=default, b=self.body)
+ else:
+ # no template at all: we can only remove padding
+ sm = SequenceMatcher(a=b'\xff'*len(self.body), b=self.body)
+ matching_blocks = sm.get_matching_blocks()
+ # we can only make use of matches that have the same offset in 'a' and 'b'
+ matching_blocks = [x for x in matching_blocks if x.size > 0 and x.a == x.b]
+ non_matching_blocks = NonMatch.from_matchlist(matching_blocks, self.file_size)
+ ret = []
+ cur = 0
+ for block in non_matching_blocks:
+ ret.append(('fillFileOffset', block.a - cur))
+ ret.append(('fillFileContent', self.body[block.a:block.a+block.size]))
+ return ret
def __str__(self) -> str:
return "File(%s)" % self.pe_name
diff --git a/tests/unittests/test_esim_saip.py b/tests/unittests/test_esim_saip.py
index e7e324d..edf6d8d 100755
--- a/tests/unittests/test_esim_saip.py
+++ b/tests/unittests/test_esim_saip.py
@@ -90,5 +90,34 @@
self.assertTrue(oid.OID('1.0.1') > oid.OID('1.0'))
self.assertTrue(oid.OID('1.0.2') > oid.OID('1.0.1'))
+class NonMatchTest(unittest.TestCase):
+ def test_nonmatch(self):
+ # non-matches before, in between and after matches
+ match_list = [Match(a=10, b=10, size=5), Match(a=20, b=20, size=4)]
+ nm_list = NonMatch.from_matchlist(match_list, 26)
+ self.assertEqual(nm_list, [NonMatch(a=0, b=0, size=10), NonMatch(a=15, b=15, size=5),
+ NonMatch(a=24, b=24, size=2)])
+
+ def test_nonmatch_beg(self):
+ # single match at beginning
+ match_list = [Match(a=0, b=0, size=5)]
+ nm_list = NonMatch.from_matchlist(match_list, 20)
+ self.assertEqual(nm_list, [NonMatch(a=5, b=5, size=15)])
+
+ def test_nonmatch_end(self):
+ # single match at end
+ match_list = [Match(a=19, b=19, size=5)]
+ nm_list = NonMatch.from_matchlist(match_list, 24)
+ self.assertEqual(nm_list, [NonMatch(a=0, b=0, size=19)])
+
+ def test_nonmatch_none(self):
+ # no match at all
+ match_list = []
+ nm_list = NonMatch.from_matchlist(match_list, 24)
+ self.assertEqual(nm_list, [NonMatch(a=0, b=0, size=24)])
+
+
+
+
if __name__ == "__main__":
unittest.main()
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/38014?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I61e4a5e04beba5c9092979fc546292d5ef3d7aad
Gerrit-Change-Number: 38014
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38013?usp=email )
Change subject: pySim.esim.saip.ProfileElementGFM: Initialize 'fileManagementCMD'
......................................................................
pySim.esim.saip.ProfileElementGFM: Initialize 'fileManagementCMD'
When constructing a ProfileElmentGFM from scratch, initialize the
decoded['fileManagementCMD'], as it is a mandatory member during
ASN.1 encode.
Change-Id: Iaae99348d36b7f0c739daf039d6ea2305b7ca9db
---
M pySim/esim/saip/__init__.py
1 file changed, 3 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/13/38013/1
diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py
index 88d7755..658810a 100644
--- a/pySim/esim/saip/__init__.py
+++ b/pySim/esim/saip/__init__.py
@@ -622,6 +622,9 @@
# indexed by PE-Name
self.files = {}
self.tdef = asn1.types['ProfileElement'].type.name_to_member[self.type]
+ if decoded:
+ return
+ self.decoded['fileManagementCMD'] = []
def supports_file_for_path(self, path: Path, adf: Optional[str] = None) -> bool:
"""Does this ProfileElement support a file of given path?"""
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/38013?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Iaae99348d36b7f0c739daf039d6ea2305b7ca9db
Gerrit-Change-Number: 38013
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>