diff options
author | Harald Welte <laforge@osmocom.org> | 2022-02-13 10:54:58 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2022-02-15 15:35:35 +0100 |
commit | bc0e209a9fe72258e64e1984629d12deb8d127d7 (patch) | |
tree | 2c0f2920c4ae504e5280961f88f3b3fb365e76da | |
parent | 3bb516b2b1537c435719a0218b97dd33578adf3b (diff) |
ts_51_011: Proper decode of EF.SMSP
Full decode of the SSM Parameters File
Change-Id: Iac5bb87ed3350978dc8b207f052510fdba2e4883
-rw-r--r-- | pySim/construct.py | 29 | ||||
-rw-r--r-- | pySim/ts_51_011.py | 34 |
2 files changed, 62 insertions, 1 deletions
diff --git a/pySim/construct.py b/pySim/construct.py index 6daa66a..fcbadd8 100644 --- a/pySim/construct.py +++ b/pySim/construct.py @@ -2,7 +2,7 @@ from construct.lib.containers import Container, ListContainer from construct.core import EnumIntegerString import typing from construct import * -from construct.core import evaluate, bytes2integer, integer2bytes +from construct.core import evaluate, bytes2integer, integer2bytes, BitwisableString from construct.lib import integertypes from pySim.utils import b2h, h2b, swap_nibbles import gsm0338 @@ -44,6 +44,25 @@ class BcdAdapter(Adapter): def _encode(self, obj, context, path): return h2b(swap_nibbles(obj)) +class InvertAdapter(Adapter): + """inverse logic (false->true, true->false).""" + @staticmethod + def _invert_bool_in_obj(obj): + for k,v in obj.items(): + # skip all private entries + if k.startswith('_'): + continue + if v == False: + obj[k] = True + elif v == True: + obj[k] = False + return obj + + def _decode(self, obj, context, path): + return self._invert_bool_in_obj(obj) + + def _encode(self, obj, context, path): + return self._invert_bool_in_obj(obj) class Rpad(Adapter): """ @@ -228,3 +247,11 @@ class GreedyInteger(Construct): data = swapbytes(data) stream_write(stream, data, length, path) return obj + +# merged definitions of 24.008 + 23.040 +TypeOfNumber = Enum(BitsInteger(3), unknown=0, international=1, national=2, network_specific=3, + short_code=4, alphanumeric=5, abbreviated=6, reserved_for_extension=7) +NumberingPlan = Enum(BitsInteger(4), unknown=0, isdn_e164=1, data_x121=3, telex_f69=4, + sc_specific_5=5, sc_specific_6=6, national=8, private=9, + ermes=10, reserved_cts=11, reserved_for_extension=15) +TonNpi = BitStruct('ext'/Flag, 'type_of_number'/TypeOfNumber, 'numbering_plan_id'/NumberingPlan) diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py index f9f1e2a..c29b54c 100644 --- a/pySim/ts_51_011.py +++ b/pySim/ts_51_011.py @@ -402,8 +402,42 @@ class EF_MSISDN(LinFixedEF): # TS 51.011 Section 10.5.6 class EF_SMSP(LinFixedEF): + class ValidityPeriodAdapter(Adapter): + def _decode(self, obj, context, path): + if obj <= 143: + return obj + 1 * 5 + elif obj <= 167: + return 12 * 60 + ((obj - 143) * 30) + elif obj <= 196: + return (obj - 166) * (24 * 60) + elif obj <= 255: + return (obj - 192) * (7 * 24 * 60) + else: + raise ValueError + def _encode(self, obj, context, path): + if obj <= 12*60: + return obj/5 - 1 + elif obj <= 24*60: + return 143 + ((obj - (12 * 60)) / 30) + elif obj <= 30 * 24 * 60: + return 166 + (obj / (24 * 60)) + elif obj <= 63 * 7 * 24 * 60: + return 192 + (obj / (7 * 24 * 60)) + else: + raise ValueError + def __init__(self, fid='6f42', sfid=None, name='EF.SMSP', desc='Short message service parameters', **kwargs): super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={28, None}, **kwargs) + ScAddr = Struct('length'/Int8ub, 'ton_npi'/TonNpi, 'call_number'/BcdAdapter(Rpad(Bytes(10)))) + self._construct = Struct('alpha_id'/COptional(GsmStringAdapter(Rpad(Bytes(this._.total_len-28)))), + 'parameter_indicators'/InvertAdapter(FlagsEnum(Byte, tp_dest_addr=1, tp_sc_addr=2, + tp_pid=3, tp_dcs=4, tp_vp=5)), + 'tp_dest_addr'/ScAddr, + 'tp_sc_addr'/ScAddr, + + 'tp_pid'/HexAdapter(Bytes(1)), + 'tp_dcs'/HexAdapter(Bytes(1)), + 'tp_vp_minutes'/EF_SMSP.ValidityPeriodAdapter(Byte)) # TS 51.011 Section 10.5.7 class EF_SMSS(TransparentEF): |