1. 3GPP的文本格式

3GPP OTA的二进制数据,通过Wireshark(tshark)解析后可以生成文本格式,该文本格式的缩进是4空格。针对此4空格的格式,使用Python脚本可以获取感兴趣的数据段落。
对于数据段落可以根据自己的需求,使用正则表达式提取部分字段以方便查看。

2. 源码

2.1 提取感兴趣的字段

extract.py:

class ExtractMultiline(object):
    '''
    3GPP Decoder工具对OTA二进制数据解析,生成文本,该文本格式是4个空格的文本格式。
    为方便解析该文本中的数据,我们需要对感兴趣的数据段落进行提取。
    该类用于提取这些数据段落。
    '''

    def get_filecontent_lines(self, multilines_file):
        '''
        Parameters
        ----------
        multilines_file : string
            文件名称

        Returns
        -------
        lines : string
            文件内容

        '''
        f = open(multilines_file, 'r', encoding='UTF-8', errors='ignore')
        lines = f.readlines()
        f.close()
        return lines
    
    def get_multilines(self, entry_string, tag_string, lines):
        '''
        Parameters
        ----------
        entry_string : string
            如果该字符串包含在某行中,该行作为启动捕获期望获取的多行字符串的开始。该标记为避免(减少)直接使用tag_string引起的冲突。
        tag_string : string
            期望获取的多行字符串的标记
        lines : string
            输入的多行文本

        Returns
        -------
        multilines_array : array
            期望获取的多行字符串,有可能有多个,这里用array返回
        '''
        entry_flag = False
        entry_nest_count = 0
        
        nest_count = 0
        multilines = []
        multilines_array = []

        tag_state = 'IDLE'
        tag_count = 0
        
        for line in lines:
            spaceNum = len(line.rstrip()) - len(line.strip())
            nest_count = int(spaceNum/4)
            
            if entry_string == line.strip():
                entry_flag = True
                entry_nest_count = nest_count
            elif entry_flag and nest_count <= entry_nest_count:
                entry_flag = False

            if entry_flag:
                if tag_string in line:
                    tag_state = 'START'
                    tag_count = nest_count
                elif tag_state == 'START' and nest_count <= tag_count:
                    tag_state = 'END'
                if tag_state == 'START':
                    multilines.append(line)
                if tag_state == 'END':
                    tag_state = 'IDLE'
                    multilines_array.append(multilines)
                    multilines = []
        
        # 文件结束还处于START状态的特殊处理,表示该最后一段multilines也需要记录下来
        if tag_state == 'START':
            tag_state = 'IDLE'
            multilines_array.append(multilines)
        return multilines_array

if __name__ == '__main__':
    extract_multiline = ExtractMultiline()
    lines = extract_multiline.get_filecontent_lines(r'nr-ueCapabilityEnquiry.txt')
    multilines_array = extract_multiline.get_multilines('ue-CapabilityRAT-RequestList:', 'UE-CapabilityRAT-Request', lines)
    print(multilines_array)

2.2 例子

2.2.1 获取LTE能力请求信息中的Band信息

get_capability_enquiry_for_lte.py:

import re
from tools.extract import ExtractMultiline

class UeCapabilityEnquiryForLTE(object):

    # 获取RAT类型列表
    def get_rat(self, multilines):
        re_rat_type = '\s*RAT-Type: (\S+) .+'
        rat_type_list = []
        
        for line in multilines:
            m_rat_type = re.match(re_rat_type, line)
            if m_rat_type:
                rat_type_list.append(m_rat_type.group(1))
        return rat_type_list

    def analyse_ota(self, ota_file):
        extract_multiline = ExtractMultiline()
        lines = extract_multiline.get_filecontent_lines(ota_file)
        multilines_array = extract_multiline.get_multilines('ueCapabilityEnquiry-r8', 'ue-CapabilityRequest:', lines)
        rat_type_list = []
        if len(multilines_array) >= 1:
            rat_type_list = self.get_rat(multilines_array[0])
        return rat_type_list

if __name__ == '__main__':
    ue_capability_enquiry_for_lte = UeCapabilityEnquiryForLTE()
    rat_type_list = ue_capability_enquiry_for_lte.analyse_ota(r'lte-ueCapabilityEnquiry.txt')
    print(rat_type_list)

2.2.2 获取NR能力请求信息中的Band信息

get_capability_enquiry_for_nr.py:

import re
from tools.extract import ExtractMultiline

class UeCapabilityEnquiryForNR(object):
    
    # 获取RAT类型列表
    def get_rat(self, multilines_array):
        re_rat_type = '\s*rat-Type: (\S+) .+'
        rat_type_list = []
        
        for multilines in multilines_array:
            for line in multilines:
                m_rat_type = re.match(re_rat_type, line)
                if m_rat_type:
                    rat_type_list.append(m_rat_type.group(1))
        return rat_type_list
    
    def analyse_ota(self, ota_file):
        extract_multiline = ExtractMultiline()
        lines = extract_multiline.get_filecontent_lines(ota_file)
        multilines_array = extract_multiline.get_multilines('ue-CapabilityRAT-RequestList:', 'UE-CapabilityRAT-Request', lines)
        rat_type_list = self.get_rat(multilines_array)
        return rat_type_list

if __name__ == '__main__':
    ue_capability_enquiry_for_nr = UeCapabilityEnquiryForNR()
    rat_type_list = ue_capability_enquiry_for_nr.analyse_ota(r'nr-ueCapabilityEnquiry.txt')
    print(rat_type_list)

2.2.3 获取能力上报信息中的Band信息(包括CA和EN-DC信息)

get_capability_information.py:

import re
from tools.extract import ExtractMultiline

class UeCapabilityInformation(object):

    # LTE Band list
    def supported_band_list_eutra(self, multilines):
        re_bandEUTRA = '\s*bandEUTRA: (\d*)'
        bandlist = []
        
        for line in multilines:
            m_bandEUTRA = re.match(re_bandEUTRA, line)
            if m_bandEUTRA:
                bandlist.append(m_bandEUTRA.group(1))
        return bandlist

    # LTE Band list extend(v9e0)
    def supported_band_list_eutra_v9e0(self, multilines):
        re_bandEUTRA_v9e0 = '\s*bandEUTRA-v9e0: (\d*)'
        bandlist_v9e0_str = ''
        bandlist_v9e0 = []
        
        for line in multilines:
            if 'SupportedBandEUTRA-v9e0' in line:
                bandlist_v9e0_str = bandlist_v9e0_str + ':B'
            m_bandEUTRA_v9e0 = re.match(re_bandEUTRA_v9e0, line)
            if m_bandEUTRA_v9e0:
                bandlist_v9e0_str = bandlist_v9e0_str + m_bandEUTRA_v9e0.group(1)
        if len(bandlist_v9e0_str) > 1:
            bandlist_v9e0 = bandlist_v9e0_str[1:].split(':')
            bandlist_v9e0 = [item.replace('B','') for item in bandlist_v9e0]
        return bandlist_v9e0

    # LTE CA band combination
    def supported_band_combination_r10(self, multilines):
        ca_array = []
        ca_str = ''
        re_bandEUTRA_r10 = '\s*bandEUTRA-r10: (\d*)'
        re_ca_BandwidthClassUL_r10 = '\s*ca-BandwidthClassUL-r10: ([abcde]{1}) .+'
        re_ca_BandwidthClassDL_r10 = '\s*ca-BandwidthClassDL-r10: ([abcde]{1}) .+'
        
        for line in multilines:
            m_bandEUTRA_r10 = re.match(re_bandEUTRA_r10, line)
            m_ca_BandwidthClassUL_r10 = re.match(re_ca_BandwidthClassUL_r10, line)
            m_ca_BandwidthClassDL_r10 = re.match(re_ca_BandwidthClassDL_r10, line)
            if 'BandCombinationParameters-r10' in line:
                ca_str = ca_str + ':'
            if m_bandEUTRA_r10:
                ca_str = ca_str + ';B' + m_bandEUTRA_r10.group(1)
            if m_ca_BandwidthClassUL_r10:
                ca_str = ca_str + '-UL' + m_ca_BandwidthClassUL_r10.group(1)
            if m_ca_BandwidthClassDL_r10:
                ca_str = ca_str + '-DL' + m_ca_BandwidthClassDL_r10.group(1)
                
        if len(ca_str) > 1:
            ca_array = ca_str[1:].split(':')
            ca_array = [item[1:] for item in ca_array] # or item.replace(';','',1)
        return ca_array

    # LTE CA band extend
    def supported_band_combination_v1090(self, multilines):
        ca_extend_str = ''
        ca_extend_array = []
        re_bandEUTRA_v1090 = '\s*bandEUTRA-v1090: (\d*)'
        
        for line in multilines:
            m_bandEUTRA_v1090 = re.match(re_bandEUTRA_v1090, line)
            if 'BandCombinationParameters-v1090' in line:
                ca_extend_str = ca_extend_str + ':'
            if 'BandParameters-v1090' in line:
                ca_extend_str = ca_extend_str + ';'
            if m_bandEUTRA_v1090:
                ca_extend_str = ca_extend_str + m_bandEUTRA_v1090.group(1)
        
        if len(ca_extend_str) > 1:
            ca_extend_array = ca_extend_str[1:].split(':')
        return ca_extend_array

    # LTE CA set
    def supported_band_combination_ext_r10(self, multilines):
        ca_set_str = ''
        ca_set_array = []
        
        for line in multilines:
            m = re.match('\s*supportedBandwidthCombinationSet-r10: ([0-9abcdefABCDEF]*) .*', line)
            if 'BandCombinationParametersExt-r10' in line:
                ca_set_str = ca_set_str + ':'
            if m:
                ca_set_str = ca_set_str + m.group(1)
        if len(ca_set_str) > 1:
            ca_set_array = ca_set_str[1:].split(':')
        for index in range(0, len(ca_set_array)):
            if ca_set_array[index] != '':
                ca_set_array[index] =  (bin(int(ca_set_array[index],16))).replace('0b', '').replace('0', '')
        return ca_set_array

    # NR Band list
    def supported_band_list_nr(self, multilines):
        re_bandNR = '\s*bandNR: (\d*)'
        bandlist = []
        
        for line in multilines:
            m_bandNR= re.match(re_bandNR, line)
            if m_bandNR:
                bandlist.append(m_bandNR.group(1))
        return bandlist

    # NR CA band combination
    def supported_band_combination_list_nr(self, multilines):
        ca_array = []
        ca_str = ''
        re_bandNR = '\s*bandNR: (\d*)'
        re_ca_BandwidthClassUL_NR = '\s*ca-BandwidthClassUL-NR: ([abcde]{1}) .+'
        re_ca_BandwidthClassDL_NR = '\s*ca-BandwidthClassDL-NR: ([abcde]{1}) .+'
        
        for line in multilines:
            m_bandNR = re.match(re_bandNR, line)
            m_ca_BandwidthClassUL_NR = re.match(re_ca_BandwidthClassUL_NR, line)
            m_ca_BandwidthClassDL_NR = re.match(re_ca_BandwidthClassDL_NR, line)
            if 'BandCombination' == line.strip():
                ca_str = ca_str + ':'
            if m_bandNR:
                ca_str = ca_str + ';N' + m_bandNR.group(1)
            if m_ca_BandwidthClassUL_NR:
                ca_str = ca_str + '-UL' + m_ca_BandwidthClassUL_NR.group(1)
            if m_ca_BandwidthClassDL_NR:
                ca_str = ca_str + '-DL' + m_ca_BandwidthClassDL_NR.group(1)
                
        if len(ca_str) > 1:
            ca_array = ca_str[1:].split(':')
            ca_array = [item[1:] for item in ca_array] # or item.replace(';','',1)
        return ca_array

    # MRDC CA band combination
    def supported_band_combination_list_mrdc(self, multilines):
        mrdc_array = []
        mrdc_str = ''
        re_bandEUTRA = '\s*bandEUTRA: (\d*)'
        re_ca_BandwidthClassUL_EUTRA = '\s*ca-BandwidthClassUL-EUTRA: ([abcde]{1}) .+'
        re_ca_BandwidthClassDL_EUTRA = '\s*ca-BandwidthClassDL-EUTRA: ([abcde]{1}) .+'
        re_bandNR = '\s*bandNR: (\d*)'
        re_ca_BandwidthClassUL_NR = '\s*ca-BandwidthClassUL-NR: ([abcde]{1}) .+'
        re_ca_BandwidthClassDL_NR = '\s*ca-BandwidthClassDL-NR: ([abcde]{1}) .+'
        
        for line in multilines:
            m_bandEUTRA = re.match(re_bandEUTRA, line)
            m_ca_BandwidthClassUL_EUTRA = re.match(re_ca_BandwidthClassUL_EUTRA, line)
            m_ca_BandwidthClassDL_EUTRA = re.match(re_ca_BandwidthClassDL_EUTRA, line)
            m_bandNR = re.match(re_bandNR, line)
            m_ca_BandwidthClassUL_NR = re.match(re_ca_BandwidthClassUL_NR, line)
            m_ca_BandwidthClassDL_NR = re.match(re_ca_BandwidthClassDL_NR, line)
            if 'BandCombination' == line.strip():
                mrdc_str = mrdc_str + ':'
            if m_bandNR:
                mrdc_str = mrdc_str + ';N' + m_bandNR.group(1)
            if m_ca_BandwidthClassUL_NR:
                mrdc_str = mrdc_str + '-UL' + m_ca_BandwidthClassUL_NR.group(1)
            if m_ca_BandwidthClassDL_NR:
                mrdc_str = mrdc_str + '-DL' + m_ca_BandwidthClassDL_NR.group(1)
            if m_bandEUTRA:
                mrdc_str = mrdc_str + ';B' + m_bandEUTRA.group(1)
            if m_ca_BandwidthClassUL_EUTRA:
                mrdc_str = mrdc_str + '-UL' + m_ca_BandwidthClassUL_EUTRA.group(1)
            if m_ca_BandwidthClassDL_EUTRA:
                mrdc_str = mrdc_str + '-DL' + m_ca_BandwidthClassDL_EUTRA.group(1)
                
        #print('MRDC str', mrdc_str)
        if len(mrdc_str) > 1:
            mrdc_array = mrdc_str[1:].split(':')
            mrdc_array = [item[1:] for item in mrdc_array] # or item.replace(';','',1)
        return mrdc_array

    # all information
    def output_ue_information(self, ota_file):
        lte_band = []
        lte_ca = []
        nr_band = []
        nr_ca = []
        mrdc = []
        
        extract_multiline = ExtractMultiline()
        lines = extract_multiline.get_filecontent_lines(ota_file)

        bandlist = []
        bandlist_v9e0 = []
        ca_array = []
        ca_extend_array = []
        ca_set_array = []
        
        # LTE Band list
        multilines_array = extract_multiline.get_multilines('UE-EUTRA-Capability', 'supportedBandListEUTRA:', lines)
        if len(multilines_array) >= 1:
            bandlist = self.supported_band_list_eutra(multilines_array[0])
        
        # LTE Band list extend(v9e0)
        multilines_array = extract_multiline.get_multilines('UE-EUTRA-Capability', 'supportedBandListEUTRA-v9e0:', lines)
        if len(multilines_array) >= 1:
            bandlist_v9e0 = self.supported_band_list_eutra_v9e0(multilines_array[0])
        
        # LTE CA band combination
        multilines_array = extract_multiline.get_multilines('UE-EUTRA-Capability', 'supportedBandCombination-r10:', lines)
        if len(multilines_array) >= 1:
            ca_array = self.supported_band_combination_r10(multilines_array[0])

        # LTE CA band extend
        multilines_array = extract_multiline.get_multilines('UE-EUTRA-Capability', 'supportedBandCombination-v1090:', lines)
        if len(multilines_array) >= 1:
            ca_extend_array = self.supported_band_combination_v1090(multilines_array[0])
        
        # LTE CA set
        multilines_array = extract_multiline.get_multilines('UE-EUTRA-Capability', 'supportedBandCombinationExt-r10:', lines)
        if len(multilines_array) >= 1:
            ca_set_array = self.supported_band_combination_ext_r10(multilines_array[0])
        #print('bandlist: ', bandlist)
        #print('bandlist_v9e0: ', bandlist_v9e0)
        #print('ca_array: ', ca_array)
        #print('ca_extend_array: ', ca_extend_array)
        #print('ca_set_array: ', ca_set_array)

        # LTE Band and CA
        for index in range(0, len(bandlist)):
            if bandlist[index] != '64':
                lte_band.append(bandlist[index])
            else:
                lte_band.append(bandlist_v9e0[index])
        
        for index in range(0, len(ca_array)):
            ca = ca_array[index]
            if len(ca_extend_array) >= 1:
                for band_extend in ca_extend_array[index].split(';')[1:]:
                    if band_extend != '':
                        ca = ca.replace('B64', 'B'+band_extend, 1)
            lte_ca.append(ca + '; BW comb set: ' + ca_set_array[index])
        print('LTE Band: ', lte_band)
        print('LTE CA: ', lte_ca)
        #for item in lte_ca:
        #    print(item)
        
        # NR Band list
        multilines_array = extract_multiline.get_multilines('UE-NR-Capability', 'supportedBandListNR:', lines)
        if len(multilines_array) >= 1:
            nr_band = self.supported_band_list_nr(multilines_array[0])
        print('NR Band:', nr_band)

        # NR CA band combination
        multilines_array = extract_multiline.get_multilines('UE-NR-Capability', 'supportedBandCombinationList:', lines)
        if len(multilines_array) >= 1:
            nr_ca = self.supported_band_combination_list_nr(multilines_array[0])
        print('NR CA:', nr_ca)

        # MRDC
        multilines_array = extract_multiline.get_multilines('UE-MRDC-Capability', 'supportedBandCombinationList:', lines)
        if len(multilines_array) >= 1:
            mrdc = self.supported_band_combination_list_mrdc(multilines_array[0])
        print('MRDC:', mrdc)
        
        return [lte_band, lte_ca, nr_band, nr_ca, mrdc]

