Commit Graph

1606 Commits

Author SHA1 Message Date
Harald Welte
07a3978748 es2p.py: also allow 18 digit ICCID
While at it, also use tuples (const) instead of lists (var).

Tweaked-by: nhofmeyr@sysmocom.de (docstring, tuples)
Change-Id: Iaa6e710132e3f4c6cecc5ff786922f6c0fcfb54e
2026-02-09 12:46:03 +00:00
Vadim Yanitskiy
a297cdba73 ModemATCommandLink: fix SyntaxWarning: invalid escape sequence '\+'
Change-Id: If8de5299a4dc5a8525ef6657213db95d30e3c83b
Fixes: OS#6948
2026-02-09 12:44:41 +00:00
Philipp Maier
f9d7c82b4d esim/http_json_api: add alternative API interface
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
2026-02-09 12:42:28 +00:00
Alexander Couzens
c6fa2b4007 saip-tool: rename parser_tree correctly
parser_info is already defined and this seems to be a copy/paste
accident.

Change-Id: Icc30dbf02a266211fa4d3aee8e7cec14185e716c
2026-02-09 12:34:35 +00:00
Philipp Maier
39d744010a pySim-shell_test/euicc: fix testcase method name
We have two test_enable_disable_profile method, the second one should
be called test_set_nickname.

Change-Id: I5ff79218fdafc8c42c8b58cc00be3e56e09d808b
2026-02-09 10:10:08 +01:00
Philipp Maier
15691233e1 tests/pySim-smpp2sim_test: add integration test
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
2026-02-04 14:05:07 +00:00
Philipp Maier
0a1c5a27d7 esim/http_json_api: add missing apidoc
Change-Id: Ibf9cf06197c9e3203c7a3ea5d77004f0ca41cd3f
2026-02-04 12:45:58 +01:00
Harald Welte
e0a9e73267 http_json_api: Only require Content-Type if response body is non-empty
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
2026-01-31 11:58:32 +01:00
Harald Welte
22c3797a89 es9p_client: MAke install notification code execute at all
The caller specified 'install' but the do_notification() function
compared with 'download' :(

Change-Id: I2d441cfbc1457688eb163301d3d91a1f1fdc7a8c
2026-01-31 10:48:28 +00:00
Harald Welte
4e35e2c357 es9p_client: Fix type conversion in installation result notification
The asn.1 encoder expects bytes-like objects, we cannot simply pass
hex-strings to it without conversion

Change-Id: I83ad047e043dc6b3462b188ce6dd0b2cc0e52e87
2026-01-31 10:48:28 +00:00
Philipp Maier
e62f160775 contrib/csv-to-pgsql: add missing copyright header
Change-Id: Iad8b2c1abb6a80764d05c823fbd03a9eae0ec0ab
2026-01-31 01:32:27 +00:00
Alexander Couzens
1f2db11d31 pySim/card_key_provider: fix typo in keys
Change-Id: Ie76f351ae221da2a0aab65c311fafe8ae6d63663
2026-01-31 01:32:12 +00:00
Vladimir Serbinenko
ae91245582 Print SMSC in pySim-read.py
Change-Id: I17067b68086316d51fd71ba77049874605594e3f
2026-01-31 01:30:32 +00:00
Harald Welte
429b12c8b5 pySim-trace: pySim.apdu_source.stdin_hex
This introduces an "APDU source" for pySim-trace which enables the
decoding of APDUs that are copy+pasted from elsewhere, for example
APDU logs in text form created by proprietary tools, or to decode
personalization scripts or the like.

Change-Id: I5aacf13b7c27cea9efd42f01dacca61068c3aa33
2026-01-31 01:22:48 +00:00
Neels Hofmeyr
ccc1a047ab personalization: set example input values
For all ConfigurableParameter subclasses, provide an example_input.

This may be useful for downstream projects' user interaction, to suggest
a value or prefill an input field, as appropriate.

Related: SYS#6768
Change-Id: I2672fedcbc32cb7a6cb0c233a4a22112bd9aae03
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
db17529136 personalization: set some typical parameter names
These names better match what humans expect to read, for example "PIN1"
instead of "Pin1".

(We still fall back to the __class__.__name__ if a subclass omits a
specific name, see the ConfigurableParameter init.)

Change-Id: I31f390d634e58c384589c50a33ca45d6f86d4e10
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
1c082da0ee personalization: refactor SmspTpScAddr
Refactor SmspTpScAddr to the new ConfigurableParameter implementation
style.

Change-Id: I2600369e195e9f5aed7f4e6ff99ae273ed3ab3bf
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
1e98856105 personalization: refactor SdKey
Refactor SdKey (and subclasses) to the new ConfigurableParameter
implementation style, keeping the same implementation.

But duly note that this implementation does not work!
It correctly patches pe.decoded[], but that gets overridden by
ProfileElementSD._pre_encode().

For a fix, see I07dfc378705eba1318e9e8652796cbde106c6a52.

Change-Id: I427ea851bfa28b2b045e70a19a9e35d361f0d393
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
ae656c66a3 personalization: refactor AlgorithmID, K, Opc
Refactor AlgorithmID, K, Opc to the new ConfigurableParameter
implementation style.

K and Opc use a common abstract BinaryParam.

Note from the future: AlgorithmID so far takes "raw" int values, but
will turn to be an "enum" parameter with predefined meaningful strings
in I71c2ec1b753c66cb577436944634f32792353240

Change-Id: I6296fdcfd5d2ed313c4aade57ff43cc362375848
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
d5b570b01d personalization: refactor Pin, Adm
Refactor Pin1, Pin2, Adm1 and Adm2 to the new ConfigurableParameter
implementation style.

Change-Id: I54aef10b6d4309398d4b779a3740a7d706d68603
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
21641816ea personalization: refactor Puk
Implement abstract DecimalHexParam, and use it to refactor Puk1 and Puk2
to the new ConfigurableParameter implementation style.

DecimalHexParam will also be used for Pin and Adm soon.

Change-Id: I271e6c030c890778ab7af9ab3bc7997e22018f6a
2026-01-30 19:34:13 +00:00
Neels Hofmeyr
742baeab56 personalization: refactor ConfigurableParameter, Iccid, Imsi
Main points/rationales of the refactoring, details below:
1) common validation implementation
2) offer classmethods

