laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/36955?usp=email )
Change subject: osmo-smdpp: Make error message more descriptive
......................................................................
osmo-smdpp: Make error message more descriptive
Before this patch we had three different error causes that would cause a
"Verification failed" error message. Let's state explicitly which part
of verification did actually fail.
Change-Id: I5030758fe365bb802ae367b494aace5a66bc7a91
---
M osmo-smdpp.py
1 file changed, 16 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/55/36955/1
diff --git a/osmo-smdpp.py b/osmo-smdpp.py
index 9ed1e39..d7fc872 100755
--- a/osmo-smdpp.py
+++ b/osmo-smdpp.py
@@ -325,14 +325,14 @@
try:
cs.verify_cert_chain(euicc_cert)
except VerifyError:
- raise ApiError('8.1.3', '6.1', 'Verification failed')
+ raise ApiError('8.1.3', '6.1', 'Verification failed (certificate chain)')
# raise ApiError('8.1.3', '6.3', 'Expired')
# Verify euiccSignature1 over euiccSigned1 using pubkey from euiccCertificate.
# Otherwise, the SM-DP+ SHALL return a status code "eUICC - Verification failed"
if not self._ecdsa_verify(euicc_cert, euiccSignature1_bin, euiccSigned1_bin):
- raise ApiError('8.1', '6.1', 'Verification failed')
+ raise ApiError('8.1', '6.1', 'Verification failed (euiccSignature1 over euiccSigned1)')
# TODO: verify EID of eUICC cert is within permitted range of EUM cert
@@ -343,7 +343,7 @@
# serverChallenge returned by the eUICC. Otherwise, the SM-DP+ SHALL return a status code "eUICC -
# Verification failed".
if euiccSigned1['serverChallenge'] != ss.serverChallenge:
- raise ApiError('8.1', '6.1', 'Verification failed')
+ raise ApiError('8.1', '6.1', 'Verification failed (serverChallenge)')
# If ctxParams1 contains a ctxParamsForCommonAuthentication data object, the SM-DP+ Shall [...]
# TODO: We really do a very simplistic job here, this needs to be properly implemented later,
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36955?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I5030758fe365bb802ae367b494aace5a66bc7a91
Gerrit-Change-Number: 36955
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/36957?usp=email )
Change subject: esim.saip: Introduce ProfileElement derived classes
......................................................................
esim.saip: Introduce ProfileElement derived classes
It's rather useful to have derived classes implementing specific
functions related to that SAIP profile type. Let's introruce that
concept and a first example for securityDomain, where methods allow
checking/adding/removing support for SCPs.
Change-Id: I0929cc704b2aabddbc2ddee79ab8b674b1ed4691
---
M pySim/esim/saip/__init__.py
1 file changed, 62 insertions(+), 8 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/57/36957/1
diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py
index b8e41ce..fc86b63 100644
--- a/pySim/esim/saip/__init__.py
+++ b/pySim/esim/saip/__init__.py
@@ -26,6 +26,8 @@
from pySim.construct import build_construct
from pySim.esim import compile_asn1_subdir
from pySim.esim.saip import templates
+from pySim.tlv import BER_TLV_IE
+from pySim.global_platform.uicc import UiccSdInstallParams
asn1 = compile_asn1_subdir('saip')
@@ -134,6 +136,9 @@
"""Class representing a Profile Element (PE) within a SAIP Profile."""
FILE_BEARING = ['mf', 'cd', 'telecom', 'usim', 'opt-usim', 'isim', 'opt-isim', 'phonebook', 'gsm-access',
'csim', 'opt-csim', 'eap', 'df-5gs', 'df-saip', 'df-snpn', 'df-5gprose', 'iot', 'opt-iot']
+ def __init__(self, decoded = None):
+ self.decoded = decoded
+
def _fixup_sqnInit_dec(self) -> None:
"""asn1tools has a bug when working with SEQUENCE OF that have DEFAULT values. Let's work around
this."""
@@ -161,12 +166,6 @@
# none of the fields were initialized with a non-default (non-zero) value, so we can skip it
del self.decoded['sqnInit']
- def parse_der(self, der: bytes) -> None:
- """Parse a sequence of PE and store the result in instance attributes."""
- self.type, self.decoded = asn1.decode('ProfileElement', der)
- # work around asn1tools bug regarding DEFAULT for a SEQUENCE OF
- self._fixup_sqnInit_dec()
-
@property
def header_name(self) -> str:
"""Return the name of the header field within the profile element."""
@@ -195,12 +194,24 @@
@classmethod
def from_der(cls, der: bytes) -> 'ProfileElement':
"""Construct an instance from given raw, DER encoded bytes."""
- inst = cls()
- inst.parse_der(der)
+ pe_type, decoded = asn1.decode('ProfileElement', der)
+ if pe_type == 'securityDomain':
+ inst = ProfileElementSD(decoded)
+ else:
+ inst = ProfileElement(decoded)
+ inst.type = pe_type
+ # work around asn1tools bug regarding DEFAULT for a SEQUENCE OF
+ inst._fixup_sqnInit_dec()
+ # run any post-decoder a derived class may have
+ if hasattr(inst, '_post_decode'):
+ inst._post_decode()
return inst
def to_der(self) -> bytes:
"""Build an encoded DER representation of the instance."""
+ # run any pre-encoder a derived class may have
+ if hasattr(self, '_pre_encode'):
+ self._pre_encode()
# work around asn1tools bug regarding DEFAULT for a SEQUENCE OF
self._fixup_sqnInit_enc()
return asn1.encode('ProfileElement', (self.type, self.decoded))
@@ -208,6 +219,35 @@
def __str__(self) -> str:
return self.type
+class ProfileElementSD(ProfileElement):
+ """Class representing a securityDomain ProfileElement."""
+ type = 'securityDomain'
+
+ class C9(BER_TLV_IE, tag=0xC9, nested=UiccSdInstallParams):
+ pass
+
+ def _post_decode(self):
+ self.usip = self.C9()
+ self.usip.from_bytes(self.decoded['instance']['applicationSpecificParametersC9'])
+
+ def _pre_encode(self):
+ self.decoded['instance']['applicationSpecificParametersC9'] = self.usip.to_bytes()
+
+ def has_scp(self, scp: int) -> bool:
+ """Determine if SD Installation parameters already specify given SCP."""
+ return self.usip.nested_collection.has_scp(scp)
+
+ def add_scp(self, scp: int, i: int):
+ """Add given SCP (and i parameter) to list of SCP of the Security Domain Install Params.
+ Example: add_scp(0x03, 0x70) for SCP03, or add_scp(0x02, 0x55) for SCP02."""
+ self.usip.nested_collection.add_scp(scp, i)
+ self._pre_encode()
+
+ def remove_scp(self, scp: int):
+ """Remove given SCP from list of SCP of the Security Domain Install Params."""
+ self.usip.nested_collection.remove_scp(scp)
+ self._pre_encode()
+
def bertlv_first_segment(binary: bytes) -> Tuple[bytes, bytes]:
"""obtain the first segment of a binary concatenation of BER-TLV objects.
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36957?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I0929cc704b2aabddbc2ddee79ab8b674b1ed4691
Gerrit-Change-Number: 36957
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/36956?usp=email )
Change subject: add globalplatform.uicc
......................................................................
add globalplatform.uicc
GlobalPlatform has a [non-public] "UICC Configuration" spec, which
defines some specific aspects of implementing GlobalPlatform in the
context of an UICC. Let's add some python definitions about it.
Change-Id: If4cb110a9bc5f873b0e097c006bef59264ee48fa
---
A pySim/global_platform/uicc.py
1 file changed, 120 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/56/36956/1
diff --git a/pySim/global_platform/uicc.py b/pySim/global_platform/uicc.py
new file mode 100644
index 0000000..2cf5e96
--- /dev/null
+++ b/pySim/global_platform/uicc.py
@@ -0,0 +1,107 @@
+# coding=utf-8
+"""GlobalPLatform UICC Configuration 1.0 parameters
+
+(C) 2024 by Harald Welte <laforge(a)osmocom.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from construct import Optional as COptional
+from construct import Struct, GreedyRange, FlagsEnum, Int16ub, Int24ub, Padding, Bit, Const
+from pySim.construct import *
+from pySim.utils import *
+from pySim.tlv import *
+
+# Section 11.6.2.3 / Table 11-58
+class SecurityDomainAid(BER_TLV_IE, tag=0x4f):
+ _construct = GreedyBytes
+class LoadFileDataBlockSignature(BER_TLV_IE, tag=0xc3):
+ _construct = GreedyBytes
+class DapBlock(BER_TLV_IE, tag=0xe2, nested=[SecurityDomainAid, LoadFileDataBlockSignature]):
+ pass
+class LoadFileDataBlock(BER_TLV_IE, tag=0xc4):
+ _construct = GreedyBytes
+class Icv(BER_TLV_IE, tag=0xd3):
+ _construct = GreedyBytes
+class CipheredLoadFileDataBlock(BER_TLV_IE, tag=0xd4):
+ _construct = GreedyBytes
+class LoadFile(TLV_IE_Collection, nested=[DapBlock, LoadFileDataBlock, Icv, CipheredLoadFileDataBlock]):
+ pass
+
+# UICC Configuration v1.0.1 / Section 4.3.2
+class UiccScp(BER_TLV_IE, tag=0x81):
+ _construct = Struct('scp'/Int8ub, 'i'/Int8ub)
+
+class AcceptExtradAppsAndElfToSd(BER_TLV_IE, tag=0x82):
+ _construct = GreedyBytes
+
+class AcceptDelOfAssocSd(BER_TLV_IE, tag=0x83):
+ _construct = GreedyBytes
+
+class LifeCycleTransitionToPersonalized(BER_TLV_IE, tag=0x84):
+ _construct = GreedyBytes
+
+class CasdCapabilityInformation(BER_TLV_IE, tag=0x86):
+ _construct = GreedyBytes
+
+class AcceptExtradAssocAppsAndElf(BER_TLV_IE, tag=0x87):
+ _construct = GreedyBytes
+
+# Security Domain Install Parameters (inside C9 during INSTALL [for install])
+class UiccSdInstallParams(TLV_IE_Collection, nested=[UiccScp, AcceptExtradAppsAndElfToSd, AcceptDelOfAssocSd,
+ LifeCycleTransitionToPersonalized,
+ CasdCapabilityInformation, AcceptExtradAssocAppsAndElf]):
+ def has_scp(self, scp: int) -> bool:
+ """Determine if SD Installation parameters already specify given SCP."""
+ for c in self.children:
+ if not isinstance(c, UiccScp):
+ continue
+ if c.decoded['scp'] == scp:
+ return True
+ return False
+
+ def add_scp(self, scp: int, i: int):
+ """Add given SCP (and i parameter) to list of SCP of the Security Domain Install Params.
+ Example: add_scp(0x03, 0x70) for SCP03, or add_scp(0x02, 0x55) for SCP02."""
+ if self.has_scp(scp):
+ raise ValueError('SCP%02x already present' % scp)
+ self.children.append(UiccScp(decoded={'scp': scp, 'i': i}))
+
+ def remove_scp(self, scp: int):
+ """Remove given SCP from list of SCP of the Security Domain Install Params."""
+ for c in self.children:
+ if not isinstance(c, UiccScp):
+ continue
+ if c.decoded['scp'] == scp:
+ self.children.remove(c)
+ return
+ raise ValueError("SCP%02x not present" % scp)
+
+
+# Key Usage:
+# KVN 0x01 .. 0x0F reserved for SCP80
+# KVN 0x11 reserved for DAP specified in ETSI TS 102 226
+# KVN 0x20 .. 0x2F reserved for SCP02
+# KID 0x01 = ENC; 0x02 = MAC; 0x03 = DEK
+# KVN 0x30 .. 0x3F reserved for SCP03
+# KID 0x01 = ENC; 0x02 = MAC; 0x03 = DEK
+# KVN 0x70 KID 0x01: Token key (RSA public or DES)
+# KVN 0x71 KID 0x01: Receipt key (DES)
+# KVN 0x73 KID 0x01: DAP verifiation key (RS public or DES)
+# KVN 0x74 reserved for CASD
+# KID 0x01: PK.CA.AUT
+# KID 0x02: SK.CASD.AUT (PK) and KS.CASD.AUT (Non-PK)
+# KID 0x03: SK.CASD.CT (P) and KS.CASD.CT (Non-PK)
+# KVN 0x75 KID 0x01: 16-byte DES key for Ciphered Load File Data Block
+# KVN 0xFF reserved for ISD with SCP02 without SCP80 s upport
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36956?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: If4cb110a9bc5f873b0e097c006bef59264ee48fa
Gerrit-Change-Number: 36956
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/36929?usp=email )
Change subject: pySim.app: Attempt to retrieve the EID of a SGP.22 / SGP.32 eUICC
......................................................................
pySim.app: Attempt to retrieve the EID of a SGP.22 / SGP.32 eUICC
... and populate the RuntimeState.identity['EID'] wit it, so other
[future] parts of the system can use it.
Let's also print the EID (if available) from the 'cardinfo' shell
command.
Change-Id: Idc2ea1d9263f39b3dff403e1535a5e6c4e88b26f
---
M pySim-shell.py
M pySim/app.py
M pySim/euicc.py
3 files changed, 37 insertions(+), 0 deletions(-)
Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
fixeria: Looks good to me, but someone else must approve
diff --git a/pySim-shell.py b/pySim-shell.py
index c7539be..26f3d9b 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -760,6 +760,9 @@
self._cmd.poutput("Card info:")
self._cmd.poutput(" Name: %s" % self._cmd.card.name)
self._cmd.poutput(" ATR: %s" % self._cmd.rs.identity['ATR'])
+ eid = self._cmd.rs.identity.get('EID', None)
+ if eid:
+ self._cmd.poutput(" EID: %s" % eid)
self._cmd.poutput(" ICCID: %s" % self._cmd.rs.identity['ICCID'])
self._cmd.poutput(" Class-Byte: %s" % self._cmd.lchan.scc.cla_byte)
self._cmd.poutput(" Select-Ctrl: %s" % self._cmd.lchan.scc.sel_ctrl)
diff --git a/pySim/app.py b/pySim/app.py
index e3878b8..5525cd1 100644
--- a/pySim/app.py
+++ b/pySim/app.py
@@ -25,6 +25,7 @@
from pySim.cdma_ruim import CardProfileRUIM
from pySim.ts_102_221 import CardProfileUICC
from pySim.utils import all_subclasses
+from pySim.exceptions import SwMatchError
# we need to import this module so that the SysmocomSJA2 sub-class of
# CardModel is created, which will add the ATR-based matching and
@@ -106,4 +107,15 @@
# inform the transport that we can do context-specific SW interpretation
sl.set_sw_interpreter(rs)
+ # try to obtain the EID, if any
+ isd_r = rs.mf.applications.get(pySim.euicc.AID_ISD_R.lower(), None)
+ if isd_r:
+ rs.lchan[0].select_file(isd_r)
+ try:
+ rs.identity['EID'] = pySim.euicc.CardApplicationISDR.get_eid(scc)
+ except SwMatchError:
+ # has ISD-R but not a SGP.22/SGP.32 eUICC - maybe SGP.02?
+ pass
+ card.reset()
+
return rs, card
diff --git a/pySim/euicc.py b/pySim/euicc.py
index e32fa4d..a771a22 100644
--- a/pySim/euicc.py
+++ b/pySim/euicc.py
@@ -345,6 +345,13 @@
else:
return None
+ @staticmethod
+ def get_eid(scc: SimCardCommands) -> str:
+ ged_cmd = GetEuiccData(children=[TagList(decoded=[0x5A])])
+ ged = CardApplicationISDR.store_data_tlv(scc, ged_cmd, GetEuiccData)
+ d = ged.to_dict()
+ return flatten_dict_lists(d['get_euicc_data'])['eid_value']
+
def decode_select_response(self, data_hex: Hexstr) -> object:
t = FciTemplate()
t.from_tlv(h2b(data_hex))
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36929?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Idc2ea1d9263f39b3dff403e1535a5e6c4e88b26f
Gerrit-Change-Number: 36929
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: merged
laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/36927?usp=email )
Change subject: runtime: Introduce an 'identity' dict for things like ATR, ICCID, EID
......................................................................
runtime: Introduce an 'identity' dict for things like ATR, ICCID, EID
This patch introduces the dict, as well as its first use for ATR storage
Change-Id: Ief5ceaf5afe82800e33da233573293527befd2f4
---
M pySim-shell.py
M pySim/runtime.py
2 files changed, 17 insertions(+), 1 deletion(-)
Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
fixeria: Looks good to me, but someone else must approve
diff --git a/pySim-shell.py b/pySim-shell.py
index 127e366..e238e6a 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -761,7 +761,7 @@
"""Display information about the currently inserted card"""
self._cmd.poutput("Card info:")
self._cmd.poutput(" Name: %s" % self._cmd.card.name)
- self._cmd.poutput(" ATR: %s" % b2h(self._cmd.lchan.scc.get_atr()))
+ self._cmd.poutput(" ATR: %s" % self._cmd.rs.identity['ATR'])
self._cmd.poutput(" ICCID: %s" % self._cmd.iccid)
self._cmd.poutput(" Class-Byte: %s" % self._cmd.lchan.scc.cla_byte)
self._cmd.poutput(" Select-Ctrl: %s" % self._cmd.lchan.scc.sel_ctrl)
diff --git a/pySim/runtime.py b/pySim/runtime.py
index d873e20..3ef9b2d 100644
--- a/pySim/runtime.py
+++ b/pySim/runtime.py
@@ -49,6 +49,9 @@
self.lchan = {}
# the basic logical channel always exists
self.lchan[0] = RuntimeLchan(0, self)
+ # this is a dict of card identities which different parts of the code might populate,
+ # typically with something like ICCID, EID, ATR, ...
+ self.identity = {}
# make sure the class and selection control bytes, which are specified
# by the card profile are used
@@ -138,6 +141,8 @@
# select MF to reset internal state and to verify card really works
self.lchan[0].select('MF', cmd_app)
self.lchan[0].selected_adf = None
+ # store ATR as part of our card identies dict
+ self.identity['ATR'] = atr
return atr
def add_lchan(self, lchan_nr: int) -> 'RuntimeLchan':
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36927?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ief5ceaf5afe82800e33da233573293527befd2f4
Gerrit-Change-Number: 36927
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: merged
Attention is currently required from: dexter, fixeria.
laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/pysim/+/36928?usp=email )
Change subject: pySim-shell: Migrate PySimApp.iccid to RuntimeState.identity['ICCID']
......................................................................
Patch Set 1: Code-Review+2
(1 comment)
File pySim-shell.py:
https://gerrit.osmocom.org/c/pysim/+/36928/comment/663a89d4_3248cb6a
PS1, Line 763: self._cmd.rs.identity['ICCID'])
> For the sake of consistency with `ATR`, which is only present in the dict if available, maybe do not […]
I'm not following you. When would we not have the ATR available? If there's no ATR, there's no card, so nothing else will work at all, including cardinfo.
For ICCID it is valid to be absent. An eUICC without any enabled eSIM profile will not have an ICCID, so that's a valid use case.
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36928?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ibdcf9a7c4e7e445201640bce33b768bcc4460db1
Gerrit-Change-Number: 36928
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Attention: dexter <pmaier(a)sysmocom.de>
Gerrit-Comment-Date: Thu, 30 May 2024 18:05:51 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-MessageType: comment
Attention is currently required from: dexter.
laforge has posted comments on this change. ( https://gerrit.osmocom.org/c/pysim/+/36927?usp=email )
Change subject: runtime: Introduce an 'identity' dict for things like ATR, ICCID, EID
......................................................................
Patch Set 1: Code-Review+2
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36927?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ief5ceaf5afe82800e33da233573293527befd2f4
Gerrit-Change-Number: 36927
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: dexter <pmaier(a)sysmocom.de>
Gerrit-Comment-Date: Thu, 30 May 2024 18:03:14 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment