Add very simplistic DF_PHONEBOOK support

This at least gives us the names for the DF and those EFs inside.

Change-Id: I12f70ae78e219e765ecb44cacff421d64c7b3f19
diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py
index cf03a50..7b71423 100644
--- a/pySim/ts_31_102.py
+++ b/pySim/ts_31_102.py
@@ -36,6 +36,7 @@
 from pySim.ts_102_221 import EF_ARR
 from pySim.tlv import *
 from pySim.filesystem import *
+from pySim.ts_31_102_telecom import DF_PHONEBOOK
 from pySim.construct import *
 from construct import Optional as COptional
 from construct import *
@@ -1282,7 +1283,7 @@
             # FIXME: from EF_ePDGSelection onwards
             EF_FromPreferred(service=114),
             # FIXME: DF_SoLSA service=23
-            # FIXME: DF_PHONEBOOK
+            DF_PHONEBOOK(),
             # FIXME: DF_GSM_ACCESS service=27
             DF_WLAN(service=[59, 60, 61, 62, 63, 66, 81, 82, 83, 84, 88]),
             DF_HNB(service=[86, 90]),
diff --git a/pySim/ts_31_102_telecom.py b/pySim/ts_31_102_telecom.py
new file mode 100644
index 0000000..49f6868
--- /dev/null
+++ b/pySim/ts_31_102_telecom.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+# without this, pylint will fail when inner classes are used
+# within the 'nested' kwarg of our TlvMeta metaclass on python 3.7 :(
+# pylint: disable=undefined-variable
+
+"""
+DF_PHONEBOOK as specified in 3GPP TS 31.102 V16.6.0
+Needs to be a separate python module to avoid cyclic imports
+"""
+
+#
+# Copyright (C) 2022 Harald Welte <laforge@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 pySim.tlv import *
+from pySim.filesystem import *
+from pySim.construct import *
+from construct import Optional as COptional
+from construct import *
+
+# TS 31.102 Section 4.4.2.1
+class EF_PBR(LinFixedEF):
+    def __init__(self, fid='4F30', name='EF.PBR', desc='Phone Book Reference', **kwargs):
+        super().__init__(fid, name=name, desc=desc, **kwargs)
+        #self._tlv = FIXME
+
+# TS 31.102 Section 4.4.2.12.2
+class EF_PSC(TransparentEF):
+    _construct = Struct('synce_counter'/Int32ub)
+    def __init__(self, fid='4F22', name='EF.PSC', desc='Phone Book Synchronization Counter', **kwargs):
+        super().__init__(fid, name=name, desc=desc, **kwargs)
+        #self._tlv = FIXME
+
+# TS 31.102 Section 4.4.2.12.3
+class EF_CC(TransparentEF):
+    _construct = Struct('change_counter'/Int16ub)
+    def __init__(self, fid='4F23', name='EF.CC', desc='Change Counter', **kwargs):
+        super().__init__(fid, name=name, desc=desc, **kwargs)
+
+# TS 31.102 Section 4.4.2.12.4
+class EF_PUID(TransparentEF):
+    _construct = Struct('previous_uid'/Int16ub)
+    def __init__(self, fid='4F24', name='EF.PUID', desc='Previous Unique Identifer', **kwargs):
+        super().__init__(fid, name=name, desc=desc, **kwargs)
+
+# TS 31.102 Section 4.4.2
+class DF_PHONEBOOK(CardDF):
+    def __init__(self, fid='5F3A', name='DF.PHONEBOOK', desc='Phonebook', **kwargs):
+        super().__init__(fid=fid, name=name, desc=desc, **kwargs)
+        files = [
+            EF_PBR(),
+            EF_PSC(),
+            EF_CC(),
+            EF_PUID(),
+            # FIXME: Those 4Fxx entries with unspecified FID...
+            ]
+        self.add_files(files)
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index 209a273..e4cbfd2 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -32,6 +32,7 @@
 from pySim.profile import match_sim
 from pySim.profile import CardProfile
 from pySim.filesystem import *
+from pySim.ts_31_102_telecom import DF_PHONEBOOK
 import enum
 from pySim.construct import *
 from construct import Optional as COptional
@@ -497,6 +498,8 @@
             EF_EXT('6f4e', None, 'EF.EXT4', 'Extension4 (BDN/SSC)'),
             EF_SMSR(),
             EF_CMI(),
+            # not really part of 51.011 but something that TS 31.102 specifies may exist here.
+            DF_PHONEBOOK(),
         ]
         self.add_files(files)