mirror of https://github.com/secdev/scapy.git
Page:
Z_Legacy Contrib: gsm_um
0
Z_Legacy Contrib: gsm_um
Gabriel edited this page 2019-04-22 14:15:16 +02:00
GSM_UM was a former contribution module of Scapy
It was introduced in this commit.
However, due to the giant size of the file, the missing tests, and the fact that the original author was unreachable, it has been removed from Scapy v2.4.1.
This page contains the legacy code - an automatically updated and fixed version - of the module before it was removed, but also a copy of its documentation, before the website of the author was shut down.
Code
#!/usr/bin/env python
# This file is part of Scapy
# Scapy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# any later version.
#
# Scapy 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
# scapy.contrib.description = PPI
# scapy.contrib.status = loads
####################################################################
# This file holds the GSM UM interface implementation for Scapy #
# author: Laurent Weber <k@0xbadcab1e.lu> #
# #
# Some examples on how to use this script: #
# http://0xbadcab1e.lu/scapy_gsm_um-howto.txt #
# #
# tested on: scapy-version: 2.2.0 (dev). #
# last updated: scapy-version: 2.4.0 (but untested) #
####################################################################
from __future__ import print_function
import socket
from scapy.compat import chb, raw
from scapy.packet import Packet
from scapy.fields import BitField, XBitField, ByteField, XByteField
# This method is intended to send gsm air packets. It uses a unix domain
# socket. It opens a socket, sends the parameter to the socket and
# closes the socket.
# typeSock determines the type of the socket, can be:
# 0 for UDP Socket
# 1 for Unix Domain Socket
# 2 for TCP
def sendum(x, typeSock=0):
try:
if not isinstance(x, bytes):
x = raw(x)
if typeSock is 0:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
host = '127.0.0.1'
port = 28670 # default for openBTS
s.connect((host, port))
elif typeSock is 1:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/tmp/osmoL")
elif typeSock is 2:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'
port = 43797
s.connect((host, port))
s.send(x)
s.close()
except BaseException:
print("[Error]: There was a problem when trying to transmit data.\
Please make sure you started the socket server.")
# Known Bugs/Problems:
# If a message uses multiple times the same IE you cannot set the values
# of this IE's if you use the preconfigured packets. You need to build
# the IE's by hand and than assemble them as entire messages.
# The ErrorLength class is a custom exception that gets raised when a
# packet doesn't have the correct size.
class ErrorLength(Exception):
def __str__(self):
error = "ERROR: Please make sure you build entire, 8 bit fields."
return repr(error)
###
# This method computes the length of the actual IE.
# It computes how many "None" fields have to be removed (if any).
# The method returns an integer containing the number of bytes that have to be
# cut off the packet.
# parameter length contains the max length of the IE can be found in
# 0408
# The parameter fields contains the value of the fields (not the default but
# the real, actual value.
# The parameter fields2 contains fields_desc.
# Location contains the location of the length field in the IE. Everything
# after the the length field has to be counted (04.07 11.2.1.1.2)
def _adapt(min_length, max_length, fields, fields2, location=2):
# find out how much bytes there are between min_length and the location of
# the length field
location = min_length - location
i = len(fields) - 1
rm = mysum = 0
while i >= 0:
if fields[i] is None:
rm += 1
try:
mysum += fields2[i].size
except AttributeError: # ByteFields don't have .size
mysum += 8
else:
break
i -= 1
if mysum % 8 is 0:
length = mysum / 8 # Number of bytes we have to delete
dyn_length = (max_length - min_length - length)
if dyn_length < 0:
dyn_length = 0
if length is max_length: # Fix for packets that have all values set
length -= min_length # to None
return [length, dyn_length + location]
else:
raise ErrorLength()
# Section 10.2/3
class TpPd(Packet):
"""Skip indicator and transaction identifier and Protocol Discriminator"""
name = "Skip Indicator And Transaction Identifier and Protocol \
Discriminator"
fields_desc = [
BitField("ti", 0x0, 4),
BitField("pd", 0x3, 4)
]
class MessageType(Packet):
"""Message Type Section 10.4"""
name = "Message Type"
fields_desc = [
XByteField("mesType", 0x3C)
]
##
# Message for Radio Resources management (RR) Section 9.1
###
# Network to MS
def additionalAssignment(MobileAllocation_presence=0,
StartingTime_presence=0):
"""ADDITIONAL ASSIGNMENT Section 9.1.1"""
# Mandatory
a = TpPd(pd=0x6)
b = MessageType(mesType=0x3B) # 00111011
c = ChannelDescription()
packet = a / b / c
# Not Mandatory
if MobileAllocation_presence is 1:
d = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0)
packet = packet / d
if StartingTime_presence is 1:
e = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / e
return packet
# Network to MS
def assignmentCommand(FrequencyList_presence=0,
CellChannelDescription_presence=0,
CellChannelDescription_presence1=0,
MultislotAllocation_presence=0,
ChannelMode_presence=0, ChannelMode_presence1=0,
ChannelMode_presence2=0, ChannelMode_presence3=0,
ChannelMode_presence4=0, ChannelMode_presence5=0,
ChannelMode_presence6=0, ChannelMode_presence7=0,
ChannelDescription=0, ChannelMode2_presence=0,
MobileAllocation_presence=0, StartingTime_presence=0,
FrequencyList_presence1=0,
ChannelDescription2_presence=0,
ChannelDescription_presence=0,
FrequencyChannelSequence_presence=0,
MobileAllocation_presence1=0,
CipherModeSetting_presence=0,
VgcsTargetModeIdentication_presence=0,
MultiRateConfiguration_presence=0):
"""ASSIGNMENT COMMAND Section 9.1.2"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2e) # 101110
c = ChannelDescription2()
d = PowerCommand()
packet = a / b / c / d
if FrequencyList_presence is 1:
e = FrequencyListHdr(ieiFL=0x05, eightBitFL=0x0)
packet = packet / e
if CellChannelDescription_presence is 1:
f = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0)
packet = packet / f
if MultislotAllocation_presence is 1:
g = MultislotAllocationHdr(ieiMSA=0x10, eightBitMSA=0x0)
packet = packet / g
if ChannelMode_presence is 1:
h = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0)
packet = packet / h
if ChannelMode_presence1 is 1:
i = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0)
packet = packet / i
if ChannelMode_presence2 is 1:
j = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0)
packet = packet / j
if ChannelMode_presence3 is 1:
k = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0)
packet = packet / k
if ChannelMode_presence4 is 1:
l = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0)
packet = packet / l
if ChannelMode_presence5 is 1:
m = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0)
packet = packet / m
if ChannelMode_presence6 is 1:
n = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0)
packet = packet / n
if ChannelMode_presence7 is 1:
o = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0)
packet = packet / o
if ChannelDescription_presence is 1:
p = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0)
packet = packet / p
if ChannelMode2_presence is 1:
q = ChannelMode2Hdr(ieiCM2=0x66, eightBitCM2=0x0)
packet = packet / q
if MobileAllocation_presence is 1:
r = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0)
packet = packet / r
if StartingTime_presence is 1:
s = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / s
if FrequencyList_presence1 is 1:
t = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0)
packet = packet / t
if ChannelDescription2_presence is 1:
u = ChannelDescription2Hdr(ieiCD2=0x1C, eightBitCD2=0x0)
packet = packet / u
if ChannelDescription_presence is 1:
v = ChannelDescriptionHdr(ieiCD=0x1D, eightBitCD=0x0)
packet = packet / v
if FrequencyChannelSequence_presence is 1:
w = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0)
packet = packet / w
if MobileAllocation_presence1 is 1:
x = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0)
packet = packet / x
if CipherModeSetting_presence is 1:
y = CipherModeSettingHdr(ieiCMS=0x9, eightBitCMS=0x0)
packet = packet / y
if VgcsTargetModeIdentication_presence is 1:
z = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0)
packet = packet / z
if MultiRateConfiguration_presence is 1:
aa = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0)
packet = packet / aa
return packet
# MS to Network
def assignmentComplete():
"""ASSIGNMENT COMPLETE Section 9.1.3"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x29) # 00101001
c = RrCause()
packet = a / b / c
return packet
# MS to Network
def assignmentFailure():
"""ASSIGNMENT FAILURE Section 9.1.4"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2F) # 00101111
c = RrCause()
packet = a / b / c
return packet
# Network to MS
def channelModeModify(VgcsTargetModeIdentication_presence=0,
MultiRateConfiguration_presence=0):
"""CHANNEL MODE MODIFY Section 9.1.5"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x8) # 0001000
c = ChannelDescription2()
d = ChannelMode()
packet = a / b / c / d
if VgcsTargetModeIdentication is 1:
e = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0)
packet = packet / e
if MultiRateConfiguration is 1:
f = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0)
packet = packet / f
return packet
def channelModeModifyAcknowledge():
"""CHANNEL MODE MODIFY ACKNOWLEDGE Section 9.1.6"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x17) # 00010111
c = ChannelDescription2()
d = ChannelMode()
packet = a / b / c / d
return packet
# Network to MS
def channelRelease(BaRange_presence=0, GroupChannelDescription_presence=0,
GroupCipherKeyNumber_presence=0, GprsResumption_presence=0,
BaListPref_presence=0):
"""CHANNEL RELEASE Section 9.1.7"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0xD) # 00001101
c = RrCause()
packet = a / b / c
if BaRange_presence is 1:
d = BaRangeHdr(ieiBR=0x73, eightBitBR=0x0)
packet = packet / d
if GroupChannelDescription_presence is 1:
e = GroupChannelDescriptionHdr(ieiGCD=0x74, eightBitGCD=0x0)
packet = packet / e
if GroupCipherKeyNumber_presence is 1:
f = GroupCipherKeyNumber(ieiGCKN=0x8)
packet = packet / f
if GprsResumption_presence is 1:
g = GprsResumptionHdr(ieiGR=0xC, eightBitGR=0x0)
packet = packet / g
if BaListPref_presence is 1:
h = BaListPrefHdr(ieiBLP=0x75, eightBitBLP=0x0)
packet = packet / h
return packet
class ChannelRequest(Packet):
"""Channel request Section 9.1.8"""
name = "Channel Request"
fields_desc = [
ByteField("estCause", 0x0)
]
def channelRequest():
return ChannelRequest()
# Network to MS
def cipheringModeCommand():
"""CIPHERING MODE COMMAND Section 9.1.9"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x35) # 00110101
c = RrCause()
# d=cipherModeSetting()
# e=cipherResponse()
# FIX
d = CipherModeSettingAndcipherResponse()
packet = a / b / c / d
return packet
def cipheringModeComplete(MobileId_presence=0):
"""CIPHERING MODE COMPLETE Section 9.1.10"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x32) # 00110010
packet = a / b
if MobileId_presence is 1:
c = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0)
packet = packet / c
return packet
# Network to MS
def classmarkChange(MobileStationClassmark3_presence=0):
"""CLASSMARK CHANGE Section 9.1.11"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x16) # 00010110
c = MobileStationClassmark2()
packet = a / b / c
if MobileStationClassmark3_presence is 1:
e = MobileStationClassmark3(ieiMSC3=0x20)
packet = packet / e
return packet
# Network to MS
def classmarkEnquiry():
"""CLASSMARK ENQUIRY Section 9.1.12"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x13) # 00010011
packet = a / b
return packet
# 9.1.12a Spare
# Network to MS
def configurationChangeCommand(ChannelMode_presence=0,
ChannelMode_presence1=0,
ChannelMode_presence2=0,
ChannelMode_presence3=0,
ChannelMode_presence4=0,
ChannelMode_presence5=0,
ChannelMode_presence6=0,
ChannelMode_presence7=0):
"""CONFIGURATION CHANGE COMMAND Section 9.1.12b"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x30) # 00110000
c = MultislotAllocation()
packet = a / b / c
if ChannelMode_presence is 1:
d = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0)
packet = packet / d
if ChannelMode_presence1 is 1:
e = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0)
packet = packet / e
if ChannelMode_presence2 is 1:
f = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0)
packet = packet / f
if ChannelMode_presence3 is 1:
g = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0)
packet = packet / g
if ChannelMode_presence4 is 1:
h = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0)
packet = packet / h
if ChannelMode_presence5 is 1:
i = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0)
packet = packet / i
if ChannelMode_presence6 is 1:
j = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0)
packet = packet / j
if ChannelMode_presence7 is 1:
k = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0)
packet = packet / k
return packet
def configurationChangeAcknowledge():
"""CONFIGURATION CHANGE ACKNOWLEDGE Section 9.1.12c"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x31) # 00110001
c = MobileId()
packet = a / b / c
return packet
def configurationChangeReject():
"""CONFIGURATION CHANGE REJECT Section 9.1.12d"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x33) # 00110011
c = RrCause()
packet = a / b / c
return packet
# Network to MS
def frequencyRedefinition(CellChannelDescription_presence=0):
"""Frequency redefinition Section 9.1.13"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x14) # 00010100
c = ChannelDescription()
d = MobileAllocation()
e = StartingTime()
packet = a / b / c / d / e
if CellChannelDescription_presence is 1:
f = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0)
packet = packet / f
return packet
# Network to MS
def pdchAssignmentCommand(ChannelDescription_presence=0,
CellChannelDescription_presence=0,
MobileAllocation_presence=0,
StartingTime_presence=0, FrequencyList_presence=0,
ChannelDescription_presence1=0,
FrequencyChannelSequence_presence=0,
MobileAllocation_presence1=0,
PacketChannelDescription_presence=0,
DedicatedModeOrTBF_presence=0):
"""PDCH ASSIGNMENT COMMAND Section 9.1.13a"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x23) # 00100011
c = ChannelDescription()
packet = a / b / c
if ChannelDescription_presence is 1:
d = ChannelDescriptionHdr(ieiCD=0x62, eightBitCD=0x0)
packet = packet / d
if CellChannelDescription_presence is 1:
e = CellChannelDescriptionHdr(ieiCCD=0x05, eightBitCCD=0x0)
packet = packet / e
if MobileAllocation_presence is 1:
f = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0)
packet = packet / f
if StartingTime_presence is 1:
g = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / g
if FrequencyList_presence is 1:
h = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0)
packet = packet / h
if ChannelDescription_presence1 is 1:
i = ChannelDescriptionHdr(ieiCD=0x1C, eightBitCD=0x0)
packet = packet / i
if FrequencyChannelSequence_presence is 1:
j = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0)
packet = packet / j
if MobileAllocation_presence1 is 1:
k = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0)
packet = packet / k
if PacketChannelDescription_presence is 1:
l = PacketChannelDescription(ieiPCD=0x22)
packet = packet / l
if DedicatedModeOrTBF_presence is 1:
m = DedicatedModeOrTBFHdr(ieiDMOT=0x23, eightBitDMOT=0x0)
packet = packet / m
return packet
def gprsSuspensionRequest():
"""GPRS SUSPENSION REQUEST Section 9.1.13b"""
a = TpPd(pd=0x6)
b = MessageType()
c = Tlli()
d = RoutingAreaIdentification()
e = SuspensionCause()
packet = a / b / c / d / e
return packet
class HandoverAccess(Packet):
name = "Handover Access" # Section 9.1.14"
fields_desc = [
ByteField("handover", None),
]
# Network to MS
def handoverCommand(SynchronizationIndication_presence=0,
FrequencyShortList_presence=0, FrequencyList_presence=0,
CellChannelDescription_presence=0,
MultislotAllocation_presence=0,
ChannelMode_presence=0, ChannelMode_presence1=0,
ChannelMode_presence2=0,
ChannelMode_presence3=0, ChannelMode_presence4=0,
ChannelMode_presence5=0,
ChannelMode_presence6=0, ChannelMode_presence7=0,
ChannelDescription_presence1=0, ChannelMode2_presence=0,
FrequencyChannelSequence_presence=0,
MobileAllocation_presence=0,
StartingTime_presence=0, TimeDifference_presence=0,
TimingAdvance_presence=0,
FrequencyShortList_presence1=0,
FrequencyList_presence1=0,
ChannelDescription2_presence=0,
ChannelDescription_presence2=0,
FrequencyChannelSequence_presence1=0,
MobileAllocation_presence1=0,
CipherModeSetting_presence=0,
VgcsTargetModeIdentication_presence=0,
MultiRateConfiguration_presence=0):
"""HANDOVER COMMAND Section 9.1.15"""
name = "Handover Command"
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2b) # 00101011
c = CellDescription()
d = ChannelDescription2()
e = HandoverReference()
f = PowerCommandAndAccessType()
packet = a / b / c / d / e / f
if SynchronizationIndication_presence is 1:
g = SynchronizationIndicationHdr(ieiSI=0xD, eightBitSI=0x0)
packet = packet / g
if FrequencyShortList_presence is 1:
h = FrequencyShortListHdr(ieiFSL=0x02)
packet = packet / h
if FrequencyList_presence is 1:
i = FrequencyListHdr(ieiFL=0x05, eightBitFL=0x0)
packet = packet / i
if CellChannelDescription_presence is 1:
j = CellChannelDescriptionHdr(ieiCCD=0x62, eightBitCCD=0x0)
packet = packet / j
if MultislotAllocation_presence is 1:
k = MultislotAllocationHdr(ieiMSA=0x10, eightBitMSA=0x0)
packet = packet / k
if ChannelMode_presence is 1:
l = ChannelModeHdr(ieiCM=0x63, eightBitCM=0x0)
packet = packet / l
if ChannelMode_presence1 is 1:
m = ChannelModeHdr(ieiCM=0x11, eightBitCM=0x0)
packet = packet / m
if ChannelMode_presence2 is 1:
n = ChannelModeHdr(ieiCM=0x13, eightBitCM=0x0)
packet = packet / n
if ChannelMode_presence3 is 1:
o = ChannelModeHdr(ieiCM=0x14, eightBitCM=0x0)
packet = packet / o
if ChannelMode_presence4 is 1:
p = ChannelModeHdr(ieiCM=0x15, eightBitCM=0x0)
packet = packet / p
if ChannelMode_presence5 is 1:
q = ChannelModeHdr(ieiCM=0x16, eightBitCM=0x0)
packet = packet / q
if ChannelMode_presence6 is 1:
r = ChannelModeHdr(ieiCM=0x17, eightBitCM=0x0)
packet = packet / r
if ChannelMode_presence7 is 1:
s = ChannelModeHdr(ieiCM=0x18, eightBitCM=0x0)
packet = packet / s
if ChannelDescription_presence1 is 1:
s1 = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0)
packet = packet / s1
if ChannelMode2_presence is 1:
t = ChannelMode2Hdr(ieiCM2=0x66, eightBitCM2=0x0)
packet = packet / t
if FrequencyChannelSequence_presence is 1:
u = FrequencyChannelSequenceHdr(ieiFCS=0x69, eightBitFCS=0x0)
packet = packet / u
if MobileAllocation_presence is 1:
v = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0)
packet = packet / v
if StartingTime_presence is 1:
w = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / w
if TimeDifference_presence is 1:
x = TimeDifferenceHdr(ieiTD=0x7B, eightBitTD=0x0)
packet = packet / x
if TimingAdvance_presence is 1:
y = TimingAdvanceHdr(ieiTA=0x7D, eightBitTA=0x0)
packet = packet / y
if FrequencyShortList_presence1 is 1:
z = FrequencyShortListHdr(ieiFSL=0x12)
packet = packet / z
if FrequencyList_presence1 is 1:
aa = FrequencyListHdr(ieiFL=0x19, eightBitFL=0x0)
packet = packet / aa
if ChannelDescription2_presence is 1:
ab = ChannelDescription2Hdr(ieiCD2=0x1C, eightBitCD2=0x0)
packet = packet / ab
if ChannelDescription_presence2 is 1:
ac = ChannelDescriptionHdr(ieiCD=0x1D, eightBitCD=0x0)
packet = packet / ac
if FrequencyChannelSequence_presence1 is 1:
ad = FrequencyChannelSequenceHdr(ieiFCS=0x1E, eightBitFCS=0x0)
packet = packet / ad
if MobileAllocation_presence1 is 1:
ae = MobileAllocationHdr(ieiMA=0x21, eightBitMA=0x0)
packet = packet / ae
if CipherModeSetting_presence is 1:
af = CipherModeSettingHdr(ieiCMS=0x9, eightBitCMS=0x0)
packet = packet / af
if VgcsTargetModeIdentication_presence is 1:
ag = VgcsTargetModeIdenticationHdr(ieiVTMI=0x01, eightBitVTMI=0x0)
packet = packet / ag
if MultiRateConfiguration_presence is 1:
ah = MultiRateConfigurationHdr(ieiMRC=0x03, eightBitMRC=0x0)
packet = packet / ah
return packet
def handoverComplete(MobileTimeDifference_presence=0):
"""HANDOVER COMPLETE Section 9.1.16"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2c) # 00101100
c = RrCause()
packet = a / b / c
if MobileTimeDifference_presence is 1:
d = MobileTimeDifferenceHdr(ieiMTD=0x77, eightBitMTD=0x0)
packet = packet / d
return packet
def handoverFailure():
"""HANDOVER FAILURE Section 9.1.17"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x28) # 00101000
c = RrCause()
packet = a / b / c
return packet
# The L2 pseudo length of this message is the sum of lengths of all
# information elements present in the message except
# the IA Rest Octets and L2 Pseudo Length information elements.
# Network to MS
def immediateAssignment(ChannelDescription_presence=0,
PacketChannelDescription_presence=0,
StartingTime_presence=0):
"""IMMEDIATE ASSIGNMENT Section 9.1.18"""
a = L2PseudoLength()
b = TpPd(pd=0x6)
c = MessageType(mesType=0x3F) # 00111111
d = PageModeAndDedicatedModeOrTBF()
packet = a / b / c / d
if ChannelDescription_presence is 1:
f = ChannelDescription()
packet = packet / f
if PacketChannelDescription_presence is 1:
g = PacketChannelDescription()
packet = packet / g
h = RequestReference()
i = TimingAdvance()
j = MobileAllocation()
packet = packet / h / i / j
if StartingTime_presence is 1:
k = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / k
l = IaRestOctets()
packet = packet / l
return packet
# The L2 pseudo length of this message is the sum of lengths of all
# information elements present in the message except
# the IAX Rest Octets and L2 Pseudo Length information elements.
# Network to MS
def immediateAssignmentExtended(StartingTime_presence=0):
"""IMMEDIATE ASSIGNMENT EXTENDED Section 9.1.19"""
a = L2PseudoLength()
b = TpPd(pd=0x6)
c = MessageType(mesType=0x39) # 00111001
d = PageModeAndSpareHalfOctets()
f = ChannelDescription()
g = RequestReference()
h = TimingAdvance()
i = MobileAllocation()
packet = a / b / c / d / f / g / h / i
if StartingTime_presence is 1:
j = StartingTimeHdr(ieiST=0x7C, eightBitST=0x0)
packet = packet / j
k = IaxRestOctets()
packet = packet / k
return packet
# This message has L2 pseudo length 19
# Network to MS
def immediateAssignmentReject():
"""IMMEDIATE ASSIGNMENT REJECT Section 9.1.20"""
a = L2PseudoLength(l2pLength=0x13)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x3a) # 00111010
d = PageModeAndSpareHalfOctets()
f = RequestReference()
g = WaitIndication()
h = RequestReference()
i = WaitIndication()
j = RequestReference()
k = WaitIndication()
l = RequestReference()
m = WaitIndication()
n = IraRestOctets()
packet = a / b / c / d / f / g / h / i / j / k / l / m / n
return packet
def measurementReport():
"""MEASUREMENT REPORT Section 9.1.21"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x15) # 00010101
c = MeasurementResults()
packet = a / b / c
return packet
# len max 20
class NotificationFacch(object):
"""NOTIFICATION/FACCH Section 9.1.21a"""
name = "Notification/facch"
fields_desc = [
BitField("rr", 0x0, 1),
BitField("msgTyoe", 0x0, 5),
BitField("layer2Header", 0x0, 2),
BitField("frChanDes", 0x0, 24)
]
# The L2 pseudo length of this message has a value one
# Network to MS
def notificationNch():
"""NOTIFICATION/NCH Section 9.1.21b"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x20) # 00100000
d = NtNRestOctets()
packet = a / b / c / d
return packet
def notificationResponse():
"""NOTIFICATION RESPONSE Section 9.1.21d"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x26) # 00100110
c = MobileStationClassmark2()
d = MobileId()
e = DescriptiveGroupOrBroadcastCallReference()
packet = a / b / c / d / e
return packet
# Network to MS
def rrCellChangeOrder():
"""RR-CELL CHANGE ORDER Section 9.1.21e"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x8) # 00001000
c = CellDescription()
d = NcModeAndSpareHalfOctets()
packet = a / b / c / d
return packet
# Network to MS
def pagingRequestType1(MobileId_presence=0):
"""PAGING REQUEST TYPE 1 Section 9.1.22"""
# The L2 pseudo length of this message is the sum of lengths of all
# information elements present in the message except
# the P1 Rest Octets and L2 Pseudo Length information elements.
a = L2PseudoLength()
b = TpPd(pd=0x6)
c = MessageType(mesType=0x21) # 00100001
d = PageModeAndChannelNeeded()
f = MobileId()
packet = a / b / c / d / f
if MobileId_presence is 1:
g = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0)
packet = packet / g
h = P1RestOctets()
packet = packet / h
return packet
# The L2 pseudo length of this message is the sum of lengths of all
# information elements present in the message except
# Network to MS
def pagingRequestType2(MobileId_presence=0):
"""PAGING REQUEST TYPE 2 Section 9.1.23"""
a = L2PseudoLength()
b = TpPd(pd=0x6)
c = MessageType(mesType=0x22) # 00100010
d = PageModeAndChannelNeeded()
f = MobileId()
g = MobileId()
packet = a / b / c / d / f / g
if MobileId_presence is 1:
h = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0)
packet = packet / h
i = P2RestOctets()
packet = packet / i
return packet
# Network to MS
def pagingRequestType3():
"""PAGING REQUEST TYPE 3 Section 9.1.24"""
# This message has a L2 Pseudo Length of 19
a = L2PseudoLength(l2pLength=0x13)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x24) # 00100100
d = PageModeAndChannelNeeded()
e = TmsiPTmsi()
f = TmsiPTmsi()
g = TmsiPTmsi()
h = TmsiPTmsi()
i = P3RestOctets()
packet = a / b / c / d / e / f / g / h / i
return packet
def pagingResponse():
"""PAGING RESPONSE Section 9.1.25"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x27) # 00100111
c = CiphKeySeqNrAndSpareHalfOctets()
d = MobileStationClassmark2()
e = MobileId()
packet = a / b / c / d / e
return packet
# Network to MS
def partialRelease():
"""PARTIAL RELEASE Section 9.1.26"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0xa) # 00001010
c = ChannelDescription()
packet = a / b / c
return packet
def partialReleaseComplete():
"""PARTIAL RELEASE COMPLETE Section 9.1.27"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0xf) # 00001111
packet = a / b
return packet
# Network to MS
def physicalInformation():
"""PHYSICAL INFORMATION Section 9.1.28"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2d) # 00101101
c = TimingAdvance()
packet = a / b / c
return packet
def rrInitialisationRequest():
"""RR Initialisation Request Section 9.1.28.a"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x3c) # 00111100
c = CiphKeySeqNrAndMacModeAndChannelCodingRequest()
e = MobileStationClassmark2()
f = Tlli()
g = ChannelRequestDescription()
h = GprsMeasurementResults()
packet = a / b / c / e / f / g / h
return packet
def rrStatus():
"""RR STATUS Section 9.1.29"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x12) # 00010010
c = RrCause()
packet = a / b / c
return packet
# It does not
# follow the basic format. Its length is _25_ bits. The
# order of bit transmission is defined in GSM 04.04.
# Network to MS
class SynchronizationChannelInformation():
"""SYNCHRONIZATION CHANNEL INFORMATION Section 9.1.30"""
name = "Synchronization Channel Information"
fields_desc = [
BitField("bsic", 0x0, 5),
BitField("t1Hi", 0x0, 3),
ByteField("t1Mi", 0x0),
BitField("t1Lo", 0x0, 1),
BitField("t2", 0x0, 5),
BitField("t3Hi", 0x0, 2),
BitField("t3Lo", 0x0, 1)
]
# This message has a L2 Pseudo Length of 21.
# Network to MS
def systemInformationType1():
"""SYSTEM INFORMATION TYPE 1 Section 9.1.31"""
a = L2PseudoLength(l2pLength=0x15)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x19) # 00011001
d = CellChannelDescription()
e = RachControlParameters()
f = Si1RestOctets()
packet = a / b / c / d / e / f
return packet
# This message has a L2 Pseudo Length of 22.
# Network to MS
def systemInformationType2():
"""SYSTEM INFORMATION TYPE 2 Section 9.1.32"""
a = L2PseudoLength(l2pLength=0x16)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x1a) # 00011010
d = NeighbourCellsDescription()
e = NccPermitted()
f = RachControlParameters()
packet = a / b / c / d / e / f
return packet
# This message has a L2 pseudo length of 21
# Network to MS
def systemInformationType2bis():
"""SYSTEM INFORMATION TYPE 2bis Section 9.1.33"""
a = L2PseudoLength(l2pLength=0x15)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x2) # 00000010
d = NeighbourCellsDescription()
e = RachControlParameters()
f = Si2bisRestOctets()
packet = a / b / c / d / e / f
return packet
# This message has a L2 pseudo length of 18
# Network to MS
def systemInformationType2ter():
"""SYSTEM INFORMATION TYPE 2ter Section 9.1.34"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x3) # 00000011
d = NeighbourCellsDescription2()
e = Si2terRestOctets()
packet = a / b / c / d / e
return packet
# This message has a L2 Pseudo Length of 18
# Network to MS
def systemInformationType3():
"""SYSTEM INFORMATION TYPE 3 Section 9.1.35"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x1b) # 00011011
d = CellIdentity()
e = LocalAreaId()
f = ControlChannelDescription()
g = CellOptionsBCCH()
h = CellSelectionParameters()
i = RachControlParameters()
j = Si3RestOctets()
packet = a / b / c / d / e / f / g / h / i / j
return packet
# The L2 pseudo length of this message is the
# sum of lengths of all information elements present in the message except
# the SI 4 Rest Octets and L2 Pseudo Length
# Network to MS
def systemInformationType4(ChannelDescription_presence=0,
MobileAllocation_presence=0):
"""SYSTEM INFORMATION TYPE 4 Section 9.1.36"""
a = L2PseudoLength()
b = TpPd(pd=0x6)
c = MessageType(mesType=0x1C) # 000111100
d = LocalAreaId()
e = CellSelectionParameters()
f = RachControlParameters()
packet = a / b / c / d / e / f
if ChannelDescription_presence is 1:
g = ChannelDescriptionHdr(ieiCD=0x64, eightBitCD=0x0)
packet = packet / g
if MobileAllocation_presence is 1:
h = MobileAllocationHdr(ieiMA=0x72, eightBitMA=0x0)
packet = packet / h
i = Si4RestOctets()
packet = packet / i
return packet
# This message has a L2 Pseudo Length of 18
# Network to MS
def systemInformationType5():
"""SYSTEM INFORMATION TYPE 5 Section 9.1.37"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x35) # 000110101
d = NeighbourCellsDescription()
packet = a / b / c / d
return packet
# This message has a L2 Pseudo Length of 18
# Network to MS
def systemInformationType5bis():
"""SYSTEM INFORMATION TYPE 5bis Section 9.1.38"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x5) # 00000101
d = NeighbourCellsDescription()
packet = a / b / c / d
return packet
# This message has a L2 Pseudo Length of 18
# Network to MS
def systemInformationType5ter():
"""SYSTEM INFORMATION TYPE 5ter Section 9.1.39"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x6) # 00000110
d = NeighbourCellsDescription2()
packet = a / b / c / d
return packet
# This message has a L2 Pseudo Length of 11
# Network to MS
def systemInformationType6():
"""SYSTEM INFORMATION TYPE 6 Section 9.1.40"""
a = L2PseudoLength(l2pLength=0x0b)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x1e) # 00011011
d = CellIdentity()
e = LocalAreaId()
f = CellOptionsBCCH()
g = NccPermitted()
h = Si6RestOctets()
packet = a / b / c / d / e / f / g
return packet
# The L2 pseudo length of this message has the value 1
# Network to MS
def systemInformationType7():
"""SYSTEM INFORMATION TYPE 7 Section 9.1.41"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x37) # 000110111
d = Si7RestOctets()
packet = a / b / c / d
return packet
# The L2 pseudo length of this message has the value 1
# Network to MS
def systemInformationType8():
"""SYSTEM INFORMATION TYPE 8 Section 9.1.42"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x18) # 00011000
d = Si8RestOctets()
packet = a / b / c / d
return packet
# The L2 pseudo length of this message has the value 1
# Network to MS
def systemInformationType9():
"""SYSTEM INFORMATION TYPE 9 Section 9.1.43"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x4) # 00000100
d = Si9RestOctets()
packet = a / b / c / d
return packet
# The L2 pseudo length of this message has the value 0
# Network to MS
def systemInformationType13():
"""SYSTEM INFORMATION TYPE 13 Section 9.1.43a"""
a = L2PseudoLength(l2pLength=0x00)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x0) # 00000000
d = Si13RestOctets()
packet = a / b / c / d
return packet
#
# 9.1.43b / c spare
#
# The L2 pseudo length of this message has the value 1
# Network to MS
def systemInformationType16():
"""SYSTEM INFORMATION TYPE 16 Section 9.1.43d"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x3d) # 00111101
d = Si16RestOctets()
packet = a / b / c / d
return packet
# The L2 pseudo length of this message has the value 1
# Network to MS
def systemInformationType17():
"""SYSTEM INFORMATION TYPE 17 Section 9.1.43e"""
a = L2PseudoLength(l2pLength=0x01)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x3e) # 00111110
d = Si17RestOctets()
packet = a / b / c / d
return packet
def talkerIndication():
"""TALKER INDICATION Section 9.1.44"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x11) # 00010001
c = MobileStationClassmark2()
d = MobileId()
packet = a / b / c / d
return packet
class UplinkAccess():
"""UPLINK ACCESS Section 9.1.45"""
name = "Uplink Access"
fields_desc = [
ByteField("establishment", 0x0)
]
# Network to MS
def uplinkBusy():
"""UPLINK BUSY Section 9.1.46"""
name = "Uplink Busy"
a = TpPd(pd=0x6)
b = MessageType(mesType=0x2a) # 00101010
packet = a / b
return packet
# Network to MS
class UplinkFree():
"""UPLINK FREE Section 9.1.47"""
name = "Uplink Free"
fields_desc = [
BitField("pd", 0x0, 1),
BitField("msgType", 0x0, 5),
BitField("layer2Header", 0x0, 2),
BitField("uplinkAccess", 0x0, 1),
BitField("lOrH", 0x0, 1), # 0 for L, 1 for H
BitField("upIdCode", 0x0, 6),
]
def uplinkRelease():
"""UPLINK RELEASE Section 9.1.48"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0xe) # 00001110
c = RrCause()
packet = a / b / c
return packet
# Network to MS
def vgcsUplinkGrant():
"""VGCS UPLINK GRANT Section 9.1.49"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x9) # 00001001
c = RrCause()
d = RequestReference()
e = TimingAdvance()
packet = a / b / c / d / e
return packet
# Network to MS
def systemInformationType10():
"""SYSTEM INFORMATION TYPE 10 Section 9.1.50"""
name = "SyStem Information Type 10"
fields_desc = [
BitField("pd", 0x0, 1),
BitField("msgType", 0x0, 5),
BitField("layer2Header", 0x0, 2),
BitField("si10", 0x0, 160)
]
# Network to MS
# The L2 pseudo length of this message has the value 18
def extendedMeasurementOrder():
"""EXTENDED MEASUREMENT ORDER Section 9.1.51"""
a = L2PseudoLength(l2pLength=0x12)
b = TpPd(pd=0x6)
c = MessageType(mesType=0x37) # 00110111
d = ExtendedMeasurementFrequencyList()
packet = a / b / c / d
return packet
def extendedMeasurementReport():
"""EXTENDED MEASUREMENT REPORT Section 9.1.52"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x36) # 00110110
c = ExtendedMeasurementResults()
packet = a / b / c
return packet
def applicationInformation():
"""APPLICATION INFORMATION Section 9.1.53"""
a = TpPd(pd=0x6)
b = MessageType(mesType=0x38) # 00111000
c = ApduIDAndApduFlags()
e = ApduData()
packet = a / b / c / e
return packet
#
# 9.2 Messages for mobility management
#
# Network to MS
def authenticationReject():
"""AUTHENTICATION REJECT Section 9.2.1"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x11) # 00010001
packet = a / b
return packet
# Network to MS
def authenticationRequest():
"""AUTHENTICATION REQUEST Section 9.2.2"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x12) # 00010010
c = CiphKeySeqNrAndSpareHalfOctets()
d = AuthenticationParameterRAND()
packet = a / b / c / d
return packet
def authenticationResponse():
"""AUTHENTICATION RESPONSE Section 9.2.3"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x14) # 00010100
c = AuthenticationParameterSRES()
packet = a / b / c
return packet
def cmReestablishmentRequest(LocalAreaId_presence=0):
"""CM RE-ESTABLISHMENT REQUEST Section 9.2.4"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x28) # 00101000
c = CiphKeySeqNrAndSpareHalfOctets()
e = MobileStationClassmark2()
f = MobileId()
if LocalAreaId_presence is 1:
g = LocalAreaId(iei=0x13, eightbit=0x0)
packet = packet / g
packet = a / b / c / e / f
return packet
# Network to MS
def cmServiceAccept():
"""CM SERVICE ACCEPT Section 9.2.5"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x21) # 00100001
packet = a / b
return packet
# Network to MS
def cmServicePrompt():
"""CM SERVICE PROMPT Section 9.2.5a"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x25) # 00100101
c = PdAndSapi()
packet = a / b / c
return packet
# Network to MS
def cmServiceReject():
"""CM SERVICE REJECT Section 9.2.6"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x22) # 00100010
c = RejectCause()
packet = a / b / c
return packet
def cmServiceAbort():
"""CM SERVICE ABORT Section 9.2.7"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x23) # 00100011
packet = a / b
return packet
# Network to MS
def abort():
"""ABORT Section 9.2.8"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x29) # 00101001
c = RejectCause()
packet = a / b / c
return packet
def cmServiceRequest(PriorityLevel_presence=0):
"""CM SERVICE REQUEST Section 9.2.9"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x24) # 00100100
c = CmServiceTypeAndCiphKeySeqNr()
e = MobileStationClassmark2()
f = MobileId()
packet = a / b / c / e / f
if PriorityLevel_presence is 1:
g = PriorityLevelHdr(ieiPL=0x8, eightBitPL=0x0)
packet = packet / g
return packet
# Network to MS
def identityRequest():
"""IDENTITY REQUEST Section 9.2.10"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x8) # 00001000
c = IdentityTypeAndSpareHalfOctets()
packet = a / b / c
return packet
def identityResponse():
"""IDENTITY RESPONSE Section 9.2.11"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x9) # 00001001
c = MobileId()
packet = a / b / c
return packet
def imsiDetachIndication():
"""IMSI DETACH INDICATION Section 9.2.12"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x1) # 00000001
c = MobileStationClassmark1()
d = MobileId()
packet = a / b / c / d
return packet
# Network to MS
def locationUpdatingAccept(MobileId_presence=0,
FollowOnProceed_presence=0,
CtsPermission_presence=0):
"""LOCATION UPDATING ACCEPT Section 9.2.13"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x02) # 00000010
c = LocalAreaId()
packet = a / b / c
if MobileId_presence is 1:
d = MobileIdHdr(ieiMI=0x17, eightBitMI=0x0)
packet = packet / d
if FollowOnProceed_presence is 1:
e = FollowOnProceed(ieiFOP=0xA1)
packet = packet / e
if CtsPermission_presence is 1:
f = CtsPermissionHdr(ieiCP=0xA2, eightBitCP=0x0)
packet = packet / f
return packet
# Network to MS
def locationUpdatingReject():
"""LOCATION UPDATING REJECT Section 9.2.14"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x4) # 0x00000100
c = RejectCause()
packet = a / b / c
return packet
def locationUpdatingRequest():
"""LOCATION UPDATING REQUEST Section 9.2.15"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x8) # 00001000
c = LocationUpdatingTypeAndCiphKeySeqNr()
e = LocalAreaId()
f = MobileStationClassmark1()
g = MobileId()
packet = a / b / c / e / f / g
return packet
# Network to MS
def mmInformation(NetworkName_presence=0, NetworkName_presence1=0,
TimeZone_presence=0, TimeZoneAndTime_presence=0,
LsaIdentifier_presence=0):
"""MM INFORMATION Section 9.2.15a"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x32) # 00110010
packet = a / b
if NetworkName_presence is 1:
c = NetworkNameHdr(ieiNN=0x43, eightBitNN=0x0)
packet = packet / c
if NetworkName_presence1 is 1:
d = NetworkNameHdr(ieiNN=0x45, eightBitNN=0x0)
packet = packet / d
if TimeZone_presence is 1:
e = TimeZoneHdr(ieiTZ=0x46, eightBitTZ=0x0)
packet = packet / e
if TimeZoneAndTime_presence is 1:
f = TimeZoneAndTimeHdr(ieiTZAT=0x47, eightBitTZAT=0x0)
packet = packet / f
if LsaIdentifier_presence is 1:
g = LsaIdentifierHdr(ieiLI=0x48, eightBitLI=0x0)
packet = packet / g
return packet
def mmStatus():
"""MM STATUS Section 9.2.16"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x31) # 00110001
c = RejectCause()
packet = a / b / c
return packet
# Network to MS
def tmsiReallocationCommand():
"""TMSI REALLOCATION COMMAND Section 9.2.17"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x1a) # 00011010
c = LocalAreaId()
d = MobileId()
packet = a / b / c / d
return packet
def tmsiReallocationComplete():
"""TMSI REALLOCATION COMPLETE Section 9.2.18"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x1b) # 00011011
packet = a / b
return packet
def mmNull():
"""MM NULL Section 9.2.19"""
a = TpPd(pd=0x5)
b = MessageType(mesType=0x30) # 00110000
packet = a / b
return packet
#
# 9.3 Messages for circuit-switched call control
#
# Network to MS
def alertingNetToMs(Facility_presence=0, ProgressIndicator_presence=0,
UserUser_presence=0):
"""ALERTING Section 9.3.1.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1) # 00000001
packet = a / b
if Facility_presence is 1:
c = FacilityHdr(ieiF=0x1C)
packet = packet / c
if ProgressIndicator_presence is 1:
d = ProgressIndicatorHdr(ieiPI=0x1E)
packet = packet / d
if UserUser_presence is 1:
e = UserUserHdr(ieiUU=0x7E)
packet = packet / e
return packet
def alertingMsToNet(Facility_presence=0, UserUser_presence=0,
SsVersionIndicator_presence=0):
"""ALERTING Section 9.3.1.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1) # 00000001
packet = a / b
if Facility_presence is 1:
c = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / c
if UserUser_presence is 1:
d = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / d
if SsVersionIndicator_presence is 1:
e = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / e
return packet
def callConfirmed(RepeatIndicator_presence=0,
BearerCapability_presence=0, BearerCapability_presence1=0,
Cause_presence=0, CallControlCapabilities_presence=0):
"""CALL CONFIRMED Section 9.3.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x8) # 00001000
packet = a / b
if RepeatIndicator_presence is 1:
c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / c
if BearerCapability_presence is 1:
d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / d
if BearerCapability_presence1 is 1:
e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / e
if Cause_presence is 1:
f = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / f
if CallControlCapabilities_presence is 1:
g = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0)
packet = packet / g
return packet
# Network to MS
def callProceeding(RepeatIndicator_presence=0,
BearerCapability_presence=0,
BearerCapability_presence1=0,
Facility_presence=0, ProgressIndicator_presence=0,
PriorityLevel_presence=0):
"""CALL PROCEEDING Section 9.3.3"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2) # 00000010
packet = a / b
if RepeatIndicator_presence is 1:
c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / c
if BearerCapability_presence is 1:
d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / d
if BearerCapability_presence1 is 1:
e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / e
if Facility_presence is 1:
f = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / f
if ProgressIndicator_presence is 1:
g = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0)
packet = packet / g
if PriorityLevel_presence is 1:
h = PriorityLevelHdr(ieiPL=0x80, eightBitPL=0x0)
packet = packet / h
return packet
# Network to MS
def congestionControl(Cause_presence=0):
"""CONGESTION CONTROL Section 9.3.4"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x39) # 00111001
c = CongestionLevelAndSpareHalfOctets()
packet = a / b / c
if Cause_presence is 1:
e = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / e
return packet
# Network to MS
def connectNetToMs(Facility_presence=0, ProgressIndicator_presence=0,
ConnectedNumber_presence=0, ConnectedSubaddress_presence=0,
UserUser_presence=0):
"""CONNECT Section 9.3.5.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x7) # 00000111
packet = a / b
if Facility_presence is 1:
c = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / c
if ProgressIndicator_presence is 1:
d = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0)
packet = packet / d
if ConnectedNumber_presence is 1:
e = ConnectedNumberHdr(ieiCN=0x4C, eightBitCN=0x0)
packet = packet / e
if ConnectedSubaddress_presence is 1:
f = ConnectedSubaddressHdr(ieiCS=0x4D, eightBitCS=0x0)
packet = packet / f
if UserUser_presence is 1:
g = UserUserHdr(ieiUU=0x7F, eightBitUU=0x0)
packet = packet / g
return packet
def connectMsToNet(Facility_presence=0, ConnectedSubaddress_presence=0,
UserUser_presence=0, SsVersionIndicator_presence=0):
"""CONNECT Section 9.3.5.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x7) # 00000111
packet = a / b
if Facility_presence is 1:
c = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / c
if ConnectedSubaddress_presence is 1:
d = ConnectedSubaddressHdr(ieiCS=0x4D, eightBitCS=0x0)
packet = packet / d
if UserUser_presence is 1:
e = UserUserHdr(ieiUU=0x7F, eightBitUU=0x0)
packet = packet / e
if SsVersionIndicator_presence is 1:
f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / f
return packet
def connectAcknowledge():
"""CONNECT ACKNOWLEDGE Section 9.3.6"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0xf) # 00001111
packet = a / b
return packet
# Network to MS
def disconnectNetToMs(Facility_presence=0, ProgressIndicator_presence=0,
UserUser_presence=0, AllowedActions_presence=0):
"""DISCONNECT Section 9.3.7.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x25) # 00100101
c = Cause()
packet = a / b / c
if Facility_presence is 1:
d = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / d
if ProgressIndicator_presence is 1:
e = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0)
packet = packet / e
if UserUser_presence is 1:
f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / f
if AllowedActions_presence is 1:
g = AllowedActionsHdr(ieiAA=0x7B, eightBitAA=0x0)
packet = packet / g
return packet
def disconnectMsToNet(Facility_presence=0, UserUser_presence=0,
SsVersionIndicator_presence=0):
"""Disconnect Section 9.3.7.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x25) # 00100101
c = Cause()
packet = a / b / c
if Facility_presence is 1:
d = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / d
if UserUser_presence is 1:
e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / e
if SsVersionIndicator_presence is 1:
f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / f
return packet
def emergencySetup(BearerCapability_presence=0):
"""EMERGENCY SETUP Section 9.3.8"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0xe) # 00001110
packet = a / b
if BearerCapability_presence is 1:
c = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / c
return packet
# Network to MS
def facilityNetToMs():
"""FACILITY Section 9.3.9.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3a) # 00111010
c = Facility()
packet = a / b / c
return packet
def facilityMsToNet(SsVersionIndicator_presence=0):
"""FACILITY Section 9.3.9.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3a) # 00111010
c = Facility()
packet = a / b / c
if SsVersionIndicator_presence is 1:
d = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / d
return packet
def hold():
"""HOLD Section 9.3.10"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x18) # 00011000
packet = a / b
return packet
# Network to MS
def holdAcknowledge():
"""HOLD ACKNOWLEDGE Section 9.3.11"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x19) # 00011001
packet = a / b
return packet
# Network to MS
def holdReject():
"""HOLD REJECT Section 9.3.12"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1a) # 00011010
c = Cause()
packet = a / b / c
return packet
def modify(LowLayerCompatibility_presence=0,
HighLayerCompatibility_presence=0,
ReverseCallSetupDirection_presence=0):
"""MODIFY Section 9.3.13"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x17) # 00010111
c = BearerCapability()
packet = a / b / c
if LowLayerCompatibility_presence is 1:
d = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / d
if HighLayerCompatibility_presence is 1:
e = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / e
if ReverseCallSetupDirection_presence is 1:
f = ReverseCallSetupDirectionHdr(ieiRCSD=0xA3)
packet = packet / f
return packet
def modifyComplete(LowLayerCompatibility_presence=0,
HighLayerCompatibility_presence=0,
ReverseCallSetupDirection_presence=0):
"""MODIFY COMPLETE Section 9.3.14"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1f) # 00011111
c = BearerCapability()
packet = a / b / c
if LowLayerCompatibility_presence is 1:
d = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / d
if HighLayerCompatibility_presence is 1:
e = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / e
if ReverseCallSetupDirection_presence is 1:
f = ReverseCallSetupDirection(ieiRCSD=0xA3)
packet = packet / f
return packet
def modifyReject(LowLayerCompatibility_presence=0,
HighLayerCompatibility_presence=0):
"""MODIFY REJECT Section 9.3.15"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x13) # 00010011
c = BearerCapability()
d = Cause()
packet = a / b / c / d
if LowLayerCompatibility_presence is 1:
e = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / e
if HighLayerCompatibility_presence is 1:
f = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / f
return packet
def notify():
"""NOTIFY Section 9.3.16"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3e) # 00111110
c = NotificationIndicator()
packet = a / b / c
return packet
# Network to MS
def progress(UserUser_presence=0):
"""PROGRESS Section 9.3.17"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3) # 00000011
c = ProgressIndicator()
packet = a / b / c
if UserUser_presence is 1:
d = UserUserHdr()
packet = packet / d
return packet
# Network to MS
def ccEstablishment():
"""CC-ESTABLISHMENT Section 9.3.17a"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x4) # 00000100
c = SetupContainer()
packet = a / b / c
return packet
def ccEstablishmentConfirmed(RepeatIndicator_presence=0,
BearerCapability_presence=0,
BearerCapability_presence1=0,
Cause_presence=0):
"""CC-ESTABLISHMENT CONFIRMED Section 9.3.17b"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x6) # 00000110
packet = a / b
if RepeatIndicator_presence is 1:
c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / c
if BearerCapability_presence is 1:
d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / d
if BearerCapability_presence1 is 1:
e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / e
if Cause_presence is 1:
f = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / f
return packet
# Network to MS
def releaseNetToMs():
"""RELEASE Section 9.3.18.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2d) # 00101101
c = CauseHdr(ieiC=0x08, eightBitC=0x0)
d = CauseHdr(ieiC=0x08, eightBitC=0x0)
e = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = a / b / c / d / e / f
return packet
def releaseMsToNet(Cause_presence=0, Cause_presence1=0,
Facility_presence=0, UserUser_presence=0,
SsVersionIndicator_presence=0):
"""RELEASE Section 9.3.18.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2d) # 00101101
packet = a / b
if Cause_presence is 1:
c = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / c
if Cause_presence1 is 1:
d = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / d
if Facility_presence is 1:
e = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / e
if UserUser_presence is 1:
f = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / f
if SsVersionIndicator_presence is 1:
g = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / g
return packet
# Network to MS
def recall():
"""RECALL Section 9.3.18a"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0xb) # 00001011
c = RecallType()
d = Facility()
packet = a / b / c / d
return packet
# Network to MS
def releaseCompleteNetToMs(Cause_presence=0, Facility_presence=0,
UserUser_presence=0):
"""RELEASE COMPLETE Section 9.3.19.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2a) # 00101010
packet = a / b
if Cause_presence is 1:
c = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / c
if Facility_presence is 1:
d = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / d
if UserUser_presence is 1:
e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / e
return packet
def releaseCompleteMsToNet(Cause_presence=0, Facility_presence=0,
UserUser_presence=0, SsVersionIndicator_presence=0):
"""RELEASE COMPLETE Section 9.3.19.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2a) # 00101010
packet = a / b
if Cause_presence is 1:
c = CauseHdr(ieiC=0x08, eightBitC=0x0)
packet = packet / c
if Facility_presence is 1:
d = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / d
if UserUser_presence is 1:
e = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / e
if SsVersionIndicator_presence is 1:
f = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / f
return packet
def retrieve():
"""RETRIEVE Section 9.3.20"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1c) # 00011100
packet = a / b
return packet
# Network to MS
def retrieveAcknowledge():
"""RETRIEVE ACKNOWLEDGE Section 9.3.21"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1d) # 00011101
packet = a / b
return packet
# Network to MS
def retrieveReject():
"""RETRIEVE REJECT Section 9.3.22"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1e) # 00011110
c = Cause()
packet = a / b / c
return packet
# Network to MS
def setupMobileTerminated(RepeatIndicator_presence=0,
BearerCapability_presence=0,
BearerCapability_presence1=0,
Facility_presence=0, ProgressIndicator_presence=0,
Signal_presence=0,
CallingPartyBcdNumber_presence=0,
CallingPartySubaddress_presence=0,
CalledPartyBcdNumber_presence=0,
CalledPartySubaddress_presence=0,
# RecallType_presence=0,
RedirectingPartyBcdNumber_presence=0,
RedirectingPartySubaddress_presence=0,
RepeatIndicator_presence1=0,
LowLayerCompatibility_presence=0,
LowLayerCompatibility_presence1=0,
RepeatIndicator_presence2=0,
HighLayerCompatibility_presence=0,
HighLayerCompatibility_presence1=0,
UserUser_presence=0, PriorityLevel_presence=0,
AlertingPattern_presence=0):
"""SETUP Section 9.3.23.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x5) # 00000101
packet = a / b
if RepeatIndicator_presence is 1:
c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / c
if BearerCapability_presence is 1:
d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / d
if BearerCapability_presence1 is 1:
e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / e
if Facility_presence is 1:
f = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / f
if ProgressIndicator_presence is 1:
g = ProgressIndicatorHdr(ieiPI=0x1E, eightBitPI=0x0)
packet = packet / g
if Signal_presence is 1:
h = SignalHdr(ieiS=0x34, eightBitS=0x0)
packet = packet / h
if CallingPartyBcdNumber_presence is 1:
i = CallingPartyBcdNumberHdr(ieiCPBN=0x5C, eightBitCPBN=0x0)
packet = packet / i
if CallingPartySubaddress_presence is 1:
j = CallingPartySubaddressHdr(ieiCPS=0x5D, eightBitCPS=0x0)
packet = packet / j
if CalledPartyBcdNumber_presence is 1:
k = CalledPartyBcdNumberHdr(ieiCPBN=0x5E, eightBitCPBN=0x0)
packet = packet / k
if CalledPartySubaddress_presence is 1:
l = CalledPartySubaddressHdr(ieiCPS=0x6D, eightBitCPS=0x0)
packet = packet / l
if RedirectingPartyBcdNumber_presence is 1:
n = RedirectingPartyBcdNumberHdr(ieiRPBN=0x74, eightBitRPBN=0x0)
packet = packet / n
if RedirectingPartySubaddress_presence is 1:
m = RedirectingPartySubaddress_presence(ieiRPBN=0x75, eightBitRPBN=0x0)
packet = packet / m
if RepeatIndicator_presence1 is 1:
o = RepeatIndicatorHdr(ieiRI=0xD0, eightBitRI=0x0)
packet = packet / o
if LowLayerCompatibility_presence is 1:
p = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / p
if LowLayerCompatibility_presence1 is 1:
q = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / q
if RepeatIndicator_presence2 is 1:
r = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / r
if HighLayerCompatibility_presence is 1:
s = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / s
if HighLayerCompatibility_presence1 is 1:
t = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / t
if UserUser_presence is 1:
u = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / u
if PriorityLevel_presence is 1:
v = PriorityLevelHdr(ieiPL=0x8, eightBitPL=0x0)
packet = packet / v
if AlertingPattern_presence is 1:
w = AlertingPatternHdr(ieiAP=0x19, eightBitAP=0x0)
packet = packet / w
return packet
def setupMobileOriginated(RepeatIndicator_presence=0,
BearerCapability_presence=0,
BearerCapability_presence1=0,
Facility_presence=0,
CallingPartySubaddress_presence=0,
CalledPartyBcdNumber_presence=0,
CalledPartySubaddress_presence=0,
RepeatIndicator_presence1=0,
LowLayerCompatibility_presence=0,
LowLayerCompatibility_presence1=0,
RepeatIndicator_presence2=0,
HighLayerCompatibility_presence=0,
HighLayerCompatibility_presence1=0,
UserUser_presence=0, SsVersionIndicator_presence=0,
ClirSuppression_presence=0,
ClirInvocation_presence=0,
CallControlCapabilities_presence=0,
Facility_presence1=0,
Facility_presence2=0):
"""SETUP Section 9.3.23.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x5) # 00000101
packet = a / b
if RepeatIndicator_presence is 1:
c = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / c
if BearerCapability_presence is 1:
d = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / d
if BearerCapability_presence1 is 1:
e = BearerCapabilityHdr(ieiBC=0x04, eightBitBC=0x0)
packet = packet / e
if Facility_presence is 1:
f = FacilityHdr(ieiF=0x1C, eightBitF=0x0)
packet = packet / f
if CallingPartySubaddress_presence is 1:
g = CallingPartySubaddressHdr(ieiCPS=0x5D, eightBitCPS=0x0)
packet = packet / g
if CalledPartyBcdNumber_presence is 1:
h = CalledPartyBcdNumberHdr(ieiCPBN=0x5E, eightBitCPBN=0x0)
packet = packet / h
if CalledPartySubaddress_presence is 1:
i = CalledPartySubaddressHdr(ieiCPS=0x6D, eightBitCPS=0x0)
packet = packet / i
if RepeatIndicator_presence1 is 1:
j = RepeatIndicatorHdr(ieiRI=0xD0, eightBitRI=0x0)
packet = packet / j
if LowLayerCompatibility_presence is 1:
k = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / k
if LowLayerCompatibility_presence1 is 1:
l = LowLayerCompatibilityHdr(ieiLLC=0x7C, eightBitLLC=0x0)
packet = packet / l
if RepeatIndicator_presence2 is 1:
m = RepeatIndicatorHdr(ieiRI=0xD, eightBitRI=0x0)
packet = packet / m
if HighLayerCompatibility_presence is 1:
n = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / n
if HighLayerCompatibility_presence1 is 1:
o = HighLayerCompatibilityHdr(ieiHLC=0x7D, eightBitHLC=0x0)
packet = packet / o
if UserUser_presence is 1:
p = UserUserHdr(ieiUU=0x7E, eightBitUU=0x0)
packet = packet / p
if SsVersionIndicator_presence is 1:
q = SsVersionIndicatorHdr(ieiSVI=0x7F, eightBitSVI=0x0)
packet = packet / q
if ClirSuppression_presence is 1:
r = ClirSuppressionHdr(ieiCS=0xA1, eightBitCS=0x0)
packet = packet / r
if ClirInvocation_presence is 1:
s = ClirInvocationHdr(ieiCI=0xA2, eightBitCI=0x0)
packet = packet / s
if CallControlCapabilities_presence is 1:
t = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0)
packet = packet / t
if Facility_presence1 is 1:
u = FacilityHdr(ieiF=0x1D, eightBitF=0x0)
packet = packet / u
if Facility_presence2 is 1:
v = FacilityHdr(ieiF=0x1B, eightBitF=0x0)
packet = packet / v
return packet
def startCc(CallControlCapabilities_presence=0):
"""START CC Section 9.3.23a"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x9) # 00001001
packet = a / b
if CallControlCapabilities_presence is 1:
c = CallControlCapabilitiesHdr(ieiCCC=0x15, eightBitCCC=0x0)
packet = packet / c
return packet
def startDtmf():
"""START DTMF Section 9.3.24"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x35) # 00110101
c = KeypadFacilityHdr(ieiKF=0x2C, eightBitKF=0x0)
packet = a / b / c
return packet
# Network to MS
def startDtmfAcknowledge():
"""START DTMF ACKNOWLEDGE Section 9.3.25"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x32) # 00110010
c = KeypadFacilityHdr(ieiKF=0x2C, eightBitKF=0x0)
packet = a / b / c
return packet
# Network to MS
def startDtmfReject():
""" START DTMF REJECT Section 9.3.26"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x37) # 00110111
c = Cause()
packet = a / b / c
return packet
def status(AuxiliaryStates_presence=0):
"""STATUS Section 9.3.27"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3d) # 00111101
c = Cause()
d = CallState()
packet = a / b / c / d
if AuxiliaryStates_presence is 1:
e = AuxiliaryStatesHdr(ieiAS=0x24, eightBitAS=0x0)
packet = packet / e
return packet
def statusEnquiry():
"""STATUS ENQUIRY Section 9.3.28"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x34) # 00110100
packet = a / b
return packet
def stopDtmf():
"""STOP DTMF Section 9.3.29"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x31) # 00110001
packet = a / b
return packet
# Network to MS
def stopDtmfAcknowledge():
"""STOP DTMF ACKNOWLEDGE Section 9.3.30"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x32) # 00110010
packet = a / b
return packet
def userInformation(MoreData_presence=0):
"""USER INFORMATION Section 9.3.31"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x20) # 000100000
c = UserUser()
packet = a / b / c
if MoreData_presence is 1:
d = MoreDataHdr(ieiMD=0xA0, eightBitMD=0x0)
packet = packet / d
return packet
#
# 9.4 GPRS Mobility Management Messages
#
def attachRequest(PTmsiSignature_presence=0, GprsTimer_presence=0,
TmsiStatus_presence=0):
"""ATTACH REQUEST Section 9.4.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1) # 0000001
c = MsNetworkCapability()
d = AttachTypeAndCiphKeySeqNr()
f = DrxParameter()
g = MobileId()
h = RoutingAreaIdentification()
i = MsRadioAccessCapability()
packet = a / b / c / d / f / g / h / i
if PTmsiSignature_presence is 1:
j = PTmsiSignature(ieiPTS=0x19)
packet = packet / j
if GprsTimer_presence is 1:
k = GprsTimer(ieiGT=0x17)
packet = packet / k
if TmsiStatus_presence is 1:
l = TmsiStatus(ieiTS=0x9)
packet = packet / l
return packet
def attachAccept(PTmsiSignature_presence=0, GprsTimer_presence=0,
MobileId_presence=0, MobileId_presence1=0,
GmmCause_presence=0):
"""ATTACH ACCEPT Section 9.4.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x2) # 00000010
c = AttachResult()
d = ForceToStandby()
e = GprsTimer()
f = RadioPriorityAndSpareHalfOctets()
h = RoutingAreaIdentification()
packet = a / b / c / d / e / f / h
if PTmsiSignature_presence is 1:
i = PTmsiSignature(ieiPTS=0x19)
packet = packet / i
if GprsTimer_presence is 1:
j = GprsTimer(ieiGT=0x17)
packet = packet / j
if MobileId_presence is 1:
k = MobileIdHdr(ieiMI=0x18, eightBitMI=0x0)
packet = packet / k
if MobileId_presence1 is 1:
l = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0)
packet = packet / l
if GmmCause_presence is 1:
m = GmmCause(ieiGC=0x25)
packet = packet / m
return packet
def attachComplete():
"""ATTACH COMPLETE Section 9.4.3"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x3) # 00000011
packet = a / b
return packet
def attachReject():
"""ATTACH REJECT Section 9.4.4"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x1) # 00000001
c = GmmCause()
packet = a / b / c
return packet
def detachRequest(GmmCause_presence=0):
"""DETACH REQUEST Section 9.4.5"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x5) # 00000101
c = DetachTypeAndForceToStandby()
packet = a / b / c
if GmmCause_presence is 1:
e = GmmCause(ieiGC=0x25)
packet = packet / e
return packet
def detachRequestMsOriginating():
"""DETACH REQUEST Section 9.4.5.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x5) # 00000101
c = DetachTypeAndSpareHalfOctets()
packet = a / b / c
return packet
def detachAcceptMsTerminated():
"""DETACH ACCEPT Section 9.4.6.1"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x6) # 00000110
packet = a / b
return packet
def detachAcceptMsOriginating():
"""DETACH ACCEPT Section 9.4.6.2"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x6) # 00000110
c = ForceToStandbyAndSpareHalfOctets()
packet = a / b / c
return packet
def ptmsiReallocationCommand(PTmsiSignature_presence=0):
"""P-TMSI REALLOCATION COMMAND Section 9.4.7"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x10) # 00010000
c = MobileId()
d = RoutingAreaIdentification()
e = ForceToStandbyAndSpareHalfOctets()
packet = a / b / c / d / e
if PTmsiSignature_presence is 1:
g = PTmsiSignature(ieiPTS=0x19)
packet = packet / g
return packet
def ptmsiReallocationComplete():
"""P-TMSI REALLOCATION COMPLETE Section 9.4.8"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x11) # 00010001
packet = a / b
return packet
def authenticationAndCipheringRequest(
AuthenticationParameterRAND_presence=0,
CiphKeySeqNr_presence=0):
"""AUTHENTICATION AND CIPHERING REQUEST Section 9.4.9"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x12) # 00010010
d = CipheringAlgorithmAndImeisvRequest()
e = ForceToStandbyAndAcReferenceNumber()
packet = a / b / d / e
if AuthenticationParameterRAND_presence is 1:
g = AuthenticationParameterRAND(ieiAPR=0x21)
packet = packet / g
if CiphKeySeqNr_presence is 1:
h = CiphKeySeqNrHdr(ieiCKSN=0x08, eightBitCKSN=0x0)
packet = packet / h
return packet
def authenticationAndCipheringResponse(
AuthenticationParameterSRES_presence=0,
MobileId_presence=0):
"""AUTHENTICATION AND CIPHERING RESPONSE Section 9.4.10"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x13) # 00010011
c = AcReferenceNumberAndSpareHalfOctets()
packet = a / b / c
if AuthenticationParameterSRES_presence is 1:
e = AuthenticationParameterSRES(ieiAPS=0x22)
packet = packet / e
if MobileId_presence is 1:
f = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0)
packet = packet / f
return packet
def authenticationAndCipheringReject():
"""AUTHENTICATION AND CIPHERING REJECT Section 9.4.11"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x14) # 00010100
packet = a / b
return packet
def identityRequest():
"""IDENTITY REQUEST Section 9.4.12"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x15) # 00010101
c = IdentityType2AndforceToStandby()
packet = a / b / c
return packet
def identityResponse():
"""IDENTITY RESPONSE Section 9.4.13"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x16) # 00010110
c = MobileId()
packet = a / b / c
return packet
def routingAreaUpdateRequest(PTmsiSignature_presence=0,
GprsTimer_presence=0,
DrxParameter_presence=0,
TmsiStatus_presence=0):
"""ROUTING AREA UPDATE REQUEST Section 9.4.14"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x8) # 00001000
c = UpdateTypeAndCiphKeySeqNr()
e = RoutingAreaIdentification()
f = MsNetworkCapability()
packet = a / b / c / e / f
if PTmsiSignature_presence is 1:
g = PTmsiSignature(ieiPTS=0x19)
packet = packet / g
if GprsTimer_presence is 1:
h = GprsTimer(ieiGT=0x17)
packet = packet / h
if DrxParameter_presence is 1:
i = DrxParameter(ieiDP=0x27)
packet = packet / i
if TmsiStatus_presence is 1:
j = TmsiStatus(ieiTS=0x9)
packet = packet / j
return packet
def routingAreaUpdateAccept(PTmsiSignature_presence=0,
MobileId_presence=0, MobileId_presence1=0,
ReceiveNpduNumbersList_presence=0,
GprsTimer_presence=0, GmmCause_presence=0):
"""ROUTING AREA UPDATE ACCEPT Section 9.4.15"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x9) # 00001001
c = ForceToStandbyAndUpdateResult()
e = GprsTimer()
f = RoutingAreaIdentification()
packet = a / b / c / e / f
if PTmsiSignature_presence is 1:
g = PTmsiSignature(ieiPTS=0x19)
packet = packet / g
if MobileId_presence is 1:
h = MobileIdHdr(ieiMI=0x18, eightBitMI=0x0)
packet = packet / h
if MobileId_presence1 is 1:
i = MobileIdHdr(ieiMI=0x23, eightBitMI=0x0)
packet = packet / i
if ReceiveNpduNumbersList_presence is 1:
j = ReceiveNpduNumbersList(ieiRNNL=0x26)
packet = packet / j
if GprsTimer_presence is 1:
k = GprsTimer(ieiGT=0x17)
packet = packet / k
if GmmCause_presence is 1:
l = GmmCause(ieiGC=0x25)
packet = packet / l
return packet
def routingAreaUpdateComplete(ReceiveNpduNumbersList_presence=0):
"""ROUTING AREA UPDATE COMPLETE Section 9.4.16"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0xa) # 00001010
packet = a / b
if ReceiveNpduNumbersList_presence is 1:
c = ReceiveNpduNumbersList(ieiRNNL=0x26)
packet = packet / c
return packet
def routingAreaUpdateReject():
"""ROUTING AREA UPDATE REJECT Section 9.4.17"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0xb) # 00001011
c = GmmCause()
d = ForceToStandbyAndSpareHalfOctets()
packet = a / b / c / d
return packet
def gmmStatus():
"""GMM STATUS Section 9.4.18"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x20) # 00100000
c = GmmCause()
packet = a / b / c
return packet
def gmmInformation(NetworkName_presence=0, NetworkName_presence1=0,
TimeZone_presence=0, TimeZoneAndTime_presence=0,
LsaIdentifier_presence=0):
"""GMM INFORMATION Section 9.4.19"""
a = TpPd(pd=0x3)
b = MessageType(mesType=0x21) # 00100001
packet = a / b
if NetworkName_presence is 1:
c = NetworkNameHdr(ieiNN=0x43, eightBitNN=0x0)
packet = packet / c
if NetworkName_presence1 is 1:
d = NetworkNameHdr(ieiNN=0x45, eightBitNN=0x0)
packet = packet / d
if TimeZone_presence is 1:
e = TimeZoneHdr(ieiTZ=0x46, eightBitTZ=0x0)
packet = packet / e
if TimeZoneAndTime_presence is 1:
f = TimeZoneAndTimeHdr(ieiTZAT=0x47, eightBitTZAT=0x0)
packet = packet / f
if LsaIdentifier_presence is 1:
g = LsaIdentifierHdr(ieiLI=0x48, eightBitLI=0x0)
packet = packet / g
return packet
#
# 9.5 GPRS Session Management Messages
#
def activatePdpContextRequest(AccessPointName_presence=0,
ProtocolConfigurationOptions_presence=0):
"""ACTIVATE PDP CONTEXT REQUEST Section 9.5.1"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x41) # 01000001
c = NetworkServiceAccessPointIdentifier()
d = LlcServiceAccessPointIdentifier()
e = QualityOfService()
f = PacketDataProtocolAddress()
packet = a / b / c / d / e / f
if AccessPointName_presence is 1:
g = AccessPointName(ieiAPN=0x28)
packet = packet / g
if ProtocolConfigurationOptions_presence is 1:
h = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / h
return packet
def activatePdpContextAccept(PacketDataProtocolAddress_presence=0,
ProtocolConfigurationOptions_presence=0):
"""ACTIVATE PDP CONTEXT ACCEPT Section 9.5.2"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x42) # 01000010
c = LlcServiceAccessPointIdentifier()
d = QualityOfService()
e = RadioPriorityAndSpareHalfOctets()
packet = a / b / c / d / e
if PacketDataProtocolAddress_presence is 1:
f = PacketDataProtocolAddress(ieiPDPA=0x2B)
packet = packet / f
if ProtocolConfigurationOptions_presence is 1:
g = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / g
return packet
def activatePdpContextReject(ProtocolConfigurationOptions_presence=0):
"""ACTIVATE PDP CONTEXT REJECT Section 9.5.3"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x43) # 01000011
c = SmCause()
packet = a / b / c
if ProtocolConfigurationOptions_presence is 1:
d = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / d
return packet
def requestPdpContextActivation(AccessPointName_presence=0):
"""REQUEST PDP CONTEXT ACTIVATION Section 9.5.4"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x44) # 01000100
c = PacketDataProtocolAddress()
packet = a / b / c
if AccessPointName_presence is 1:
d = AccessPointName(ieiAPN=0x28)
packet = packet / d
return packet
def requestPdpContextActivationReject():
"""REQUEST PDP CONTEXT ACTIVATION REJECT Section 9.5.5"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x45) # 01000101
c = SmCause()
packet = a / b / c
return packet
def modifyPdpContextRequest():
"""MODIFY PDP CONTEXT REQUEST Section 9.5.6"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x48) # 01001000
c = RadioPriorityAndSpareHalfOctets()
d = LlcServiceAccessPointIdentifier()
e = QualityOfService()
packet = a / b / c / d / e
return packet
def modifyPdpContextAccept():
"""MODIFY PDP CONTEXT ACCEPT Section 9.5.7"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x45) # 01000101
packet = a / b
return packet
def deactivatePdpContextRequest():
"""DEACTIVATE PDP CONTEXT REQUEST Section 9.5.8"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x46) # 01000110
c = SmCause()
packet = a / b / c
return packet
def deactivatePdpContextAccept():
"""DEACTIVATE PDP CONTEXT ACCEPT Section 9.5.9"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x47) # 01000111
packet = a / b
return packet
def activateAaPdpContextRequest(AccessPointName_presence=0,
ProtocolConfigurationOptions_presence=0,
GprsTimer_presence=0):
"""ACTIVATE AA PDP CONTEXT REQUEST Section 9.5.10"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x50) # 01010000
c = NetworkServiceAccessPointIdentifier()
d = LlcServiceAccessPointIdentifier()
e = QualityOfService()
f = PacketDataProtocolAddress()
packet = a / b / c / d / e / f
if AccessPointName_presence is 1:
g = AccessPointName(ieiAPN=0x28)
packet = packet / g
if ProtocolConfigurationOptions_presence is 1:
h = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / h
if GprsTimer_presence is 1:
i = GprsTimer(ieiGT=0x29)
packet = packet / i
return packet
def activateAaPdpContextAccept(ProtocolConfigurationOptions_presence=0,
GprsTimer_presence=0):
"""ACTIVATE AA PDP CONTEXT ACCEPT Section 9.5.11"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x51) # 01010001
c = LlcServiceAccessPointIdentifier()
d = QualityOfService()
e = MobileId()
f = PacketDataProtocolAddress()
g = RadioPriorityAndSpareHalfOctets()
packet = a / b / c / d / e / f / g
if ProtocolConfigurationOptions_presence is 1:
i = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / i
if GprsTimer_presence is 1:
j = GprsTimer(ieiGT=0x29)
packet = packet / j
return packet
def activateAaPdpContextReject(ProtocolConfigurationOptions_presence=0):
"""ACTIVATE AA PDP CONTEXT REJECT Section 9.5.12"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x52) # 01010010
c = SmCause()
packet = a / b / c
if ProtocolConfigurationOptions_presence is 1:
d = ProtocolConfigurationOptions(ieiPCO=0x27)
packet = packet / d
return packet
def deactivateAaPdpContextRequest():
"""DEACTIVATE AA PDP CONTEXT REQUEST Section 9.5.13"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x53) # 01010011
c = AaDeactivationCauseAndSpareHalfOctets()
packet = a / b / c
return packet
def deactivateAaPdpContextAccept():
"""DEACTIVATE AA PDP CONTEXT ACCEPT Section 9.5.14"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x54) # 01010100
packet = a / b
return packet
def smStatus():
"""SM STATUS Section 9.5.15"""
a = TpPd(pd=0x8)
b = MessageType(mesType=0x55) # 01010101
c = SmCause()
packet = a / b / c
return packet
# ============================================#
# Information Elements contents (Section 10) #
# =========================================== #
####
# This section contains the elements we need to build the messages
####
#
# Common information elements:
#
class CellIdentityHdr(Packet):
""" Cell identity Section 10.5.1.1 """
name = "Cell Identity"
fields_desc = [
BitField("eightBitCI", None, 1),
XBitField("ieiCI", None, 7),
ByteField("ciValue1", 0x0),
ByteField("ciValue2", 0x0)
]
class CiphKeySeqNrHdr(Packet):
""" Ciphering Key Sequence Number Section 10.5.1.2 """
name = "Cipher Key Sequence Number"
fields_desc = [
XBitField("ieiCKSN", None, 4),
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3)
]
# Fix 1/2 len problem
class CiphKeySeqNrAndSpareHalfOctets(Packet):
name = "Cipher Key Sequence Number and Spare Half Octets"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3),
BitField("spareHalfOctets", 0x0, 4)
]
# Fix 1/2 len problem
class CiphKeySeqNrAndMacModeAndChannelCodingRequest(Packet):
name = "Cipher Key Sequence Number and Mac Mode And Channel Coding Request"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3),
BitField("macMode", 0x0, 2),
BitField("cs", 0x0, 2)
]
class LocalAreaIdHdr(Packet):
""" Local Area Identification Section 10.5.1.3 """
name = "Location Area Identification"
fields_desc = [
BitField("eightBitLAI", None, 1),
XBitField("ieiLAI", None, 7),
BitField("mccDigit2", 0x0, 4),
BitField("mccDigit1", 0x0, 4),
BitField("mncDigit3", 0x0, 4),
BitField("mccDigit3", 0x0, 4),
BitField("mncDigit2", 0x0, 4),
BitField("mncDigit1", 0x0, 4),
ByteField("lac1", 0x0),
ByteField("lac2", 0x0)
]
#
# The Mobile Identity is a type 4 information element with a minimum
# length of 3 octet and 11 octets length maximal.
#
# len 3 - 11
class MobileIdHdr(Packet):
""" Mobile Identity Section 10.5.1.4 """
name = "Mobile Identity"
fields_desc = [
BitField("eightBitMI", 0x0, 1),
XBitField("ieiMI", 0x0, 7),
XByteField("lengthMI", None),
BitField("idDigit1", 0x0, 4),
BitField("oddEven", 0x0, 1),
BitField("typeOfId", 0x0, 3),
# optional
] + list(itertools.chain(*[[
BitField("idDigit%d_1" % x, None, 4),
BitField("idDigit%d" % x, None, 4),
] for x in range(2, 10)]))
def post_build(self, p, pay):
# this list holds the values of the variables, the
# INTERESTING value!
a = [getattr(self, fld.name, None) for fld in self.fields_desc]
res = _adapt(3, 11, a, self.fields_desc)
if self.lengthMI is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MobileStationClassmark1Hdr(Packet):
""" Mobile Station Classmark 1 Section 10.5.1.5 """
name = "Mobile Station Classmark 1"
fields_desc = [
BitField("eightBitiMSC1", None, 1),
XBitField("ieiMSC1", None, 7),
BitField("spare", 0x0, 1),
BitField("revisionLvl", 0x0, 2),
BitField("esInd", 0x0, 1),
BitField("a51", 0x0, 1),
BitField("rfPowerCap", 0x0, 3)
]
class MobileStationClassmark2Hdr(Packet):
""" Mobile Station Classmark 2 Section 10.5.1.6 """
name = "Mobile Station Classmark 2"
fields_desc = [
BitField("eightBitMSC2", None, 1),
XBitField("ieiMSC2", None, 7),
XByteField("lengthMSC2", 0x3),
BitField("spare", 0x0, 1),
BitField("revisionLvl", 0x0, 2),
BitField("esInd", 0x0, 1),
BitField("a51", 0x0, 1),
BitField("rfPowerCap", 0x0, 3),
BitField("spare1", 0x0, 1),
BitField("psCap", 0x0, 1),
BitField("ssScreenInd", 0x0, 2),
BitField("smCaPabi", 0x0, 1),
BitField("vbs", 0x0, 1),
BitField("vgcs", 0x0, 1),
BitField("fc", 0x0, 1),
BitField("cm3", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("lcsvaCap", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("soLsa", 0x0, 1),
BitField("cmsp", 0x0, 1),
BitField("a53", 0x0, 1),
BitField("a52", 0x0, 1)
]
# len max 14
class MobileStationClassmark3(Packet):
""" Mobile Station Classmark 3 Section 10.5.1.7 """
name = "Mobile Station Classmark 3"
fields_desc = [
# FIXME
ByteField("ieiMSC3", 0x0),
ByteField("byte2", 0x0),
ByteField("byte3", 0x0),
ByteField("byte4", 0x0),
ByteField("byte5", 0x0),
ByteField("byte6", 0x0),
ByteField("byte7", 0x0),
ByteField("byte8", 0x0),
ByteField("byte9", 0x0),
ByteField("byte10", 0x0),
ByteField("byte11", 0x0),
ByteField("byte12", 0x0),
ByteField("byte13", 0x0),
ByteField("byte14", 0x0)
]
class SpareHalfOctets(Packet):
""" Spare Half Octet Section 10.5.1.8 """
name = "Spare Half Octet"
fields_desc = [
BitField("filler", None, 4),
BitField("spareHalfOctets", 0x0, 4)
]
class DescriptiveGroupOrBroadcastCallReferenceHdr(Packet):
""" Descriptive group or broadcast call reference Section 10.5.1.9 """
name = "Descriptive Group or Broadcast Call Reference"
fields_desc = [
BitField("eightBitDGOBCR", None, 1),
XBitField("ieiDGOBCR", None, 7),
BitField("binCallRef", 0x0, 27),
BitField("sf", 0x0, 1),
BitField("fa", 0x0, 1),
BitField("callPrio", 0x0, 3),
BitField("cipherInfo", 0x0, 4),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("spare4", 0x0, 1)
]
class GroupCipherKeyNumber(Packet):
""" Group Cipher Key Number reference Section 10.5.1.10 """
name = "Group Cipher Key Number"
fields_desc = [
XBitField("ieiGCKN", None, 4),
BitField("groupCipher", 0x0, 4)
]
class PdAndSapiHdr(Packet):
""" PD and SAPI $(CCBS)$ Section 10.5.1.10a """
name = "PD and SAPI $(CCBS)$"
fields_desc = [
BitField("eightBitPAS", None, 1),
XBitField("ieiPAS", None, 7),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("sapi", 0x0, 2),
BitField("pd", 0x0, 4)
]
class PriorityLevelHdr(Packet):
""" Priority Level Section 10.5.1.11 """
name = "Priority Level"
fields_desc = [
XBitField("ieiPL", None, 4),
BitField("spare", 0x0, 1),
BitField("callPrio", 0x0, 3)
]
#
# Radio Resource management information elements
#
# len 6 to max for L3 message (251)
class BaRangeHdr(Packet):
""" BA Range Section 10.5.2.1a """
name = "BA Range"
fields_desc = [
BitField("eightBitBR", None, 1),
XBitField("ieiBR", None, 7),
XByteField("lengthBR", None),
# error: byte format requires -128 <= number <= 127
ByteField("nrOfRanges", 0x0),
# # rX = range X
# # L o = Lower H i = higher
# # H p = high Part Lp = low Part
ByteField("r1LoHp", 0x0),
BitField("r1LoLp", 0x0, 3),
BitField("r1HiHp", 0x0, 5),
BitField("r1HiLp", 0x0, 4),
BitField("r2LoHp", 0x0, 4),
# optional
BitField("r2LoLp", None, 5),
BitField("r2HiHp", None, 3),
ByteField("r2HiLp", None),
] + list(itertools.chain(*[[
ByteField("r%dLoHp" % x, None),
BitField("r%dLoLp" % x, None, 5),
BitField("r%dHiHp" % x, None, 3),
ByteField("r%dHiLp" % x, None),
] for x in range(3, 85)]))
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(6, 251, a, self.fields_desc)
if self.lengthBR is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 3 to max for L3 message (251)
class BaListPrefHdr(Packet):
""" BA List Pref Section 10.5.2.1c """
name = "BA List Pref"
fields_desc = [
# FIXME dynamic
BitField("eightBitBLP", None, 1),
XBitField("ieiBLP", None, 7),
XByteField("lengthBLP", None),
BitField("fixBit", 0x0, 1),
BitField("rangeLower", 0x0, 10),
BitField("fixBit2", 0x0, 1),
BitField("rangeUpper", 0x0, 10),
BitField("baFreq", 0x0, 10),
BitField("sparePad", 0x0, 8)
]
# len 17 || Have a look at the specs for the field format
# Bit map 0 format
# Range 1024 format
# Range 512 format
# Range 256 format
# Range 128 format
# Variable bit map format
class CellChannelDescriptionHdr(Packet):
""" Cell Channel Description Section 10.5.2.1b """
name = "Cell Channel Description "
fields_desc = [
BitField("eightBitCCD", None, 1),
XBitField("ieiCCD", None, 7),
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
ByteField("bit120", 0x0),
ByteField("bit112", 0x0),
ByteField("bit104", 0x0),
ByteField("bit96", 0x0),
ByteField("bit88", 0x0),
ByteField("bit80", 0x0),
ByteField("bit72", 0x0),
ByteField("bit64", 0x0),
ByteField("bit56", 0x0),
ByteField("bit48", 0x0),
ByteField("bit40", 0x0),
ByteField("bit32", 0x0),
ByteField("bit24", 0x0),
ByteField("bit16", 0x0),
ByteField("bit8", 0x0)
]
class CellDescriptionHdr(Packet):
""" Cell Description Section 10.5.2.2 """
name = "Cell Description"
fields_desc = [
BitField("eightBitCD", None, 1),
XBitField("ieiCD", None, 7),
BitField("bcchHigh", 0x0, 2),
BitField("ncc", 0x0, 3),
BitField("bcc", 0x0, 3),
ByteField("bcchLow", 0x0)
]
class CellOptionsBCCHHdr(Packet):
""" Cell Options (BCCH) Section 10.5.2.3 """
name = "Cell Options (BCCH)"
fields_desc = [
BitField("eightBitCOB", None, 1),
XBitField("ieiCOB", None, 7),
BitField("spare", 0x0, 1),
BitField("pwrc", 0x0, 1),
BitField("dtx", 0x0, 2),
BitField("rLinkTout", 0x0, 4)
]
class CellOptionsSACCHHdr(Packet):
""" Cell Options (SACCH) Section 10.5.2.3a """
name = "Cell Options (SACCH)"
fields_desc = [
BitField("eightBitCOS", None, 1),
XBitField("ieiCOS", None, 7),
BitField("dtx", 0x0, 1),
BitField("pwrc", 0x0, 1),
BitField("dtx", 0x0, 1),
BitField("rLinkTout", 0x0, 4)
]
class CellSelectionParametersHdr(Packet):
""" Cell Selection Parameters Section 10.5.2.4 """
name = "Cell Selection Parameters"
fields_desc = [
BitField("eightBitCSP", None, 1),
XBitField("ieiCSP", None, 7),
BitField("cellReselect", 0x0, 3),
BitField("msTxPwrMax", 0x0, 5),
BitField("acs", None, 1),
BitField("neci", None, 1),
BitField("rxlenAccMin", None, 6)
]
class MacModeAndChannelCodingRequestHdr(Packet):
""" MAC Mode and Channel Coding Requested Section 10.5.2.4a """
name = "MAC Mode and Channel Coding Requested"
fields_desc = [
XBitField("ieiMMACCR", None, 4),
BitField("macMode", 0x0, 2),
BitField("cs", 0x0, 2)
]
class ChannelDescriptionHdr(Packet):
""" Channel Description Section 10.5.2.5 """
name = "Channel Description"
fields_desc = [
BitField("eightBitCD", None, 1),
XBitField("ieiCD", None, 7),
BitField("channelTyp", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x1, 1),
# if h=1 maybe we find a better solution here...
BitField("maioHi", 0x0, 4),
BitField("maioLo", 0x0, 2),
BitField("hsn", 0x0, 6)
#BitField("spare", 0x0, 2),
#BitField("arfcnHigh", 0x0, 2),
#ByteField("arfcnLow", 0x0)
]
class ChannelDescription2Hdr(Packet):
""" Channel Description 2 Section 10.5.2.5a """
name = "Channel Description 2"
fields_desc = [
BitField("eightBitCD2", None, 1),
XBitField("ieiCD2", None, 7),
BitField("channelTyp", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x0, 1),
# if h=1
# BitField("maioHi", 0x0, 4),
# BitField("maioLo", 0x0, 2),
# BitField("hsn", 0x0, 6)
BitField("spare", 0x0, 2),
BitField("arfcnHigh", 0x0, 2),
ByteField("arfcnLow", 0x0)
]
class ChannelModeHdr(Packet):
""" Channel Mode Section 10.5.2.6 """
name = "Channel Mode"
fields_desc = [
BitField("eightBitCM", None, 1),
XBitField("ieiCM", None, 7),
ByteField("mode", 0x0)
]
class ChannelMode2Hdr(Packet):
""" Channel Mode 2 Section 10.5.2.7 """
name = "Channel Mode 2"
fields_desc = [
BitField("eightBitCM2", None, 1),
XBitField("ieiCM2", None, 7),
ByteField("mode", 0x0)
]
class ChannelNeededHdr(Packet):
""" Channel Needed Section 10.5.2.8 """
name = "Channel Needed"
fields_desc = [
XBitField("ieiCN", None, 4),
BitField("channel2", 0x0, 2),
BitField("channel1", 0x0, 2),
]
class ChannelRequestDescriptionHdr(Packet):
"""Channel Request Description Section 10.5.2.8a """
name = "Channel Request Description"
fields_desc = [
BitField("eightBitCRD", None, 1),
XBitField("ieiCRD", None, 7),
BitField("mt", 0x0, 1),
ConditionalField(BitField("spare", 0x0, 39),
lambda pkt: pkt.mt == 0),
ConditionalField(BitField("spare", 0x0, 3),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("priority", 0x0, 2),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("rlcMode", 0x0, 1),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("llcFrame", 0x1, 1),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("reqBandMsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("reqBandLsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("rlcMsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("rlcLsb", 0x0),
lambda pkt: pkt.mt == 1)
]
class CipherModeSettingHdr(Packet):
"""Cipher Mode Setting Section 10.5.2.9 """
name = "Cipher Mode Setting"
fields_desc = [
XBitField("ieiCMS", None, 4),
BitField("algoId", 0x0, 3),
BitField("sc", 0x0, 1),
]
class CipherResponseHdr(Packet):
"""Cipher Response Section 10.5.2.10 """
name = "Cipher Response"
fields_desc = [
XBitField("ieiCR", None, 4),
BitField("spare", 0x0, 3),
BitField("cr", 0x0, 1),
]
# This packet fixes the problem with the 1/2 Byte length. Concatenation
# of cipherModeSetting and cipherResponse
class CipherModeSettingAndcipherResponse(Packet):
name = "Cipher Mode Setting And Cipher Response"
fields_desc = [
BitField("algoId", 0x0, 3),
BitField("sc", 0x0, 1),
BitField("spare", 0x0, 3),
BitField("cr", 0x0, 1)
]
class ControlChannelDescriptionHdr(Packet):
"""Control Channel Description Section 10.5.2.11 """
name = "Control Channel Description"
fields_desc = [
BitField("eightBitCCD", None, 1),
XBitField("ieiCCD", None, 7),
BitField("spare", 0x0, 1),
BitField("att", 0x0, 1),
BitField("bsAgBlksRes", 0x0, 3),
BitField("ccchConf", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("spare4", 0x0, 1),
BitField("bsPaMfrms", 0x0, 3),
ByteField("t3212", 0x0)
]
class FrequencyChannelSequenceHdr(Packet):
"""Frequency Channel Sequence Section 10.5.2.12"""
name = "Frequency Channel Sequence"
fields_desc = [
BitField("eightBitFCS", None, 1),
XBitField("ieiFCS", None, 7),
BitField("spare", 0x0, 1),
BitField("lowestArfcn", 0x0, 7),
] + [BitField("skipArfcn%02d" % x, 0x0, 4) for x in range(1, 17)]
class FrequencyListHdr(Packet):
"""Frequency List Section 10.5.2.13"""
name = "Frequency List"
# Problem:
# There are several formats for the Frequency List information
# element, distinguished by the "format indicator" subfield.
# Some formats are frequency bit maps, the others use a special encoding
# scheme.
fields_desc = [
BitField("eightBitFL", None, 1),
XBitField("ieiFL", None, 7),
XByteField("lengthFL", None),
BitField("formatID", 0x0, 2),
BitField("spare", 0x0, 2),
BitField("arfcn124", 0x0, 1),
BitField("arfcn123", 0x0, 1),
BitField("arfcn122", 0x0, 1),
BitField("arfcn121", 0x0, 1),
ByteField("arfcn120", 0x0),
ByteField("arfcn112", 0x0),
ByteField("arfcn104", 0x0),
ByteField("arfcn96", 0x0),
ByteField("arfcn88", 0x0),
ByteField("arfcn80", 0x0),
ByteField("arfcn72", 0x0),
ByteField("arfcn64", 0x0),
ByteField("arfcn56", 0x0),
ByteField("arfcn48", 0x0),
ByteField("arfcn40", 0x0),
ByteField("arfcn32", 0x0),
ByteField("arfcn24", 0x0),
ByteField("arfcn16", 0x0),
ByteField("arfcn8", 0x0)
]
class FrequencyShortListHdr(Packet):
"""Frequency Short List Section 10.5.2.14"""
name = "Frequency Short List"
# len is 10
# This element is encoded exactly as the Frequency List information element,
# except that it has a fixed length instead of a
# variable length and does not contain a length indicator and that it
# shall not be encoded in bitmap 0 format.
fields_desc = [
ByteField("ieiFSL", 0x0),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 11)]
class FrequencyShortListHdr2(Packet):
"""Frequency Short List2 Section 10.5.2.14a"""
name = "Frequency Short List 2"
fields_desc = [
ByteField("byte%d" % x, 0x0) for x in range(1, 9)
]
# len 4 to 13
class GroupChannelDescriptionHdr(Packet):
"""Group Channel Description Section 10.5.2.14b"""
name = "Group Channel Description"
fields_desc = [
BitField("eightBitGCD", None, 1),
XBitField("ieiGCD", None, 7),
XByteField("lengthGCD", None),
BitField("channelType", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x0, 1),
# if h == 0 the packet looks the following way:
ConditionalField(BitField("spare", 0x0, 2),
lambda pkt: pkt. h == 0x0),
ConditionalField(BitField("arfcnHi", 0x0, 2),
lambda pkt: pkt. h == 0x0),
ConditionalField(ByteField("arfcnLo", None),
lambda pkt: pkt. h == 0x0),
# if h == 1 the packet looks the following way:
ConditionalField(BitField("maioHi", 0x0, 4),
lambda pkt: pkt. h == 0x1),
ConditionalField(BitField("maioLo", None, 2),
lambda pkt: pkt. h == 0x1),
ConditionalField(BitField("hsn", None, 6),
lambda pkt: pkt. h == 0x1),
# finished with conditional fields
] + [ByteField("maC%d" % x, None) for x in range(6, 15)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 13, a, self.fields_desc)
if self.lengthGCD is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class GprsResumptionHdr(Packet):
"""GPRS Resumption Section 10.5.2.14c"""
name = "GPRS Resumption"
fields_desc = [
XBitField("ieiGR", None, 4),
BitField("spare", 0x0, 3),
BitField("ack", 0x0, 1)
]
class HandoverReferenceHdr(Packet):
"""Handover Reference Section 10.5.2.15"""
name = "Handover Reference"
fields_desc = [
BitField("eightBitHR", None, 1),
XBitField("ieiHR", None, 7),
ByteField("handoverRef", 0x0)
]
# len 1-12
class IaRestOctets(Packet):
"""IA Rest Octets Section 10.5.2.16"""
name = "IA Rest Octets"
fields_desc = [
ByteField("ieiIRO", 0x0),
# FIXME brainfuck packet
XByteField("lengthIRO", None),
] + [ByteField("spare%d", None) for x in range(2, 12)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 12, a, self.fields_desc)
if self.lengthIRO is None:
if res[1] < 0: # FIXME better fix
res[1] = 0
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class IraRestOctetsHdr(Packet):
"""IAR Rest Octets Section 10.5.2.17"""
name = "IAR Rest Octets"
fields_desc = [
BitField("eightBitIRO", None, 1),
XBitField("ieiIRO", None, 7),
] + [BitField("spare%02d", 0x1, 1) for x in range(1, 25)]
# len is 1 to 5 what do we do with the variable size? no length
# field?! WTF
class IaxRestOctetsHdr(Packet):
"""IAX Rest Octets Section 10.5.2.18"""
name = "IAX Rest Octets"
fields_desc = [
BitField("eightBitIRO", None, 1),
XBitField("ieiIRO", None, 7),
BitField("spare01", 0x0, 1),
BitField("spare02", 0x0, 1),
BitField("spare03", 0x1, 1),
BitField("spare04", 0x0, 1),
BitField("spare05", 0x1, 1),
BitField("spare06", 0x0, 1),
BitField("spare07", 0x1, 1),
BitField("spare08", 0x1, 1),
ByteField("spareB1", None),
ByteField("spareB2", None),
ByteField("spareB3", None)
]
class L2PseudoLengthHdr(Packet):
"""L2 Pseudo Length Section 10.5.2.19"""
name = "L2 Pseudo Length"
fields_desc = [
BitField("eightBitPL", None, 1),
XBitField("ieiPL", None, 7),
BitField("l2pLength", None, 6),
BitField("bit2", 0x0, 1),
BitField("bit1", 0x1, 1)
]
class MeasurementResultsHdr(Packet):
"""Measurement Results Section 10.5.2.20"""
name = "Measurement Results"
fields_desc = [
BitField("eightBitMR", None, 1),
XBitField("ieiMR", None, 7),
BitField("baUsed", 0x0, 1),
BitField("dtxUsed", 0x0, 1),
BitField("rxLevFull", 0x0, 6),
BitField("spare", 0x0, 1),
BitField("measValid", 0x0, 1),
BitField("rxLevSub", 0x0, 6),
BitField("spare0", 0x0, 1),
BitField("rxqualFull", 0x0, 3),
BitField("rxqualSub", 0x0, 3),
BitField("noNcellHi", 0x0, 1),
BitField("noNcellLo", 0x0, 2),
BitField("rxlevC1", 0x0, 6),
BitField("bcchC1", 0x0, 5),
BitField("bsicC1Hi", 0x0, 3),
BitField("bsicC1Lo", 0x0, 3),
BitField("rxlevC2", 0x0, 5),
BitField("rxlevC2Lo", 0x0, 1),
BitField("bcchC2", 0x0, 5),
BitField("bsicC1Hi", 0x0, 2),
BitField("bscicC2Lo", 0x0, 4),
BitField("bscicC2Hi", 0x0, 4),
BitField("rxlevC3Lo", 0x0, 2),
BitField("bcchC3", 0x0, 5),
BitField("rxlevC3Hi", 0x0, 1),
BitField("bsicC3Lo", 0x0, 5),
BitField("bsicC3Hi", 0x0, 3),
BitField("rxlevC4Lo", 0x0, 3),
BitField("bcchC4", 0x0, 5),
BitField("bsicC4", 0x0, 6),
BitField("rxlevC5Hi", 0x0, 2),
BitField("rxlevC5Lo", 0x0, 4),
BitField("bcchC5Hi", 0x0, 4),
BitField("bcchC5Lo", 0x0, 1),
BitField("bsicC5", 0x0, 6),
BitField("rxlevC6", 0x0, 1),
BitField("rxlevC6Lo", 0x0, 5),
BitField("bcchC6Hi", 0x0, 3),
BitField("bcchC6Lo", 0x0, 3),
BitField("bsicC6", 0x0, 5)
]
class GprsMeasurementResultsHdr(Packet):
"""GPRS Measurement Results Section 10.5.2.20a"""
name = "GPRS Measurement Results"
fields_desc = [
BitField("eightBitGMR", None, 1),
XBitField("ieiGMR", None, 7),
BitField("cValue", 0x0, 6),
BitField("rxqualHi", 0x0, 2),
BitField("rxqL", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("signVar", 0x0, 6)
]
# len 3 to 10
class MobileAllocationHdr(Packet):
"""Mobile Allocation Section 10.5.2.21"""
name = "Mobile Allocation"
fields_desc = [
BitField("eightBitMA", None, 1),
XBitField("ieiMA", None, 7),
XByteField("lengthMA", None),
ByteField("maC64", 0x12),
ByteField("maC56", None), # optional fields start here
ByteField("maC48", None),
ByteField("maC40", None),
ByteField("maC32", None),
ByteField("maC24", None),
ByteField("maC16", None),
ByteField("maC8", None)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 10, a, self.fields_desc)
if self.lengthMA is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MobileTimeDifferenceHdr(Packet):
"""Mobile Time Difference Section 10.5.2.21a"""
name = "Mobile Time Difference"
fields_desc = [
BitField("eightBitMTD", None, 1),
XBitField("ieiMTD", None, 7),
XByteField("lengthMTD", 0x5),
ByteField("valueHi", 0x0),
ByteField("valueCnt", 0x0),
BitField("valueLow", 0x0, 5),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1)
]
# min 4 octets max 8
class MultiRateConfigurationHdr(Packet):
""" MultiRate configuration Section 10.5.2.21aa"""
name = "MultiRate Configuration"
fields_desc = [
BitField("eightBitMRC", None, 1),
XBitField("ieiMRC", None, 7),
XByteField("lengthMRC", None),
BitField("mrVersion", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("icmi", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("startMode", 0x0, 2),
ByteField("amrCodec", 0x0),
BitField("spare", None, 2),
BitField("threshold1", None, 6),
BitField("hysteresis1", None, 4),
BitField("threshold2", None, 4),
BitField("threshold2cnt", None, 2),
BitField("hysteresis2", None, 4),
BitField("threshold3", None, 2),
BitField("threshold3cnt", None, 4),
BitField("hysteresis3", None, 4)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 8, a, self.fields_desc)
if self.lengthMRC is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 3 to 12
class MultislotAllocationHdr(Packet):
"""Multislot Allocation Section 10.5.2.21b"""
name = "Multislot Allocation"
fields_desc = [
BitField("eightBitMSA", None, 1),
XBitField("ieiMSA", None, 7),
XByteField("lengthMSA", None),
BitField("ext0", 0x1, 1),
BitField("da", 0x0, 7),
ConditionalField(BitField("ext1", 0x1, 1), # optional
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("ua", 0x0, 7),
lambda pkt: pkt.ext0 == 0),
] + [ByteField("chan%d" % x, None) for x in range(1, 9)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 12, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthMSA is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
class NcModeHdr(Packet):
"""NC mode Section 10.5.2.21c"""
name = "NC Mode"
fields_desc = [
XBitField("ieiNM", None, 4),
BitField("spare", 0x0, 2),
BitField("ncMode", 0x0, 2)
]
# Fix for len problem
# concatenation NC Mode And Spare Half Octets
class NcModeAndSpareHalfOctets(Packet):
name = "NC Mode And Spare Half Octets"
fields_desc = [
BitField("spare", 0x0, 2),
BitField("ncMode", 0x0, 2),
BitField("spareHalfOctets", 0x0, 4)
]
class NeighbourCellsDescriptionHdr(Packet):
"""Neighbour Cells Description Section 10.5.2.22"""
name = "Neighbour Cells Description"
fields_desc = [
BitField("eightBitNCD", None, 1),
XBitField("ieiNCD", None, 7),
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("extInd", 0x0, 1),
BitField("baInd", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("120bits", 0x0, 120)
]
class NeighbourCellsDescription2Hdr(Packet):
"""Neighbour Cells Description 2 Section 10.5.2.22a"""
name = "Neighbour Cells Description 2"
fields_desc = [
BitField("eightBitNCD2", None, 1),
XBitField("ieiNCD2", None, 7),
BitField("bit128", 0x0, 1),
BitField("multiband", 0x0, 2),
BitField("baInd", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("120bits", 0x0, 120)
]
class NtNRestOctets(Packet):
"""NT/N Rest Octets Section 10.5.2.22c"""
name = "NT/N Rest Octets"
fields_desc = [
BitField("nln", 0x0, 2),
BitField("ncnInfo", 0x0, 4),
BitField("spare", 0x0, 2)
]
#
# The following packet has no length info!
#
# len 1-18
class P1RestOctets(Packet):
"""P1 Rest Octets Section 10.5.2.23"""
name = "P1 Rest Octets"
fields_desc = [
BitField("nln", 0x0, 2),
BitField("nlnStatus", 0x0, 1),
BitField("prio1", 0x0, 3),
BitField("prio2", 0x0, 3),
# optional
BitField("pageIndication1", 0x0, 1),
BitField("pageIndication2", 0x0, 1),
BitField("spare", 0x0, 5),
] + [ByteField("spareB%d" % x, None) for x in range(1, 17)]
# len 2-12
class P2RestOctets(Packet):
"""P2 Rest Octets Section 10.5.2.24"""
name = "P2 Rest Octets"
fields_desc = [
BitField("cn3", 0x0, 2),
BitField("nln", 0x0, 2),
BitField("nlnStatus", 0x0, 1),
BitField("prio1", 0x0, 3),
BitField("prio2", 0x0, 3),
BitField("prio3", 0x0, 3),
BitField("pageIndication3", 0x0, 1),
BitField("spare", 0x0, 1),
# optinal (No length field!)
] + [ByteField("spareB%d" % x, None) for x in range(1, 11)]
# len 4
class P3RestOctets(Packet):
"""P3 Rest Octets Section 10.5.2.25"""
name = "P3 Rest Octets"
fields_desc = [
BitField("cn3", 0x0, 2),
BitField("cn4", 0x0, 2),
BitField("nln", 0x0, 2),
BitField("nlnStatus", 0x0, 1),
BitField("prio1", 0x0, 3),
BitField("prio2", 0x0, 3),
BitField("prio3", 0x0, 3),
BitField("prio4", 0x0, 3),
BitField("spare", 0x0, 5)
]
# len 4
# strange packet, lots of valid formats
# ideas for the dynamic packets:
# 1] for user interaction: Create an interactive "builder" based on a
# Q/A process (not very scapy like)
# 2] for usage in scripts, create an alternative packet for every
# possible packet layout
#
class PacketChannelDescription(Packet):
"""Packet Channel Description Section 10.5.2.25a"""
name = "Packet Channel Description"
fields_desc = [
ByteField("ieiPCD", None),
BitField("chanType", 0x0, 5), # This packet has multiple
# possible layouts. I moddeled the first one
BitField("tn", 0x0, 3), # maybe build an
#"interactive" builder. Like
# a Q/A then propose a
# packet?
BitField("tsc", 0x0, 3),
BitField("chooser1", 0x0, 1),
BitField("chooser2", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("arfcn", 0x0, 10),
]
class DedicatedModeOrTBFHdr(Packet):
"""Dedicated mode or TBF Section 10.5.2.25b"""
name = "Dedicated Mode or TBF"
fields_desc = [
XBitField("ieiDMOT", None, 4),
BitField("spare", 0x0, 1),
BitField("tma", 0x0, 1),
BitField("downlink", 0x0, 1),
BitField("td", 0x0, 1)
]
# FIXME add implementation
class RrPacketUplinkAssignment(Packet):
"""RR Packet Uplink Assignment Section 10.5.2.25c"""
name = "RR Packet Uplink Assignment"
fields_desc = [
# Fill me
]
class PageModeHdr(Packet):
"""Page Mode Section 10.5.2.26"""
name = "Page Mode"
fields_desc = [
XBitField("ieiPM", None, 4),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("pm", 0x0, 2)
]
# Fix for 1/2 len problem
# concatenation: pageMode and dedicatedModeOrTBF
class PageModeAndDedicatedModeOrTBF(Packet):
name = "Page Mode and Dedicated Mode Or TBF"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("pm", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("tma", 0x0, 1),
BitField("downlink", 0x0, 1),
BitField("td", 0x0, 1)
]
# Fix for 1/2 len problem
# concatenation: pageMode and spareHalfOctets
class PageModeAndSpareHalfOctets(Packet):
name = "Page Mode and Spare Half Octets"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("pm", 0x0, 2),
BitField("spareHalfOctets", 0x0, 4)
]
# Fix for 1/2 len problem
# concatenation: pageMode and Channel Needed
class PageModeAndChannelNeeded(Packet):
name = "Page Mode and Channel Needed"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("pm", 0x0, 2),
BitField("channel2", 0x0, 2),
BitField("channel1", 0x0, 2)
]
class NccPermittedHdr(Packet):
"""NCC Permitted Section 10.5.2.27"""
name = "NCC Permitted"
fields_desc = [
BitField("eightBitNP", None, 1),
XBitField("ieiNP", None, 7),
ByteField("nccPerm", 0x0)
]
class PowerCommandHdr(Packet):
"""Power Command Section 10.5.2.28"""
name = "Power Command"
fields_desc = [
BitField("eightBitPC", None, 1),
XBitField("ieiPC", None, 7),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("powerLvl", 0x0, 5)
]
class PowerCommandAndAccessTypeHdr(Packet):
"""Power Command and access type Section 10.5.2.28a"""
name = "Power Command and Access Type"
fields_desc = [
BitField("eightBitPCAAT", None, 1),
XBitField("ieiPCAAT", None, 7),
BitField("atc", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("powerLvl", 0x0, 5)
]
class RachControlParametersHdr(Packet):
"""RACH Control Parameters Section 10.5.2.29"""
name = "RACH Control Parameters"
fields_desc = [
BitField("eightBitRCP", None, 1),
XBitField("ieiRCP", None, 7),
BitField("maxRetrans", 0x0, 2),
BitField("txInteger", 0x0, 4),
BitField("cellBarrAccess", 0x0, 1),
BitField("re", 0x0, 1),
] + [BitField("ACC" + "%02d" % x, 0x0, 1) for x in range(15, -1, -1)]
class RequestReferenceHdr(Packet):
"""Request Reference Section 10.5.2.30"""
name = "Request Reference"
fields_desc = [
BitField("eightBitRR", None, 1),
XBitField("ieiRR", None, 7),
ByteField("ra", 0x0),
BitField("t1", 0x0, 5),
BitField("t3Hi", 0x0, 3),
BitField("t3Lo", 0x0, 3),
BitField("t2", 0x0, 5)
]
class RrCauseHdr(Packet):
"""RR Cause Section 10.5.2.31"""
name = "RR Cause"
fields_desc = [
BitField("eightBitRC", None, 1),
XBitField("ieiRC", None, 7),
ByteField("rrCause", 0x0)
]
class Si1RestOctets(Packet):
"""SI 1 Rest Octets Section 10.5.2.32"""
name = "SI 1 Rest Octets"
fields_desc = [
ByteField("nchPos", 0x0)
]
class Si2bisRestOctets(Packet):
"""SI 2bis Rest Octets Section 10.5.2.33"""
name = "SI 2bis Rest Octets"
fields_desc = [
ByteField("spare", 0x0)
]
class Si2terRestOctets(Packet):
"""SI 2ter Rest Octets Section 10.5.2.33a"""
name = "SI 2ter Rest Octets"
fields_desc = [
ByteField("spare%d" % x, 0x0) for x in range(1, 5)
]
# len 5
class Si3RestOctets(Packet):
"""SI 3 Rest Octets Section 10.5.2.34"""
name = "SI 3 Rest Octets"
fields_desc = [
ByteField("byte1", 0x0),
ByteField("byte2", 0x0),
ByteField("byte3", 0x0),
ByteField("byte4", 0x0),
ByteField("byte5", 0x0)
]
# len 1 to 11
class Si4RestOctets(Packet):
"""SI 4 Rest Octets Section 10.5.2.35"""
name = "SI 4 Rest Octets"
fields_desc = [
XByteField("lengthSI4", None),
] + [ByteField("byte%d" % x, None) for x in range(2, 12)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 11, a, self.fields_desc, 1)
if self.lengthSI4 is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
if len(p) is 1: # length of this packet can be 0, but packet is
p = '' # but the IE is manadatory 0_o
return p + pay
class Si6RestOctets(Packet):
"""SI 6 Rest Octets Section 10.5.2.35a"""
name = "SI 4 Rest Octets"
fields_desc = [
# FIXME
]
# len 21
class Si7RestOctets(Packet):
"""SI 7 Rest Octets Section 10.5.2.36"""
name = "SI 7 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI7", 0x15),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 22)]
# len 21
class Si8RestOctets(Packet):
"""SI 8 Rest Octets Section 10.5.2.37"""
name = "SI 8 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI8", 0x15),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 22)]
# len 17
class Si9RestOctets(Packet):
"""SI 9 Rest Octets Section 10.5.2.37a"""
name = "SI 9 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI9", 0x11),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 18)]
# len 21
class Si13RestOctets(Packet):
"""SI 13 Rest Octets Section 10.5.2.37b"""
name = "SI 13 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI3", 0x15),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 22)]
# 10.5.2.37c [spare]
# 10.5.2.37d [spare]
# len 21
class Si16RestOctets(Packet):
"""SI 16 Rest Octets Section 10.5.2.37e"""
name = "SI 16 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI16", 0x15),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 22)]
# len 21
class Si17RestOctets(Packet):
"""SI 17 Rest Octets Section 10.5.2.37f"""
name = "SI 17 Rest Octets"
fields_desc = [
# FIXME
XByteField("lengthSI17", 0x15),
] + [ByteField("byte%d" % x, 0x0) for x in range(2, 22)]
class StartingTimeHdr(Packet):
"""Starting Time Section 10.5.2.38"""
name = "Starting Time"
fields_desc = [
BitField("eightBitST", None, 1),
XBitField("ieiST", None, 7),
ByteField("ra", 0x0),
BitField("t1", 0x0, 5),
BitField("t3Hi", 0x0, 3),
BitField("t3Lo", 0x0, 3),
BitField("t2", 0x0, 5)
]
class SynchronizationIndicationHdr(Packet):
"""Synchronization Indication Section 10.5.2.39"""
name = "Synchronization Indication"
fields_desc = [
XBitField("ieiSI", None, 4),
BitField("nci", 0x0, 1),
BitField("rot", 0x0, 1),
BitField("si", 0x0, 2)
]
class TimingAdvanceHdr(Packet):
"""Timing Advance Section 10.5.2.40"""
name = "Timing Advance"
fields_desc = [
BitField("eightBitTA", None, 1),
XBitField("ieiTA", None, 7),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("timingVal", 0x0, 6)
]
class TimeDifferenceHdr(Packet):
""" Time Difference Section 10.5.2.41"""
name = "Time Difference"
fields_desc = [
BitField("eightBitTD", None, 1),
XBitField("ieiTD", None, 7),
XByteField("lengthTD", 0x3),
ByteField("timeValue", 0x0)
]
class TlliHdr(Packet):
""" TLLI Section Section 10.5.2.41a"""
name = "TLLI"
fields_desc = [
BitField("eightBitT", None, 1),
XBitField("ieiT", None, 7),
ByteField("value", 0x0),
ByteField("value1", 0x0),
ByteField("value2", 0x0),
ByteField("value3", 0x0)
]
class TmsiPTmsiHdr(Packet):
""" TMSI/P-TMSI Section 10.5.2.42"""
name = "TMSI/P-TMSI"
fields_desc = [
BitField("eightBitTPT", None, 1),
XBitField("ieiTPT", None, 7),
ByteField("value", 0x0),
ByteField("value1", 0x0),
ByteField("value2", 0x0),
ByteField("value3", 0x0)
]
class VgcsTargetModeIdenticationHdr(Packet):
""" VGCS target Mode Indication 10.5.2.42a"""
name = "VGCS Target Mode Indication"
fields_desc = [
BitField("eightBitVTMI", None, 1),
XBitField("ieiVTMI", None, 7),
XByteField("lengthVTMI", 0x2),
BitField("targerMode", 0x0, 2),
BitField("cipherKeyNb", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1)
]
class WaitIndicationHdr(Packet):
""" Wait Indication Section 10.5.2.43"""
name = "Wait Indication"
fields_desc = [ # asciiart of specs strange
BitField("eightBitWI", None, 1),
XBitField("ieiWI", None, 7),
ByteField("timeoutVal", 0x0)
]
# len 17
class ExtendedMeasurementResultsHdr(Packet):
"""EXTENDED MEASUREMENT RESULTS Section 10.5.2.45"""
name = "Extended Measurement Results"
fields_desc = [
BitField("eightBitEMR", None, 1),
XBitField("ieiEMR", None, 7),
BitField("scUsed", None, 1),
BitField("dtxUsed", None, 1),
BitField("rxLevC0", None, 6),
BitField("rxLevC1", None, 6),
BitField("rxLevC2Hi", None, 2),
BitField("rxLevC2Lo", None, 4),
BitField("rxLevC3Hi", None, 4),
BitField("rxLevC3Lo", None, 3),
BitField("rxLevC4", None, 5),
BitField("rxLevC5", None, 6),
BitField("rxLevC6Hi", None, 2),
BitField("rxLevC6Lo", None, 4),
BitField("rxLevC7Hi", None, 4),
BitField("rxLevC7Lo", None, 2),
BitField("rxLevC8", None, 6),
BitField("rxLevC9", None, 6),
BitField("rxLevC10Hi", None, 2),
BitField("rxLevC10Lo", None, 4),
BitField("rxLevC11Hi", None, 4),
BitField("rxLevC13Lo", None, 2),
BitField("rxLevC12", None, 6),
BitField("rxLevC13", None, 6),
BitField("rxLevC14Hi", None, 2),
BitField("rxLevC14Lo", None, 4),
BitField("rxLevC15Hi", None, 4),
BitField("rxLevC15Lo", None, 2),
BitField("rxLevC16", None, 6),
BitField("rxLevC17", None, 6),
BitField("rxLevC18Hi", None, 2),
BitField("rxLevC18Lo", None, 4),
BitField("rxLevC19Hi", None, 4),
BitField("rxLevC19Lo", None, 2),
BitField("rxLevC20", None, 6)
]
# len 17
class ExtendedMeasurementFrequencyListHdr(Packet):
"""Extended Measurement Frequency List Section 10.5.2.46"""
name = "Extended Measurement Frequency List"
fields_desc = [
BitField("eightBitEMFL", None, 1),
XBitField("ieiEMFL", None, 7),
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("seqCode", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("bitsRest", 0x0, 128)
]
class SuspensionCauseHdr(Packet):
"""Suspension Cause Section 10.5.2.47"""
name = "Suspension Cause"
fields_desc = [
BitField("eightBitSC", None, 1),
XBitField("ieiSC", None, 7),
ByteField("suspVal", 0x0)
]
class ApduIDHdr(Packet):
"""APDU Flags Section 10.5.2.48"""
name = "Apdu Id"
fields_desc = [
XBitField("ieiAI", None, 4),
BitField("id", None, 4)
]
class ApduFlagsHdr(Packet):
"""APDU Flags Section 10.5.2.49"""
name = "Apdu Flags"
fields_desc = [
XBitField("iei", None, 4),
BitField("spare", 0x0, 1),
BitField("cr", 0x0, 1),
BitField("firstSeg", 0x0, 1),
BitField("lastSeg", 0x0, 1)
]
# Fix 1/2 len problem
class ApduIDAndApduFlags(Packet):
name = "Apu Id and Apdu Flags"
fields_desc = [
BitField("id", None, 4),
BitField("spare", 0x0, 1),
BitField("cr", 0x0, 1),
BitField("firstSeg", 0x0, 1),
BitField("lastSeg", 0x0, 1)
]
# len 2 to max L3 (251) (done)
class ApduDataHdr(Packet):
"""APDU Data Section 10.5.2.50"""
name = "Apdu Data"
fields_desc = [
BitField("eightBitAD", None, 1),
XBitField("ieiAD", None, 7),
XByteField("lengthAD", None),
# optional
] + [ByteField("apuInfo%d" % x, None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 251, a, self.fields_desc)
if self.lengthAD is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
#
# 10.5.3 Mobility management information elements
#
class AuthenticationParameterRAND(Packet):
"""Authentication parameter RAND Section 10.5.3.1"""
name = "Authentication Parameter Rand"
fields_desc = [
ByteField("ieiAPR", None),
BitField("randValue", 0x0, 128)
]
class AuthenticationParameterSRES(Packet):
"""Authentication parameter SRES Section 10.5.3.2"""
name = "Authentication Parameter Sres"
fields_desc = [
ByteField("ieiAPS", None),
BitField("sresValue", 0x0, 40)
]
class CmServiceType(Packet):
"""CM service type Section 10.5.3.3"""
name = "CM Service Type"
fields_desc = [
XBitField("ieiCST", 0x0, 4),
BitField("serviceType", 0x0, 4)
]
class CmServiceTypeAndCiphKeySeqNr(Packet):
name = "CM Service Type and Cipher Key Sequence Number"
fields_desc = [
BitField("keySeq", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("serviceType", 0x0, 4)
]
class IdentityType(Packet):
"""Identity type Section 10.5.3.4"""
name = "Identity Type"
fields_desc = [
XBitField("ieiIT", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("idType", 0x1, 3)
]
# Fix 1/2 len problem
class IdentityTypeAndSpareHalfOctet(Packet):
name = "Identity Type and Spare Half Octet"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("idType", 0x1, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class LocationUpdatingType(Packet):
"""Location updating type Section 10.5.3.5"""
name = "Location Updating Type"
fields_desc = [
XBitField("ieiLUT", 0x0, 4),
BitField("for", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("lut", 0x0, 2)
]
class LocationUpdatingTypeAndCiphKeySeqNr(Packet):
name = "Location Updating Type and Cipher Key Sequence Number"
fields_desc = [
BitField("for", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("lut", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3)
]
# len 3 to L3 max (251) (done)
class NetworkNameHdr(Packet):
"""Network Name Section 10.5.3.5a"""
name = "Network Name"
fields_desc = [
BitField("eightBitNN", None, 1),
XBitField("ieiNN", None, 7),
XByteField("lengthNN", None),
BitField("ext1", 0x1, 1),
BitField("codingScheme", 0x0, 3),
BitField("addCi", 0x0, 1),
BitField("nbSpare", 0x0, 3),
# optional
] + [ByteField("txtString%d" % x, None) for x in range(1, 249)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 251, a, self.fields_desc)
if self.lengthNN is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class RejectCause(Packet):
"""Reject cause Section 10.5.3.6"""
name = "Reject Cause"
fields_desc = [
ByteField("ieiRC", 0x0),
ByteField("rejCause", 0x0)
]
class FollowOnProceed(Packet):
"""Follow-on Proceed Section 10.5.3.7"""
name = "Follow-on Proceed"
fields_desc = [
ByteField("ieiFOP", 0x0),
]
class TimeZoneHdr(Packet):
"""Time Zone Section 10.5.3.8"""
name = "Time Zone"
fields_desc = [
BitField("eightBitTZ", None, 1),
XBitField("ieiTZ", None, 7),
ByteField("timeZone", 0x0),
]
class TimeZoneAndTimeHdr(Packet):
"""Time Zone and Time Section 10.5.3.9"""
name = "Time Zone and Time"
fields_desc = [
BitField("eightBitTZAT", None, 1),
XBitField("ieiTZAT", None, 7),
ByteField("year", 0x0),
ByteField("month", 0x0),
ByteField("day", 0x0),
ByteField("hour", 0x0),
ByteField("minute", 0x0),
ByteField("second", 0x0),
ByteField("timeZone", 0x0)
]
class CtsPermissionHdr(Packet):
"""CTS permission Section 10.5.3.10"""
name = "Cts Permission"
fields_desc = [
BitField("eightBitCP", None, 1),
XBitField("ieiCP", None, 7),
]
class LsaIdentifierHdr(Packet):
"""LSA Identifier Section 10.5.3.11"""
name = "Lsa Identifier"
fields_desc = [
BitField("eightBitLI", None, 1),
XBitField("ieiLI", None, 7),
ByteField("lsaID", 0x0),
ByteField("lsaID1", 0x0),
ByteField("lsaID2", 0x0)
]
#
# 10.5.4 Call control information elements
#
# 10.5.4.1 Extensions of codesets
# This is only text and no packet
class LockingShiftProcedureHdr(Packet):
"""Locking shift procedure Section 10.5.4.2"""
name = "Locking Shift Procedure"
fields_desc = [
XBitField("ieiLSP", None, 4),
BitField("lockShift", 0x0, 1),
BitField("codesetId", 0x0, 3)
]
class NonLockingShiftProcedureHdr(Packet):
"""Non-locking shift procedure Section 10.5.4.3"""
name = "Non-locking Shift Procedure"
fields_desc = [
XBitField("ieiNLSP", None, 4),
BitField("nonLockShift", 0x1, 1),
BitField("codesetId", 0x0, 3)
]
class AuxiliaryStatesHdr(Packet):
"""Auxiliary states Section 10.5.4.4"""
name = "Auxiliary States"
fields_desc = [
BitField("eightBitAS", None, 1),
XBitField("ieiAS", None, 7),
XByteField("lengthAS", 0x3),
BitField("ext", 0x1, 1),
BitField("spare", 0x0, 3),
BitField("holdState", 0x0, 2),
BitField("mptyState", 0x0, 2)
]
# len 3 to 15
class BearerCapabilityHdr(Packet):
"""Bearer capability Section 10.5.4.5"""
name = "Bearer Capability"
fields_desc = [
BitField("eightBitBC", None, 1),
XBitField("ieiBC", None, 7),
XByteField("lengthBC", None),
BitField("ext0", 0x1, 1),
BitField("radioChReq", 0x1, 2),
BitField("codingStd", 0x0, 1),
BitField("transMode", 0x0, 1),
BitField("infoTransCa", 0x0, 3),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("coding", None, 1),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("spare", None, 2),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("speechVers", 0x0, 4),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("ext2", 0x1, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("compress", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("structure", None, 2),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("dupMode", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("config", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("nirr", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("establi", 0x0, 1),
lambda pkt: pkt.ext1 == 0),
BitField("ext3", None, 1),
BitField("accessId", None, 2),
BitField("rateAda", None, 2),
BitField("signaling", None, 3),
ConditionalField(BitField("ext4", None, 1),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("otherITC", None, 2),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("otherRate", None, 2),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("spare1", 0x0, 3),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("ext5", 0x1, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("hdr", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("multiFr", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("mode", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("lli", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("assig", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("inbNeg", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("spare2", 0x0, 1),
lambda pkt: pkt.ext4 == 0),
BitField("ext6", None, 1),
BitField("layer1Id", None, 2),
BitField("userInf", None, 4),
BitField("sync", None, 1),
ConditionalField(BitField("ext7", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("stopBit", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("negoc", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("nbDataBit", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("userRate", None, 4),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("ext8", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("interRate", None, 2),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("nicTX", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("nicRX", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("parity", None, 3),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("ext9", None, 1),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("connEle", None, 2),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("modemType", None, 5),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("ext10", None, 1),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("otherModemType", None, 2),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("netUserRate", None, 5),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("ext11", None, 1),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("chanCoding", None, 4),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("maxTrafficChan", None, 3),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("ext12", None, 1),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("uimi", None, 3),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("airInterfaceUserRate", None, 4),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("ext13", 0x1, 1),
lambda pkt: pkt.ext12 == 0),
ConditionalField(BitField("layer2Ch", None, 2),
lambda pkt: pkt.ext12 == 0),
ConditionalField(BitField("userInfoL2", 0x0, 5),
lambda pkt: pkt.ext12 == 0)
]
# We have a bug here. packet is not working if used in message
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 15, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
# avoids a bug. find better way
if len(p) is 5:
p = p[:-2]
if self.lengthBC is None:
p = p[:1] + chb(len(p) - 3) + p[2:]
return p + pay
class CallControlCapabilitiesHdr(Packet):
"""Call Control Capabilities Section 10.5.4.5a"""
name = "Call Control Capabilities"
fields_desc = [
BitField("eightBitCCC", None, 1),
XBitField("ieiCCC", None, 7),
XByteField("lengthCCC", 0x3),
BitField("spare", 0x0, 6),
BitField("pcp", 0x0, 1),
BitField("dtmf", 0x0, 1)
]
class CallStateHdr(Packet):
"""Call State Section 10.5.4.6"""
name = "Call State"
fields_desc = [
BitField("eightBitCS", None, 1),
XBitField("ieiCS", None, 7),
BitField("codingStd", 0x0, 2),
BitField("stateValue", 0x0, 6)
]
# len 3 to 43
class CalledPartyBcdNumberHdr(Packet):
"""Called party BCD number Section 10.5.4.7"""
name = "Called Party BCD Number"
fields_desc = [
BitField("eightBitCPBN", None, 1),
XBitField("ieiCPBN", None, 7),
XByteField("lengthCPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("nbPlanId", 0x0, 4),
# optional
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 80)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 43, a, self.fields_desc, 2)
if self.lengthCPBN is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to 23
class CalledPartySubaddressHdr(Packet):
"""Called party subaddress Section 10.5.4.8"""
name = "Called Party Subaddress"
fields_desc = [
BitField("eightBitCPS", None, 1),
XBitField("ieiCPS", None, 7),
XByteField("lengthCPS", None),
# optional
BitField("ext", None, 1),
BitField("subAddr", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo%d" % x, None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 23, a, self.fields_desc)
if self.lengthCPS is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 3 to 14
class CallingPartyBcdNumberHdr(Packet):
"""Called party subaddress Section 10.5.4.9"""
name = "Called Party Subaddress"
fields_desc = [
BitField("eightBitCPBN", None, 1),
XBitField("ieiCPBN", None, 7),
XByteField("lengthCPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("nbPlanId", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", None, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", None, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", 0x0, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 20)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 14, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthCPBN is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
# len 2 to 23
class CallingPartySubaddressHdr(Packet):
"""Calling party subaddress Section 10.5.4.10"""
name = "Calling Party Subaddress"
fields_desc = [
BitField("eightBitCPS", None, 1),
XBitField("ieiCPS", None, 7),
XByteField("lengthCPS", None),
# optional
BitField("ext1", None, 1),
BitField("typeAddr", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo%d" % x, None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 23, a, self.fields_desc)
if self.lengthCPS is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 4 to 32
class CauseHdr(Packet):
"""Cause Section 10.5.4.11"""
name = "Cause"
fields_desc = [
BitField("eightBitC", None, 1),
XBitField("ieiC", None, 7),
XByteField("lengthC", None),
BitField("ext", 0x1, 1),
BitField("codingStd", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("location", 0x0, 4),
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("recommendation", 0x0, 7),
lambda pkt: pkt.ext == 0),
# optional
BitField("ext2", None, 1),
BitField("causeValue", None, 7),
] + [ByteField("diagnositc%d" % x, None) for x in range(0, 27)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 32, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthC is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
class ClirSuppressionHdr(Packet):
"""CLIR suppression Section 10.5.4.11a"""
name = "Clir Suppression"
fields_desc = [
BitField("eightBitCS", None, 1),
XBitField("ieiCS", None, 7),
]
class ClirInvocationHdr(Packet):
"""CLIR invocation Section 10.5.4.11b"""
name = "Clir Invocation"
fields_desc = [
BitField("eightBitCI", None, 1),
XBitField("ieiCI", None, 7),
]
class CongestionLevelHdr(Packet):
"""Congestion level Section 10.5.4.12"""
name = "Congestion Level"
fields_desc = [
XBitField("ieiCL", None, 4),
BitField("notDef", 0x0, 4)
]
# Fix 1/2 len problem
class CongestionLevelAndSpareHalfOctets(Packet):
name = "Congestion Level and Spare Half Octets"
fields_desc = [
BitField("ieiCL", 0x0, 4),
BitField("spareHalfOctets", 0x0, 4)
]
# len 3 to 14
class ConnectedNumberHdr(Packet):
"""Connected number Section 10.5.4.13"""
name = "Connected Number"
fields_desc = [
BitField("eightBitCN", None, 1),
XBitField("ieiCN", None, 7),
XByteField("lengthCN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("typePlanId", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", None, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", None, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", None, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 20)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 14, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthCN is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
# len 2 to 23
class ConnectedSubaddressHdr(Packet):
"""Connected subaddress Section 10.5.4.14"""
name = "Connected Subaddress"
fields_desc = [
BitField("eightBitCS", None, 1),
XBitField("ieiCS", None, 7),
XByteField("lengthCS", None),
# optional
BitField("ext", None, 1),
BitField("typeOfSub", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo%d" % x, None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 23, a, self.fields_desc)
if self.lengthCS is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to L3 (251) (done)
class FacilityHdr(Packet):
"""Facility Section 10.5.4.15"""
name = "Facility"
fields_desc = [
BitField("eightBitF", None, 1),
XBitField("ieiF", None, 7),
XByteField("lengthF", None),
# optional
] + [ByteField("facilityInfo%d" % x, None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 251, a, self.fields_desc)
if self.lengthF is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to 5
class HighLayerCompatibilityHdr(Packet):
"""High layer compatibility Section 10.5.4.16"""
name = "High Layer Compatibility"
fields_desc = [
BitField("eightBitHLC", None, 1),
XBitField("ieiHLC", None, 7),
XByteField("lengthHLC", None),
# optional
BitField("ext", None, 1),
BitField("codingStd", None, 2),
BitField("interpret", None, 3),
BitField("presMeth", None, 2),
BitField("ext1", None, 1),
BitField("highLayerId", None, 7),
ConditionalField(BitField("ext2", 0x1, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("exHiLayerId", 0x0, 7),
lambda pkt: pkt.ext1 == 0)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 5, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthHLC is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
#
# 10.5.4.16.1 Static conditions for the high layer
# compatibility IE contents
#
class KeypadFacilityHdr(Packet):
"""Keypad facility Section 10.5.4.17"""
name = "Keypad Facility"
fields_desc = [
BitField("eightBitKF", None, 1),
XBitField("ieiKF", None, 7),
BitField("spare", 0x0, 1),
BitField("keyPadInfo", 0x0, 7)
]
# len 2 to 15
class LowLayerCompatibilityHdr(Packet):
"""Low layer compatibility Section 10.5.4.18"""
name = "Low Layer Compatibility"
fields_desc = [
BitField("eightBitLLC", None, 1),
XBitField("ieiLLC", None, 7),
XByteField("lengthLLC", None),
# optional
] + [ByteField("rest%d" % x, None) for x in range(0, 13)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 15, a, self.fields_desc)
if self.lengthLLC is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MoreDataHdr(Packet):
"""More data Section 10.5.4.19"""
name = "More Data"
fields_desc = [
BitField("eightBitMD", None, 1),
XBitField("ieiMD", None, 7),
]
class NotificationIndicatorHdr(Packet):
"""Notification indicator Section 10.5.4.20"""
name = "Notification Indicator"
fields_desc = [
BitField("eightBitNI", None, 1),
XBitField("ieiNI", None, 7),
BitField("ext", 0x1, 1),
BitField("notifDesc", 0x0, 7)
]
class ProgressIndicatorHdr(Packet):
"""Progress indicator Section 10.5.4.21"""
name = "Progress Indicator"
fields_desc = [
BitField("eightBitPI", None, 1),
XBitField("ieiPI", None, 7),
XByteField("lengthPI", 0x2),
BitField("ext", 0x1, 1),
BitField("codingStd", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("location", 0x0, 4),
BitField("ext1", 0x1, 1),
BitField("progressDesc", 0x0, 7)
]
class RecallTypeHdr(Packet):
"""Recall type $(CCBS)$ Section 10.5.4.21a"""
name = "Recall Type $(CCBS)$"
fields_desc = [
BitField("eightBitRT", None, 1),
XBitField("ieiRT", None, 7),
BitField("spare", 0x0, 5),
BitField("recallType", 0x0, 3)
]
# len 3 to 19
class RedirectingPartyBcdNumberHdr(Packet):
"""Redirecting party BCD number Section 10.5.4.21b"""
name = "Redirecting Party BCD Number"
fields_desc = [
BitField("eightBitRPBN", None, 1),
XBitField("ieiRPBN", None, 7),
XByteField("lengthRPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("numberingPlan", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", None, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", None, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", None, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 30)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 19, a, self.fields_desc)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthRPBN is None:
p = p[:1] + chb(len(p) - 2) + p[2:]
return p + pay
# length 2 to 23
class RedirectingPartySubaddressHdr(Packet):
"""Redirecting party subaddress Section 10.5.4.21c"""
name = "Redirecting Party BCD Number"
fields_desc = [
BitField("eightBitRPS", None, 1),
XBitField("ieiRPS", None, 7),
XByteField("lengthRPS", None),
# optional
BitField("ext", None, 1),
BitField("typeSub", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo%d" % x, None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 23, a, self.fields_desc)
if self.lengthRPS is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class RepeatIndicatorHdr(Packet):
"""Repeat indicator Section 10.5.4.22"""
name = "Repeat Indicator"
fields_desc = [
XBitField("ieiRI", None, 4),
BitField("repeatIndic", 0x0, 4)
]
class ReverseCallSetupDirectionHdr(Packet):
"""Reverse call setup direction Section 10.5.4.22a"""
name = "Reverse Call Setup Direction"
fields_desc = [
ByteField("ieiRCSD", 0x0)
]
# no upper length min 2(max for L3) (251)
class SetupContainerHdr(Packet):
"""SETUP Container $(CCBS)$ Section 10.5.4.22b"""
name = "Setup Container $(CCBS)$"
fields_desc = [
BitField("eightBitSC", None, 1),
XBitField("ieiSC", None, 7),
XByteField("lengthSC", None),
# optional
] + [ByteField("mess%d" % x, None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 251, a, self.fields_desc)
if self.lengthSC is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class SignalHdr(Packet):
"""Signal Section 10.5.4.23"""
name = "Signal"
fields_desc = [
BitField("eightBitS", None, 1),
XBitField("ieiS", None, 7),
ByteField("sigValue", 0x0)
]
# length 2 to max for L3 message (251)
class SsVersionIndicatorHdr(Packet):
"""SS Version Indicator Section 10.5.4.24"""
name = "SS Version Indicator"
fields_desc = [
BitField("eightBitSVI", None, 1),
XBitField("ieiSVI", None, 7),
XByteField("lengthSVI", None),
# optional
] + [ByteField("info%d" % x, None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 251, a, self.fields_desc)
if self.lengthSVI is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# length 3 to 35 or 131
class UserUserHdr(Packet):
"""User-user Section 10.5.4.25"""
name = "User-User"
fields_desc = [
BitField("eightBitUU", None, 1),
XBitField("ieiUU", None, 7),
XByteField("lengthUU", None), # dynamic length of field depending
# of the type of message
# let user decide which length he
# wants to take
# => more fuzzing options
ByteField("userUserPD", 0x0),
# optional
] + [ByteField("userUserInfo%d" % x, None) for x in range(1, 132)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 131, a, self.fields_desc)
if self.lengthUU is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class AlertingPatternHdr(Packet):
"""Alerting Pattern 10.5.4.26"""
name = "Alerting Pattern"
fields_desc = [
BitField("eightBitAP", None, 1),
XBitField("ieiAP", None, 7),
XByteField("lengthAP", 0x3),
BitField("spare", 0x0, 4),
BitField("alertingValue", 0x0, 4)
]
class AllowedActionsHdr(Packet):
"""Allowed actions $(CCBS)$ Section 10.5.4.26"""
name = "Allowed Actions $(CCBS)$"
fields_desc = [
BitField("eightBitAA", None, 1),
XBitField("ieiAA", None, 7),
XByteField("lengthAP", 0x3),
BitField("CCBS", 0x0, 1),
BitField("spare", 0x0, 7)
]
#
# 10.5.5 GPRS mobility management information elements
#
class AttachResult(Packet):
"""Attach result Section 10.5.5.1"""
name = "Attach Result"
fields_desc = [
XBitField("ieiAR", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("result", 0x1, 3)
]
class AttachTypeHdr(Packet):
"""Attach type Section 10.5.5.2"""
name = "Attach Type"
fields_desc = [
XBitField("ieiAT", None, 4),
BitField("spare", 0x0, 1),
BitField("type", 0x1, 3)
]
# Fix 1/2 len problem
class AttachTypeAndCiphKeySeqNr(Packet):
name = "Attach Type and Cipher Key Sequence Number"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("type", 0x1, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class CipheringAlgorithm(Packet):
"""Ciphering algorithm Section 10.5.5.3"""
name = "Ciphering Algorithm"
fields_desc = [
XBitField("ieiCA", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("type", 0x1, 3)
]
# Fix 1/2 len problem
class CipheringAlgorithmAndImeisvRequest(Packet):
name = "Ciphering Algorithm and Imeisv Request"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("type", 0x1, 3),
BitField("spare", 0x0, 1),
BitField("imeisvVal", 0x0, 3)
]
# [Spare]
class TmsiStatus(Packet):
"""[Spare] TMSI status Section 10.5.5.4"""
name = "[Spare] TMSI Status"
fields_desc = [
XBitField("ieiTS", None, 4),
BitField("spare", 0x0, 3),
BitField("flag", 0x1, 1)
]
class DetachType(Packet):
"""Detach type Section 10.5.5.5"""
name = "Detach Type"
fields_desc = [
XBitField("ieiDT", 0x0, 4),
BitField("poweroff", 0x0, 1),
BitField("type", 0x1, 3)
]
# Fix 1/2 len problem
class DetachTypeAndForceToStandby(Packet):
name = "Detach Type and Force To Standby"
fields_desc = [
BitField("poweroff", 0x0, 1),
BitField("type", 0x1, 3),
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3)
]
# Fix 1/2 len problem
class DetachTypeAndSpareHalfOctets(Packet):
name = "Detach Type and Spare Half Octets"
fields_desc = [
BitField("poweroff", 0x0, 1),
BitField("type", 0x1, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class DrxParameter(Packet):
"""DRX parameter Section 10.5.5.6"""
name = "DRX Parameter"
fields_desc = [
ByteField("ieiDP", 0x0),
ByteField("splitPG", 0x0),
BitField("spare", 0x0, 4),
BitField("splitCCCH", 0x0, 1),
BitField("NonDrxTimer", 0x1, 3)
]
class ForceToStandby(Packet):
"""Force to standby Section 10.5.5.7"""
name = "Force To Standby"
fields_desc = [
XBitField("ieiFTS", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3)
]
# Fix 1/2 len problem
class ForceToStandbyAndAcReferenceNumber(Packet):
name = "Force To Standby And Ac Reference Number"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3),
BitField("acRefVal", 0x0, 4)
]
# Fix 1/2 len problem
class ForceToStandbyAndUpdateResult(Packet):
name = "Force To Standby And Update Result"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("updateResVal", 0x0, 3)
]
# Fix 1/2 len problem
class ForceToStandbyAndSpareHalfOctets(Packet):
name = "Force To Standby And Spare Half Octets"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class PTmsiSignature(Packet):
"""P-TMSI signature Section 10.5.5.8"""
name = "P-TMSI Signature"
fields_desc = [
ByteField("ieiPTS", 0x0),
BitField("signature", 0x0, 24)
]
class IdentityType2(Packet):
"""Identity type 2 Section 10.5.5.9"""
name = "Identity Type 2"
fields_desc = [
XBitField("ieiIT2", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("typeOfIdentity", 0x0, 3)
]
# Fix 1/2 len problem
class IdentityType2AndforceToStandby(Packet):
name = "Identity Type 2 and Force to Standby"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("typeOfIdentity", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("forceStandby", 0x0, 3)
]
class ImeisvRequest(Packet):
"""IMEISV request Section 10.5.5.10"""
name = "IMEISV Request"
fields_desc = [
XBitField("ieiIR", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("imeisvVal", 0x0, 3)
]
# Fix 1/2 len problem
class ImeisvRequestAndForceToStandby(Packet):
name = "IMEISV Request and Force To Standby"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("imeisvVal", 0x0, 3),
BitField("spareHalfOctets", 0x0, 4)
]
# length 4 to 19
class ReceiveNpduNumbersList(Packet):
"""Receive N-PDU Numbers list Section 10.5.5.11"""
name = "Receive N-PDU Numbers list"
fields_desc = [
ByteField("ieiRNNL", 0x0),
XByteField("lengthRNNL", None),
BitField("nbList0", 0x0, 16),
# optional
] + [ByteField("nbList%d" % x, None) for x in range(1, 16)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 19, a, self.fields_desc)
if self.lengthRNNL is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MsNetworkCapability(Packet):
"""MS network capability Section 10.5.5.12"""
name = "MS Network Capability"
fields_desc = [
ByteField("ieiMNC", 0x0),
XByteField("lengthMNC", 0x3),
ByteField("msNetValue", 0x0)
]
# length 6 to 14
class MsRadioAccessCapability(Packet):
"""MS Radio Access capability Section 10.5.5.12a"""
name = "MS Radio Access Capability"
fields_desc = [
ByteField("ieiMRAC", 0x24),
XByteField("lengthMRAC", None),
BitField("spare1", 0x0, 1), # ...
BitField("accessCap", 0x0, 4),
BitField("accessTechType", 0x0, 4),
# access capability
BitField("bool", 0x0, 1),
BitField("lengthContent", 0x0, 7),
BitField("spare1", 0x0, 1), # ...
# content
BitField("pwrCap", 0x0, 3),
BitField("bool1", 0x0, 1),
BitField("a51", 0x0, 1),
BitField("a52", 0x0, 1),
BitField("a53", 0x0, 1),
BitField("a54", 0x0, 1),
BitField("a55", 0x0, 1),
BitField("a56", 0x0, 1),
BitField("a57", 0x0, 1),
BitField("esInd", 0x0, 1),
BitField("ps", 0x0, 1),
BitField("vgcs", 0x0, 1),
BitField("vbs", 0x0, 1),
BitField("bool2", 0x0, 1),
# multislot
BitField("bool3", 0x0, 1),
BitField("hscsd", 0x0, 5),
BitField("bool4", 0x0, 1),
BitField("gprs", 0x0, 5),
BitField("gprsExt", 0x0, 1),
BitField("bool5", 0x0, 1),
BitField("smsVal", 0x0, 4),
BitField("smVal", 0x0, 4)
]
# 10.5.5.13 Spare
# This is intentionally left spare.
class GmmCause(Packet):
"""GMM cause Section 10.5.5.14"""
name = "GMM Cause"
fields_desc = [
ByteField("ieiGC", 0x0),
ByteField("causeValue", 0x0)
]
class RoutingAreaIdentification(Packet):
"""Routing area identification Section 10.5.5.15"""
name = "Routing Area Identification"
fields_desc = [
ByteField("ieiRAI", 0x0),
BitField("mccDigit2", 0x0, 4),
BitField("mccDigit1", 0x0, 4),
BitField("mncDigit3", 0x0, 4),
BitField("mccDigit3", 0x0, 4),
BitField("mccDigit2", 0x0, 4),
BitField("mccDigit1", 0x0, 4),
ByteField("LAC", 0x0),
ByteField("LAC1", 0x0),
ByteField("LAC", 0x0)
]
# 10.5.5.16 Spare
# This is intentionally left spare.
class UpdateResult(Packet):
"""Update result Section 10.5.5.17"""
name = "Update Result"
fields_desc = [
XBitField("ieiUR", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("updateResVal", 0x0, 3)
]
class UpdateType(Packet):
"""Update type Section 10.5.5.18"""
name = "Update Type"
fields_desc = [
XBitField("ieiUT", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("updateTypeVal", 0x0, 3)
]
# Fix 1/2 len problem
class UpdateTypeAndCiphKeySeqNr(Packet):
name = "Update Type and Cipher Key Sequence Number"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("updateTypeVal", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3)
]
class AcReferenceNumber(Packet):
"""A&C reference number Section 10.5.5.19"""
name = "A&C Reference Number"
fields_desc = [
XBitField("ieiARN", 0x0, 4),
BitField("acRefVal", 0x0, 4)
]
# Fix 1/2 len problem
class AcReferenceNumberAndSpareHalfOctets(Packet):
name = "A&C Reference Number and Spare Half Octets"
fields_desc = [
BitField("acRefVal", 0x0, 4),
BitField("spareHalfOctets", 0x0, 4)
]
#
# 10.5.6 Session management information elements
#
# length 3 to 102
class AccessPointName(Packet):
"""Access Point Name Section 10.5.6.1"""
name = "Access Point Name"
fields_desc = [
ByteField("ieiAPN", 0x0),
XByteField("lengthAPN", None),
ByteField("apName", 0x0),
# optional
] + [ByteField("apName%d" % x, None) for x in range(1, 100)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 102, a, self.fields_desc)
if self.lengthAPN is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class NetworkServiceAccessPointIdentifier(Packet):
"""Network service access point identifier Section 10.5.6.2"""
name = "Network Service Access Point Identifier"
fields_desc = [
ByteField("ieiNSAPI", 0x0),
BitField("spare", 0x0, 4),
BitField("nsapiVal", 0x0, 4)
]
# length 2 to 253
class ProtocolConfigurationOptions(Packet):
"""Protocol configuration options Section 10.5.6.3"""
name = "Protocol Configuration Options"
fields_desc = [
ByteField("ieiPCO", 0x0),
XByteField("lengthPCO", None),
# optional
BitField("ext", None, 1),
BitField("spare", None, 4),
BitField("configProto", None, 3),
] + list(itertools.chain(*[[
ByteField("protoId%d" % x, None),
ByteField("lenProto%d" % x, None),
ByteField("proto%dContent" % x, None),
] for x in range(1, 84)]))
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 253, a, self.fields_desc)
if self.lengthPCO is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 4 to 20
class PacketDataProtocolAddress(Packet):
"""Packet data protocol address Section 10.5.6.4"""
name = "Packet Data Protocol Address"
fields_desc = [
ByteField("ieiPDPA", 0x0),
XByteField("lengthPDPA", None),
BitField("spare", 0x0, 4),
BitField("pdpTypeOrga", 0x0, 4),
ByteField("pdpTypeNb", 0x0),
# optional
] + [ByteField("addressInfo%d" % x, None) for x in range(1, 17)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 20, a, self.fields_desc)
if self.lengthPDPA is None:
p = p[:1] + chb(res[1]) + p[2:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class QualityOfService(Packet):
"""Quality of service Section 10.5.6.5"""
name = "Quality of Service"
fields_desc = [
ByteField("ieiQOS", 0x0),
XByteField("lengthQOS", 0x5),
BitField("spare", 0x0, 2),
BitField("delayClass", 0x0, 3),
BitField("reliaClass", 0x0, 3),
BitField("peak", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("precedenceCl", 0x0, 3),
BitField("spare", 0x0, 3),
BitField("mean", 0x0, 5)
]
class SmCause(Packet):
"""SM cause Section 10.5.6.6"""
name = "SM Cause"
fields_desc = [
ByteField("ieiSC", 0x0),
ByteField("causeVal", 0x0)
]
# 10.5.6.7 Spare
# This is intentionally left spare.
class AaDeactivationCause(Packet):
"""AA deactivation cause Section 10.5.6.8"""
name = "AA Deactivation Cause"
fields_desc = [
XBitField("ieiADC", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("aaVal", 0x0, 3)
]
# Fix 1/2 len problem
class AaDeactivationCauseAndSpareHalfOctets(Packet):
name = "AA Deactivation Cause and Spare Half Octets"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("aaVal", 0x0, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class LlcServiceAccessPointIdentifier(Packet):
"""LLC service access point identifier Section 10.5.6.9"""
name = "LLC Service Access Point Identifier"
fields_desc = [
ByteField("ieiLSAPI", None),
BitField("spare", 0x0, 4),
BitField("llcVal", 0x0, 4)
]
#
# 10.5.7 GPRS Common information elements
#
# 10.5.7.1 [Spare]
class RadioPriority(Packet):
"""Radio priority Section 10.5.7.2"""
name = "Radio Priority"
fields_desc = [
XBitField("ieiRP", 0x0, 4),
BitField("spare", 0x1, 1),
BitField("rplv", 0x0, 3)
]
# Fix 1/2 len problem
class RadioPriorityAndSpareHalfOctets(Packet):
name = "Radio Priority and Spare Half Octets"
fields_desc = [
BitField("spare", 0x1, 1),
BitField("rplv", 0x0, 3),
BitField("spareHalfOctets", 0x0, 4)
]
class GprsTimer(Packet):
"""GPRS Timer Section 10.5.7.3"""
name = "GPRS Timer"
fields_desc = [
ByteField("ieiGT", 0x0),
BitField("unit", 0x0, 3),
BitField("timerVal", 0x0, 5)
]
class CellIdentity(Packet):
""" Cell identity Section 10.5.1.1 """
name = "Cell Identity"
fields_desc = [
ByteField("ciValue1", 0x0),
ByteField("ciValue2", 0x0)
]
class CiphKeySeqNr(Packet):
""" Ciphering Key Sequence Number Section 10.5.1.2 """
name = "Cipher Key Sequence Number"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("keySeq", 0x0, 3)
]
class LocalAreaId(Packet):
""" Local Area Identification Section 10.5.1.3 """
name = "Location Area Identification"
fields_desc = [
BitField("mccDigit2", 0x0, 4),
BitField("mccDigit1", 0x0, 4),
BitField("mncDigit3", 0x0, 4),
BitField("mccDigit3", 0x0, 4),
BitField("mncDigit2", 0x0, 4),
BitField("mncDigit1", 0x0, 4),
ByteField("lac1", 0x0),
ByteField("lac2", 0x0)
]
#
# The Mobile Identity is a type 4 information element with a minimum
# length of 3 octet and 11 octets length maximal.
#
# len 3 - 11
class MobileId(Packet):
""" Mobile Identity Section 10.5.1.4 """
name = "Mobile Identity"
fields_desc = [
XByteField("lengthMI", None),
BitField("idDigit1", 0x0, 4),
BitField("oddEven", 0x0, 1),
BitField("typeOfId", 0x0, 3),
# optional
] + list(itertools.chain(*[[
BitField("idDigit%d_1" % x, None, 4),
BitField("idDigit%d" % x, None, 4),
] for x in range(2, 10)]))
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 10, a, self.fields_desc, 1)
if self.lengthMI is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MobileStationClassmark1(Packet):
""" Mobile Station Classmark 1 Section 10.5.1.5 """
name = "Mobile Station Classmark 1"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("revisionLvl", 0x0, 2),
BitField("esInd", 0x0, 1),
BitField("a51", 0x0, 1),
BitField("rfPowerCap", 0x0, 3)
]
class MobileStationClassmark2(Packet):
""" Mobile Station Classmark 2 Section 10.5.1.6 """
name = "Mobile Station Classmark 2"
fields_desc = [
XByteField("lengthMSC2", 0x3),
BitField("spare", 0x0, 1),
BitField("revisionLvl", 0x0, 2),
BitField("esInd", 0x0, 1),
BitField("a51", 0x0, 1),
BitField("rfPowerCap", 0x0, 3),
BitField("spare1", 0x0, 1),
BitField("psCap", 0x0, 1),
BitField("ssScreenInd", 0x0, 2),
BitField("smCaPabi", 0x0, 1),
BitField("vbs", 0x0, 1),
BitField("vgcs", 0x0, 1),
BitField("fc", 0x0, 1),
BitField("cm3", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("lcsvaCap", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("soLsa", 0x0, 1),
BitField("cmsp", 0x0, 1),
BitField("a53", 0x0, 1),
BitField("a52", 0x0, 1)
]
class DescriptiveGroupOrBroadcastCallReference(Packet):
""" Descriptive group or broadcast call reference Section 10.5.1.9 """
name = "Descriptive Group or Broadcast Call Reference"
fields_desc = [
BitField("binCallRef", 0x0, 27),
BitField("sf", 0x0, 1),
BitField("fa", 0x0, 1),
BitField("callPrio", 0x0, 3),
BitField("cipherInfo", 0x0, 4),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("spare4", 0x0, 1)
]
class PdAndSapi(Packet):
""" PD and SAPI $(CCBS)$ Section 10.5.1.10a """
name = "PD and SAPI $(CCBS)$"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("sapi", 0x0, 2),
BitField("pd", 0x0, 4)
]
class PriorityLevel(Packet):
""" Priority Level Section 10.5.1.11 """
name = "Priority Level"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("callPrio", 0x0, 3)
]
#
# Radio Resource management information elements
#
# len 6 to max for L3 message (251)
class BaRange(Packet):
""" BA Range Section 10.5.2.1a """
name = "BA Range"
fields_desc = [
XByteField("lengthBR", None),
# error: byte format requires -128 <= number <= 127
ByteField("nrOfRanges", 0x0),
# # rX = range X
# # L o = Lower H i = higher
# # H p = high Part Lp = low Part
ByteField("r1LoHp", 0x0),
BitField("r1LoLp", 0x0, 3),
BitField("r1HiHp", 0x0, 5),
BitField("r1HiLp", 0x0, 4),
BitField("r2LoHp", 0x0, 4),
# optional
BitField("r2LoLp", None, 5),
BitField("r2HiHp", None, 3),
ByteField("r2HiLp", None),
] + list(itertools.chain(*[[
ByteField("r%dLoHp" % x, None),
BitField("r%dLoLp" % x, None, 5),
BitField("r%dHiHp" % x, None, 3),
ByteField("r%dHiLp" % x, None),
] for x in range(3, 85)]))
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(5, 253, a, self.fields_desc, 1)
if self.lengthBR is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 3 to max for L3 message (251)
class BaListPref(Packet):
""" BA List Pref Section 10.5.2.1c """
name = "BA List Pref"
fields_desc = [
XByteField("lengthBLP", None),
BitField("fixBit", 0x0, 1),
BitField("rangeLower", 0x0, 10),
BitField("fixBit2", 0x0, 1),
BitField("rangeUpper", 0x0, 10),
BitField("baFreq", 0x0, 10),
BitField("sparePad", 0x0, 8)
]
# len 17 || Have a look at the specs for the field format
# Bit map 0 format
# Range 1024 format
# Range 512 format
# Range 256 format
# Range 128 format
# Variable bit map format
class CellChannelDescription(Packet):
""" Cell Channel Description Section 10.5.2.1b """
name = "Cell Channel Description "
fields_desc = [
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
ByteField("bit120", 0x0),
ByteField("bit112", 0x0),
ByteField("bit104", 0x0),
ByteField("bit96", 0x0),
ByteField("bit88", 0x0),
ByteField("bit80", 0x0),
ByteField("bit72", 0x0),
ByteField("bit64", 0x0),
ByteField("bit56", 0x0),
ByteField("bit48", 0x0),
ByteField("bit40", 0x0),
ByteField("bit32", 0x0),
ByteField("bit24", 0x0),
ByteField("bit16", 0x0),
ByteField("bit8", 0x0)
]
class CellDescription(Packet):
""" Cell Description Section 10.5.2.2 """
name = "Cell Description"
fields_desc = [
BitField("bcchHigh", 0x0, 2),
BitField("ncc", 0x0, 3),
BitField("bcc", 0x0, 3),
ByteField("bcchLow", 0x0)
]
class CellOptionsBCCH(Packet):
""" Cell Options (BCCH) Section 10.5.2.3 """
name = "Cell Options (BCCH)"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("pwrc", 0x0, 1),
BitField("dtx", 0x0, 2),
BitField("rLinkTout", 0x0, 4)
]
class CellOptionsSACCH(Packet):
""" Cell Options (SACCH) Section 10.5.2.3a """
name = "Cell Options (SACCH)"
fields_desc = [
BitField("dtx", 0x0, 1),
BitField("pwrc", 0x0, 1),
BitField("dtx", 0x0, 1),
BitField("rLinkTout", 0x0, 4)
]
class CellSelectionParameters(Packet):
""" Cell Selection Parameters Section 10.5.2.4 """
name = "Cell Selection Parameters"
fields_desc = [
BitField("cellReselect", 0x0, 3),
BitField("msTxPwrMax", 0x0, 5),
BitField("acs", None, 1),
BitField("neci", None, 1),
BitField("rxlenAccMin", None, 6)
]
class MacModeAndChannelCodingRequest(Packet):
""" MAC Mode and Channel Coding Requested Section 10.5.2.4a """
name = "MAC Mode and Channel Coding Requested"
fields_desc = [
BitField("macMode", 0x0, 2),
BitField("cs", 0x0, 2)
]
class ChannelDescription(Packet):
""" Channel Description Section 10.5.2.5 """
name = "Channel Description"
fields_desc = [
BitField("channelTyp", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x1, 1),
BitField("maioHi", 0x0, 4),
BitField("maioLo", 0x0, 2),
BitField("hsn", 0x0, 6)
]
class ChannelDescription2(Packet):
""" Channel Description 2 Section 10.5.2.5a """
name = "Channel Description 2"
fields_desc = [
BitField("channelTyp", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x0, 1),
# if h=1
# BitField("maioHi", 0x0, 4),
# BitField("maioLo", 0x0, 2),
# BitField("hsn", 0x0, 6)
BitField("spare", 0x0, 2),
BitField("arfcnHigh", 0x0, 2),
ByteField("arfcnLow", 0x0)
]
class ChannelMode(Packet):
""" Channel Mode Section 10.5.2.6 """
name = "Channel Mode"
fields_desc = [
ByteField("mode", 0x0)
]
class ChannelMode2(Packet):
""" Channel Mode 2 Section 10.5.2.7 """
name = "Channel Mode 2"
fields_desc = [
ByteField("mode", 0x0)
]
class ChannelNeeded(Packet):
""" Channel Needed Section 10.5.2.8 """
name = "Channel Needed"
fields_desc = [
BitField("channel2", 0x0, 2),
BitField("channel1", 0x0, 2),
]
class ChannelRequestDescription(Packet):
"""Channel Request Description Section 10.5.2.8a """
name = "Channel Request Description"
fields_desc = [
BitField("mt", 0x0, 1),
ConditionalField(BitField("spare", 0x0, 39),
lambda pkt: pkt.mt == 0),
ConditionalField(BitField("spare", 0x0, 3),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("priority", 0x0, 2),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("rlcMode", 0x0, 1),
lambda pkt: pkt.mt == 1),
ConditionalField(BitField("llcFrame", 0x1, 1),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("reqBandMsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("reqBandLsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("rlcMsb", 0x0),
lambda pkt: pkt.mt == 1),
ConditionalField(ByteField("rlcLsb", 0x0),
lambda pkt: pkt.mt == 1)
]
class CipherModeSetting(Packet):
"""Cipher Mode Setting Section 10.5.2.9 """
name = "Cipher Mode Setting"
fields_desc = [
BitField("algoId", 0x0, 3),
BitField("sc", 0x0, 1),
]
class CipherResponse(Packet):
"""Cipher Response Section 10.5.2.10 """
name = "Cipher Response"
fields_desc = [
BitField("spare", 0x0, 3),
BitField("cr", 0x0, 1),
]
class ControlChannelDescription(Packet):
"""Control Channel Description Section 10.5.2.11 """
name = "Control Channel Description"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("att", 0x0, 1),
BitField("bsAgBlksRes", 0x0, 3),
BitField("ccchConf", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("spare3", 0x0, 1),
BitField("spare4", 0x0, 1),
BitField("bsPaMfrms", 0x0, 3),
ByteField("t3212", 0x0)
]
class FrequencyChannelSequence(Packet):
"""Frequency Channel Sequence Section 10.5.2.12"""
name = "Frequency Channel Sequence"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("lowestArfcn", 0x0, 7),
] + [
BitField("skipArfcn" + "%02d" % x, 0x0, 4) for x in range(1, 17)
]
class FrequencyList(Packet):
"""Frequency List Section 10.5.2.13"""
name = "Frequency List"
# Problem:
# There are several formats for the Frequency List information
# element, distinguished by the "format indicator" subfield.
# Some formats are frequency bit maps, the others use a special encoding
# scheme.
fields_desc = [
XByteField("lengthFL", None),
BitField("formatID", 0x0, 2),
BitField("spare", 0x0, 2),
BitField("arfcn124", 0x0, 1),
BitField("arfcn123", 0x0, 1),
BitField("arfcn122", 0x0, 1),
BitField("arfcn121", 0x0, 1),
ByteField("arfcn120", 0x0),
ByteField("arfcn112", 0x0),
ByteField("arfcn104", 0x0),
ByteField("arfcn96", 0x0),
ByteField("arfcn88", 0x0),
ByteField("arfcn80", 0x0),
ByteField("arfcn72", 0x0),
ByteField("arfcn64", 0x0),
ByteField("arfcn56", 0x0),
ByteField("arfcn48", 0x0),
ByteField("arfcn40", 0x0),
ByteField("arfcn32", 0x0),
ByteField("arfcn24", 0x0),
ByteField("arfcn16", 0x0),
ByteField("arfcn8", 0x0)
]
# len 4 to 13
class GroupChannelDescription(Packet):
"""Group Channel Description Section 10.5.2.14b"""
name = "Group Channel Description"
fields_desc = [
XByteField("lengthGCD", None),
BitField("channelType", 0x0, 5),
BitField("tn", 0x0, 3),
BitField("tsc", 0x0, 3),
BitField("h", 0x0, 1),
# if h == 0 the packet looks the following way:
ConditionalField(BitField("spare", 0x0, 2),
lambda pkt: pkt. h == 0x0),
ConditionalField(BitField("arfcnHi", 0x0, 2),
lambda pkt: pkt. h == 0x0),
ConditionalField(ByteField("arfcnLo", None),
lambda pkt: pkt. h == 0x0),
# if h == 1 the packet looks the following way:
ConditionalField(BitField("maioHi", 0x0, 4),
lambda pkt: pkt. h == 0x1),
ConditionalField(BitField("maioLo", None, 2),
lambda pkt: pkt. h == 0x1),
ConditionalField(BitField("hsn", None, 6),
lambda pkt: pkt. h == 0x1),
# finished with conditional fields
ByteField("maC6", None),
ByteField("maC7", None),
ByteField("maC8", None),
ByteField("maC9", None),
ByteField("maC10", None),
ByteField("maC11", None),
ByteField("maC12", None),
ByteField("maC13", None),
ByteField("maC14", None)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(4, 13, a, self.fields_desc, 1)
if self.lengthGCD is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class GprsResumption(Packet):
"""GPRS Resumption Section 10.5.2.14c"""
name = "GPRS Resumption"
fields_desc = [
BitField("spare", 0x0, 3),
BitField("ack", 0x0, 1)
]
class HandoverReference(Packet):
"""Handover Reference Section 10.5.2.15"""
name = "Handover Reference"
fields_desc = [
ByteField("handoverRef", 0x0)
]
class IraRestOctets(Packet):
"""IAR Rest Octets Section 10.5.2.17"""
name = "IAR Rest Octets"
fields_desc = [
BitField("spare" + str(x), 0x1, 1) for x in range(1, 25)
]
# len is 1 to 5 what do we do with the variable size? no length
# field?! WTF
class IaxRestOctets(Packet):
"""IAX Rest Octets Section 10.5.2.18"""
name = "IAX Rest Octets"
fields_desc = [
BitField("spare01", 0x0, 1),
BitField("spare02", 0x0, 1),
BitField("spare03", 0x1, 1),
BitField("spare04", 0x0, 1),
BitField("spare05", 0x1, 1),
BitField("spare06", 0x0, 1),
BitField("spare07", 0x1, 1),
BitField("spare08", 0x1, 1),
ByteField("spareB1", None),
ByteField("spareB2", None),
ByteField("spareB3", None)
]
class L2PseudoLength(Packet):
"""L2 Pseudo Length Section 10.5.2.19"""
name = "L2 Pseudo Length"
fields_desc = [
BitField("l2pLength", None, 6),
BitField("bit2", 0x0, 1),
BitField("bit1", 0x1, 1)
]
class MeasurementResults(Packet):
"""Measurement Results Section 10.5.2.20"""
name = "Measurement Results"
fields_desc = [
BitField("baUsed", 0x0, 1),
BitField("dtxUsed", 0x0, 1),
BitField("rxLevFull", 0x0, 6),
BitField("spare", 0x0, 1),
BitField("measValid", 0x0, 1),
BitField("rxLevSub", 0x0, 6),
BitField("spare0", 0x0, 1),
BitField("rxqualFull", 0x0, 3),
BitField("rxqualSub", 0x0, 3),
BitField("noNcellHi", 0x0, 1),
BitField("noNcellLo", 0x0, 2),
BitField("rxlevC1", 0x0, 6),
BitField("bcchC1", 0x0, 5),
BitField("bsicC1Hi", 0x0, 3),
BitField("bsicC1Lo", 0x0, 3),
BitField("rxlevC2", 0x0, 5),
BitField("rxlevC2Lo", 0x0, 1),
BitField("bcchC2", 0x0, 5),
BitField("bsicC2Hi", 0x0, 2),
BitField("bscicC2Lo", 0x0, 4),
BitField("bscicC2Hi", 0x0, 4),
BitField("rxlevC3Lo", 0x0, 2),
BitField("bcchC3", 0x0, 5),
BitField("rxlevC3Hi", 0x0, 1),
BitField("bsicC3Lo", 0x0, 5),
BitField("bsicC3Hi", 0x0, 3),
BitField("rxlevC4Lo", 0x0, 3),
BitField("bcchC4", 0x0, 5),
BitField("bsicC4", 0x0, 6),
BitField("rxlevC5Hi", 0x0, 2),
BitField("rxlevC5Lo", 0x0, 4),
BitField("bcchC5Hi", 0x0, 4),
BitField("bcchC5Lo", 0x0, 1),
BitField("bsicC5", 0x0, 6),
BitField("rxlevC6", 0x0, 1),
BitField("rxlevC6Lo", 0x0, 5),
BitField("bcchC6Hi", 0x0, 3),
BitField("bcchC6Lo", 0x0, 3),
BitField("bsicC6", 0x0, 5)
]
class GprsMeasurementResults(Packet):
"""GPRS Measurement Results Section 10.5.2.20a"""
name = "GPRS Measurement Results"
fields_desc = [
BitField("cValue", 0x0, 6),
BitField("rxqualHi", 0x0, 2),
BitField("rxqL", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("signVar", 0x0, 6)
]
# len 3 to 10
class MobileAllocation(Packet):
"""Mobile Allocation Section 10.5.2.21"""
name = "Mobile Allocation"
fields_desc = [
XByteField("lengthMA", None),
ByteField("maC64", 0x12),
ByteField("maC56", None), # optional fields start here
ByteField("maC48", None),
ByteField("maC40", None),
ByteField("maC32", None),
ByteField("maC24", None),
ByteField("maC16", None),
ByteField("maC8", None)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 9, a, self.fields_desc, 1)
if self.lengthMA is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MobileTimeDifference(Packet):
"""Mobile Time Difference Section 10.5.2.21a"""
name = "Mobile Time Difference"
fields_desc = [
XByteField("lengthMTD", 0x5),
ByteField("valueHi", 0x0),
ByteField("valueCnt", 0x0),
BitField("valueLow", 0x0, 5),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1)
]
# min 4 octets max 8
class MultiRateConfiguration(Packet):
""" MultiRate configuration Section 10.5.2.21aa"""
name = "MultiRate Configuration"
# This packet has a variable length and hence structure. This packet
# implements the longest possible packet. If you build a shorter
# packet, for example having only 6 bytes, the last 4 bytes are named
# "Spare" in the specs. Here they are named "threshold2"
fields_desc = [
XByteField("lengthMRC", None),
BitField("mrVersion", 0x0, 3),
BitField("spare", 0x0, 1),
BitField("icmi", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("startMode", 0x0, 2),
ByteField("amrCodec", None),
BitField("spare", None, 2),
BitField("threshold1", None, 6),
BitField("hysteresis1", None, 4),
BitField("threshold2", None, 4),
BitField("threshold2cnt", None, 2),
BitField("hysteresis2", None, 4),
BitField("threshold3", None, 2),
BitField("threshold3cnt", None, 4),
BitField("hysteresis3", None, 4)
]
def post_build(self, p, pay):
# we set the length
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 7, a, self.fields_desc, 1)
if self.lengthMRC is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to 11
class MultislotAllocation(Packet):
"""Multislot Allocation Section 10.5.2.21b"""
name = "Multislot Allocation"
fields_desc = [
XByteField("lengthMSA", None),
BitField("ext0", 0x1, 1),
BitField("da", 0x0, 7),
ConditionalField(BitField("ext1", 0x1, 1), # optional
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("ua", 0x0, 7),
lambda pkt: pkt.ext0 == 0),
] + [ByteField("chan" + str(x), None) for x in range(1, 9)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 11, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthMSA is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
class NcMode(Packet):
"""NC mode Section 10.5.2.21c"""
name = "NC Mode"
fields_desc = [
BitField("spare", 0x0, 2),
BitField("ncMode", 0x0, 2)
]
class NeighbourCellsDescription(Packet):
"""Neighbour Cells Description Section 10.5.2.22"""
name = "Neighbour Cells Description"
fields_desc = [
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("extInd", 0x0, 1),
BitField("baInd", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("120bits", 0x0, 120)
]
class NeighbourCellsDescription2(Packet):
"""Neighbour Cells Description 2 Section 10.5.2.22a"""
name = "Neighbour Cells Description 2"
fields_desc = [
BitField("bit128", 0x0, 1),
BitField("multiband", 0x0, 2),
BitField("baInd", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("120bits", 0x0, 120)
]
# len 4
# strange packet, lots of valid formats
# ideas for the dynamic packets:
# 1] for user interaction: Create an interactive "builder" based on a
# Q/A process (not very scapy like)
# 2] for usage in scripts, create an alternative packet for every
# possible packet layout
#
class DedicatedModeOrTBF(Packet):
"""Dedicated mode or TBF Section 10.5.2.25b"""
name = "Dedicated Mode or TBF"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("tma", 0x0, 1),
BitField("downlink", 0x0, 1),
BitField("td", 0x0, 1)
]
class PageMode(Packet):
"""Page Mode Section 10.5.2.26"""
name = "Page Mode"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("pm", 0x0, 2)
]
class NccPermitted(Packet):
"""NCC Permitted Section 10.5.2.27"""
name = "NCC Permitted"
fields_desc = [
ByteField("nccPerm", 0x0)
]
class PowerCommand(Packet):
"""Power Command Section 10.5.2.28"""
name = "Power Command"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("spare2", 0x0, 1),
BitField("powerLvl", 0x0, 5)
]
class PowerCommandAndAccessType(Packet):
"""Power Command and access type Section 10.5.2.28a"""
name = "Power Command and Access Type"
fields_desc = [
BitField("atc", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("powerLvl", 0x0, 5)
]
class RachControlParameters(Packet):
"""RACH Control Parameters Section 10.5.2.29"""
name = "RACH Control Parameters"
fields_desc = [
BitField("maxRetrans", 0x0, 2),
BitField("txInteger", 0x0, 4),
BitField("cellBarrAccess", 0x0, 1),
BitField("re", 0x0, 1),
] + [BitField("ACC" + "%02d" % x, 0x0, 1) for x in range(15, -1, -1)]
class RequestReference(Packet):
"""Request Reference Section 10.5.2.30"""
name = "Request Reference"
fields_desc = [
ByteField("ra", 0x0),
BitField("t1", 0x0, 5),
BitField("t3Hi", 0x0, 3),
BitField("t3Lo", 0x0, 3),
BitField("t2", 0x0, 5)
]
class RrCause(Packet):
"""RR Cause Section 10.5.2.31"""
name = "RR Cause"
fields_desc = [
ByteField("rrCause", 0x0)
]
class StartingTime(Packet):
"""Starting Time Section 10.5.2.38"""
name = "Starting Time"
fields_desc = [
ByteField("ra", 0x0),
BitField("t1", 0x0, 5),
BitField("t3Hi", 0x0, 3),
BitField("t3Lo", 0x0, 3),
BitField("t2", 0x0, 5)
]
class SynchronizationIndication(Packet):
"""Synchronization Indication Section 10.5.2.39"""
name = "Synchronization Indication"
fields_desc = [
BitField("nci", 0x0, 1),
BitField("rot", 0x0, 1),
BitField("si", 0x0, 2)
]
class TimingAdvance(Packet):
"""Timing Advance Section 10.5.2.40"""
name = "Timing Advance"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1),
BitField("timingVal", 0x0, 6)
]
class TimeDifference(Packet):
""" Time Difference Section 10.5.2.41"""
name = "Time Difference"
fields_desc = [
XByteField("lengthTD", 0x3),
ByteField("timeValue", 0x0)
]
class Tlli(Packet):
""" TLLI Section Section 10.5.2.41a"""
name = "TLLI"
fields_desc = [
ByteField("value", 0x0),
ByteField("value1", 0x0),
ByteField("value2", 0x0),
ByteField("value3", 0x0)
]
class TmsiPTmsi(Packet):
""" TMSI/P-TMSI Section 10.5.2.42"""
name = "TMSI/P-TMSI"
fields_desc = [
ByteField("value", 0x0),
ByteField("value1", 0x0),
ByteField("value2", 0x0),
ByteField("value3", 0x0)
]
class VgcsTargetModeIdentication(Packet):
""" VGCS target Mode Indication 10.5.2.42a"""
name = "VGCS Target Mode Indication"
fields_desc = [
XByteField("lengthVTMI", 0x2),
BitField("targerMode", 0x0, 2),
BitField("cipherKeyNb", 0x0, 4),
BitField("spare", 0x0, 1),
BitField("spare1", 0x0, 1)
]
class WaitIndication(Packet):
""" Wait Indication Section 10.5.2.43"""
name = "Wait Indication"
fields_desc = [ # asciiart of specs strange
ByteField("timeoutVal", 0x0)
]
# class Si10RestOctets(Packet):
# """SI10 rest octets 10.5.2.44"""
# name = "SI10 rest octets"
# fields_desc = [
# len 17
class ExtendedMeasurementResults(Packet):
"""EXTENDED MEASUREMENT RESULTS Section 10.5.2.45"""
name = "Extended Measurement Results"
fields_desc = [
BitField("scUsed", None, 1),
BitField("dtxUsed", None, 1),
BitField("rxLevC0", None, 6),
BitField("rxLevC1", None, 6),
BitField("rxLevC2Hi", None, 2),
BitField("rxLevC2Lo", None, 4),
BitField("rxLevC3Hi", None, 4),
BitField("rxLevC3Lo", None, 3),
BitField("rxLevC4", None, 5),
BitField("rxLevC5", None, 6),
BitField("rxLevC6Hi", None, 2),
BitField("rxLevC6Lo", None, 4),
BitField("rxLevC7Hi", None, 4),
BitField("rxLevC7Lo", None, 2),
BitField("rxLevC8", None, 6),
BitField("rxLevC9", None, 6),
BitField("rxLevC10Hi", None, 2),
BitField("rxLevC10Lo", None, 4),
BitField("rxLevC11Hi", None, 4),
BitField("rxLevC13Lo", None, 2),
BitField("rxLevC12", None, 6),
BitField("rxLevC13", None, 6),
BitField("rxLevC14Hi", None, 2),
BitField("rxLevC14Lo", None, 4),
BitField("rxLevC15Hi", None, 4),
BitField("rxLevC15Lo", None, 2),
BitField("rxLevC16", None, 6),
BitField("rxLevC17", None, 6),
BitField("rxLevC18Hi", None, 2),
BitField("rxLevC18Lo", None, 4),
BitField("rxLevC19Hi", None, 4),
BitField("rxLevC19Lo", None, 2),
BitField("rxLevC20", None, 6)
]
# len 17
class ExtendedMeasurementFrequencyList(Packet):
"""Extended Measurement Frequency List Section 10.5.2.46"""
name = "Extended Measurement Frequency List"
fields_desc = [
BitField("bit128", 0x0, 1),
BitField("bit127", 0x0, 1),
BitField("spare", 0x0, 1),
BitField("seqCode", 0x0, 1),
BitField("bit124", 0x0, 1),
BitField("bit123", 0x0, 1),
BitField("bit122", 0x0, 1),
BitField("bit121", 0x0, 1),
BitField("bitsRest", 0x0, 128)
]
class SuspensionCause(Packet):
"""Suspension Cause Section 10.5.2.47"""
name = "Suspension Cause"
fields_desc = [
ByteField("suspVal", 0x0)
]
class ApduID(Packet):
"""APDU Flags Section 10.5.2.48"""
name = "Apdu Id"
fields_desc = [
BitField("id", None, 4)
]
class ApduFlags(Packet):
"""APDU Flags Section 10.5.2.49"""
name = "Apdu Flags"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("cr", 0x0, 1),
BitField("firstSeg", 0x0, 1),
BitField("lastSeg", 0x0, 1)
]
# len 1 to max L3 (251) (done)
class ApduData(Packet):
"""APDU Data Section 10.5.2.50"""
name = "Apdu Data"
fields_desc = [
XByteField("lengthAD", None),
# optional
] + [ByteField("apuInfo" + str(x), None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 250, a, self.fields_desc, 1)
if self.lengthAD is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
#
# 10.5.3 Mobility management information elements
#
# len 3 to L3 max (251) (done)
class NetworkName(Packet):
"""Network Name Section 10.5.3.5a"""
name = "Network Name"
fields_desc = [
XByteField("lengthNN", None),
BitField("ext", 0x1, 1),
BitField("codingScheme", 0x0, 3),
BitField("addCi", 0x0, 1),
BitField("nbSpare", 0x0, 3),
# optional
] + [ByteField("txtString" + str(x), None) for x in range(1, 249)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 250, a, self.fields_desc, 1)
if self.lengthNN is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class TimeZone(Packet):
"""Time Zone Section 10.5.3.8"""
name = "Time Zone"
fields_desc = [
ByteField("timeZone", 0x0),
]
class TimeZoneAndTime(Packet):
"""Time Zone and Time Section 10.5.3.9"""
name = "Time Zone and Time"
fields_desc = [
ByteField("year", 0x0),
ByteField("month", 0x0),
ByteField("day", 0x0),
ByteField("hour", 0x0),
ByteField("minute", 0x0),
ByteField("second", 0x0),
ByteField("timeZone", 0x0)
]
class CtsPermission(Packet):
"""CTS permission Section 10.5.3.10"""
name = "Cts Permission"
fields_desc = [
]
class LsaIdentifier(Packet):
"""LSA Identifier Section 10.5.3.11"""
name = "Lsa Identifier"
fields_desc = [
ByteField("lsaID", 0x0),
ByteField("lsaID1", 0x0),
ByteField("lsaID2", 0x0)
]
#
# 10.5.4 Call control information elements
#
# 10.5.4.1 Extensions of codesets
# This is only text and no packet
class LockingShiftProcedure(Packet):
"""Locking shift procedure Section 10.5.4.2"""
name = "Locking Shift Procedure"
fields_desc = [
BitField("lockShift", 0x0, 1),
BitField("codesetId", 0x0, 3)
]
class NonLockingShiftProcedure(Packet):
"""Non-locking shift procedure Section 10.5.4.3"""
name = "Non-locking Shift Procedure"
fields_desc = [
BitField("nonLockShift", 0x1, 1),
BitField("codesetId", 0x0, 3)
]
class AuxiliaryStates(Packet):
"""Auxiliary states Section 10.5.4.4"""
name = "Auxiliary States"
fields_desc = [
XByteField("lengthAS", 0x3),
BitField("ext", 0x1, 1),
BitField("spare", 0x0, 3),
BitField("holdState", 0x0, 2),
BitField("mptyState", 0x0, 2)
]
# len 3 to 15
class BearerCapability(Packet):
"""Bearer capability Section 10.5.4.5"""
name = "Bearer Capability"
fields_desc = [
XByteField("lengthBC", None),
BitField("ext0", 0x1, 1),
BitField("radioChReq", 0x1, 2),
BitField("codingStd", 0x0, 1),
BitField("transMode", 0x0, 1),
BitField("infoTransCa", 0x0, 3),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("coding", None, 1),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("spare", None, 2),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("speechVers", 0x0, 4),
lambda pkt: pkt.ext0 == 0),
ConditionalField(BitField("ext2", 0x1, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("compress", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("structure", None, 2),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("dupMode", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("config", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("nirr", None, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("establi", 0x0, 1),
lambda pkt: pkt.ext1 == 0),
BitField("ext3", None, 1),
BitField("accessId", None, 2),
BitField("rateAda", None, 2),
BitField("signaling", None, 3),
ConditionalField(BitField("ext4", None, 1),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("otherITC", None, 2),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("otherRate", None, 2),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("spare1", 0x0, 3),
lambda pkt: pkt.ext3 == 0),
ConditionalField(BitField("ext5", 0x1, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("hdr", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("multiFr", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("mode", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("lli", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("assig", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("inbNeg", None, 1),
lambda pkt: pkt.ext4 == 0),
ConditionalField(BitField("spare2", 0x0, 1),
lambda pkt: pkt.ext4 == 0),
BitField("ext6", None, 1),
BitField("layer1Id", None, 2),
BitField("userInf", None, 4),
BitField("sync", None, 1),
ConditionalField(BitField("ext7", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("stopBit", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("negoc", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("nbDataBit", None, 1),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("userRate", None, 4),
lambda pkt: pkt.ext6 == 0),
ConditionalField(BitField("ext8", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("interRate", None, 2),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("nicTX", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("nicRX", None, 1),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("parity", None, 3),
lambda pkt: pkt.ext7 == 0),
ConditionalField(BitField("ext9", None, 1),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("connEle", None, 2),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("modemType", None, 5),
lambda pkt: pkt.ext8 == 0),
ConditionalField(BitField("ext10", None, 1),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("otherModemType", None, 2),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("netUserRate", None, 5),
lambda pkt: pkt.ext9 == 0),
ConditionalField(BitField("ext11", None, 1),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("chanCoding", None, 4),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("maxTrafficChan", None, 3),
lambda pkt: pkt.ext10 == 0),
ConditionalField(BitField("ext12", None, 1),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("uimi", None, 3),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("airInterfaceUserRate", None, 4),
lambda pkt: pkt.ext11 == 0),
ConditionalField(BitField("ext13", 0x1, 1),
lambda pkt: pkt.ext12 == 0),
ConditionalField(BitField("layer2Ch", None, 2),
lambda pkt: pkt.ext12 == 0),
ConditionalField(BitField("userInfoL2", 0x0, 5),
lambda pkt: pkt.ext12 == 0)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 15, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthBC is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
class CallControlCapabilities(Packet):
"""Call Control Capabilities Section 10.5.4.5a"""
name = "Call Control Capabilities"
fields_desc = [
XByteField("lengthCCC", 0x3),
BitField("spare", 0x0, 6),
BitField("pcp", 0x0, 1),
BitField("dtmf", 0x0, 1)
]
class CallState(Packet):
"""Call State Section 10.5.4.6"""
name = "Call State"
fields_desc = [
BitField("codingStd", 0x0, 2),
BitField("stateValue", 0x0, 6)
]
# len 3 to 43
class CalledPartyBcdNumber(Packet):
"""Called party BCD number Section 10.5.4.7"""
name = "Called Party BCD Number"
fields_desc = [
XByteField("lengthCPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("nbPlanId", 0x0, 4),
# optional
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 80)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 42, a, self.fields_desc, 1)
if self.lengthCPBN is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to 23
class CalledPartySubaddress(Packet):
"""Called party subaddress Section 10.5.4.8"""
name = "Called Party Subaddress"
fields_desc = [
XByteField("lengthCPS", None),
# optional
BitField("ext", None, 1),
BitField("subAddr", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo" + str(x), None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 23, a, self.fields_desc, 1)
if self.lengthCPS is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 3 to 14
class CallingPartyBcdNumber(Packet):
"""Called party subaddress Section 10.5.4.9"""
name = "Called Party Subaddress"
fields_desc = [
XByteField("lengthCPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("nbPlanId", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", None, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", None, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", 0x0, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 20)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 13, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthCPBN is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
# len 2 to 23
class CallingPartySubaddress(Packet):
"""Calling party subaddress Section 10.5.4.10"""
name = "Calling Party Subaddress"
fields_desc = [
XByteField("lengthCPS", None),
# optional
BitField("ext1", None, 1),
BitField("typeAddr", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo" + str(x), None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 22, a, self.fields_desc, 1)
if self.lengthCPS is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 4 to 32
class Cause(Packet):
"""Cause Section 10.5.4.11"""
name = "Cause"
fields_desc = [
XByteField("lengthC", None),
BitField("ext", 0x1, 1),
BitField("codingStd", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("location", 0x0, 4),
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("recommendation", 0x1, 7),
lambda pkt: pkt.ext == 0),
# optional
BitField("ext2", None, 1),
BitField("causeValue", None, 7),
] + [ByteField("diagnositc" + str(x), None) for x in range(0, 27)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(3, 31, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthC is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
class ClirSuppression(Packet):
"""CLIR suppression Section 10.5.4.11a"""
name = "Clir Suppression"
fields_desc = [
]
class ClirInvocation(Packet):
"""CLIR invocation Section 10.5.4.11b"""
name = "Clir Invocation"
fields_desc = [
]
class CongestionLevel(Packet):
"""Congestion level Section 10.5.4.12"""
name = "Congestion Level"
fields_desc = [
BitField("notDef", 0x0, 4) # not defined by the std
]
# len 3 to 14
class ConnectedNumber(Packet):
"""Connected number Section 10.5.4.13"""
name = "Connected Number"
fields_desc = [
XByteField("lengthCN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("typePlanId", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", None, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", None, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", None, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 20)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 13, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthCN is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
# len 2 to 23
class ConnectedSubaddress(Packet):
"""Connected subaddress Section 10.5.4.14"""
name = "Connected Subaddress"
fields_desc = [
XByteField("lengthCS", None),
# optional
BitField("ext", None, 1),
BitField("typeOfSub", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo" + str(x), None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 22, a, self.fields_desc, 1)
if self.lengthCS is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to L3 (251) (done)
class Facility(Packet):
"""Facility Section 10.5.4.15"""
name = "Facility"
fields_desc = [
XByteField("lengthF", None),
# optional
] + [ByteField("facilityInfo" + str(x), None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(7, 250, a, self.fields_desc, 1)
if self.lengthF is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# len 2 to 5
class HighLayerCompatibility(Packet):
"""High layer compatibility Section 10.5.4.16"""
name = "High Layer Compatibility"
fields_desc = [
XByteField("lengthHLC", None),
# optional
BitField("ext", None, 1),
BitField("codingStd", None, 2),
BitField("interpret", None, 3),
BitField("presMeth", None, 2),
BitField("ext1", None, 1),
BitField("highLayerId", None, 7),
ConditionalField(BitField("ext2", 0x1, 1),
lambda pkt: pkt.ext1 == 0),
ConditionalField(BitField("exHiLayerId", 0x0, 7),
lambda pkt: pkt.ext1 == 0),
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 4, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthHLC is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
#
# 10.5.4.16.1 Static conditions for the high layer
# compatibility IE contents
#
class KeypadFacility(Packet):
"""Keypad facility Section 10.5.4.17"""
name = "Keypad Facility"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("keyPadInfo", 0x0, 7)
]
# len 2 to 15
class LowLayerCompatibility(Packet):
"""Low layer compatibility Section 10.5.4.18"""
name = "Low Layer Compatibility"
fields_desc = [
XByteField("lengthLLC", None),
# optional
] + [ByteField("rest" + str(x), None) for x in range(0, 13)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 14, a, self.fields_desc, 1)
if self.lengthLLC is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class MoreData(Packet):
"""More data Section 10.5.4.19"""
name = "More Data"
fields_desc = [
]
class NotificationIndicator(Packet):
"""Notification indicator Section 10.5.4.20"""
name = "Notification Indicator"
fields_desc = [
BitField("ext1", 0x1, 1),
BitField("notifDesc", 0x0, 7)
]
class ProgressIndicator(Packet):
"""Progress indicator Section 10.5.4.21"""
name = "Progress Indicator"
fields_desc = [
XByteField("lengthPI", 0x2),
BitField("ext", 0x1, 1),
BitField("codingStd", 0x0, 2),
BitField("spare", 0x0, 1),
BitField("location", 0x0, 4),
BitField("ext1", 0x1, 1),
BitField("progressDesc", 0x0, 7)
]
class RecallType(Packet):
"""Recall type $(CCBS)$ Section 10.5.4.21a"""
name = "Recall Type $(CCBS)$"
fields_desc = [
BitField("spare", 0x0, 5),
BitField("recallType", 0x0, 3)
]
# len 3 to 19
class RedirectingPartyBcdNumber(Packet):
"""Redirecting party BCD number Section 10.5.4.21b"""
name = "Redirecting Party BCD Number"
fields_desc = [
XByteField("lengthRPBN", None),
BitField("ext", 0x1, 1),
BitField("typeNb", 0x0, 3),
BitField("numberingPlan", 0x0, 4),
# optional
ConditionalField(BitField("ext1", 0x1, 1),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("presId", 0x0, 2),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("spare", 0x0, 3),
lambda pkt: pkt.ext == 0),
ConditionalField(BitField("screenId", 0x0, 2),
lambda pkt: pkt.ext == 0),
] + [
BitField("nbDigit" + (str(x + 1) if x % 2 != 0 else str(x - 1)), None, 4) for x in range(1, 31)
]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 18, a, self.fields_desc, 1)
if res[0] != 0:
p = p[:-res[0]]
if self.lengthRPBN is None:
p = chb(len(p) - 1) + p[1:]
return p + pay
# length 2 to 23
class RedirectingPartySubaddress(Packet):
"""Redirecting party subaddress Section 10.5.4.21c"""
name = "Redirecting Party BCD Number"
fields_desc = [
XByteField("lengthRPS", None),
# optional
BitField("ext", None, 1),
BitField("typeSub", None, 3),
BitField("oddEven", None, 1),
BitField("spare", None, 3),
] + [ByteField("subInfo" + str(x), None) for x in range(0, 20)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 22, a, self.fields_desc, 1)
if self.lengthRPS is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class RepeatIndicator(Packet):
"""Repeat indicator Section 10.5.4.22"""
name = "Repeat Indicator"
fields_desc = [
BitField("repeatIndic", 0x0, 4)
]
# no upper length min 2(max for L3) (251)
class SetupContainer(Packet):
"""SETUP Container $(CCBS)$ Section 10.5.4.22b"""
name = "Setup Container $(CCBS)$"
fields_desc = [
XByteField("lengthSC", None),
# optional
] + [ByteField("mess" + str(x), None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 250, a, self.fields_desc, 1)
if self.lengthSC is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class Signal(Packet):
"""Signal Section 10.5.4.23"""
name = "Signal"
fields_desc = [
ByteField("sigValue", 0x0)
]
# length 2 to max for L3 message (251)
class SsVersionIndicator(Packet):
"""SS Version Indicator Section 10.5.4.24"""
name = "SS Version Indicator"
fields_desc = [
XByteField("lengthSVI", None),
# optional
] + [ByteField("info" + str(x), None) for x in range(1, 250)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(1, 250, a, self.fields_desc, 1)
if self.lengthSVI is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
# length 3 to 35 or 131
class UserUser(Packet):
"""User-user Section 10.5.4.25"""
name = "User-User"
fields_desc = [
XByteField("lengthUU", None), # dynamic length of field depending
# of the type of message
# let user decide which length he
# wants to take
# => more fuzzing options
ByteField("userUserPD", 0x0),
# optional
] + [ByteField("userUserInfo" + str(x), None) for x in range(1, 132)]
def post_build(self, p, pay):
a = [getattr(self, fld.name) for fld in self.fields_desc]
res = _adapt(2, 133, a, self.fields_desc, 1)
if self.lengthUU is None:
p = chb(res[1]) + p[1:]
if res[0] != 0:
p = p[:-res[0]]
return p + pay
class AlertingPattern(Packet):
"""Alerting Pattern 10.5.4.26"""
name = "Alerting Pattern"
fields_desc = [
XByteField("lengthAP", 0x3),
BitField("spare", 0x0, 4),
BitField("alertingValue", 0x0, 4)
]
class AllowedActions(Packet):
"""Allowed actions $(CCBS)$ Section 10.5.4.26"""
name = "Allowed Actions $(CCBS)$"
fields_desc = [
XByteField("lengthAP", 0x3),
BitField("CCBS", 0x0, 1),
BitField("spare", 0x0, 7)
]
#
# 10.5.5 GPRS mobility management information elements
#
class AttachType(Packet):
"""Attach type Section 10.5.5.2"""
name = "Attach Type"
fields_desc = [
BitField("spare", 0x0, 1),
BitField("type", 0x1, 3)
]
Doc & TODO (if someone wants to fix the module)
### STATUS ###
This file was originaly located as http://0xbadcab1e.lu/scapy_gsm_um-howto.txt
but has been deleted since its creation. It was retrieved using the wayback machine
http://archive.org/web/
--> It should be used to create tests for the contrib/gsm_um module, which needs first
to be fixed on Python 3.
##############
This files shows how to create and send packets using scapy gsm-um addon. The
packets are taken out of [0]. The frames number at the top of each example are
a reference to the pcap capture.
+-------------------+
|- Examples |
Scapy GSM um Addon |- Sending messages |
================== |- Contact |
+-------------------+
- Examples:
---------
Frame 28
>>> a=immediateAssignment()
>>> a.channelTyp=12; a.tn=2; tsc=6; a.h=1; a.hsn=41; a.tsc=6; a.t1=4
>>> a.t2=0xf; a.t3Lo=1; a.ra=0x49; a.timingVal=1; a.maC64=0x;
>>> a.l2pLength=12
>>> hexdump(a)
0000 31 06 3F 00 62 D0 29 49 20 2F 01 01 03 1.?.b.)I /...
Frame 34
>>> a=cmServiceRequest()
>>> a.keySeq=3; a.serviceType=1
>>> a.revisionLvl=1; a.esInd=1; a.rfPowerCap=3; a.ssScreenInd=1;
>>> a.smCaPabi=1; a.fc=1; a.cm3=1; a.a52=1; a.idDigit1=0xf;
>>> a.idDigit2_1=2; a.idDigit2=0xe; a.idDigit3_1=4; a.idDigit3=8;
>>> a.idDigit4_1=4; a.idDigit4=1; a.idDigit5_1=1; a.idDigit5=5;
>>> hexdump(a)
0000 05 24 31 03 33 19 81 05 F4 2E 48 41 15 .$..3.....HA.
Frame 35
>>> a=classmarkChange(MobileStationClassmark3_presence=1)
>>> a.revisionLvl=1; a.esInd=1; a.rfPowerCap=3; a.ssScreenInd=1
>>> a.smCaPabi=1; a.fc=1; a.cm3=1; a.a52=1; a.byte2=0x60; a.byte3=0x14
>>> hexdump(a)
0000 06 16 03 33 19 81 20 60 14 00 00 00 00 00 00 00 ...3.. `........
0010 00 00 00 00 ....
Frame 36
>>> a=cipheringModeCommand()
>>> a.sc=1; a.cr=1
>>> hexdump(a)
0000 06 35 00 11 .5..
Frame 39
>>> a=releaseCompleteMsToNet(Cause_presence=1)
>>> a.codingStd=3; a.ext2=1; a.causeValue=16
>>> a.mesType=0x6a # due to the sequence number we need to change this
>>> hexdump(a)
0000 03 6A 08 02 E0 90 .j....
Frame 40
>>> a=cipheringModeComplete(MobileId_presence=1)
>>> a.idDigit1=3; a.typeOfId=3
>>> a.idDigit2_1=0; a.idDigit2=5; a.idDigit3_1=3; a.idDigit3=1
>>> a.idDigit4_1=2; a.idDigit4=7; a.idDigit5_1=6; a.idDigit5=0
>>> a.idDigit6_1=4;a.idDigit6=5;
>>> a.idDigit7_1=5;a.idDigit7=6; a.idDigit8_1=1; a.idDigit8=4
>>> a.idDigit9_1=0xf; a.idDigit9=0
>>> hexdump(a)
0000 06 32 17 09 33 05 31 27 60 45 56 14 F0 .2..3.1'`EV..
Frame 45
a=tmsiReallocationCommand()
>>> a.oddEven=1
>>> a.typeOfId=4
>>> a.idDigit2_1=2; a.idDigit2=e; a.idDigit3_1=4; a.idDigit3=8 ;
>>> a.idDigit4_1=e ; a.idDigit4=5 ; a.idDigit5_1=e ; a.idDigit5=0
>>> a.mccDigit2=0x4; a.mccDigit1=2; a.mccDigit3=6; a.mncDigit1=0
>>> a.mncDigit3=0xf; a.mncDigit2=0x3; a.lac1=0x0; a.lac2=0x4
>>> a.idDigit1=0xf; a.oddEven=0
>>> hexdump(a)
0000 05 1A 42 F6 30 00 04 05 F4 2E 48 E5 E0 ..B.0.....H..
Frame 47
>>> a=callProceeding()
>>> a.ti=8
>>> hexdump(a)
0000 83 02 ..
Frame 48
>>> a=tmsiReallocationComplete()
>>> hexdump(a)
0000 05 1B ..
Frame 51
>>> a=immediateAssignment()
>>> a.tsc=6; a.tn=5; a.channelTyp=1; a.codingStd=3;
>>> a.location=0xa; a.progressDesc=8; a.arfcnLow=0xff
>>> a.arfcnHigh=3; a.powerLvl=5
>>> hexdump(a)
0000 06 2E 0D C3 FF 05 ......
Frame 55
>>> a=assignmentComplete()
>>> hexdump(a)
0000 06 29 00 .).
Frame 60
>>> a=progress()
>>> a.ti=8; a.codingStd=3; a.location=0xa; a.progressDesc=8
>>> hexdump(a)
0000 83 03 02 EA 88 .....
Frame 65
>>> a=alertingNetToMs(ProgressIndicator_presence=1)
>>> a.ti=8; a.codingStd=3; a.location=0xa; a.progressDesc=8
>>> hexdump(a)
0000 83 01 1E 02 EA 88 ......
Frame 68
>>> a=connectNetToMs()
>>> a.ti=8
>>> hexdump(a)
0000 83 07 ..
Frame 70
>>> a=connectAcknowledge()
>>> a.mesType=0x4f
>>> hexdump(a)
0000 03 4F .O
Frame 88
>>> a=disconnectMsToNet()
>>> a.codingStd=3; a.ext2=1; a.causeValue=16
>>> hexdump(a)
0000 03 25 02 E0 90 .%...
Frame 90
>>> a=systemInformationType6()
>>> a.ciValue1=0x40; a.ciValue2=0x5c
>>> a.mccDigit2=4; a.mccDigit1=2; a.mncDigit3=0xf; a.mccDigit3=6;
>>> a.mncDigit2=3; a.mncDigit1=0; a.lac1=0; a.lac2=4
>>> a.l2pLength=11; a.nccPerm=0xc; a.dtx=1; a.rLinkTout=4
>>> hexdump(a)
0000 2D 06 1e 40 5C 42 F6 30 00 04 14 0C -.6@\B.0....
Frame 91
>>> a=releaseNetToMs()
>>> a.ti=8; a.codingStd=3; a.ext2=1; a.causeValue=16
>>> hexdump(a)
0000 83 2D 08 02 E0 90 .-....
Frame 94
>>> a=measurementReport()
>>> a.baUsed=1; a.dtxUsed=1; a.rxLevFull=39;
>>> a.noNcellHi=1; a.rxlevC1=38;
>>> a.bcchC1=4; a.bsicC1Hi=2; a.rxlevC2=18;
>>> a.bsicC1Hi=1; a.bsicC3Lo=1; a.bsicC3Hi=3;
>>> a.bcchC5Hi=10; a.bsicC6=29; a.bsicC5=18; a.bcchC6Hi=2;
>>> a.rxlevC6Lo=18; a.bcchC6Lo=2; a.bcchC6Hi=2;
>>> a.rxlevC5Lo=3; a.rxlevC5Hi=1; a.bsicC4=25;
>>> a.bcchC4=0xa; a.bcchC2=3;
>>> a.bsicC2Lo=0; a.bcchC2=3; a.bsicC1Hi=1;
>>> a.bsicC3Lo=25; a.bsicC1Hi=1; a.bscicC2Hi=6; a.rxLevSub=39;
>>> a.noNcellLo=2; a.rxlevC4Lo=3;
>>> a.rxlevC3Lo=3; a.bcchC3=12; a.bcchC5Hi=3;
>>> a.bsicC1Hi=2; a.bsicC2Hi=1
>>> hexdump(a)
0000 06 15 E7 27 01 A6 22 12 0D 06 D8 CB 6A 65 33 24 ...'..".....je3$
0010 92 5D .]
Frame 129
>>> a=systemInformationType3()
>>> a.mccDigit2=4; a.mccDigit1=2; a.mncDigit3=0xf; a.mccDigit3=6;
>>> a.mncDigit2=3; a.mncDigit1=0; a.lac1=0; a.lac2=04
>>> a.ciValue2=0x5c; a.t3212=0xc8; a.bsPaMfrms=7; a.dtx=1
>>> a.rLinkTout=4; a.cellReselect=4; a.msTxPwrMax=5; a.neci=1;
>>> a.maxRetrans=1; a.txInteger=9; a.re=1; a.byte1=0x80; a.byte5=0x1b
>>> hexdump(a)
0000 49 06 1B 40 5C 42 F6 30 00 04 48 07 C8 14 85 40 I..@\B.0..H....@
0010 65 00 00 80 00 00 00 1B e.......
Frame 158
>>> a=pagingRequestType1()
>>> a.idDigit1=0xf; a.l2pLength=5
>>> hexdump(a)
0000 15 06 21 00 01 F0 ..!...
Frame 168
>>> a=pagingRequestType1()
>>> a.idDigit1=0xf; a.typeOfId=4; a.idDigit2_1=0x2; a.idDigit2=0xe
>>> a.idDigit3_1=4; a.idDigit3=8; a.idDigit4=0xd; a.idDigit5=0xf
>>> a.l2pLength=9
>>> hexdump(a)
0000 25 06 21 00 05 F4 2E 48 0D 0F %.!....H..
Frame 179
>>> a=systemInformationType4()
>>> a.maxRetrans=1; a.txInteger=0x9; a.cellBarrAccess=0x0; a.re=1
>>> a.cellReselect=0x4; a.msTxPwrMax=0x5; a.neci=1; a.rxlenAccMin=0
>>> a.lac1=0x0; a.lac2=0x4; a.mccDigit2=0x4; a.mccDigit1=0x2
>>> a.mncDigit3=0xf; a.mccDigit3=0x3; a.l2pLength=12
>>> hexdump(a)
0000 31 06 1C 42 F6 30 00 04 85 40 65 00 00 1..B.0...@e..
Frame 179
>>> a=systemInformationType4()
>>> a.maxRetrans=1; a.txInteger=0x9; a.cellBarrAccess=0x0; a.re=1
>>> a.cellReselect=0x4; a.msTxPwrMax=0x5; a.neci=1; a.rxlenAccMin=0
>>> a.lac1=0x0; a.lac2=0x4; a.mccDigit2=0x4; a.mccDigit1=0x2
>>> a.mncDigit3=0xf; a.mccDigit3=0x3; a.l2pLength=12
>>> hexdump(a)
0000 31 06 1C 42 F6 30 00 04 85 40 65 00 00 1..B.0...@e..
[0]: http://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=view&target=gsm_call_1525.xml
- Sending messages:
-----------------
Use the sendum() method. It profides 3 ways to send messages over your prefered hardware.
* method 1:
UDP Socket (use parameter 0 (default)) Default port is 28670 (default for OpenBTS).
* method 2:
Unix Domain Socket (use parameter 1) Default file '/tmp/osmoL'.
* method 3:
TCP Socket (use parameter 2) Default port is 43797.
Example:
>>> semdum(systemInformationType4(),1)
if you want to send your layer3 message over a Unix Domain Socket.
- Contact:
--------
Bugs, feedback: <k@0xbadcab1e.lu>