mobile: almost finishing 5G NAS
This commit is contained in:
parent
f388afebe8
commit
53b08239fd
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
#/**
|
||||
# * Software Name : pycrate
|
||||
# * Version : 0.4
|
||||
# *
|
||||
# * Copyright 2019. Benoit Michau. P1Sec.
|
||||
# *
|
||||
# * This library is free software; you can redistribute it and/or
|
||||
# * modify it under the terms of the GNU Lesser General Public
|
||||
# * License as published by the Free Software Foundation; either
|
||||
# * version 2.1 of the License, or (at your option) any later version.
|
||||
# *
|
||||
# * This library 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
|
||||
# * Lesser General Public License for more details.
|
||||
# *
|
||||
# * You should have received a copy of the GNU Lesser General Public
|
||||
# * License along with this library; if not, write to the Free Software
|
||||
# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# * MA 02110-1301 USA
|
||||
# *
|
||||
# *--------------------------------------------------------
|
||||
# * File Name : pycrate_mobile/NAS5G.py
|
||||
# * Created : 2019-12-02
|
||||
# * Authors : Benoit Michau
|
||||
# *--------------------------------------------------------
|
||||
#*/
|
||||
|
||||
from pycrate_core.utils import *
|
||||
|
||||
from .TS24501_FGMM import FGMMTypeClasses, FGMMSecProtNASMessage
|
||||
from .TS24501_FGSM import FGSMTypeClasses
|
||||
from .TS24011_PPSMS import PPSMSCPTypeClasses
|
||||
|
||||
|
||||
def parse_NAS5G(buf, inner=True, sec_hdr=True):
|
||||
"""Parses a 5G NAS message bytes' buffer
|
||||
|
||||
Args:
|
||||
buf: 5G NAS message bytes' buffer
|
||||
inner: if True, decode NASMessage within security header if possible
|
||||
decode ?
|
||||
|
||||
sec_hdr: if True, handle the 5GMM security header
|
||||
otherwise, just consider the NAS message is in plain text
|
||||
|
||||
Returns:
|
||||
element, err: 2-tuple
|
||||
element: Element instance, if err is null (no error)
|
||||
element: None, if err is not null (standard 5G NAS error code)
|
||||
"""
|
||||
try:
|
||||
# this corresponds actually only to the layout of the 5GMM header
|
||||
pd, shr, typ = unpack('>BBB', buf)
|
||||
except Exception:
|
||||
# error 111, unspecified protocol error
|
||||
return None, 111
|
||||
#
|
||||
if pd == 146:
|
||||
# 5GMM
|
||||
if sec_hdr and shdr in (1, 2, 3, 4):
|
||||
# 5GMM security protected NAS message
|
||||
Msg = FGMMSecProtNASMessage()
|
||||
try:
|
||||
Msg.from_bytes(buf)
|
||||
except Exception:
|
||||
# error 96, invalid mandatory info
|
||||
return None, 96
|
||||
if inner and shdr in (1, 3):
|
||||
# parse clear-text NAS message container
|
||||
cont, err = parse_NAS5G(Msg[3].get_val(), inner=inner)
|
||||
if cont is not None:
|
||||
Msg.replace(Msg[3], cont)
|
||||
return Msg, err
|
||||
else:
|
||||
return Msg, 0
|
||||
else:
|
||||
# sec hdr == 0 or undefined
|
||||
# no security, straight 5GMM message
|
||||
try:
|
||||
Msg = FGMMTypeClasses[typ]()
|
||||
except KeyError:
|
||||
# error 97, message type non-existent or not implemented
|
||||
return None, 97
|
||||
#
|
||||
elif pd == 46:
|
||||
# 5GSM
|
||||
try:
|
||||
if python_version < 3:
|
||||
typ = ord(buf[3:4])
|
||||
else:
|
||||
typ = buf[3]
|
||||
except:
|
||||
# error 111, unspecified protocol error
|
||||
return None, 111
|
||||
try:
|
||||
Msg = FGSMTypeClasses[typ]()
|
||||
except KeyError:
|
||||
# error 97, message type non-existent or not implemented
|
||||
return None, 97
|
||||
#
|
||||
else:
|
||||
# error 97: message type non-existent or not implemented
|
||||
return None, 97
|
||||
#
|
||||
if inner and pd == 146:
|
||||
if typ in (65, 76, 79, 94):
|
||||
nasc = Msg['NASContainer']
|
||||
if not nasc.get_trans():
|
||||
# NAS Container present in Msg
|
||||
cont, err = parse_NAS5G(nasc[-1].get_val(), inner=inner)
|
||||
if err:
|
||||
return Msg, err
|
||||
else:
|
||||
nasc.replace(nasc[-1], cont)
|
||||
#
|
||||
if typ in (65, 79, 103, 104):
|
||||
payc = Msg['PayloadContainer']
|
||||
if not payc.get_trans():
|
||||
# Payload container present in Msg
|
||||
# TODO: check if IE decoded properly, then decode each entry into a proper msg
|
||||
# 5GSM and SMS at 1st
|
||||
pass
|
||||
#
|
||||
return Msg, 0
|
||||
|
||||
'''payload container entries:
|
||||
1 : 'N1 SM information',
|
||||
2 : 'SMS',
|
||||
3 : 'LTE Positioning Protocol message container',
|
||||
4 : 'SOR transparent container',
|
||||
5 : 'UE policy container',
|
||||
6 : 'UE parameters update transparent container',
|
||||
7 : 'Location services message container',
|
||||
8 : 'CIoT user data container',
|
||||
'''
|
||||
|
||||
|
|
@ -148,7 +148,6 @@ def parse_NASLTE_MO(buf, inner=True, sec_hdr=True):
|
|||
return Msg, err
|
||||
else:
|
||||
esmc.replace(esmc[-1], cont)
|
||||
#esmc[-2].set_valauto(cont.get_len)
|
||||
elif typ in (98, 99):
|
||||
# PP-SMS
|
||||
nasc = Msg['NASContainer']
|
||||
|
|
|
@ -36,8 +36,10 @@ from binascii import unhexlify
|
|||
from time import struct_time
|
||||
|
||||
from pycrate_core.utils import *
|
||||
from pycrate_core.elt import Envelope, Array, Sequence, REPR_RAW, REPR_HEX, \
|
||||
REPR_BIN, REPR_HD, REPR_HUM
|
||||
from pycrate_core.elt import (
|
||||
Envelope, Array, Sequence, Alt,
|
||||
REPR_RAW, REPR_HEX, REPR_BIN, REPR_HD, REPR_HUM
|
||||
)
|
||||
from pycrate_core.base import *
|
||||
from pycrate_core.repr import *
|
||||
from pycrate_core.charpy import Charpy
|
||||
|
@ -3287,36 +3289,42 @@ class TFTPktFilterId(Envelope):
|
|||
Uint('Id', bl=4)
|
||||
)
|
||||
|
||||
|
||||
class _CompIPv4(Envelope):
|
||||
_GEN = (
|
||||
Buf('Address', bl=32, rep=REPR_HEX),
|
||||
Buf('Netmask', bl=32, rep=REPR_HEX)
|
||||
)
|
||||
|
||||
|
||||
class _CompIPv6(Envelope):
|
||||
_GEN = (
|
||||
Buf('Address', bl=128, rep=REPR_HEX),
|
||||
Buf('Netmask', bl=128, rep=REPR_HEX)
|
||||
)
|
||||
|
||||
|
||||
class _CompIPv6Pref(Envelope):
|
||||
_GEN = (
|
||||
Buf('Address', bl=128, rep=REPR_HEX),
|
||||
Uint8('PrefixLen')
|
||||
)
|
||||
|
||||
|
||||
class _CompPortRange(Envelope):
|
||||
_GEN = (
|
||||
Uint16('PortLo'),
|
||||
Uint16('PortHi')
|
||||
)
|
||||
|
||||
|
||||
class _CompTrafficClass(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Class'),
|
||||
Uint8('Mask')
|
||||
)
|
||||
|
||||
'''
|
||||
class TFTPktFilterComp(Envelope):
|
||||
_ValueLUT = {
|
||||
16 : _CompIPv4('IPv4'),
|
||||
|
@ -3356,6 +3364,7 @@ class TFTPktFilterComp(Envelope):
|
|||
self.replace(self[1], self._ValueLUT[t].clone())
|
||||
self[1]._from_char(char)
|
||||
|
||||
|
||||
class TFTPktFilter(Envelope):
|
||||
_Cont = Sequence('Cont', GEN=TFTPktFilterComp())
|
||||
_GEN = (
|
||||
|
@ -3401,18 +3410,72 @@ class TFTPktFilter(Envelope):
|
|||
else:
|
||||
char._cur = ccur
|
||||
char._len_bit = clen
|
||||
'''
|
||||
|
||||
class TFTPktFilterComp(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Type', dic=_PktFilterCompType_dict),
|
||||
Alt('Value', GEN={
|
||||
16 : _CompIPv4('IPv4'),
|
||||
17 : _CompIPv4('IPv4'),
|
||||
32 : _CompIPv6('IPv6'),
|
||||
33 : _CompIPv6Pref('IPv6Pref'),
|
||||
35 : _CompIPv6Pref('IPv6Pref'),
|
||||
48 : Uint8('ProtId'),
|
||||
64 : Uint16('Port'),
|
||||
65 : _CompPortRange('PortRange'),
|
||||
80 : Uint16('Port'),
|
||||
81 : _CompPortRange('PortRange'),
|
||||
96 : Uint32('SPI'),
|
||||
112 : _CompTrafficClass('TrafficClass'),
|
||||
128 : Uint24('FlowLabel')
|
||||
},
|
||||
DEFAULT=Buf('unk', val=b'', rep=REPR_HEX),
|
||||
sel=lambda self: self.get_env()['Type'].get_val())
|
||||
)
|
||||
|
||||
|
||||
class TFTPktFilter(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=2),
|
||||
Uint('Dir', bl=2, dic=_PktFilterDir_dict),
|
||||
Uint('Id', bl=4),
|
||||
Uint8('Precedence'),
|
||||
Uint8('Len'),
|
||||
Sequence('Cont', GEN=TFTPktFilterComp())
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self['Len'].set_valauto(lambda: self['Cont'].get_len())
|
||||
|
||||
def _from_char(self, char):
|
||||
if self.get_trans():
|
||||
return
|
||||
self[0]._from_char(char)
|
||||
self[1]._from_char(char)
|
||||
self[2]._from_char(char)
|
||||
self[3]._from_char(char)
|
||||
self[4]._from_char(char)
|
||||
char_lb = char._len_bit
|
||||
char._len_bit = char._cur + (self[4].get_val()<<3)
|
||||
self[5]._from_char(char)
|
||||
char._len_bit = char_lb
|
||||
|
||||
|
||||
class TFTParameter(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Id'),
|
||||
Uint8('Len'),
|
||||
Buf('Cont', val=b'')
|
||||
Buf('Cont', val=b'', rep=REPR_HEX)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self[1].set_valauto(self[2].get_len)
|
||||
self[2].set_blauto(lambda: 8*self[1]())
|
||||
|
||||
|
||||
class TFT(Envelope):
|
||||
ENV_SEL_TRANS = False
|
||||
_GEN = (
|
||||
|
@ -3423,6 +3486,7 @@ class TFT(Envelope):
|
|||
Sequence('PktFilters', GEN=TFTPktFilter()),
|
||||
Sequence('Parameters', GEN=TFTParameter())
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self[2].set_valauto(lambda: self[3].get_num() if \
|
||||
|
|
|
@ -158,7 +158,7 @@ class FGMMAuthenticationRequest(Layer3):
|
|||
Type4LV('ABBA', val={'V':b'\0\0'}),
|
||||
Type3TV('RAND', val={'T':0x21, 'V':16*b'\0'}, bl={'V':128}),
|
||||
Type4LV('AUTN', val={'V':16*b'\0'}, IE=AUTN()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'})
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'})
|
||||
)
|
||||
|
||||
|
||||
|
@ -172,7 +172,7 @@ class FGMMAuthenticationResponse(Layer3):
|
|||
_GEN = (
|
||||
FGMMHeader(val={'Type':87}),
|
||||
Type4TLV('RES', val={'T':0x2D, 'V':16*b'\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'})
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'})
|
||||
)
|
||||
|
||||
|
||||
|
@ -187,7 +187,7 @@ class FGMMAuthenticationResult(Layer3):
|
|||
FGMMHeader(val={'Type':90}),
|
||||
Uint('spare', bl=4, rep=REPR_HEX),
|
||||
Type1V('NAS_KSI', val={'V':7}, IE=NAS_KSI()),
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0'}),
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('ABBA', val={'T':0x38, 'V':b'\0\0'})
|
||||
)
|
||||
|
||||
|
@ -215,7 +215,7 @@ class FGMMAuthenticationReject(Layer3):
|
|||
_name = '5GMMAuthenticationReject'
|
||||
_GEN = (
|
||||
FGMMHeader(val={'Type':88}),
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0'})
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0\0'})
|
||||
)
|
||||
|
||||
|
||||
|
@ -235,7 +235,7 @@ class FGMMRegistrationRequest(Layer3):
|
|||
Type4TLV('5GMMCap', val={'T':0x10, 'V':b'\0'}, IE=FGMMCap()),
|
||||
Type4TLV('UESecCap', val={'T':0x2E, 'V':b'\0\0'}, IE=UESecCap()),
|
||||
Type4TLV('NSSAI', val={'T':0x2F, 'V':b'\0\0'}, IE=NSSAI()),
|
||||
Type3TV('TAI', val={'T':0x52, 'V':6*b'\0'}, IE=FGSTAI()),
|
||||
Type3TV('TAI', val={'T':0x52, 'V':6*b'\0'}, bl={'V':48}, IE=FGSTAI()),
|
||||
Type4TLV('EPSUENetCap', val={'T':0x17, 'V':b'\0\0'}, IE=EPSUENetCap()),
|
||||
Type4TLV('ULDataStat', val={'T':0x40, 'V':b'\0\0'}, IE=ULDataStat()),
|
||||
Type1TV('MICOInd', val={'T':0xB, 'V':0}, IE=MICOInd()),
|
||||
|
@ -290,7 +290,7 @@ class FGMMRegistrationAccept(Layer3):
|
|||
Type4TLV('EmergNumList', val={'T':0x34, 'V':b'\x02\x01\0'}, IE=EmergNumList()),
|
||||
Type6TLVE('ExtEmergNumList', val={'T':0x7A, 'V':b'\0\0\0\0'}, IE=ExtEmergNumList()),
|
||||
Type6TLVE('SORTransparentContainer', val={'T':0x73, 'V':17*b'\0'}, IE=SORTransparentContainer()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type1TV('NSSAIInclMode', val={'T':0xA, 'V':0}, IE=NSSAIInclMode()),
|
||||
Type6TLVE('OperatorAccessCatDefs', val={'T':0x76, 'V':b''}, IE=OperatorAccessCatDefs()),
|
||||
Type4TLV('5GSDRXParam', val={'T':0x51, 'V':b'\0'}, IE=FGSDRXParam()),
|
||||
|
@ -330,7 +330,7 @@ class FGMMRegistrationReject(Layer3):
|
|||
Type3V('5GMMCause', val={'V':b'\x16'}, bl={'V':8}, IE=FGMMCause()),
|
||||
Type4TLV('T3346', val={'T':0x5F, 'V':b'\0'}, IE=GPRSTimer()),
|
||||
Type4TLV('T3502', val={'T':0x16, 'V':b'\0'}, IE=GPRSTimer()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('RejectedNSSAI', val={'T':0x69, 'V':b'\0\0'}, IE=RejectedNSSAI())
|
||||
)
|
||||
|
||||
|
@ -462,7 +462,7 @@ class FGMMServiceAccept(Layer3):
|
|||
Type4TLV('PDUSessStat', val={'T':0x50, 'V':b'\0\0'}, IE=PDUSessStat()),
|
||||
Type4TLV('PDUSessStatReactResult', val={'T':0x26, 'V':b'\0\0'}, IE=PDUSessStat()),
|
||||
Type6TLVE('PDUSessReactResultErr', val={'T':0x72, 'V':b'\0\0'}, IE=PDUSessReactResultErr()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('T3448', val={'T':0x6B, 'V':b'\0'}, IE=GPRSTimer())
|
||||
)
|
||||
|
||||
|
@ -479,7 +479,7 @@ class FGMMServiceReject(Layer3):
|
|||
Type3V('5GMMCause', val={'V':b'\x16'}, bl={'V':8}, IE=FGMMCause()),
|
||||
Type4TLV('PDUSessStat', val={'T':0x50, 'V':b'\0\0'}, IE=PDUSessStat()),
|
||||
Type4TLV('T3346', val={'T':0x5F, 'V':b'\0'}, IE=GPRSTimer()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('T3448', val={'T':0x6B, 'V':b'\0'}, IE=GPRSTimer())
|
||||
)
|
||||
|
||||
|
@ -599,7 +599,7 @@ class FGMMSecurityModeCommand(Layer3):
|
|||
Type1TV('IMEISVReq', val={'T':0xC, 'V':0}, IE=IMEISVReq()),
|
||||
Type3TV('EPSNASSecAlgo', val={'T':0x57, 'V':b'\x11'}, bl={'V':8}, IE=EPSNASSecAlgo()),
|
||||
Type4TLV('Add5GSecInfo', val={'T':0x36, 'V':b'\0'}, IE=Add5GSecInfo()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0'}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('ABBA', val={'T':0x38, 'V':b'\0\0'}),
|
||||
Type4TLV('EPSUESecCap', val={'T':0x19, 'V':b'\0\0'}, IE=EPSUESecCap())
|
||||
)
|
||||
|
|
|
@ -44,7 +44,7 @@ from .TS24008_IE import (
|
|||
ProtConfig, GPRSTimer,
|
||||
)
|
||||
from .TS24301_IE import (
|
||||
HdrCompConfig,
|
||||
HdrCompConfig, ServingPLMNRateCtrl,
|
||||
)
|
||||
from .TS24501_IE import *
|
||||
|
||||
|
@ -96,8 +96,8 @@ class FGSMHeader(Envelope):
|
|||
class FGSMPDUSessionEstabRequest(Layer3):
|
||||
_name = '5GSMPDUSessionEstabRequest'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':193})
|
||||
Type3V('IntegrityProtMaxDataRate', val={'V':b'\0\0'}, IE=IntegrityProtMaxDataRate()),
|
||||
FGSMHeader(val={'Type':193}),
|
||||
Type3V('IntegrityProtMaxDataRate', val={'V':b'\0\0'}, bl={'V':16}, IE=IntegrityProtMaxDataRate()),
|
||||
Type1TV('PDUSessType', val={'T':0x9, 'V':1}, IE=PDUSessType()),
|
||||
Type1TV('SSCMode', val={'T':0xA, 'V':1}, IE=SSCMode()),
|
||||
Type4TLV('5GSMCap', val={'T':0x28, 'V':b'\0'}, IE=FGSMCap()),
|
||||
|
@ -119,18 +119,27 @@ class FGSMPDUSessionEstabRequest(Layer3):
|
|||
class FGSMPDUSessionEstabAccept(Layer3):
|
||||
_name = '5GSMPDUSessionEstabAccept'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':194})
|
||||
FGSMHeader(val={'Type':194}),
|
||||
Type1V('SSCMode', val={'V':1}, IE=SSCMode()),
|
||||
Type1V('PDUSessType', val={'V':1}, IE=PDUSessType()),
|
||||
Type6LVE('QoSRules', val={'V':b'\0\0\0\0'}, IE=QoSRules()),
|
||||
Type4LV('SessAMBR', val={'V':b'\x06\0\x01\x06\0\x01'}, IE=SessAMBR()),
|
||||
Type3TV('FGSMCause', val={'T':0x59, 'V':b'\x1a'}, IE=FGSMCause()),
|
||||
Type3TV('5GSMCause', val={'T':0x59, 'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type4TLV('PDUAddress', val={'T':0x29, 'V':b'\x01\x7f\0\0\x01'}, IE=PDUAddress()),
|
||||
Type3TV('RQTimer', val={'T':0x56, 'V':b'\0'}, IE=GPRSTimer()),
|
||||
Type3TV('RQTimer', val={'T':0x56, 'V':b'\0'}, bl={'V':8}, IE=GPRSTimer()),
|
||||
Type4TLV('SNSSAI', val={'T':0x22, 'V':b'\0'}, IE=SNSSAI()),
|
||||
Type1TV('AlwaysOnPDUSessInd', val={'T':0x8, 'V':0}, IE=AlwaysOnPDUSessInd()),
|
||||
# TODO
|
||||
|
||||
Type6TLVE('MappedEPSBearerCtxt', val={'T':0x75, 'V':b'\0\0\0\0'}, IE=MappedEPSBearerCtxt()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type6TLVE('QoSFlowDesc', val={'T':0x79, 'V':b'\0\0\0'}, IE=QoSFlowDesc()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
Type4TLV('DNN', val={'T':0x25, 'V':b'\0'}, IE=APN('DNN')),
|
||||
#Type4TLV('5GSMNetFeat', val={'T':0x00, 'V':b'\0'}, IE=FGSMNetFeat()), # WNG: tag is undefined in current TS
|
||||
#Type4TLV('SessTMBR', val={'T':0x00, 'V':6*b'\0'}, IE=SessTMBR()), # WNG: tag is undefined in current TS
|
||||
#Type4TLV('ServingPLMNRateCtrl', val={'T':0x00, 'V':b'\0\0'}, IE=ServingPLMNRateCtrl()), # WNG: tag is undefined in current TS
|
||||
#Type6TLVE('ATSSSContainer', val={'T':0x00, 'B':b''}), # WNG: tag is undefined in current TS
|
||||
#Type1TV('CtrlPlaneOnlyInd', val={'T':0x0, 'V':1}, IE=CtrlPlaneOnlyInd()), # WNG: tag is undefined in current TS
|
||||
Type4TLV('HdrCompConfig', val={'T':0x66, 'V':b'\0\0\0'}, IE=HdrCompConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -142,8 +151,14 @@ class FGSMPDUSessionEstabAccept(Layer3):
|
|||
class FGSMPDUSessionEstabReject(Layer3):
|
||||
_name = '5GSMPDUSessionEstabReject'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':195})
|
||||
|
||||
FGSMHeader(val={'Type':195}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type4TLV('BackOffTimer', val={'T':0x37, 'V':b'\0'}, IE=GRPSTimer3()),
|
||||
Type1TV('AllowedSSCMode', val={'T':0xF, 'V':0}, IE=AllowedSSCMode()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
#Type4TLV('ReattemptInd', val={'V':0x00, 'V':b'\0'}, IE=ReattemptInd()), # WNG: tag is undefined in current TS
|
||||
Type4TLV('CongestReattemptInd', val={'T':0x61, 'V':b'\0'}, IE=CongestReattemptInd())
|
||||
)
|
||||
|
||||
|
||||
|
@ -155,8 +170,9 @@ class FGSMPDUSessionEstabReject(Layer3):
|
|||
class FGSMPDUSessionAuthentCommand(Layer3):
|
||||
_name = '5GSMPDUSessionAuthentCommand'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':197})
|
||||
|
||||
FGSMHeader(val={'Type':197}),
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0\0'}),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -168,8 +184,9 @@ class FGSMPDUSessionAuthentCommand(Layer3):
|
|||
class FGSMPDUSessionAuthentComplete(Layer3):
|
||||
_name = '5GSMPDUSessionAuthentComplete'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':198})
|
||||
|
||||
FGSMHeader(val={'Type':198}),
|
||||
Type6LVE('EAPMsg', val={'V':b'\0\0\0\0\0'}),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -181,8 +198,9 @@ class FGSMPDUSessionAuthentComplete(Layer3):
|
|||
class FGSMPDUSessionAuthentResult(Layer3):
|
||||
_name = '5GSMPDUSessionAuthentResult'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':199})
|
||||
|
||||
FGSMHeader(val={'Type':199}),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
)
|
||||
|
||||
|
||||
|
@ -194,8 +212,17 @@ class FGSMPDUSessionAuthentResult(Layer3):
|
|||
class FGSMPDUSessionModifRequest(Layer3):
|
||||
_name = '5GSMPDUSessionModifRequest'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':201})
|
||||
|
||||
FGSMHeader(val={'Type':201}),
|
||||
Type4TLV('5GSMCap', val={'T':0x28, 'V':b'\0'}, IE=FGSMCap()),
|
||||
Type3TV('5GSMCause', val={'T':0x59, 'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type3TV('MaxPktFilters', val={'T':0x55, 'V':b'\x02\x20'}, bl={'V':16}, IE=MaxPktFilters()),
|
||||
Type1TV('AlwaysOnPDUSessReq', val={'T':0xB, 'V':0}, IE=AlwaysOnPDUSessReq()),
|
||||
Type3TV('IntegrityProtMaxDataRate', val={'V':b'\0\0'}, bl={'V':16}, IE=IntegrityProtMaxDataRate()),
|
||||
Type6TLVE('QoSRules', val={'T':0x7A, 'V':b'\0\0\0\0'}, IE=QoSRules()),
|
||||
Type6TLVE('QoSFlowDesc', val={'T':0x79, 'V':b'\0\0\0'}, IE=QoSFlowDesc()),
|
||||
Type6TLVE('MappedEPSBearerCtxt', val={'T':0x75, 'V':b'\0\0\0\0'}, IE=MappedEPSBearerCtxt()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
#Type6TLVE('PortMgmtInfoContainer', val={'T':0x00, 'V':b'\0'}), # WNG: tag is undefined in current TS
|
||||
)
|
||||
|
||||
|
||||
|
@ -207,8 +234,12 @@ class FGSMPDUSessionModifRequest(Layer3):
|
|||
class FGSMPDUSessionModifReject(Layer3):
|
||||
_name = '5GSMPDUSessionModifReject'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':202})
|
||||
|
||||
FGSMHeader(val={'Type':202}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type4TLV('BackOffTimer', val={'T':0x37, 'V':b'\0'}, IE=GRPSTimer3()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
#Type4TLV('ReattemptInd', val={'V':0x00, 'V':b'\0'}, IE=ReattemptInd()), # WNG: tag is undefined in current TS
|
||||
Type4TLV('CongestReattemptInd', val={'T':0x61, 'V':b'\0'}, IE=CongestReattemptInd())
|
||||
)
|
||||
|
||||
|
||||
|
@ -220,8 +251,19 @@ class FGSMPDUSessionModifReject(Layer3):
|
|||
class FGSMPDUSessionModifCommand(Layer3):
|
||||
_name = '5GSMPDUSessionModifCommand'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':203})
|
||||
|
||||
FGSMHeader(val={'Type':203}),
|
||||
Type3TV('5GSMCause', val={'T':0x59, 'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type4TLV('SessAMBR', val={'T':0x2A, 'V':b'\x06\0\x01\x06\0\x01'}, IE=SessAMBR()),
|
||||
Type3TV('RQTimer', val={'T':0x56, 'V':b'\0'}, bl={'V':8}, IE=GPRSTimer()),
|
||||
Type1TV('AlwaysOnPDUSessInd', val={'T':0x8, 'V':0}, IE=AlwaysOnPDUSessInd()),
|
||||
Type6TLVE('QoSRules', val={'T':0x7A, 'V':b'\0\0\0\0'}, IE=QoSRules()),
|
||||
Type6TLVE('MappedEPSBearerCtxt', val={'T':0x75, 'V':b'\0\0\0\0'}, IE=MappedEPSBearerCtxt()),
|
||||
Type6TLVE('QoSFlowDesc', val={'T':0x79, 'V':b'\0\0\0'}, IE=QoSFlowDesc()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
#Type4TLV('SessTMBR', val={'T':0x00, 'V':6*b'\0'}, IE=SessTMBR()), # WNG: tag is undefined in current TS
|
||||
#Type6TLVE('ATSSSContainer', val={'T':0x00, 'B':b''}), # WNG: tag is undefined in current TS
|
||||
Type4TLV('HdrCompConfig', val={'T':0x66, 'V':b'\0\0\0'}, IE=HdrCompConfig()),
|
||||
#Type6TLVE('PortMgmtInfoContainer', val={'T':0x00, 'V':b'\0'}), # WNG: tag is undefined in current TS
|
||||
)
|
||||
|
||||
|
||||
|
@ -233,8 +275,9 @@ class FGSMPDUSessionModifCommand(Layer3):
|
|||
class FGSMPDUSessionModifComplete(Layer3):
|
||||
_name = '5GSMPDUSessionModifComplete'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':204})
|
||||
|
||||
FGSMHeader(val={'Type':204}),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig()),
|
||||
#Type6TLVE('PortMgmtInfoContainer', val={'T':0x00, 'V':b'\0'}), # WNG: tag is undefined in current TS
|
||||
)
|
||||
|
||||
|
||||
|
@ -246,8 +289,9 @@ class FGSMPDUSessionModifComplete(Layer3):
|
|||
class FGSMPDUSessionModifCommandReject(Layer3):
|
||||
_name = '5GSMPDUSessionModifCommandReject'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':205})
|
||||
|
||||
FGSMHeader(val={'Type':205}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -259,8 +303,9 @@ class FGSMPDUSessionModifCommandReject(Layer3):
|
|||
class FGSMPDUSessionReleaseRequest(Layer3):
|
||||
_name = '5GSMPDUSessionReleaseRequest'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':209})
|
||||
|
||||
FGSMHeader(val={'Type':209}),
|
||||
Type3TV('5GSMCause', val={'T':0x59, 'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -272,8 +317,9 @@ class FGSMPDUSessionReleaseRequest(Layer3):
|
|||
class FGSMPDUSessionReleaseReject(Layer3):
|
||||
_name = '5GSMPDUSessionReleaseReject'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':210})
|
||||
|
||||
FGSMHeader(val={'Type':210}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -285,8 +331,12 @@ class FGSMPDUSessionReleaseReject(Layer3):
|
|||
class FGSMPDUSessionReleaseCommand(Layer3):
|
||||
_name = '5GSMPDUSessionReleaseCommand'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':211})
|
||||
|
||||
FGSMHeader(val={'Type':211}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type4TLV('BackOffTimer', val={'T':0x37, 'V':b'\0'}, IE=GRPSTimer3()),
|
||||
Type6TLVE('EAPMsg', val={'T':0x78, 'V':b'\0\0\0\0\0'}),
|
||||
Type4TLV('CongestReattemptInd', val={'T':0x61, 'V':b'\0'}, IE=CongestReattemptInd()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -298,8 +348,9 @@ class FGSMPDUSessionReleaseCommand(Layer3):
|
|||
class FGSMPDUSessionReleaseComplete(Layer3):
|
||||
_name = '5GSMPDUSessionReleaseComplete'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':212})
|
||||
|
||||
FGSMHeader(val={'Type':212}),
|
||||
Type3TV('5GSMCause', val={'T':0x59, 'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause()),
|
||||
Type6TLVE('ExtProtConfig', val={'T':0x7B, 'V':b'\0'}, IE=ProtConfig())
|
||||
)
|
||||
|
||||
|
||||
|
@ -311,8 +362,8 @@ class FGSMPDUSessionReleaseComplete(Layer3):
|
|||
class FGSMStatus(Layer3):
|
||||
_name = '5GSMStatus'
|
||||
_GEN = (
|
||||
FGSMHeader(val={'Type':214})
|
||||
|
||||
FGSMHeader(val={'Type':214}),
|
||||
Type3V('5GSMCause', val={'V':b'\x1a'}, bl={'V':8}, IE=FGSMCause())
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -44,10 +44,11 @@ from pycrate_core.charpy import Charpy
|
|||
from pycrate_ether.Ethernet import EtherType_dict
|
||||
from pycrate_ether.IP import IPProt_dict
|
||||
from pycrate_mobile.TS24008_IE import (
|
||||
BufBCD, PLMN, GPRSTimer3, APN,
|
||||
BufBCD, PLMN, GPRSTimer3, APN, TFT,
|
||||
)
|
||||
from pycrate_mobile.TS24301_IE import (
|
||||
EPSQoS, ExtEPSQoS, APN_AMBR, ExtAPN_AMBR,
|
||||
)
|
||||
#from pycrate_mobile.TS24301_IE import (
|
||||
# )
|
||||
|
||||
_str_reserved = 'reserved'
|
||||
_str_mnospec = 'operator-specific'
|
||||
|
@ -1805,6 +1806,20 @@ class AlwaysOnPDUSessReq(Envelope):
|
|||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Allowed SSC mode
|
||||
# TS 24.501, 9.11.4.5
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class AllowedSSCMode(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=1),
|
||||
Uint('SSC3', bl=1),
|
||||
Uint('SSC2', bl=1),
|
||||
Uint('SSC1', bl=1)
|
||||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Integrity protection maximum data rate
|
||||
# TS 24.501, 9.11.4.7
|
||||
|
@ -1822,6 +1837,92 @@ class IntegrityProtMaxDataRate(Envelope):
|
|||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Mapped EPS bearer contexts
|
||||
# TS 24.501, 9.11.4.8
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
_EPSBearerCtxtOC_dict = {
|
||||
0 : _str_reserved,
|
||||
1 : 'Create new EPS bearer',
|
||||
2 : 'Delete new EPS bearer',
|
||||
3 : 'Modify new EPS bearer'
|
||||
}
|
||||
|
||||
_EPSBearerCtxtEDict_sel = {
|
||||
1 : {
|
||||
0 : 'parameters not included',
|
||||
1 : 'parameters included'
|
||||
},
|
||||
2 : {
|
||||
0 : 'previously provided parameters extension',
|
||||
1 : 'previously provided parameters replacement'
|
||||
},
|
||||
3 : { # TS unclear there !
|
||||
}
|
||||
}
|
||||
|
||||
_EPSParamType_dict = {
|
||||
1 : 'Mapped EPS QoS parameters',
|
||||
2 : 'Mapped extended EPS QoS parameters',
|
||||
3 : 'Traffic flow template',
|
||||
4 : 'APN-AMBR',
|
||||
5 : 'extended APN-AMBR',
|
||||
}
|
||||
|
||||
|
||||
class EPSParam(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Type', dic=_EPSParamType_dict),
|
||||
Uint8('Len'),
|
||||
Alt('Content', GEN={
|
||||
1 : EPSQoS(),
|
||||
2 : ExtEPSQoS(),
|
||||
3 : TFT(),
|
||||
4 : APN_AMBR(),
|
||||
5 : ExtAPN_AMBR()
|
||||
},
|
||||
DEFAULT=Buf('unk', val=b'', rep=REPR_HEX),
|
||||
sel=lambda self: self.get_env()['Type'].get_val())
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self['Len'].set_valauto(lambda: self['Content'].get_len())
|
||||
|
||||
def _from_char(self, char):
|
||||
self[0]._from_char(char)
|
||||
self[1]._from_char(char)
|
||||
char_lb = char._len_bit
|
||||
char._len_bit = char._cur + (self[1].get_val()<<3)
|
||||
self[2]._from_char(char)
|
||||
char._len_bit = char_lb
|
||||
|
||||
|
||||
class EPSBearerCtxt(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=4),
|
||||
Uint('EBI', bl=4),
|
||||
Uint16('Len'),
|
||||
Uint('OpCode', bl=2, dic=_EPSBearerCtxtOC_dict),
|
||||
Uint('spare', bl=2),
|
||||
Uint('E', bl=1),
|
||||
Uint('Num', bl=3),
|
||||
Sequence('EPSParams', GEN=EPSParam())
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self['Len'].set_valauto(lambda: 1 + self['EPSParams'].get_len()) # TS does not define which length it is...
|
||||
self['E'].set_dicauto(lambda: _EPSBearerCtxtEDict_sel[self['OpCode'].get_val()])
|
||||
self['Num'].set_valauto(lambda: self['EPSParams'].get_num())
|
||||
self['EPSParams'].set_numauto(lambda: self['Num'].get_val())
|
||||
|
||||
|
||||
class MappedEPSBearerCtxt(Sequence):
|
||||
_GEN = EPSBearerCtxt()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Maximum number of supported packet filters
|
||||
# TS 24.501, 9.11.4.9
|
||||
|
@ -1877,10 +1978,131 @@ class PDUSessType(Envelope):
|
|||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# QoS flow descriptions
|
||||
# TS 24.501, 9.11.4.12
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
_UnitBitrate_dict = {
|
||||
1 : '1 Kbps',
|
||||
2 : '4 Kbps',
|
||||
3 : '16 Kbps',
|
||||
4 : '64 Kbps',
|
||||
5 : '256 kbps',
|
||||
6 : '1 Mbps',
|
||||
7 : '4 Mbps',
|
||||
8 : '16 Mbps',
|
||||
9 : '64 Mbps',
|
||||
10 : '256 Mbps',
|
||||
11 : '1 Gbps',
|
||||
12 : '4 Gbps',
|
||||
13 : '16 Gbps',
|
||||
14 : '64 Gbps',
|
||||
15 : '256 Gbps',
|
||||
16 : '1 Tbps',
|
||||
17 : '4 Tbps',
|
||||
18 : '16 Tbps',
|
||||
19 : '64 Tbps',
|
||||
20 : '256 Tbps',
|
||||
21 : '1 Pbps',
|
||||
22 : '4 Pbps',
|
||||
23 : '16 Pbps',
|
||||
24 : '64 Pbps',
|
||||
25 : '256 Pbps'
|
||||
}
|
||||
|
||||
_QoSFlowOC_dict = {
|
||||
1 : 'Create new QoS flow description',
|
||||
2 : 'Delete existing QoS flow description',
|
||||
3 : 'Modify existing QoS flow description'
|
||||
}
|
||||
|
||||
_QoSFlowE_dict = {
|
||||
1 : {
|
||||
0 : _str_reserved,
|
||||
1 : 'parameters list is included'
|
||||
},
|
||||
2 : {
|
||||
0 : 'parameters list is not included',
|
||||
1 : _str_reserved
|
||||
},
|
||||
3 : {
|
||||
0 : 'extension of previously provided parameters',
|
||||
1 : 'replacement of all previously provided parameters'
|
||||
}
|
||||
}
|
||||
|
||||
_QoSFlowParamType_dict = {
|
||||
1 : '5QI',
|
||||
2 : 'GFBR uplink',
|
||||
3 : 'GFBR downlink',
|
||||
4 : 'MFBR uplink',
|
||||
5 : 'MFBR downlink',
|
||||
6 : 'Averaging window',
|
||||
7 : 'EPS bearer identity'
|
||||
}
|
||||
|
||||
|
||||
class _QoSFlowParamFBR(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Unit', dic=_UnitBitrate_dict),
|
||||
Uint16('Value')
|
||||
)
|
||||
|
||||
|
||||
class _QoSFlowParamEBI(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=4),
|
||||
Uint('EBI', bl=4),
|
||||
)
|
||||
|
||||
|
||||
class QoSFlowParam(Envelope):
|
||||
_GEN = (
|
||||
Uint8('Type', dic=_QoSFlowParamType_dict),
|
||||
Uint8('Len'),
|
||||
Alt('Content', GEN={
|
||||
1 : Uint8('5GQI'),
|
||||
2 : _QoSFlowParamFBR('GFBR'),
|
||||
3 : _QoSFlowParamFBR('GFBR'),
|
||||
4 : _QoSFlowParamFBR('MFBR'),
|
||||
5 : _QoSFlowParamFBR('MFBR'),
|
||||
6 : Uint16('Win', desc='millisecond'),
|
||||
7 : _QoSFlowParamEBI('EBI')
|
||||
},
|
||||
DEFAULT=Buf('unk', val=b'', rep=REPR_HEX),
|
||||
sel=lambda self: self.get_env()['Type'].get_val())
|
||||
)
|
||||
|
||||
|
||||
class QoSFlow(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=2),
|
||||
Uint('QFI', bl=6),
|
||||
Uint('OpCode', bl=3, dic=_QoSFlowOC_dict),
|
||||
Uint('spare', bl=6), # last 5 bit of 2nd octet and 1st bit of 3rd octet
|
||||
Uint('E', bl=1),
|
||||
Uint('Num', bl=6),
|
||||
Sequence('Params', GEN=QoSFlowParam('Param'))
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Envelope.__init__(self, *args, **kwargs)
|
||||
self['E'].set_dicauto(lambda: _QoSFlowE_dict[self['OpCode'].get_val()])
|
||||
self['Num'].set_valauto(lambda: self['Params'].get_num())
|
||||
self['Params'].set_numauto(lambda: self['Num'].get_val())
|
||||
|
||||
|
||||
class QoSFlowDesc(Sequence):
|
||||
_GEN = QoSFlow()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# QoS rules
|
||||
# TS 24.501, 9.11.4.13
|
||||
#------------------------------------------------------------------------------#
|
||||
# similar to Traffic Flow Template for PS and EPS domains
|
||||
# TS 24.008, 10.5.6.12
|
||||
|
||||
_QoSRuleOpCode_dict = {
|
||||
0 : _str_reserved,
|
||||
|
@ -1985,17 +2207,16 @@ class PktFilterComp(Envelope):
|
|||
_GEN = (
|
||||
Uint8('Type', dic=_PktFilterCompType_dict),
|
||||
Alt('Value', GEN={
|
||||
# TODO
|
||||
1 : Buf('none', bl=0),
|
||||
16 : _PktFilterCompIPv4('IPv4RemoteAddr'),
|
||||
17 : _PktFilterCompIPv4('IPv4LocalAddr'),
|
||||
33 : _PktFilterCompIPv6('IPv6RemoteAddr'),
|
||||
35 : _PktFilterCompIPv6('IPv6LocalAddr'),
|
||||
48 : Uint8('ProtID', dic=IPProt_dict),
|
||||
64 : Uint16('PortLocal'),
|
||||
65 : _PktFilterCompPortRange('PortRangeLocal'),
|
||||
80 : Uint16('PortRemote'),
|
||||
81 : _PktFilterCompPortRange('PortRangeRemote'),
|
||||
16 : _PktFilterCompIPv4('IPv4'),
|
||||
17 : _PktFilterCompIPv4('IPv4'),
|
||||
33 : _PktFilterCompIPv6('IPv6Pref'),
|
||||
35 : _PktFilterCompIPv6('IPv6Pref'),
|
||||
48 : Uint8('ProtId', dic=IPProt_dict),
|
||||
64 : Uint16('Port'),
|
||||
65 : _PktFilterCompPortRange('PortRange'),
|
||||
80 : Uint16('Port'),
|
||||
81 : _PktFilterCompPortRange('PortRange'),
|
||||
96 : Uint32('SPI', rep=REPR_HEX),
|
||||
112 : _PktFilterTrafficClass('TrafficClass'),
|
||||
128 : _PktFilterFlowLabel('FlowLabel'),
|
||||
|
@ -2007,7 +2228,7 @@ class PktFilterComp(Envelope):
|
|||
134 : _PktFilterPCPDEI('STagPCPDEI'),
|
||||
135 : Uint16('EtherType', dic=EtherType_dict)
|
||||
},
|
||||
DEFAULT=Buf('unk', rep=REPR_HEX),
|
||||
DEFAULT=Buf('unk', val=b'', rep=REPR_HEX),
|
||||
sel=lambda self: self.get_env()['Type'].get_val())
|
||||
)
|
||||
|
||||
|
@ -2015,8 +2236,8 @@ class PktFilterComp(Envelope):
|
|||
class PktFilterAdd(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=2),
|
||||
Uint('Direction', bl=2, dict=_PktFilterDir_dict),
|
||||
Uint('ID', bl=4),
|
||||
Uint('Dir', bl=2, dict=_PktFilterDir_dict),
|
||||
Uint('Id', bl=4),
|
||||
Uint8('Len'),
|
||||
Sequence('PktFilter', GEN=PktFilterComp())
|
||||
)
|
||||
|
@ -2080,34 +2301,6 @@ class QoSRules(Sequence):
|
|||
# TS 24.501, 9.11.4.14
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
_UnitBitrate_dict = {
|
||||
1 : '1 Kbps',
|
||||
2 : '4 Kbps',
|
||||
3 : '16 Kbps',
|
||||
4 : '64 Kbps',
|
||||
5 : '256 kbps',
|
||||
6 : '1 Mbps',
|
||||
7 : '4 Mbps',
|
||||
8 : '16 Mbps',
|
||||
9 : '64 Mbps',
|
||||
10 : '256 Mbps',
|
||||
11 : '1 Gbps',
|
||||
12 : '4 Gbps',
|
||||
13 : '16 Gbps',
|
||||
14 : '64 Gbps',
|
||||
15 : '256 Gbps',
|
||||
16 : '1 Tbps',
|
||||
17 : '4 Tbps',
|
||||
18 : '16 Tbps',
|
||||
19 : '64 Tbps',
|
||||
20 : '256 Tbps',
|
||||
21 : '1 Pbps',
|
||||
22 : '4 Pbps',
|
||||
23 : '16 Pbps',
|
||||
24 : '64 Pbps',
|
||||
25 : '256 Pbps'
|
||||
}
|
||||
|
||||
class SessAMBR(Envelope):
|
||||
_GEN = (
|
||||
Uint8('DLUnit', dic=_UnitBitrate_dict),
|
||||
|
@ -2149,5 +2342,80 @@ class SSCMode(Envelope):
|
|||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Re-attempt indicator
|
||||
# TS 24.501, 9.11.4.17
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class ReattemptInd(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=6, rep=REPR_HEX),
|
||||
Uint('EPLMNC', bl=1),
|
||||
Uint('RATC', bl=1)
|
||||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# 5GSM network feature support
|
||||
# TS 24.501, 9.11.4.18
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class FGSNetFeat(Envelope):
|
||||
_name = '5GSMNetFeat'
|
||||
_GEN = (
|
||||
Uint('spare', bl=7),
|
||||
Uint('EPT-S1', bl=1),
|
||||
Buf('spare', val=b'', rep=REPR_HEX)
|
||||
)
|
||||
|
||||
def disable_from(self, ind):
|
||||
"""disables all elements from index `ind' excluded (element offset or name)
|
||||
"""
|
||||
if isinstance(ind, str_types) and ind in self._by_name:
|
||||
ind = self._by_name.index(ind)
|
||||
[e.set_trans(True) for e in self._content[ind:]]
|
||||
|
||||
def enable_upto(self, ind):
|
||||
"""enables all elements up to index `ind' included (element offset or name)
|
||||
"""
|
||||
if isinstance(ind, str_types) and ind in self._by_name:
|
||||
ind = 1 + self._by_name.index(ind)
|
||||
[e.set_trans(False) for e in self._content[:ind]]
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Session-TMBR
|
||||
# TS 24.501, 9.11.4.19
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class SessTMBR(SessAMBR):
|
||||
pass
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Re-attempt indicator
|
||||
# TS 24.501, 9.11.4.17
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class CongestReattemptInd(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=7, rep=REPR_HEX),
|
||||
Uint('ABO', bl=1)
|
||||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
# Control plane only indication
|
||||
# TS 24.501, 9.11.4.23
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
class CtrlPlaneOnlyInd(Envelope):
|
||||
_GEN = (
|
||||
Uint('spare', bl=3),
|
||||
Uint('Value', val=1, bl=1,
|
||||
dic={1:'PDU session can be used for control plane CIoT 5GS optimization only'})
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue