def encode_7b(txt): """translates the unicode string `txt' to a GSM 7 bit characters buffer """ arr, cnt = [], 0 for c in reversed(txt): try: arr.append((TYPE_UINT, _GSM7bLUTInv[c], 7)) except KeyError: try: arr.append((TYPE_UINT, _GSM7bExtLUTInv[c], 7)) except KeyError: raise (PycrateErr('invalid GSM 7 bit char: %r' % c)) else: # add an escape char arr.append((TYPE_UINT, 27, 7)) cnt += 2 else: cnt += 1 # check the length in bits and add padding bits pad = (8 - (7 * len(arr)) % 8) % 8 arr.insert(0, (TYPE_UINT, 0, pad)) if python_version < 3: return ''.join(reversed(pack_val(*arr)[0])), cnt else: return bytes(reversed(pack_val(*arr)[0])), cnt
def encode_7b(txt, off=0): """translates the unicode string `txt' to a GSM 7 bit characters buffer Args: txt (utf8 str): text string to encode off (uint): bit offset Returns: encoded buffer and septet count (bytes, uint) """ arr, cnt = [], 0 for c in reversed(txt): try: arr.append( (TYPE_UINT, _GSM7bLUTInv[c], 7) ) except KeyError: try: arr.append( (TYPE_UINT, _GSM7bExtLUTInv[c], 7) ) except KeyError: raise(PycrateErr('invalid GSM 7 bit char: %r' % c)) else: # add an escape char arr.append( (TYPE_UINT, 27, 7) ) cnt += 2 else: cnt += 1 # check the length in bits and add padding bits pad = ((8-(7*len(arr)+off)%8)%8) arr.insert(0, (TYPE_UINT, 0, pad)) if python_version < 3: return ''.join(reversed(pack_val(*arr)[0])), cnt else: return bytes(reversed(pack_val(*arr)[0])), cnt
def add_segment_and_decode(self, radio_bearer, sfn_prime, sib_type, segment_index, is_final, segment_data_int, segment_data_bitlen, on_sib_decoding_error): if (self.last_sfn and not (1 <= sfn_prime - self.last_sfn <= 16)) or \ (len(self.segment_bitstrings) != segment_index): on_sib_decoding_error( 'DEBUG: Uncomplete %s reassembly: SFN jump from %s to %s (%d), index expected to be %d but is %d' % (getattr(self, 'sib_type', sib_type), self.last_sfn, sfn_prime, sfn_prime - (self.last_sfn or 0), len(self.segment_bitstrings), segment_index)) self.__init__() # Reset state if len(self.segment_bitstrings) != segment_index: return if not segment_index: self.first_sfn = sfn_prime self.last_sfn = sfn_prime self.segment_bitstrings.append( [TYPE_UINT, segment_data_int, segment_data_bitlen]) if is_final: # Convert segments bitstrings to bytes sib_byte_string = pack_val(*self.segment_bitstrings)[0] """ From spec: "If the value "Extension Type" is signalled, the UE shall use the scheduling information in the MIB and, if present, in the SB1 and SB2 to identify the specific type of system information block." """ if sib_type == 'extensionType': for sib_schedule, sib_ext_type in bearer_to_sib_schedule_to_sib_type[ radio_bearer].items(): if self.first_sfn % sib_schedule.sib_period == sib_schedule.sib_position and \ len(self.segment_bitstrings) == sib_schedule.num_segments: self.sib_type = sib_type = sib_ext_type if sib_type == 'extensionType': on_sib_decoding_error( 'DEBUG: Received an extensionType SIB with SFN %d for which no scheduling information is known from MIB/SBs' % sfn_prime) return sib_object = SIB_NAME_TO_CLASS[sib_type] try: sib_object.from_uper(sib_byte_string) except Exception: on_sib_decoding_error( 'ERROR: SIB decoding failed for %s (%s): %s' % (sib_type, repr(sib_byte_string), format_exc())) return sib_dict = sib_object() # Reset state self.__init__() return sib_type, sib_dict, sib_byte_string