3GPP

The threegpp.l3msg module

3GPP Layer 3 Message Processing Library

This module provides classes and utilities for processing 3GPP Layer 3 messages, particularly for 5G Session Management (5GSM) and 5G Mobility Management (5GMM) protocols. It builds upon the encoding module to provide high-level message parsing and generation.

class threegpp.l3msg.FGMMMessageType

5G Mobility Management (5GMM) message type identifiers.

  • RegistrationRequest = 0x41

  • RegistrationAccept = 0x42

  • RegistrationComplete = 0x43

  • RegistrationReject = 0x44

  • DeregistrationRequestUEOriginating = 0x45

  • DeregistrationAcceptUEOriginating = 0x46

  • DeregistrationRequestNetworkOriginating = 0x47

  • DeregistrationAcceptNetworkOriginating = 0x48

  • ServiceRequest = 0x4C

  • ServiceReject = 0x4D

  • ServiceAccept = 0x4E

  • ControlPlaneServiceRequest = 0x4F

  • NetworkSliceSpecificAuthenticationCommand = 0x50

  • NetworkSliceSpecificAuthenticationComplete = 0x51

  • NetworkSliceSpecificAuthenticationResult = 0x52

  • ConfigurationUpdateCommand = 0x54

  • ConfigurationUpdateComplete = 0x55

  • AuthenticationRequest = 0x56

  • AuthenticationResponse = 0x57

  • AuthenticationReject = 0x58

  • AuthenticationFailure = 0x59

  • AuthenticationResult = 0x5A

  • IdentityRequest = 0x5B

  • IdentityResponse = 0x5C

  • SecurityModeCommand = 0x5D

  • SecurityModeComplete = 0x5E

  • SecurityModeReject = 0x5F

  • FiveGMMStatus = 0x64

  • Notification = 0x65

  • NotificationResponse = 0x66

  • UplinkNasTransport = 0x67

  • DownlinkNasTransport = 0x68

  • RelayKeyRequest = 0x69

  • RelayKeyAccept = 0x6A

  • RelayKeyReject = 0x6B

  • RelayAuthenticationRequest = 0x6C

  • RelayAuthenticationResponse = 0x6D

class threegpp.l3msg.FGSMMessageType

5G Session Management (5GSM) message type identifiers.

  • PDUSessionEstablishmentRequest = 0xC1

  • PDUSessionEstablishmentAccept = 0xC2

  • PDUSessionEstablishmentReject = 0xC3

  • PDUSessionAuthenticationCommand = 0xC5

  • PDUSessionAuthenticationComplete = 0xC6

  • PDUSessionAuthenticationResult = 0xC7

  • PDUSessionModificationRequest = 0xC9

  • PDUSessionModificationReject = 0xCA

  • PDUSessionModificationCommand = 0xCB

  • PDUSessionModificationComplete = 0xCC

  • PDUSessionModificationCompleteReject = 0xCD

  • PDUSessionReleaseRequest = 0xD1

  • PDUSessionReleaseReject = 0xD2

  • PDUSessionReleaseCommand = 0xD3

  • PDUSessionReleaseComplete = 0xD4

  • FiveGSMStatus = 0xD6

  • ServiceLevelAuthenticationCommand = 0xD8

  • ServiceLevelAuthenticationComplete = 0xD9

  • RemoteUEReport = 0xDA

  • RemoteUEReportResponse = 0xDB

class threegpp.l3msg.IE(desc, value)

Information Element within a message.

Represents a single Information Element (IE) in a 3GPP message. It contains a value property which can be either an integer for single-octet IEs or a bytes object for multi-octet IEs. Upon setting this property the value is validated against the format defined in the IE descriptor.

Objects of this class know how to encode themselves into binary format using their descriptor attribute desc.

Parameters
  • desc (IEDesc) – IE descriptor defining the structure.

  • value (any) – Value of the IE.

encode(buffer)

Encode the IE into a buffer.

Parameters

buffer (bytearray) – Buffer to encode into.

property value

Get the IE value.

Returns

Current value of the IE.

Return type

any

class threegpp.l3msg.IEDesc(iei, name, fmt)

Information Element Descriptor.

Describes a single Information Element (IE) within a 3GPP message, including its identifier, name, and encoding format.

Parameters
  • iei (int or None) – Information Element Identifier (IEI). None for mandatory IEs.

  • name (str) – Descriptive name of the IE.

  • fmt (encoding format object) – Encoding format specification for this IE.

property mandatory

Check if this IE is mandatory.

Returns

True if the IE is mandatory (iei is None).

Return type

bool

class threegpp.l3msg.Message(desc, ies)

Represents a 3GPP Layer 3 message.

A Message consists of an ordered list of IEs. This list is accessible via the ies parameter and can be modified by inserting, deleting, or reordering the elements.

However, this is not the preferred method of interacting with a Message. Instead, Nokia advises to use the provided methods and operators to get, set, or delete Information Elements. This ensures that the message remains valid according to its descriptor:

  • mandatory IEs cannot be deleted,

  • optional IEs are inserted at the correct position,

  • values are validated according to their format, but without further semantic checks.

By default these methods act on the assumption that only a single IE of each type will be present. This is the most common case. However, if multiple IEs of the same type are expected, the all parameter can be set to True to modify the behavior accordingly; that is, the values being passed and returned are lists instead of single values.

Parameters
  • desc (MessageDescriptor) – Message descriptor defining the structure.

  • ies (list of IE) – List of Information Elements in this message.

static decode(data)

Decode a Layer 3 message from binary data.

Automatically determines the protocol type from the protocol discriminator and uses the appropriate decoder.

Parameters

data (bytes or bytearray) – Binary message data to decode.

Returns

Decoded Message object.

Return type

Message

Raises
  • ValueError – If data is too short.

  • RuntimeError – If protocol is not supported.

delIE(key, all=False)

Delete Information Element(s) by key.

Parameters
  • key (int or str) – IEI (as int) or name (as str) of the IE.

  • all (bool) – If True, delete all occurrences; if False, delete first only.

Raises

RuntimeError – If attempting to delete mandatory IEs.

encode()

Encode the message to binary format.

Returns

Binary representation of the message.

Return type

bytes

getIE(key, all=False)

Get the value(s) of an Information Element by key.

Parameters
  • key (int or str) – IEI (as int) or name (as str) of the IE.

  • all (bool) – If True, return all occurrences; if False, return first only.

Returns

IE value(s) - single value if all=False, list if all=True.

Return type

any or list

property protocol

Get the protocol discriminator value.

Returns

Extended or regular protocol discriminator value.

Return type

int or None

setIE(key, value, all=False)

Set the value(s) of an Information Element by key.

Parameters
  • key (int or str) – IEI (as int) or name (as str) of the IE.

  • value (any or list or tuple) – Value to set. Must be list/tuple if all=True.

  • all (bool) – If True, set multiple occurrences; if False, set first only.

Raises
  • TypeError

  • ValueError – If value format is incorrect or IE is unknown.

class threegpp.l3msg.MessageDescriptor(ies)

Message Descriptor for 3GPP Layer 3 messages.

Defines the structure of a message including its mandatory and optional Information Elements, and provides methods for decoding messages.

Parameters

ies (list of IEDesc) – List of Information Element descriptors for this message.

decode(data, unknown)

Decode a message from binary data.

Parameters
  • data (bytes or bytearray) – Binary data to decode.

  • unknown (callable) – Callback function to handle unknown IE types.

Returns

Decoded Message object.

Return type

Message

Raises

ValueError – If an IE cannot be decoded or set.

class threegpp.l3msg.ProtocolDiscriminator