The new features are optional, and will be heavily used by batch
personalization patches coming soon.

Implement Iccid and Imsi to use the new way, with a common abstract
DecimalParam implementation.

So far leave the other parameter classes working as they always did, to
follow suit in subsequent commits.

Details:

1) common validation implementation:
There are very common validation steps in the various parameter
implementations. It is more convenient and much more readable to
implement those once and set simple validation parameters per subclass.
So there now is a validate_val() classmethod, which subclasses can use
as-is to apply the validation parameters -- or subclasses can override
their cls.validate_val() for specialized validation.
(Those subclasses that this patch doesn't touch still override the
self.validate() instance method. Hence they still work as before this
patch, but don't use the new common features yet.)

2) offer stateless classmethods:
It is useful for...
- batch processing of multiple profiles (in upcoming patches) and
- user input validation
to be able to have classmethods that do what self.validate() and
self.apply() do, but do not modify any self.* members.
So far the paradigm was to create a class instance to keep state about
the value. This remains available, but in addition we make available the
paradigm of a singleton that is stateless (the classmethods).
Using self.validate() and self.apply() still work the same as before
this patch, i.e. via self.input_value and self.value -- but in addition,
there are now classmethods that don't touch self.* members.

Related: SYS#6768
Change-Id: I6522be4c463e34897ca9bff2309b3706a88b3ce8
2026-01-30 19:34:13 +00:00
Philipp Maier
a4895702d7 transport/init: use PySimLogger to print messages
The module still uses print to output information. Let's replace
those print calls with the more modern PySimLogger method calls.

Change-Id: I2e2ec2b84f3b84dbd8a029ae9bb64b7a96ddbde3
2026-01-28 12:19:54 +01:00
Philipp Maier
2b42877389 pySimLogger: user __name__ of the module when creating a new logger
At the moment we use random identifiers as names when we create a
new logger for pySimLogger. Let's switch to consistently use the
module name here. For the top level modules let's use the program
name so that it will show up in the log instead of __init__.

Change-Id: I49a9beb98845f66247edd42ed548980c97a7151a
2026-01-28 12:19:54 +01:00
Harald Welte
167d6aca36 pySim.esim.saip: Don't try to generate file contents for MF/DF/ADF
only EFs have data content

Change-Id: I02a54a3b2f73a0e9118db87f8b514d1dbf53971f
2026-01-26 21:19:17 +01:00
Harald Welte
d8c45dc07e 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
2026-01-26 21:19:05 +01:00
Philipp Maier
0a36ba257c pySim/runtime: use log.warning instead of log.warn
The python logger method warn is deprecated since pyton 3.3, let's us
the warning method as suggested.

