`members_by_name` is a plain dictionary. Calling it with `()` raises:
TypeError: 'dict' object is not callable
Change-Id: I7e0c09aa7303f1506fe3a025fdc3779919dd0e6c
* OtaAlgoCrypt.from_keyset() searches by `otak.algo_crypt`
but the error message prints `otak.algo_auth`. Should be
`otak.algo_crypt` instead.
* OtaAlgoAuth.__init__() checks `algo_auth` but the error message
prints `algo_crypt`. Should be `otak.algo_auth` instead.
Change-Id: Ia636fffaeadc68e3f6d5b65d477e753834c95895
* field `tp_rp` appears at bit positions 7 and 5
** bit 7 should be `tp_rp` (Reply Path)
** bit 5 should be `tp_sri` (Status Report Indication)
* field `tp_lp` is completely missing
** should be at bit position 3
Change-Id: I0274849f0fa07281b5e050af429ffda7d249f9e8
Both `do_store_data` and `store_data` have identical docstrings that
incorrectly describe the command as GET DATA. Should be "STORE DATA".
Take a chance to fix missing space between `v2.3` and `Section`.
Change-Id: I33fc80ab8ca50fadc38217b0005eec6169c8e34e
The loop builds up `response` across multiple STORE DATA blocks,
but the function returns only `data` - the response from the
*last* block. It should return the accumulated response instead.
Change-Id: I3e15c8004d1e366e8c3896e559656622f48bb1a2
The keyword argument should be `nested=`. As written `ApplicationAID`
is silently ignored - `ApplicationTemplate` will not descend into its
nested TLVs.
Change-Id: If45dbb0c9b09fe53560d109957ce339267a9f2b0
The attribute name is misspelled. The BER-TLV infrastructure looks
for `_construct`; this typo means `SupportedTlsCipherSuitesForScp81`
will never decode its content.
Change-Id: I0f637951b0eeb7eca2a8b543baa737f216a935ed
gen_install_parameters() had contradictory logic: the outer guard
required all three arguments to be non-None/non-empty (making them
mutually inclusive), while the inner checks then treated each one
as optional.
Make each parameter independently optional (defaulting to None) and
remove the all-or-nothing guard from both the function and its caller.
Simplify the function body to a straightforward single-pass
construction of system_specific_params.
Change-Id: I8756fb38016cdf0527fe2e21edb44381d1dc557f
pySim-shell currently does not work on systems with Python 3.14+:
File ".../pysim/pySim/global_platform/__init__.py", line 868, in AddlShellCommands
install_cap_parser_inst_prm_g_grp = install_cap_parser_inst_prm_g.add_argument_group()
File "/usr/lib/python3.14/argparse.py", line 1794, in add_argument_group
raise ValueError('argument groups cannot be nested')
ValueError('argument groups cannot be nested')
The problem is that install_cap_parser creates a nested group inside
of mutually exclusive group. argparse never supported group nesting
properly, so it has been deprecated since Python 3.11, and eventually
got removed in Python 3.14.
Remove group nesting, adjust the usage string, and implement the
mutual exclusiveness/inclusiveness manually in do_install_cap().
Change-Id: Idddf72d5a745345e134b23f2f01e0257d0667579
The tuples defining a DF or ADF in an eSIM template must contain a
pinStatusTemplateDO. When parsing tuples into a File() instance, we
must save it, and re-create it at the time we re-encode that file.
Same applies to the lcsi (life cycle state indicator), which may
optionally exist for any file.
Change-Id: I073aa4374f2cd664d07fa0224bf0d4c809cdf4aa
Closes: OS#6955
We already have documentation that explains how to run pySim-smpp2sim.
With smpp-ota-tool we now have a counterpart for pySim-smpp2sim, so
let's add documentation for this tool as well.
Related: SYS#7881
Change-Id: If0d18a263f5a6dc035b90f5c5c6a942d46bbba49
The commandline arguments are currently defined under __main__ in a
private scope. From there they are not reachable to the sphinx
argparse module. We have to define the arguments globally at the
top. (like in the other applications)
Related: SYS#7881
Change-Id: I2d9782e3f5b1cac78c22d206fdcac4118c7d5e7c
Some commandline arguments have an underscore in their name. Let's
replace those with dashes.
Change-Id: Icbe9d753d59263997e9ca34d46ed0daca36ca16c
Related: SYS#6868
Extend the existing test script so that it can handle multiple
testcases. Also add support for switching eUICC profiles.
Finally, add a testcases to test OTA-SMS (RFM) with AES128 and
AES256 encryption.
Change-Id: I1f10504f3a29a8c74a17991632d932819fecfa5a
Related: OS#6868
In our test setup we run the card_sanitizer.py script regualary to ensure that
we have consistent start conditions when running our tests. In case a testcase
crashes for some reason and leaves messed up files on a test card. The
card_sanitizer.py script will ensure that any problem like that is cleaned up
over night.
For the testcases we are about to add in the patch following this one, we need
to provision a new test keyset to one of our test cards. This has been already
done manually. However since the card_sanitizer still has the old keys in its
backup we will have to update that as well.
Change-Id: I5aa8a413b19b3e43a79d03e904daab50b4b1e767
Related: OS#6868
The methods dek_encrypt/dek_decrypt use the wrong algorithm and the
wrong key material. The algorithm should be 3DES rather then single
DES and the key must be the DEK session key instead of the static
DEK key from which the DEK session key is derived.
Related: SYS#7902
Change-Id: I3d0cc7378680b346fa39152c8b7074446d2c869d
Cards usually have multiple sets of KIC, KID (and KIK). The keys
are selected through an index. However, mixing keys from different
sets is concidered as a security violation and cards should reject
such configurations.
Let's print a warning to make users aware that something is off.
Change-Id: Ieb4e14145baba1c2cb4a237b612b04694940f402
Related: OS#6868
(normally KID index and KIC index should be the same since mixing keys
is a concidered as a security violation. However, in this tool we
want to allow users to specify different indexes for KIC and KIC so that
they can make tests to make sure their cards correctly reject mixed up
key indexes)
Change-Id: I8847ccc39e4779971187e7877b8902fca7f8bfc1
Related: OS#6868
When testing commands like get_profile_info, enable_profile,
disable_profile or the commands to manage notifications, we
should ensure that the correct profile is enabled before
executing the actual testcase.
Change-Id: Ie57b0305876bc5001ab3a9c3a3b5711408161b74
When I open the .asn file in vim, pySim should not attempt to read the
vim .swp file as asn.1.
File "/home/moi/osmo-dev/src/pysim/pySim/esim/saip/__init__.py", line 45, in <module>
asn1 = compile_asn1_subdir('saip')
[...]
File "<frozen codecs>", line 325, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 21: invalid start byte
Related: OS#6937
Change-Id: I37df3fc081e51e2ed2198876c63f6e68ecc8fcd8
The class Iccid uses a BcdAdapter to encoded/decode the ICCID. This
works fine for ICCIDs that have an even (20) number of digits. In case
the digit count is odd (19), the ICCID the last digit requires padding.
Let's switch to PaddedBcdAdapter for encoding/decoding, to ensure that
odd-length ICCIDs are padded automatically.
Change-Id: I527a44ba454656a0d682ceb590eec6d9d0ac883a
Related: OS#6868
This is a follow up patch to change:
I2a5d4b59b12e08d5eae7a1215814d3a69c8921f6
- do not ignore length of kwargs
- fix role parameter (roles other than 'legacy_client' can be used now)
- use startswith instead of match
Related: SYS#7866
Change-Id: Ifae13e82d671ff09bddf771f063a388d2ab283eb
this fixes the following two warnings:
pySim/esim/saip/__init__.py:docstring of pySim.esim.saip.FsNode.walk:1: WARNING: Inline strong start-string without end-string. [docutils]
pySim/esim/saip/__init__.py:docstring of pySim.esim.saip.FsNodeDF.walk:1: WARNING: Inline strong start-string without end-string. [docutils]
Change-Id: Id7debf9296923b735f76623808cee68967a1ece7
While at it, also use tuples (const) instead of lists (var).
Tweaked-by: nhofmeyr@sysmocom.de (docstring, tuples)
Change-Id: Iaa6e710132e3f4c6cecc5ff786922f6c0fcfb54e
unfortunately the API changes introduced in change
I277aa90fddb5171c4bf6c3436259aa371d30d092
broke the API interface of http_json_api.py. This was taken into
account and necessary to introduce add the server functionality next
to the already existing client functionality. The changes to the API
were minimal and all code locations that use http_json_api.py
were re-aligned.
Unfortunately it was not clear at this point in time that there are
out-of-tree projects that could be affected by API changes in
http_json_api.py
To mitigate the problem this patch introduces an alternative API
interface to the JsonHttpApiFunction base class. This alternative
API interface works like the old API interface when the class is
instantiated in the original way. To make use of the revised client
the API use has to pass an additional keyword argument that defines
the role.
Related: SYS#7866
Change-Id: I2a5d4b59b12e08d5eae7a1215814d3a69c8921f6
We have two test_enable_disable_profile method, the second one should
be called test_set_nickname.
Change-Id: I5ff79218fdafc8c42c8b58cc00be3e56e09d808b
At the moment pySim.ota codebase is not covered by any of the
integration tests (we have only normal unittests so far). To
increase the test coverage, let's add an integration test that
sends exchanges an RFM OTA-SMS with a real-world card.
However, there is no tool avaliable that can be used as an SMPP
client for pySim-smpp2sim yet. Let's use smpp_ota_apdu2.py on
laforge/ota to develop a tool that we can use to exchange SMS-TPDUs
that contain remote APDU scripts (RFM/RAM).
Finally let's use the tool we have created as a basis to create
an integration test that exchanges an SMS-TPDU with the RFM
application of a sysmoISIM-SJA5 card. The testcase shall pass
when we get the expected response from the card.
Related: OS#6868
Change-Id: If25e38be004cc1c7aeeb130431831377e78fe28d
If there is an empty body returned, such as in the case of the response
to an es9p notification, then it is of course also legal to not set the
content-type header.
This patch fixes an exception when talking to certain SM-DP+ with
es9p_client.py:
DEBUG:pySim.esim.http_json_api:HTTP RSP-STS: [204] hdr: {'X-Admin-Protocol': 'gsma/rsp/v2.5.0', 'Date': 'Wed, 28 Jan 2026 18:26:39 GMT', 'Server': 'REDACTED'}
DEBUG:pySim.esim.http_json_api:HTTP RSP: b''
{'X-Admin-Protocol': 'gsma/rsp/v2.5.0', 'Date': 'Wed, 28 Jan 2026 18:26:39 GMT', 'Server': 'REDACTED'}
<Response [204]>
Traceback (most recent call last):
File "gprojects/git/pysim/es9p/../contrib/es9p_client.py", line 315, in <module>
c.do_notification()
~~~~~~~~~~~~~~~~~^^
File "projects/git/pysim/es9p/../contrib/es9p_client.py", line 159, in do_notification
res = self.peer.call_handleNotification(data)
File "projects/git/pysim/contrib/pySim/esim/es9p.py", line 174, in call_handleNotification
return self.handleNotification.call(data)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "projects/git/pysim/contrib/pySim/esim/http_json_api.py", line 335, in call
if not response.headers.get('Content-Type').startswith(req_headers['Content-Type']):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'startswith'
Change-Id: I99e8f167b7bb869c5ff6d908ba673dac87fef71a
The asn.1 encoder expects bytes-like objects, we cannot simply pass
hex-strings to it without conversion
Change-Id: I83ad047e043dc6b3462b188ce6dd0b2cc0e52e87