blob: a2812131feb4106a0721fd91eeca52c622d0c79c [file] [log] [blame]
Harald Welte75a58d12022-07-31 15:51:19 +02001"""Code related to SMS Encoding/Decoding"""
2# simplistic SMS T-PDU code, as unfortunately nobody bothered to port the python smspdu
3# module to python3, and I gave up after >= 3 hours of trying and failing to do so
4
5# (C) 2022 by Harald Welte <laforge@osmocom.org>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20import typing
21from construct import Int8ub, Bytes
22from construct import Struct, Tell, this, RepeatUntil
23
24from pySim.utils import Hexstr, h2b, b2h
25
26BytesOrHex = typing.Union[Hexstr, bytes]
27
28class UserDataHeader:
29 # a single IE in the user data header
30 ie_c = Struct('offset'/Tell, 'iei'/Int8ub, 'length'/Int8ub, 'data'/Bytes(this.length))
31 # parser for the full UDH: Length octet followed by sequence of IEs
32 _construct = Struct('udhl'/Int8ub,
33 # FIXME: somehow the below lambda is not working, we always only get the first IE?
34 'ies'/RepeatUntil(lambda obj,lst,ctx: ctx._io.tell() > 1+this.udhl, ie_c))
35
36 def __init__(self, ies=[]):
37 self.ies = ies
38
39 def __repr__(self) -> str:
40 return 'UDH(%r)' % self.ies
41
42 def has_ie(self, iei:int) -> bool:
43 for ie in self.ies:
44 if ie['iei'] == iei:
45 return True
46 return False
47
48 @classmethod
49 def fromBytes(cls, inb: BytesOrHex) -> typing.Tuple['UserDataHeader', bytes]:
50 if isinstance(inb, str):
51 inb = h2b(inb)
52 res = cls._construct.parse(inb)
53 return cls(res['ies']), inb[1+res['udhl']:]