Change-Id: I3a4c0ca43768198ac6011ebe79050f91c04862e5
2026-01-26 15:21:37 +00:00
Philipp Maier
1f36c9c28a contrib: add utility to receive ES2+handleDownloadProgressInfo calls
We already have a tool to work with the ES2+ API provided by an SMDP+
(es2p_client.py) With this tool we can only make API calls towards
an SMDP+. However, SGP.22 also defines a "reverse direction" ES2+
interface through wich the SMDP+ may make API calls towards the MNO.

At the moment the only possible MNO originated API call is
ES2+handleDownloadProgressInfo. Let's add a simple tool that runs a
HTTP server to receive and log the ES2+handleDownloadProgressInfo
requests.

Related: SYS#7825
Change-Id: I95af30cebae31f7dc682617b1866f4a2dc9b760c
2026-01-22 19:38:01 +01:00
Philipp Maier
e00c0becca esim/http_json_api: extend JSON API with server functionality
At the moment http_json_api only supports the client role. Let's also add
support for the server role.

This patch refactors the existing client code. This in particular means
that the following preperations have to be made:

- To use the existing JsonHttpApiFunction definitions in the client and
  server the scheme has to be symetric. It already is for the most part,
  but it treads the header field differently. So let's just treat the
  header field like any other mandatory field and add it input_params.
  (this does not affect the es9p.py code since in ES9+ the requests have
   no header messages, see also SGP.22, section 6.5.1.1)

- The JsonHttpApiFunction class currently also has the code to perform
  the client requests. Let's seperate that code in a JsonHttpApiClient
  class to which we pass an JsonHttpApiFunction object.

- The code that does the encoding and decoding in the client role has
  lots of conditions the treat the header differently. Let's do the
  decisions about the header in the JsonHttpApiClient. The encoder
  and decoder function should do the generic encoding and decoding
  only. (however, some generic header specific conditions will remain).

The code for the server role logically mirrors the code for the client
role. We add a JsonHttpApiServer class that can be used to create
API endpoints. The API user has to pass in a call_handler through which
the application logic is defined. Above that we add an Es2pApiServer
class in es2p. In this class we implement the logic that runs the
HTTP server and receives the requests. The Es2pApiServer supports all
ES2+ functions defined by GSMA SGP.22. The user may use the provided
Es2pApiServerHandler base class to define the application logic for each
ES2+ function.

Related: SYS#7825
Change-Id: I277aa90fddb5171c4bf6c3436259aa371d30d092
2026-01-22 19:38:01 +01:00
Philipp Maier
148d0a6f90 esim/http_json_api: add missing check
The line actual_sec = func_ex_status.get('statusCodeData', None) suggests
that 'statusCodeData' may be None under normal circumstances. So let's guard
sec.update(actual_sec) so that we won't run into an exception in case
'statusCodeData' is not in func_ex_status.

Related: SYS#7825
Change-Id: I8a1a3cd5e029dba4a3aec1a64702e19b0d694ae2
2026-01-22 18:51:16 +01:00
Harald Welte
51da6263b7 Fix esim.saip.ProfileElementSequence.remove_naas_of_type
This method did not work at all at the moment, likely due to API churn
over time.  This change makes the following exception go away:

Traceback (most recent call last):
  File "projects/git/pysim/contrib/saip-tool.py", line 473, in <module>
    do_remove_naa(pes, opts)
    ~~~~~~~~~~~~~^^^^^^^^^^^
  File "projects/git/pysim/contrib/saip-tool.py", line 203, in do_remove_naa
    pes.remove_naas_of_type(naa)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "projects/git/pysim/contrib/pySim/esim/saip/__init__.py", line 1748, in remove_naas_of_type
    if template in hdr.decoded['eUICC-Mandatory-GFSTEList']:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "projects/git/pysim/contrib/pySim/esim/saip/oid.py", line 48, in __eq__
    return (self.intlist == other.intlist)
                            ^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'intlist'

A subsequent patch should introduce unit tests to avoid such breakage in
the future.

Change-Id: I88d862d751198c3d1648ab7f11d6e6a8fdbc41c9
2026-01-20 09:50:03 +01:00
Harald Welte
4f1d7d7ac6 saip.validation: Verify unused mandatory services in header
This adds a new check method to the pySim.esim.saip.validation.CheckBasicStructure
class, which ensures that no unused authentication algorithm related mandatory
services are indicated in the ProfileHeader.

