diff --git a/pySim/commands.py b/pySim/commands.py index 477cb2b9..e0720696 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -26,7 +26,7 @@ import typing # construct also has a Union, so we do typing.Union below from construct import * from pySim.construct import LV -from pySim.utils import rpad, b2h, h2b, sw_match, bertlv_encode_len, Hexstr, h2i, str_sanitize, expand_hex +from pySim.utils import rpad, lpad, b2h, h2b, sw_match, bertlv_encode_len, Hexstr, h2i, str_sanitize, expand_hex from pySim.utils import Hexstr, SwHexstr, ResTuple from pySim.exceptions import SwMatchError from pySim.transport import LinkBase @@ -269,7 +269,7 @@ class SimCardCommands: data.lower(), res[0].lower())) def update_record(self, ef: Path, rec_no: int, data: Hexstr, force_len: bool = False, - verify: bool = False, conserve: bool = False) -> ResTuple: + verify: bool = False, conserve: bool = False, leftpad: bool = False) -> ResTuple: """Execute UPDATE RECORD. Args: @@ -279,6 +279,7 @@ class SimCardCommands: force_len : enforce record length by using the actual data length verify : verify data by re-reading the record conserve : read record and compare it with data, skip write on match + leftpad : apply 0xff padding from the left instead from the right side. """ res = self.select_path(ef) @@ -295,7 +296,10 @@ class SimCardCommands: raise ValueError('Data length exceeds record length (expected max %d, got %d)' % ( rec_length, len(data) // 2)) elif (len(data) // 2 < rec_length): - data = rpad(data, rec_length * 2) + if leftpad: + data = lpad(data, rec_length * 2) + else: + data = rpad(data, rec_length * 2) # Save write cycles by reading+comparing before write if conserve: diff --git a/pySim/filesystem.py b/pySim/filesystem.py index 9f3ee174..5950ad14 100644 --- a/pySim/filesystem.py +++ b/pySim/filesystem.py @@ -920,7 +920,7 @@ class LinFixedEF(CardEF): self._cmd.poutput_json(data) def __init__(self, fid: str, sfid: str = None, name: str = None, desc: str = None, - parent: Optional[CardDF] = None, rec_len: Size = (1, None), **kwargs): + parent: Optional[CardDF] = None, rec_len: Size = (1, None), leftpad: bool = False, **kwargs): """ Args: fid : File Identifier (4 hex digits) @@ -929,9 +929,11 @@ class LinFixedEF(CardEF): desc : Description of the file parent : Parent CardFile object within filesystem hierarchy rec_len : Tuple of (minimum_length, recommended_length) + leftpad: On write, data must be padded from the left to fit pysical record length """ super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, parent=parent, **kwargs) self.rec_len = rec_len + self.leftpad = leftpad self.shell_commands = [self.ShellCommands()] self._construct = None self._tlv = None diff --git a/pySim/runtime.py b/pySim/runtime.py index 422e916c..d6c6d19c 100644 --- a/pySim/runtime.py +++ b/pySim/runtime.py @@ -458,7 +458,9 @@ class RuntimeLchan: """ if not isinstance(self.selected_file, LinFixedEF): raise TypeError("Only works with Linear Fixed EF") - return self.rs.card._scc.update_record(self.selected_file.fid, rec_nr, data_hex, conserve=self.rs.conserve_write) + return self.rs.card._scc.update_record(self.selected_file.fid, rec_nr, data_hex, + conserve=self.rs.conserve_write, + leftpad=self.selected_file.leftpad) def update_record_dec(self, rec_nr: int, data: dict): """Update a record with given abstract data. Will encode abstract to binary data diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py index c81bfdfb..d8cbabd2 100644 --- a/pySim/ts_51_011.py +++ b/pySim/ts_51_011.py @@ -181,7 +181,7 @@ class EF_SMS(LinFixedEF): # TS 51.011 Section 10.5.5 class EF_MSISDN(LinFixedEF): def __init__(self, fid='6f40', sfid=None, name='EF.MSISDN', desc='MSISDN', **kwargs): - super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(15, 34), **kwargs) + super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(15, 34), leftpad=True, **kwargs) def _decode_record_hex(self, raw_hex_data, **kwargs): return {'msisdn': dec_msisdn(raw_hex_data)} @@ -192,8 +192,7 @@ class EF_MSISDN(LinFixedEF): encoded_msisdn = enc_msisdn(msisdn) else: encoded_msisdn = enc_msisdn(msisdn[2], msisdn[0], msisdn[1]) - alpha_identifier = (list(self.rec_len)[ - 0] - len(encoded_msisdn) // 2) * "ff" + alpha_identifier = (list(self.rec_len)[0] - len(encoded_msisdn) // 2) * "ff" return alpha_identifier + encoded_msisdn # TS 51.011 Section 10.5.6