Protocol Discriminator values for 3GPP Layer 3 messages.

  • GroupCallControl = 0x00

  • BroadcastCallControl = 0x01

  • EPSSessionManagement = 0x02

  • CallControl = 0x03

  • GTTP = 0x04

  • MobilityManagement = 0x05

  • RadioResourceManagement = 0x06

  • EPSMobilityManagement = 0x07

  • GPRSMobilityManagement = 0x08

  • SMSMessages = 0x09

  • GRPSSessionManagement = 0x0A

  • NonCallRelatedSS = 0x0B

  • LocationServices = 0x0C

  • FiveGSessionManagement = 0x2E

  • FiveGMobilityManagement = 0x7E

SPEC_VERSION = 'V17.9.0'

3GPP specification version used for message definitions. This constant indicates the version of 3GPP TS 24.501 specification that was used to define the message structures and IEs in this module.

threegpp.l3msg.fgmm_ie_descriptors

5G Mobility Management (5GMM) Information Element descriptors.

threegpp.l3msg.fgmm_security_protected_encrypted_msg

5GMM security protected and encrypted message descriptor. MessageDescriptor for 5GMM messages with both integrity protection and encryption. Used when the security header type indicates both integrity and ciphering (security header types 2 and 4). The payload contains encrypted NAS message data.

threegpp.l3msg.fgmm_security_protected_msg

5GMM security protected message descriptor. MessageDescriptor for 5GMM messages with integrity protection (no encryption). Used when the security header type indicates integrity protection only (security header types 1 and 3).

threegpp.l3msg.fgsm_ie_descriptors

5G Session Management (5GSM) Information Element descriptors.

The threegpp.encoding module

3GPP Message Encoding Library

This module provides encoding and decoding functionality for 3GPP Layer 3 message Information Elements (IEs) according to the format specifications in TS 24.007.

The module implements all standard IE encoding formats:

  • Type 1: V format and TV format

  • Type 2: T format

  • Type 3: V format and TV format

  • Type 4: LV format and TLV format

  • Type 6: LVE format and TLVE format

Each format class adheres to the interface defined by the abstract base class Formatter.

class threegpp.encoding.Formatter

Abstract base class for 3GPP message format encoders/decoders.

Note

This class is abstract and documents the interface implemented by objects returned by factory functions such as LV(). It should not be used directly.

Defines the interface that all format classes must implement for encoding and decoding Information Elements in 3GPP messages.

check_value(value)

Validate the value to be encoded.

Parameters

value (any) – Value to validate.

Raises

ValueError – If value is invalid for this format.

decode(data)

Decode an Information Element from binary data.

Parameters

data (bytes or bytearray) – Binary data to decode.

Returns

Tuple of (iei, value, remaining_data).

Raises

ValueError – If data cannot be decoded.

encode(iei, value, buffer)

Encode an Information Element into a buffer.

Parameters
  • iei (int or None) – Information Element Identifier.

  • value (any) – Value to encode.

  • buffer (bytearray) – Buffer to append encoded data to.

Raises

ValueError – If IEI or value is invalid.

threegpp.encoding.LV(min_len=None, max_len=None)

Create a formatter for Type 4 Format LV.

Parameters
  • min_len (int or None) – Minimum total length in bytes (including length field).

  • max_len (int or None) – Maximum total length in bytes (including length field).

Return type

Formatter instance

threegpp.encoding.LVE(min_len=None, max_len=None)

Create a formatter for Type 6 Format LVE.

Parameters
  • min_len (int or None) – Minimum total length in bytes (including length field).

  • max_len (int or None) – Maximum total length in bytes (including length field).

Return type

Formatter instance

threegpp.encoding.T

Formatter for Type 2 Format T IE.

threegpp.encoding.TLV(min_len=None, max_len=None)

Create a formatter for Type 4 Format TLV.

Parameters
  • min_len (int or None) – Minimum total length in bytes (including IEI and length field).

  • max_len (int or None) – Maximum total length in bytes (including IEI and length field).

Return type

Formatter instance

threegpp.encoding.TLVE(min_len=None, max_len=None)

Create a formatter for Type 6 Format TLVE.

Parameters
  • min_len (int or None) – Minimum total length in bytes (including IEI and length field).

  • max_len (int or None) – Maximum total length in bytes (including IEI and length field).

Return type

Formatter instance

threegpp.encoding.TV(length)

Create a Formatter for Type 3 Format TV.

Parameters

length (int) – Total length including IEI (minimum 1 byte).

Return type

Formatter instance

threegpp.encoding.TV1

Formatter for Type 1 Format TV IE.

threegpp.encoding.V(length, remainder=None)

Create a Formatter for Type 3 Format V.

Parameters
  • length (int) – Fixed length of the value field in bytes.

  • remainder ('n' or None) – If 'n', allows variable length from length to max. If None, fixed length.

Return type

Formatter instance

threegpp.encoding.Vlower

Formatter for Type 1 Format V lower half-octet IE.

threegpp.encoding.Vupper

Formatter for Type 1 Format V upper half-octet IE.

Examples

1. Basic modification

 1from binascii import unhexlify
 2from threegpp.l3msg import Message
 3
 4data = unhexlify(b"2e0101c1ffff91a12801017b001380000100001000000c00000e00000300000d00")
 5
 6# Decode a message from a byte string
 7msg = Message.decode(data)
 8
 9# Access the protocol discriminator value
10protocol = msg.protocol  # Returns 0x2E for 5GSM
11
12# Get the value of an IE
13capability = msg["5GSMCapability"]
14
15# Check if an IE is present in the message
16if "SuggestedInterfaceIdentifier" in msg:
17    # Delete the IE from the message
18    del msg["SuggestedInterfaceIdentifier"]
19
20# Set a new value for an existing IE
21msg["5GSMCapability"] = 2
22
23# Setting a value for a non-existing IE adds it to the message
24msg["MaximumNumberOfSupportedPacketFilters"] = b"\x01\x02"
25
26# The IE-indexing functions also work with IEIs
27msg[0x55] = b"\x03\x04"
28
29# Encode the modified message back to a byte string
30modified_data = msg.encode()

2. Messages with multi-valued IEs

 1from binascii import unhexlify
 2from threegpp.l3msg import Message
 3
 4# Example message with multiple optional IEs
 5data = unhexlify(b"2e0101c1ffff91a12801017b001380000100001000000c00000e00000300000d00")
 6
 7# Decode a message from a byte string
 8msg = Message.decode(data)
 9
10# getIE() - Get a single IE value (first occurrence by default)
11capability = msg.getIE("5GSMCapability")
12
13# getIE(all=True) - Get all occurrences of an IE
14all_capabilities = msg.getIE("5GSMCapability", all=True)
15
16# setIE(all=True) - Replace all occurrences with new values
17# This replaces all occurrences with the values in the list
18msg.setIE("5GSMCapability", [0xAA, 0xBB, 0xCC], all=True)
19
20# delIE() - Delete first occurrence of an IE
21msg.delIE("5GSMCapability")
22
23# delIE(all=True) - Delete all remaining occurrences of an IE
24msg.delIE("5GSMCapability", all=True)
25
26# Check if IE exists after deletion
27exists = "5GSMCapability" in msg
28
29# Using IEI (0x28) instead of name
30msg.setIE(0x28, [0x12, 0x34], all=True)
31capabilities_by_iei = msg.getIE(0x28, all=True)
32
33# Difference between [] and getIE()
34first_only = msg["5GSMCapability"]  # Returns first value only
35first_getie = msg.getIE("5GSMCapability")  # Also returns first value only
36all_getie = msg.getIE("5GSMCapability", all=True)  # Returns list of all values

