laforge has submitted this change. (
https://gerrit.osmocom.org/c/pysim/+/35451?usp=email
)
Change subject: add PlmnAdapter for decoding PLMN bcd-strings like 262f01 to 262-01
......................................................................
add PlmnAdapter for decoding PLMN bcd-strings like 262f01 to 262-01
The human representation of a PLMN is usually MCC-MNC like 262-01
or 262-001. Let's add a PlmnAdapter for use within construct, so we
can properly decode that.
Change-Id: I96f276e6dcdb54a5a3d2bcde5ee6dbaf981ed789
---
M pySim/cat.py
M pySim/construct.py
M pySim/gsm_r.py
M pySim/ts_31_102.py
M pySim/ts_51_011.py
M pysim-testdata/pySim-trace_test_gsmtap.pcapng.ok
6 files changed, 47 insertions(+), 17 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
fixeria: Looks good to me, but someone else must approve
diff --git a/pySim/cat.py b/pySim/cat.py
index e98ce4a..5925bf3 100644
--- a/pySim/cat.py
+++ b/pySim/cat.py
@@ -22,7 +22,7 @@
from typing import List
from pySim.utils import b2h, h2b, dec_xplmn_w_act
from pySim.tlv import TLV_IE, COMPR_TLV_IE, BER_TLV_IE, TLV_IE_Collection
-from pySim.construct import BcdAdapter, HexAdapter, GsmStringAdapter, TonNpi
+from pySim.construct import PlmnAdapter, BcdAdapter, HexAdapter, GsmStringAdapter,
TonNpi
from construct import Int8ub, Int16ub, Byte, Bytes, Bit, Flag, BitsInteger
from construct import Struct, Enum, Tell, BitStruct, this, Padding, RepeatUntil
from construct import GreedyBytes, Switch, GreedyRange, FlagsEnum
@@ -597,7 +597,7 @@
# TS 31.111 Section 8.91
class RoutingAreaIdentification(COMPR_TLV_IE, tag=0xF3):
- _construct = Struct('mcc_mnc'/BcdAdapter(Bytes(3)),
+ _construct = Struct('mcc_mnc'/PlmnAdapter(Bytes(3)),
'lac'/HexAdapter(Bytes(2)),
'rac'/Int8ub)
@@ -645,7 +645,7 @@
# TS 31.111 Section 8.97
class PlmnList(COMPR_TLV_IE, tag=0xF9):
- _construct = GreedyRange('mcc_mnc'/HexAdapter(Bytes(3)))
+ _construct = GreedyRange('mcc_mnc'/PlmnAdapter(Bytes(3)))
# TS 102 223 Section 8.98
class EcatSequenceNumber(COMPR_TLV_IE, tag=0xA1):
diff --git a/pySim/construct.py b/pySim/construct.py
index cef9557..f78adfe 100644
--- a/pySim/construct.py
+++ b/pySim/construct.py
@@ -58,6 +58,23 @@
def _encode(self, obj, context, path):
return h2b(swap_nibbles(obj))
+class PlmnAdapter(BcdAdapter):
+ """convert a bytes(3) type to BCD string like 262-02 or
262-002."""
+ def _decode(self, obj, context, path):
+ bcd = super()._decode(obj, context, path)
+ if bcd[3] == 'f':
+ return '-'.join([bcd[:3], bcd[4:]])
+ else:
+ return '-'.join([bcd[:3], bcd[3:]])
+
+ def _encode(self, obj, context, path):
+ l = obj.split('-')
+ if len(l[1]) == 2:
+ bcd = l[0] + 'f' + l[1]
+ else:
+ bcd = l[0] + l[1]
+ return super()._encode(bcd, context, path)
+
class InvertAdapter(Adapter):
"""inverse logic (false->true, true->false)."""
@staticmethod
diff --git a/pySim/gsm_r.py b/pySim/gsm_r.py
index cd111d6..db7819c 100644
--- a/pySim/gsm_r.py
+++ b/pySim/gsm_r.py
@@ -202,12 +202,12 @@
class EF_GsmrPLMN(LinFixedEF):
"""Section 7.7"""
_test_de_encode = [
- ( "22f860f86f8d6f8e01", { "plmn": "228f06",
"class_of_network": {
+ ( "22f860f86f8d6f8e01", { "plmn": "228-06",
"class_of_network": {
"supported": { "vbs": True,
"vgcs": True, "emlpp": True,
"fn": True, "eirene": True },
"preference": 0 },
"ic_incoming_ref_tbl": "6f8d",
"outgoing_ref_tbl": "6f8e",
"ic_table_ref": "01" } ),
- ( "22f810416f8d6f8e02", { "plmn": "228f01",
"class_of_network": {
+ ( "22f810416f8d6f8e02", { "plmn": "228-01",
"class_of_network": {
"supported": { "vbs": False,
"vgcs": False, "emlpp": False,
"fn": True, "eirene": False },
"preference": 1 },
"ic_incoming_ref_tbl": "6f8d",
"outgoing_ref_tbl": "6f8e",
@@ -216,7 +216,7 @@
def __init__(self):
super().__init__(fid='6ff5', sfid=None, name='EF.GsmrPLMN',
desc='GSM-R network selection', rec_len=(9, 9))
- self._construct = Struct('plmn'/BcdAdapter(Bytes(3)),
+ self._construct = Struct('plmn'/PlmnAdapter(Bytes(3)),
'class_of_network'/BitStruct('supported'/FlagsEnum(BitsInteger(5), vbs=1,
vgcs=2, emlpp=4, fn=8, eirene=16),
'preference'/BitsInteger(3)),
'ic_incoming_ref_tbl'/HexAdapter(Bytes(2)),
diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py
index b5faf08..16526c2 100644
--- a/pySim/ts_31_102.py
+++ b/pySim/ts_31_102.py
@@ -566,14 +566,14 @@
class EF_LOCI(TransparentEF):
_test_de_encode = [
( '47d1264a62f21037211e00',
- { "tmsi": "47d1264a", "lai": {
"mcc_mnc": "262f01", "lac": "3721" },
+ { "tmsi": "47d1264a", "lai": {
"mcc_mnc": "262-01", "lac": "3721" },
"rfu": 30, "lu_status": 0 } ),
( 'ffffffff62f2200000ff01',
- {"tmsi": "ffffffff", "lai": {"mcc_mnc":
"262f02", "lac": "0000"}, "rfu": 255,
"lu_status": 1} ),
+ {"tmsi": "ffffffff", "lai": {"mcc_mnc":
"262-02", "lac": "0000"}, "rfu": 255,
"lu_status": 1} ),
]
def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI',
desc='Location information', size=(11, 11)):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
- Lai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)),
'lac'/HexAdapter(Bytes(2)))
+ Lai = Struct('mcc_mnc'/PlmnAdapter(Bytes(3)),
'lac'/HexAdapter(Bytes(2)))
self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/Lai,
'rfu'/Int8ub, 'lu_status'/Int8ub)
# TS 31.102 Section 4.2.18
@@ -905,11 +905,11 @@
# TS 31.102 Section 4.2.104
class EF_ePDGSelection(TransparentEF):
_test_de_encode = [
- ( '80060001f1000100', {'e_pdg_selection': [{'plmn':
'00101f', 'epdg_priority': 1, 'epdg_fqdn_format':
'operator_identified' }] }),
- ( '800600011000a001', {'e_pdg_selection': [{'plmn':
'001001', 'epdg_priority': 160, 'epdg_fqdn_format':
'location_based' }] }),
+ ( '800600f110000100', {'e_pdg_selection': [{'plmn':
'001-01', 'epdg_priority': 1, 'epdg_fqdn_format':
'operator_identified' }] }),
+ ( '800600011000a001', {'e_pdg_selection': [{'plmn':
'001-001', 'epdg_priority': 160, 'epdg_fqdn_format':
'location_based' }] }),
]
class ePDGSelection(BER_TLV_IE, tag=0x80):
- _construct = GreedyRange(Struct('plmn'/BcdAdapter(Bytes(3)),
+ _construct = GreedyRange(Struct('plmn'/PlmnAdapter(Bytes(3)),
'epdg_priority'/Int16ub,
'epdg_fqdn_format'/Enum(Int8ub,
operator_identified=0, location_based=1)))
@@ -980,7 +980,7 @@
class EF_OPL5G(LinFixedEF):
def __init__(self, fid='4f08', sfid=0x08, name='EF.OPL5G',
desc='5GS Operator PLMN List', **kwargs):
super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(10, None),
**kwargs)
- Tai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)),
'tac_min'/HexAdapter(Bytes(3)),
+ Tai = Struct('mcc_mnc'/PlmnAdapter(Bytes(3)),
'tac_min'/HexAdapter(Bytes(3)),
'tac_max'/HexAdapter(Bytes(3)))
self._construct = Struct('tai'/Tai, 'pnn_record_id'/Int8ub)
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index 0a803b9..422b35e 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -845,11 +845,11 @@
class EF_OPL(LinFixedEF):
_test_de_encode = [
( '62f2100000fffe01',
- { "lai": { "mcc_mnc": "262f01",
"lac_min": "0000", "lac_max": "fffe" },
"pnn_record_id": 1 } ),
+ { "lai": { "mcc_mnc": "262-01",
"lac_min": "0000", "lac_max": "fffe" },
"pnn_record_id": 1 } ),
]
def __init__(self, fid='6fc6', sfid=None, name='EF.OPL', rec_len=(8,
8), desc='Operator PLMN List', **kwargs):
super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len,
**kwargs)
- self._construct =
Struct('lai'/Struct('mcc_mnc'/BcdAdapter(Bytes(3)),
+ self._construct =
Struct('lai'/Struct('mcc_mnc'/PlmnAdapter(Bytes(3)),
'lac_min'/HexAdapter(Bytes(2)),
'lac_max'/HexAdapter(Bytes(2))), 'pnn_record_id'/Int8ub)
# TS 51.011 Section 10.3.44 + TS 31.102 4.2.62
@@ -884,7 +884,7 @@
# TODO: a305800337f800ffffffffffffffffffffffffffffffffffffffffffffff
class ServiceProviderPLMN(BER_TLV_IE, tag=0x80):
# flexible numbers of 3-byte PLMN records
- _construct = GreedyRange(BcdAdapter(Bytes(3)))
+ _construct = GreedyRange(PlmnAdapter(Bytes(3)))
class SPDI(BER_TLV_IE, tag=0xA3, nested=[ServiceProviderPLMN]):
pass
diff --git a/pysim-testdata/pySim-trace_test_gsmtap.pcapng.ok
b/pysim-testdata/pySim-trace_test_gsmtap.pcapng.ok
index 873574c..2d9d951 100644
--- a/pysim-testdata/pySim-trace_test_gsmtap.pcapng.ok
+++ b/pysim-testdata/pySim-trace_test_gsmtap.pcapng.ok
@@ -57,7 +57,7 @@
===============================
00 READ BINARY MF/ADF.USIM/EF.ACC - 9000 {'ACC0':
True, 'ACC1': False, 'ACC2': False, 'ACC3': False, 'ACC4':
False, 'ACC5': False, 'ACC6': False, 'ACC7': False,
'ACC8': False, 'ACC9': False, 'ACC10': False, 'ACC11':
False, 'ACC12': False, 'ACC13': False, 'ACC14': False,
'ACC15': False}
===============================
-00 READ BINARY MF/ADF.USIM/EF.LOCI - 9000 {'tmsi':
'ffffffff', 'lai': {'mcc_mnc': 'ffffff', 'lac':
'fffe'}, 'rfu': 255, 'lu_status': 3}
+00 READ BINARY MF/ADF.USIM/EF.LOCI - 9000 {'tmsi':
'ffffffff', 'lai': {'mcc_mnc': 'fff-ff', 'lac':
'fffe'}, 'rfu': 255, 'lu_status': 3}
===============================
00 READ BINARY MF/ADF.USIM/EF.PSLOCI - 9000 {'ptmsi':
'ffffffff', 'ptmsi_sig': 'ffffff', 'rai':
'ffff00fffeff', 'rau_status': 2}
===============================
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/35451?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: I96f276e6dcdb54a5a3d2bcde5ee6dbaf981ed789
Gerrit-Change-Number: 35451
Gerrit-PatchSet: 3
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: merged