So if a profile e.g. states in the header it requires
usim-test-algorithm, but then the actual akaParameter instances do not
actually use that algorithm, it would raise an exception.

Change-Id: Id0e1988ae1936a321d04bc7c3c3a33262c767d30
Related: SYS#7826
2026-01-20 09:50:03 +01:00
Alexander Couzens
8557ec86be saip: ProfileElementSD: call _post_decode() when instantiating with decoded argument
Otherwise self.keys is not generated from the given data and encoding will fail.

Change-Id: I3020f581a908fecc01d5d255ab5991ce1652e3ec
2026-01-17 21:52:38 +00:00
Alexander Couzens
2e7944cc98 saip: calculate the number of records for LF and CY
Some templates (e.g. for 5GS) define files which aren't completely defined.
5GS OPL5G: doesn't have a file size defined in the template,
but a record size.

Change-Id: I5ec1757d6852eb24d3662ec1c3fc88365e90a616
2026-01-14 00:21:33 +00:00
Alexander Couzens
1347d5ffa2 saip: rework file sizes for "half-defined" template files
Define the file size early if possible.
Some templates (e.g. for 5GS) define files which aren't completely defined.
Fixes the parsing for 5GS SUCI_Calc_Info which doesn't have a file size defined.

The saip-tool will other crash when reading a 5G enabled profile:
```
Traceback (most recent call last):
  File "./contrib/saip-tool.py", line 458, in <module>
    pes = ProfileElementSequence.from_der(f.read())
  File "pySim/esim/saip/__init__.py", line 1679, in from_der
    inst.parse_der(der)
    ~~~~~~~~~~~~~~^^^^^
  File "pySim/esim/saip/__init__.py", line 1552, in parse_der
    self.pe_list.append(ProfileElement.from_der(first_tlv, pe_sequence=self))
                        ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pySim/esim/saip/__init__.py", line 557, in from_der
    inst._post_decode()
    ~~~~~~~~~~~~~~~~~^^
  File "pySim/esim/saip/__init__.py", line 668, in _post_decode
    self.pe2files()
    ~~~~~~~~~~~~~^^
  File "pySim/esim/saip/__init__.py", line 655, in pe2files
    file = File(k, v, template.files_by_pename.get(k, None))
  File "pySim/esim/saip/__init__.py", line 133, in __init__
    self.from_tuples(l)
    ~~~~~~~~~~~~~~~~^^^
  File "pySim/esim/saip/__init__.py", line 358, in from_tuples
    self._body = self.file_content_from_tuples(l)
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "pySim/esim/saip/__init__.py", line 393, in file_content_from_tuples
    stream.write(self.template.expand_default_value_pattern(self.file_size))
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "pySim/esim/saip/templates.py", line 123, in expand_default_value_pattern
    raise ValueError("%s does not have a default length" % self)
ValueError: FileTemplate(EF.SUCI_Calc_Info) does not have a default length
```

Change-Id: I7c4a0914aef1049a416e6b091f23daab39a1dd9c
2026-01-14 00:21:33 +00:00
Philipp Maier
fddab8639f card_key_provider: add PostgreSQL support
The Card Key Provider currently only has support for CSV files
as input. Unfortunately using CSV files does not scale very well
when the card inventory is very large and continously updated.
In this case a centralized storage in the form of a database
is the more suitable approach.

This patch adds PostgreSQL support next to the existing CSV
file support. It also adds an importer tool to import existing
CSV files into the database.

Change-Id: Icba625c02a60d7e1f519b506a46bda5ded0537d3
Related: SYS#7725
2026-01-12 10:57:27 +01:00
Philipp Maier
eb7c5d85d0 runtime/cosmetic: add line break
The other source files have a line break between the character encoding
qualifier line and the python comment. Let's add a line break here
as well to maintain consistency.

Change-Id: Ied6b77eede748f1ddf6fde17c9b434fa4dd1114a
2026-01-06 15:03:53 +01:00
Philipp Maier
eda6182edd transport/init/cosmetic: move copryight header to the top
The copyright header seems to be misplaced, let's move it to the top.

Change-Id: I8358cca3bc9adb5a186a8b38a3bd90d7aec60d5c
2026-01-06 15:00:49 +01:00
Alexander Couzens
725ffffda1 RFC: saip: templates: fix naming of EF.SUPI_NAI
Fixes parsing of a 2.3 UICC profile.
This might be the wrong end as the spec says this is
NSI, but somehow it's working