3. Working with custom IEs and the IE list

 1from binascii import unhexlify
 2from threegpp.l3msg import Message, IE, IEDesc
 3from threegpp.encoding import TLV
 4
 5# Example message
 6data = unhexlify(b"2e0101c1ffff91a12801017b001380000100001000000c00000e00000300000d00")
 7
 8msg = Message.decode(data)
 9
10# Direct access to the IEs list
11# Message.ies is a list of IE objects
12ies_list = msg.ies
13
14# Iterate over all IEs in the message
15for ie in msg.ies:
16    # Each IE has a descriptor (desc) and a value
17    ie_name = ie.desc.name
18    ie_value = ie.value
19    ie_iei = ie.desc.iei
20
21# Find a specific IE by examining the list
22capability_ie = next((ie for ie in msg.ies if ie.desc.name == "5GSMCapability"), None)
23
24# Modify an IE's value directly
25if capability_ie:
26    capability_ie.value = 0xAB
27
28# Add a new IE by creating an IE object and appending to the list
29# Note: No ordering checks are performed when manipulating the list directly
30new_ie_desc = IEDesc(0x99, "CustomIE", TLV(3, 255))
31new_ie = IE(new_ie_desc, b"\x01\x02")
32msg.ies.append(new_ie)
33
34# Insert an IE at a specific position
35another_ie_desc = IEDesc(0xAA, "AnotherCustomIE", TV(2))
36another_ie = IE(another_ie_desc, 1)
37msg.ies.insert(5, another_ie)  # Insert at position 5
38
39# Remove an IE from the list by index
40del msg.ies[5]
41
42# Remove an IE by finding it first
43ie_to_remove = next((ie for ie in msg.ies if ie.desc.name == "5GSMCapability"), None)
44if ie_to_remove:
45    msg.ies.remove(ie_to_remove)
46
47# Add multiple IEs of the same type
48for value in [0x11, 0x22, 0x33]:
49    ie_desc = msg.desc["5GSMCapability"]
50    msg.ies.append(IE(ie_desc, value))
51
52# Encode the modified message
53modified_data = msg.encode()

4. Custom messages

 1from threegpp.l3msg import Message, MessageDescriptor, IEDesc, fgsm_ie_descriptors
 2from threegpp.encoding import V, TV, TLV, LV
 3
 4# Define a custom message type code (use a reserved/unassigned value)
 5CUSTOM_MESSAGE_TYPE = 0xFF
 6
 7# Create a MessageDescriptor for the custom message
 8# This defines the structure of IEs for this new message type
 9custom_message_descriptor = MessageDescriptor(
10    [
11        # Mandatory IEs
12        IEDesc(None, "ExtendedProtocolDiscriminator", V(1)),
13        IEDesc(None, "PDUSessionID", V(1)),
14        IEDesc(None, "PTI", V(1)),
15        IEDesc(None, "MessageType", V(1)),
16        IEDesc(None, "CustomMandatoryField", V(2)),
17
18        # Optional IEs (with IEI values)
19        IEDesc(0x10, "CustomOptionalField1", TV(2)),
20        IEDesc(0x20, "CustomOptionalField2", TLV(3, 255)),
21        IEDesc(0x30, "CustomOptionalField3", TLV(3, 255)),
22    ]
23)
24
25# Add the custom message descriptor to the 5GSM descriptor table
26fgsm_ie_descriptors[CUSTOM_MESSAGE_TYPE] = custom_message_descriptor
27
28# Now we can decode a message of this custom type
29# Construct a raw message with the custom message type
30custom_message_data = bytes([
31    0x2E,        # Extended Protocol Discriminator (5GSM)
32    0x05,        # PDU Session ID
33    0x01,        # PTI
34    0xFF,        # Message Type (our custom type)
35    0x12, 0x34,  # CustomMandatoryField (2 bytes)
36    0x10, 0xAB,  # CustomOptionalField1 (TV format, IEI=0x10, value=0xAB)
37    0x20, 0x03, 0x01, 0x02, 0x03,  # CustomOptionalField2 (TLV format)
38])
39
40# Decode the custom message
41msg = Message.decode(custom_message_data)
42
43# Access the custom IEs
44protocol_disc = msg["ExtendedProtocolDiscriminator"]
45session_id = msg["PDUSessionID"]
46mandatory_field = msg["CustomMandatoryField"]
47optional_field1 = msg["CustomOptionalField1"]
48optional_field2 = msg["CustomOptionalField2"]
49
50# Modify custom IE values
51# For V format fields, value must match the exact length
52msg["CustomMandatoryField"] = b"\x56\x78"
53msg["CustomOptionalField1"] = 0xCD
54
55# Add another optional IE
56msg["CustomOptionalField3"] = b"\x01\x02\x03\x04"
57
58# Encode the modified message back
59encoded_data = msg.encode()

