esim.saip: Fix computation of file content

When generating the file content (body), we need to proceed in the
following order:

1a) If FCP contains fillPattern/repeatPattern, compute file content from those

1b) If FCP doesn't contain fillPattern/repeatPattern but template
    exists, compute file content from template

2)  Apply any fillFileConten / fillFileOffset from the SAIP File on top
    of the above

Change-Id: I822bb5fbec11a3be35910a496af7168458fd949c
Closes: OS#6642
This commit is contained in:
Harald Welte
2024-11-22 15:55:35 +01:00
parent 6046102cbb
commit 779092b0cd
2 changed files with 27 additions and 4 deletions

View File

@@ -18,6 +18,7 @@
import logging import logging
import abc import abc
import io import io
import os
from typing import Tuple, List, Optional, Dict, Union from typing import Tuple, List, Optional, Dict, Union
from collections import OrderedDict from collections import OrderedDict
import asn1tools import asn1tools
@@ -25,6 +26,7 @@ from osmocom.utils import b2h, h2b, Hexstr
from osmocom.tlv import BER_TLV_IE, bertlv_parse_tag, bertlv_parse_len from osmocom.tlv import BER_TLV_IE, bertlv_parse_tag, bertlv_parse_len
from osmocom.construct import build_construct, parse_construct, GreedyInteger from osmocom.construct import build_construct, parse_construct, GreedyInteger
from pySim import ts_102_222
from pySim.utils import dec_imsi from pySim.utils import dec_imsi
from pySim.ts_102_221 import FileDescriptor from pySim.ts_102_221 import FileDescriptor
from pySim.filesystem import CardADF, Path from pySim.filesystem import CardADF, Path
@@ -352,18 +354,29 @@ class File:
ret += self.file_content_to_tuples() ret += self.file_content_to_tuples()
return ret return ret
@staticmethod def expand_fill_pattern(self) -> bytes:
def file_content_from_tuples(l: List[Tuple]) -> Optional[bytes]: """Expand the fill/repeat pattern as per TS 102 222 Section 6.3.2.2.2"""
return ts_102_222.expand_pattern(self.fill_pattern, self.fill_pattern_repeat, self.file_size)
def file_content_from_tuples(self, l: List[Tuple]) -> Optional[bytes]:
"""linearize a list of fillFileContent / fillFileOffset tuples into a stream of bytes.""" """linearize a list of fillFileContent / fillFileOffset tuples into a stream of bytes."""
stream = io.BytesIO() stream = io.BytesIO()
# Providing file content within "fillFileContent" / "fillFileOffset" shall have the same effect as
# creating a file with a fill/repeat pattern and thereafter updating the content via Update.
# Step 1: Fill with pattern from Fcp or Template
if self.fill_pattern:
stream.write(self.expand_fill_pattern())
elif self.template and self.template.default_val:
stream.write(self.template.expand_default_value_pattern(self.file_size))
stream.seek(0)
# then process the fillFileContent/fillFileOffset
for k, v in l: for k, v in l:
if k == 'doNotCreate': if k == 'doNotCreate':
return None return None
if k == 'fileDescriptor': if k == 'fileDescriptor':
pass pass
elif k == 'fillFileOffset': elif k == 'fillFileOffset':
# FIXME: respect the fillPattern! stream.seek(v, os.SEEK_CUR)
stream.write(b'\xff' * v)
elif k == 'fillFileContent': elif k == 'fillFileContent':
stream.write(v) stream.write(v)
else: else:

View File

@@ -25,6 +25,16 @@ from osmocom.utils import b2h, auto_uint8, auto_uint16, is_hexstr
from pySim.ts_102_221 import * from pySim.ts_102_221 import *
def expand_pattern(pattern: bytes, repeat: bool, size: int) -> bytes:
"""Expand the fill/repeat pattern as per TS 102 222 Section 6.3.2.2.2 Tags C1/C2."""
if not repeat:
pad_len = size - len(pattern)
return pattern + pattern[-1:] * pad_len
else:
count = size // len(pattern)
part_len = size - count * len(pattern)
return pattern * count + pattern[:part_len]
@with_default_category('TS 102 222 Administrative Commands') @with_default_category('TS 102 222 Administrative Commands')
class Ts102222Commands(CommandSet): class Ts102222Commands(CommandSet):
"""Administrative commands for telecommunication applications.""" """Administrative commands for telecommunication applications."""