Change-Id: I3cde1093156db274458d76e2c1c2e304d55a8466
2026-01-07 12:28:25 +00:00
Alexander Couzens
777d005350 saip: templates: IsimOptional: add missing pe_name=ef-pcscf
The file EF.P-CSCF is named ef-pcscf in the asn1 (tested with version 2.3)

Change-Id: I0cfba8f4e97fd6e2d8e21edf0439692b58a78ded
2026-01-07 12:28:25 +00:00
Neels Hofmeyr
6e9625213a fix typo in doc TuakNumberOfKeccak
Change-Id: Ie6f2260d5632dea7409cffd3afa7c8d0b1986a7c
2026-01-07 00:00:21 +01:00
Philipp Maier
4c8a9478c2 cosmetic: fix company name in copyright header.
The correct abbreviated version of the company name is
"sysmocom - s.f.m.c. GmbH", i.e. lowercase and with dash.

Change-Id: Id768d2f4b78162ff83320a800e4e66f1bd324d6d
2026-01-06 21:41:23 +00:00
Philipp Maier
dfe4d9c8ac contrib: add a tool to parse the SIMA response from an eUICC
When an eUICC performs a profile installation it returns a (concatenated)
series of ASN.1 encoded strings as "simaResponse". In case the profile
installation fails for some reason the simaResponse contains diagnostic
information to diagnose why the profile installation failed.

Unfortunately there are currently no practical tools available to decode
and display the information in the simaResponse. Let's add a tool for that.

Related SYS#7617

Change-Id: Ida4c3c5446653b283a3869c0c387f328ae51e55e
2026-01-06 21:41:23 +00:00
Philipp Maier
8e048820d4 pySim-shell: renovate version command
In case pySim-shell is used directly from the git repository (not
installed via a package manager), the version command fails with an
exception because pkg_resources.get_distribution('pySim') fails.

Let's renovate the version command and migrate from pkg_resources to
importlib.resources. There are many users and developers out there who
retrieve pySim-shell directly from the git repository and not via pip3.
To accommodate for that, let's check if pySim-shell.py is located in a
git repository and if so, let's display the HEAD commit hash instead.

Since the version of the currently installed pyosmocom version also
plays a critical role, let's display the pyosmocom version as well.

Related: OS#6830
Change-Id: I2b9038f88cfcaa07894a2f09c7f5ad8a5474083d
2026-01-06 21:11:16 +00:00
Philipp Maier
c2ace3d8cf unittests/test_utils: add unittests for enc_imsi and dec_imsi
So far we seem to have no unittests for enc_imsi and dec_imsi.

Change-Id: Iae55485c5ec7763aa4aaa25fd1910b854adaab60
2026-01-06 21:10:40 +00:00
Harald Welte
097d565310 esim.saip: Better docstring about FsNode class
Change-Id: Id9d196e8d9b1d1b892ec50100b170d72d2c3910b
2026-01-06 21:10:29 +00:00
Harald Welte
a8ae89a041 pySim.esim.saip.ProfileElementSequence: Update type annotations
The type annotations didn't reflect reality in two cases.

Change-Id: Ib99c00a38bf009c63180b4a593d6cc796ff282d3
2026-01-06 21:10:19 +00:00
Philipp Maier
d764659a30 pySim-shell: do not show user home path in help text
At the moment, the help text for the --csv option shows the path to
the users home. This is due to the default value, which is dynamically
generated. Let's use a static string with "~/" and resolve the full
path later when we need it.

Related: SYS#7725
Change-Id: Ied8b1e553de8f5370369c4485a2360906c874ed2
2026-01-05 14:54:26 +00:00
Philipp Maier
3ca25219bc pySim-shell/cosmetic: remove unnecessary brackets
Change-Id: I6929aa4fa189414217c05a4ef5180d4ed44eb3a4
2026-01-05 14:42:49 +00:00
Harald Welte
1da34c1a4f Fix more odd-length digit sequences via PaddedBcdAdapter
There are more files where trailing digits are indicated using 'f' and
should be stripped during decode, including EF.MSISDN and EF.VGCS

This is not just a presentation issue, but actually rendered wrong data
before, see the modified test output where our "read_record_uicc.ok"
file contained "bcd_len: 7" but then only 6 BCD digits due to this bug.

Change-Id: I4571482da924a3d645caa297108279d182448d21
2025-12-23 20:57:03 +01:00