5. Error handling

 1from threegpp.l3msg import Message
 2
 3# Example 1: Handling unknown message types
 4# Attempting to decode a message with an unknown message type
 5try:
 6    unknown_msg_data = bytes([
 7        0x2E,  # Extended Protocol Discriminator (5GSM)
 8        0x05,  # PDU Session ID
 9        0x01,  # PTI
10        0xEE,  # Unknown Message Type
11    ])
12    msg = Message.decode(unknown_msg_data)
13except RuntimeError as e:
14    # Will raise: "Unknown 5GSM message type: 0xee"
15    print(e)
16
17# Example 2: Data too short for message header
18try:
19    short_data = bytes([0x2E, 0x01])  # Only 2 bytes, needs at least 4 for 5GSM
20    msg = Message.decode(short_data)
21except ValueError as e:
22    # Will raise: "Data too short to contain 5GSM header"
23    print(e)
24
25# Example 3: Invalid protocol discriminator
26try:
27    invalid_protocol = bytes([0xFF, 0x01, 0x02, 0x03])
28    msg = Message.decode(invalid_protocol)
29except RuntimeError as e:
30    # Protocol discriminator not in decoder table
31    print(e)
32
33# Example 4: Attempting to delete a mandatory IE
34# Create a RegistrationComplete message (5GMM message type 0x43)
35msg = Message.decode(bytes([
36    0x7E,  # Extended Protocol Discriminator (5GMM)
37    0x00,  # Security Header Type (0) | Spare Half Octet (0)
38    0x43,  # Message Type (RegistrationComplete)
39]))
40
41try:
42    del msg["MessageType"]  # MessageType is mandatory
43except RuntimeError as e:
44    # Will raise: "Cannot delete mandatory IEs"
45    print(e)
46
47# Example 5: Setting invalid value for IE
48try:
49    # SORTransparentContainer expects TLVE format (min 20 bytes)
50    # The format validates the value length
51    msg["SORTransparentContainer"] = b"\x01"  # Too short
52except ValueError as e:
53    # Format validation error
54    print(e)
55
56# Example 6: Attempting to set unknown IE when not allowed
57# This is caught when trying to insert an IE that doesn't exist in the descriptor
58try:
59    msg["NonExistentIE"] = b"\x01\x02\x03"
60except RuntimeError as e:
61    # Will raise: "Cannot insert unknown IE"
62    print(e)
63
64# Example 7: Value validation - out of range for nibble fields
65try:
66    # SecurityHeaderType is a nibble field (upper 4 bits), values 0x0-0xF only
67    msg["SecurityHeaderType"] = 0x20  # Too large for a nibble
68except ValueError as e:
69    # Will raise: "Value out of range"
70    print(e)
71
72# Example 8: Encoding with invalid data
73try:
74    # Create a message with invalid mandatory field value
75    msg["ExtendedProtocolDiscriminator"] = 0x1234  # Too large for 1 byte
76except ValueError as e:
77    # Value validation fails
78    print(e)