if __name__ == '__main__':
    ue_capability_information = UeCapabilityInformation()
    #[lte_band, lte_ca, nr_band, nr_ca, mrdc] = ue_capability_information.output_ue_information(r'nr-ueCapabilityInformation.txt')
    [lte_band, lte_ca, nr_band, nr_ca, mrdc] = ue_capability_information.output_ue_information(r'lte-ueCapabilityInformation.txt')

3. 测试数据

测试数据EN-DC ueCapabilityInformation:

38 03 08 13 ad d9 a0 4b 00 10 40 c1 c9 99 36 7d 2a 75 02 e5 ff f9 1f f9 7f fe 47 fe 5f ff 91 ff 97 ff e4 7f e5 ff f9 1f f9 7f fe 47 fe 5f ff 91 ff 97 ff e4 7f e5 ff f9 1f f9 7f fe 47 fe 5f ff 91 ff 97 ff e4 7f ff f3 ff af a2 08 00 8c 87 0c a7 4a 93 bb f1 59 c0 80 00 00 7d bf f0 00 00 00 78 d4 00 c0 0a 00 40 00 34 05 af aa dc bf ff 1a 06 38 00 20 01 80 00 08 20 61 00 02 08 18 80 00 80 06 30 00 20 81 a6 00 08 00 6c 80 02 00 1b 60 00 80 02 f8 40 03 94 00 10 00 e7 00 04 00 3a 00 01 00 1c 00 00 40 47 08 00 e3 80 02 02 00 40 1b 2f ff c8 ff cb ff f2 3f f2 ff fc 8f fc bf ff 23 ff 2f ff c8 ff cb ff f2 3f f2 ff fc 8f fc bf ff 23 ff 2f ff c8 ff cb ff f2 3f f2 ff fc 8f fc bf ff 23 ff 2f ff c8 ff cb ff f2 3f ff fe c0 00 19 8d 00 08 bc 5d 98 a2 27 38 10 70 0c f6 91 84 92 5f ff ff fe ef 73 5e 08 04 cc 11 99 41 24 30 00 80 05 09 08 25 cf 01 80 00 08 06 01 c1 b0 9c 4d 78 08 00 00 08 51 90 00 00 00 cd 07 ff 20 00 70 c1 96 03 80 00 10 08 03 00 e0 d8 4e 26 d8 05 83 15 e1 a0 3f a0 47 4e 7a ef ff ff af 01 40 78 2e 02 03 c1 27 be 7f ff ff 80 07 03 1b ef 80 01 40 dc 04 07 e3 80 f5 17 c0 0f f8 bc 21 d8 be 08 21 fd 50 08 83 d9 51 d2 20 62 4f ac 41 e4 20 f0 81 42 5b e7 e4 ff e3 f8 00 3f f8 fe 00 00 d8 05 00 07 42 a2 f8 05 ff 17 84 3b 17 c1 04 3f aa 01 10 7b 2a 3a 44 0c 49 f5 88 3c 84 1e 10 28 4b 7c fc 9f f8 7e 00 07 fe 1f 80 00 1b 00 a0 00 e8 54 5f 01 3f e2 f0 87 62 f8 20 87 f5 40 22 0f 65 47 48 81 89 3e b1 07 90 83 c2 05 09 6f 9f 93 f8 0e 00 00 fe 03 80 00 03 60 14 00 1d 0a 8b e0 37 fc 5e 10 ec 5f 04 10 fe a8 04 41 ec a8 e9 10 31 27 d6 20 f2 10 78 40 a1 2d f3 f2 7f f1 fc 00 1f fc 7f 00 00 6c 02 80 03 a1 51 7c 07 ff 8b c2 1d 8b e0 82 1f d5 00 88 3d 95 1d 22 06 24 fa c4 1e 42 0f 08 14 25 be 7e 42 00 08 00 0d 80 50 00 74 2a 2f 83 7f f1 78 43 b1 7c 10 43 fa a0 11 07 b2 a3 a4 40 c4 9f 58 83 c8 41 e1 02 84 b7 cf c9 fd 07 40 00 7f 41 d0 00 01 b0 0a 00 0e 85 45 f0 9f fe 2f 08 76 2f 82 08 7f 54 02 20 f6 54 74 88 18 93 eb 10 79 08 3c 20 50 96 f9 f9 08 00 20 00 36 01 40 01 d0 a8 be 26 ff c5 e1 0e c5 f0 41 0f ea 80 44 1e ca 8e 91 03 12 7d 62 0f 21 07 84 0a 12 df 3f 27 7f 1f f0 01 df c7 fc 00 06 e0 28 00 3a 00 d9 40 00 14 00 00 00 4a 0f 00 00 03 09 a0 00 03 d0 2a 0e 00 00 e2 68 00 00 13 d0 20 0e 00 04 04 d0 0e 00 01 50 d8 0a 14 e9 db 24 f8 10 a7 4e d9 27 c0 00 38 10 c6 0f ff f8 00 02 e0 3e 00 28 00 30 1c 04 07 03 10 5c 07 00 07 00 06 03 e0 40 82 00 00 00 41 00 00 02 20 80 00 02 10 40 00 01 88 20 00 01 04 10 00 00 a2 08 00 00 61 04 00 00 38 82 00 00 20 08 60 6d 60 ed 64 ed 60 cd 64 cd 64 6d 65 0d 65 2d e5 4d 02 01 00 00 09 65 94 04 00 00 65 96 50 10 00 02 96 59 40 40 00 0e 59 65 01 00 00 49 65 94 04 00 01 65 96 50 10 00 06 96 59 40 40 00 1e 59 65 01 00 00 89 65 94 02 14 0e 2a 83 c5 52 78 aa 0d 15 49 a2 a9 1c 55 28 8a a5 31 74 aa 28 18 d2 01 1e 6f c0 70 1c 01 e6 fc 07 01 c0 1e 6f c0 70 1c 01 e6 fc 07 01 c0 1e 6f c0 70 1c 01 e6 fc 07 01 c0 1e 6f c0 70 1c 01 e6 fc 07 01 c0 1e 6f c0 70 1c 00 00 01 08 98 01 00 30 04 00 a0 0c 01 c0 18 03 80 40 09 00 a0 16 01 40 2c 00 80 18 06 00 d0 0c 01 84 c0 10 00 80 70 01 00 40 02 01 c0 04 04 00 08 02 00 10 10 00 20 24 00 40 10 00 80 90 00 11 30 02 00 20 08 00 40 18 00 80 30 01 00 80 02 01 40 04 02 80 08 01 00 10 0c 00 20 18 00 09 80 20 05 00 e0 1e 00 80 14 03 80 78 08 01 10 04 00 a0 20 04 40 48 09 80 20 05 01 20 24 6a c2 c0 00 81 01 81 c4 c6 46 c7 c9 49 ca 1d c0 00 00 00 d0 4a 65 3a 18 ff 02 f0 58 38 07 00 00 00 00 10 3d 19 03 e0 b0 00 0e 26 80 00 01 20 7a 32 04 01 c0 00 80 9a 01 c0 00 2a 1a 81 42 9d 3b 64 9f 02 14 e9 db 24 f8 00 07 01 0c 60 e0 04 20 40 10 08 02 01 03 00 40 0a 00 c0 18 40 80 40 10 08 02 06 00 80 14 04 80 9c 00 00

无痕1024
1 声望0 粉丝