smalltalk
/
osmo-st-gsm
Archived
1
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
osmo-st-gsm/GSM48.st

3220 lines
97 KiB
Smalltalk

"
(C) 2010-2012 by Holger Hans Peter Freyther
All Rights Reserved
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"
"Messages for GSM04.08"
"""
IEs for GSM48MSG
"""
IEBase subclass: GSM48IE [
<category: 'OsmoGSM'>
<comment: 'I am a Information Element for GSM48'>
GSM48IE class [
| gsmName gsmElementId gsmIeMask |
gsmName: aName [
<category: 'gsm-pragma'>
gsmName := aName asSymbol
]
gsmElementId: anId [
<category: 'gsm-pragma'>
gsmElementId := anId
]
gsmIeMask: aMask [
<category: 'gsm-pragma'>
gsmIeMask := aMask
]
ieMask [
"Some IEs encode the IE and the value into one. Return the mask to be used
to determine the IE and see if it is matching."
<category: 'parsing'>
^ gsmIeMask ifNil: [16rFF]
]
gsmName [
<category: 'gsm-pragma'>
^gsmName
]
gsmElementId [
<category: 'gsm-pragma'>
^gsmElementId
]
gsmIeMask [
<category: 'gsm-pragma'>
^gsmIeMask
]
classPragmas [
<category: 'gsm-pragma'>
^super classPragmas, #(#gsmName #gsmElementId #gsmIeMask)
]
]
GSM48IE class >> elementId [
<category: 'gsm-pragma'>
^ gsmElementId
]
GSM48IE class >> asTLVDescription [
<category: 'parsing'>
^ Osmo.TLVDescription new
tag: gsmElementId; parseClass: self;
instVarName: gsmName; yourself
]
]
GSM48IE subclass: GSM48FixedSizeIE [
<category: 'OsmoGSM'>
<comment: 'I am a base class for fixed size values. TV, T, V'>
GSM48FixedSizeIE class [
| gsmValueLength |
gsmValueLength: aLength [
<category: 'gsm-pragma'>
gsmValueLength := aLength
]
classPragmas [
<category: 'gsm-pragma'>
^super classPragmas, #(#gsmValueLength)
]
length: aStream [
<category: 'parsing'>
^ self gsmValueLength
]
length [
<category: 'parsing'>
"TODO: deprecate and remove"
^ self gsmValueLength
]
gsmValueLength [
<category: 'parsing'>
^ gsmValueLength ifNil: [
self = GSM48FixedSizeIE
ifTrue: [nil]
ifFalse: [self superclass gsmValueLength]]
]
asTLVDescription [
<category: 'parsing'>
^ super asTLVDescription
beTV; valueSize: gsmValueLength; yourself
]
]
]
GSM48IE subclass: GSM48VariableSizedIE [
<category: 'OsmoGSM'>
<comment: 'I am a baseclass for variable sized IEs'>
GSM48VariableSizedIE class [
| gsmValueRange |
length: aStream [
<category: 'parsing'>
^ aStream peek + 1
]
asTLVDescription [
<category: 'parsing'>
^ super asTLVDescription
minSize: self validSizes first maxSize: self validSizes last;
beTLV; yourself
]
gsmMinValueSize: aMin max: aMax [
<category: 'gsm-pragma'>
gsmValueRange := aMin to: aMax.
]
gsmValueSizeMin [
<category: 'gsm-pragma'>
^(self = GSM48VariableSizedIE or: [self = GSM48DataHolder])
ifTrue: [nil]
ifFalse: [gsmValueRange first]
]
gsmValueSizeMax [
<category: 'gsm-pragma'>
^(self = GSM48VariableSizedIE or: [self = GSM48DataHolder])
ifTrue: [nil]
ifFalse: [gsmValueRange last]
]
gsmValueSizeMin: aMin [
| last |
<category: 'gsm-pragma'>
last := gsmValueRange isNil
ifTrue: [aMin]
ifFalse: [gsmValueRange last].
gsmValueRange := aMin to: last.
]
gsmValueSizeMax: aMax [
| first |
<category: 'gsm-pragma'>
first := gsmValueRange isNil
ifTrue: [aMax]
ifFalse: [gsmValueRange first].
gsmValueRange := first to: aMax.
]
classPragmas [
<category: 'gsm-pragma'>
"The gsmMinValueSize:max: can not be expressed right now."
^super classPragmas, #(#gsmValueSizeMin #gsmValueSizeMax).
]
validSizes [
<category: 'parsing'>
"Default size"
^ gsmValueRange ifNil: [1 to: 180].
]
]
]
GSM48FixedSizeIE subclass: GSM48SimpleTag [
| value |
<category: 'OsmoGSM'>
<comment: 'I am a simple Tag. Some TAGs even share the value in there'>
<gsmIeMask: 16rF0>
<gsmValueLength: 0>
GSM48SimpleTag class >> initWithData: aData [
^ self new
value: aData;
yourself
]
GSM48SimpleTag class >> asTLVDescription [
<category: 'parsing'>
^ super asTLVDescription beTagOnly; valueSize: 0; yourself
]
value: aValue [
| inv |
inv := 255 - self class ieMask.
value := (aValue bitAnd: inv)
]
value [
^ value ifNil: [ 0 ]
]
writeOn: aMsg [
| combined |
combined := self class elementId bitOr: value.
aMsg putByte: combined.
]
writeOnDirect: aMsg [
self shouldNotImplement
]
]
GSM48VariableSizedIE subclass: GSM48DataHolder [
| data |
<category: 'OsmoGSM'>
<comment: 'A simple wrapper for the lazy ones'>
GSM48DataHolder class >> createDefault [
| size data |
size := self validSizes first.
data := ByteArray new: size.
^ self new data: data; yourself.
]
GSM48DataHolder class >> initWithData: aData [
^ self new
data: aData;
yourself.
]
GSM48DataHolder class >> parseFrom: aStream [
| len |
len := aStream next.
^ self initWithData: (aStream next: len)
]
data: aData [
| size |
"Add the size for the length header"
(self class validSizes includes: aData size)
ifFalse: [
^ self error: 'The data is not of a valid size: %1 "%2"' % {aData size. self class validSizes}.
].
data := aData.
]
data [ ^ data ]
writeOn: aMsg [
aMsg putByte: self class elementId.
aMsg putByte: data size.
aMsg putByteArray: data.
]
writeOnDirect: aMsg [
aMsg putByte: data size.
aMsg putByteArray: data.
]
]
GSM48FixedSizeIE subclass: GSM48SimpleData [
| data |
<category: 'OsmoGSM'>
<comment: 'I am the base for some simple data encapsulated'>
GSM48SimpleData class >> initWithData: aData [
^ self new
data: aData;
yourself.
]
GSM48SimpleData class >> defaultValue [
^ ByteArray new: self length
]
GSM48SimpleData class >> createDefault [
^ self new
data: self defaultValue;
yourself
]
GSM48SimpleData class >> parseFrom: aStream [
| dat |
dat := aStream next: self length.
^ self new
data: dat;
yourself
]
data [
^ data
]
data: aData [
aData size = self class length
ifFalse: [
Error signal: 'DATA needs to be ', self class length asString, ' long.',
'But it was ', aData size asString, ' long.'.
].
data := aData.
]
writeOnDirect: aMsg [
aMsg putByteArray: data.
]
writeOn: aMsg [
"Write a TV"
aMsg putByte: self class elementId.
self writeOnDirect: aMsg
]
]
GSM48SimpleData subclass: GSM48PageAndDedicatedMode [
<category: 'OsmoGSM'>
<comment: 'I represent IE 10.5.2.26 and 10.5.2.25b'>
<gsmName: 'pageAndDedicatedMode'>
<gsmValueLength: 1>
]
GSM48SimpleData subclass: GSM48CellDescription [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.2 Cell Description'>
<gsmName: 'cellDescription'>
<gsmValueLength: 2>
ncc [
<category: 'accessing'>
^ (data first bitShift: -3) bitAnd: 2r111
]
bcc [
<category: 'accessing'>
^ (data first bitShift: -0) bitAnd: 2r111
]
bcch [
| hi low |
hi := data first bitShift: -6.
low := data second.
^ (hi bitShift: 8) bitOr: low.
]
]
GSM48SimpleData subclass: GSM48ChannelDescription [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.5 channel description'>
<gsmName: 'channelDescription'>
<gsmValueLength: 3>
timeslotNumber [
<category: 'channel-description'>
^ (data at: 1) bitAnd: 2r111
]
channelType [
<category: 'channel-description'>
^ (data at: 1) bitShift: -3
]
]
GSM48SimpleData subclass: GSM48ChannelDescription2 [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.5a channel description 2'>
<gsmName: 'channelDescription2'>
<gsmValueLength: 3>
channelType [
<category: 'accessing'>
^ data first bitShift: -3.
]
timeSlot [
^ data first bitAnd: 2r111
]
isH1 [
^ (data second bitAt: 5) = 1
]
isH0 [
^ (data second bitAt: 5) = 0
]
arfcn [
| low |
self isH0 ifFalse: [^self error: 'ARFCN requires H=0'].
low := data second bitAnd: 2r11.
^ (low bitShift: 8) bitOr: data third.
]
]
GSM48SimpleData subclass: GSM48ChannelMode [
| mode |
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.6'>
<gsmName: 'channelMode'>
<gsmValueLength: 1>
GSM48ChannelMode class [
modeSignallingOnly [ <category: 'attr'> ^ 2r00000000 ]
modeSpeechVersion1 [ <category: 'attr'> ^ 2r00000001 ]
modeSpeechVersion2 [ <category: 'attr'> ^ 2r00100001 ]
modeSpeechVersion3 [ <category: 'attr'> ^ 2r01000001 ]
modeData145 [ <category: 'attr'> ^ 2r00001111 ]
modeData120 [ <category: 'attr'> ^ 2r00000011 ]
modeData60 [ <category: 'attr'> ^ 2r00001011 ]
modeData36 [ <category: 'attr'> ^ 2r00010011 ]
]
GSM48ChannelMode class >> defaultValue [
<category: 'creation'>
^ ByteArray with: self modeSignallingOnly
]
mode [
^ data first
]
mode: aMode [
data := ByteArray with: aMode.
]
]
GSM48SimpleData subclass: GSM48ChannelMode2 [
| mode |
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.7 channel mode2'>
<gsmName: 'channelMode2'>
<gsmValueLength: 1>
<gsmElementId: 16r66>
]
GSM48ChannelDescription subclass: GSM48ChannelOrPacketDescription [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.5 or 10.5.2.25a. Conditionals
can not be easily expressed yet.'>
<gsmName: 'channelOrPacketDescription'>
"broken stuff.. I really need to add a proper conditional
checking here..."
]
GSM48SimpleTag subclass: GSM48CipherModeSetting [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.9 cipher mode setting'>
<gsmName: 'cipherModeSetting'>
<gsmIeMask: 16rF0>
<gsmElementId: 16r90>
]
GSM48SimpleData subclass: GSM48CipherModeSettingResponse [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.9 cipher mode setting and the
10.5.2.10 cipher response. We still need to implement 4bit values
and fix the parser to consume/write only half bits..'>
<gsmName: 'cipherModeSettingResponse'>
<gsmValueLength: 1>
]
GSM48SimpleData subclass: GSM48FrequencyChannelSequence [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.12 Frequency channel sequence'>
<gsmName: 'frequencySequence'>
<gsmElementId: 16r1E>
<gsmValueLength: 9>
]
GSM48DataHolder subclass: GSM48FrequencyList [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.13 frequency list'>
<gsmName: 'frequencyList'>
<gsmElementId: 16r19>
<gsmMinValueSize: 2 max: 129>
]
GSM48SimpleData subclass: GSM48FrequencyShortList [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.14 frequency short list'>
<gsmName: 'frequencyShortList'>
<gsmElementId: 16r12>
<gsmValueLength: 8>
]
GSM48SimpleData subclass: GSM48HandoverReference [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.15 handover reference'>
<gsmName: 'handoverReference'>
<gsmValueLength: 1>
value [
<category: 'accessing'>
^ data first
]
]
GSM48DataHolder subclass: GSM48MultislotAllocation [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.21b multi slot allocation'>
<gsmName: 'multiSlotAllocation'>
<gsmMinValueSize: 1 max: 10>
<gsmElementId: 16r10>
]
GSM48SimpleData subclass: GSM48PowerCommandAndAccess [
<category: 'OsmoGSM'>
<comment: 'I represnt a 10.5.2.28a power command and access'>
<gsmName: 'powerCommandAndAccess'>
<gsmValueLength: 1>
]
GSM48SimpleData subclass: GSM48TimingAdvance [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.40'>
<gsmName: 'timingAdvance'>
<gsmValueLength: 1>
]
GSM48SimpleData subclass: GSM48TimingDifference [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.41 real time difference'>
<gsmName: 'timingDifference'>
<gsmValueLength: 1>
]
GSM48DataHolder subclass: GSM48VGCSTargetModeIndication [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.42a'>
<gsmName: 'vgcsTargetMode'>
<gsmMinValueSize: 1 max: 1>
]
GSM48SimpleData subclass: GSM48StartingTime [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.38'>
<gsmName: 'startingTime'>
<gsmValueLength: 3>
<gsmElementId: 16r7C>
]
GSM48SimpleTag subclass: GSM48SynchronizationInd [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.39'>
<gsmName: 'syncInd'>
<gsmElementId: 16rD0>
<gsmIeMask: 16rF0>
]
GSM48SimpleData subclass: GSM48RequestReference [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.30 Request Reference'>
<gsmName: 'requestReference'>
<gsmValueLength: 3>
ra [
<category: 'decoding'>
^ data at: 1
]
t1 [
<category: 'decoding'>
^ (data at: 2) bitShift: - 3
]
t2 [
<category: 'decoding'>
^ (data at: 3) bitAnd: 2r00011111
]
t3 [
| high low |
<category: 'decoding'>
high := (data at: 2) bitAnd: 2r111.
low := (data at: 3) bitShift: -5.
^ low bitOr: (high bitShift: 3)
]
]
GSM48DataHolder subclass: GSM48IARestOctets [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 IA Rest Octets as of 10.5.2.16'>
<gsmName: 'rest_octets'>
<gsmMinValueSize: 0 max: 11>
GSM48IARestOctets class >> length: aStream [
<category: 'parsing'>
self shouldNotImplement
]
GSM48IARestOctets class >> asTLVDescription [
<category: 'parsing'>
^ super asTLVDescription beTV; yourself
]
GSM48IARestOctets class >> parseFrom: aStream [
<category: 'parsing'>
"Consume the rest of the stream. There is no length for the octets"
^ self initWithData: (aStream upToEnd)
]
writeOn: aMsg [
<category: 'serialization'>
^ self shouldNotImplement
]
writeOnDirect: aMsg [
<category: 'serialization'>
aMsg putByteArray: self data
]
]
GSM48DataHolder subclass: GSM48MobileAllocation [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 Mobile Allocation as of 10.5.2.21'>
<gsmName: 'mobileAllocation'>
<gsmMinValueSize: 0 max: 8>
]
GSM48DataHolder subclass: GSM48MultiRateConfiguration [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 Multi-rate configuration as of
10.5.2.21aa'>
<gsmName: 'multiRate'>
<gsmElementId: 16r03>
<gsmMinValueSize: 2 max: 6>
]
GSM48SimpleData subclass: GSM48KeySeqLuType [
<category: 'OsmoGSM'>
<comment: 'This byte is shared for two things. 10.5.3.5 location updating
type and the 10.5.1.2 for the ciphering key state. TODO: use the bitfield
class for both of them.'>
<gsmName: 'luType'>
<gsmValueLength: 1>
GSM48KeySeqLuType class >> cmTypeMOCall [ <category: 'cm-types'> ^ 2r0001 ]
GSM48KeySeqLuType class >> cmTypeEmergency [ <category: 'cm-types'> ^ 2r0010 ]
GSM48KeySeqLuType class >> cmTypeSMS [ <category: 'cm-types'> ^ 2r0100 ]
GSM48KeySeqLuType class >> cmTypeSS [ <category: 'cm-types'> ^ 2r1000 ]
GSM48KeySeqLuType class >> cmTypeVGCall [ <category: 'cm-types'> ^ 2r1001 ]
GSM48KeySeqLuType class >> cmTypeVBCall [ <category: 'cm-types'> ^ 2r1010 ]
GSM48KeySeqLuType class >> cmTypeLocation [ <category: 'cm-types'> ^ 2r1011 ]
GSM48KeySeqLuType class >> luFollowOnRequest [ <category: 'lu-for'> ^ 2r1000 ]
GSM48KeySeqLuType class >> luTypeNormal [ <category: 'lu-type'> ^ 2r00 ]
GSM48KeySeqLuType class >> luTypePeriodic [ <category: 'lu-type'> ^ 2r01 ]
GSM48KeySeqLuType class >> luTypeIMSIAttach [ <category: 'lu-type'> ^ 2r10 ]
GSM48KeySeqLuType class >> luTypeReserved [ <category: 'lu-type'> ^ 2r11 ]
GSM48KeySeqLuType class >> createDefault [
<category: 'creation'>
^ (self new)
val: 16r70;
yourself
]
luType: aVal [
| tmp |
<category: 'creation'>
tmp := self val clearBit: 2r11.
tmp := tmp bitOr: (aVal bitAnd: 2r11).
self val: tmp.
]
val [
<category: 'direct-access'>
^ self data at: 1
]
val: aVal [
<category: 'creation'>
self data: (ByteArray with: aVal).
]
]
GSM48FixedSizeIE subclass: GSM48Lai [
| lai lac |
<category: 'OsmoGSM'>
<gsmName: 'lai'>
<gsmValueLength: 5>
GSM48Lai class >> createDefault [
<category: 'creation'>
^ (self new)
lai: (LAI initWith: 0 mnc: 0);
lac: 0;
yourself
]
GSM48Lai class >> parseFrom: aStream [
"TODO: as nextUShort to the ReadStream..."
^ (self new)
lai: (LAI parseFrom: aStream);
lac: ((aStream next: 2) asByteArray ushortAt: 1) swap16;
yourself
]
mcc: aMcc [ <category: 'creation'> lai mcc: aMcc ]
mnc: aMnc [ <category: 'creation'> lai mnc: aMnc ]
lai: aLai [ <category: 'creation'> lai := aLai ]
lac: aLac [ <category: 'creation'> lac := aLac ]
mcc [ ^ lai mcc ]
mnc [ ^ lai mnc ]
lac [ ^ lac ]
writeOnDirect: aMsg [
<category: 'creation'>
lai writeOn: aMsg.
aMsg putLen16: lac.
]
]
GSM48FixedSizeIE subclass: GSM48Classmark1 [
| cm1 |
<category: 'OsmoGSM'>
<gsmName: 'cm1'>
<gsmValueLength: 1>
GSM48Classmark1 class >> createDefault [
<category: 'creation'>
^ (self new)
cm1: 16r33;
yourself
]
GSM48Classmark1 class >> parseFrom: aStream [
^ (self new)
cm1: aStream next;
yourself
]
cm1: aCm [ <category: 'creation'> cm1 := aCm ]
cm1 [ ^ cm1 ]
writeOnDirect: aMsg [
<category: 'creation'>
aMsg putByte: cm1.
]
]
GSM48DataHolder subclass: GSM48Classmark2 [
"TODO: This is broken... it needs to be a simple data holder"
<category: 'OsmoGSM'>
<comment: 'I am CM2 of 10.5.1.6'>
<gsmName: 'cm2'>
<gsmMinValueSize: 3 max: 3>
GSM48Classmark2 class >> createDefault [
^ self new
data: self defaultValue;
yourself
]
GSM48Classmark2 class >> defaultValue [
^ ByteArray with: 16r33 with: 16r19 with: 16rA2.
]
]
GSM48DataHolder subclass: GSM48Classmark3 [
<category: 'OsmoGSM'>
<comment: 'I am CM3 of 10.5.1.7'>
<gsmName: 'cm3'>
<gsmElementId: 2r00100000>
<gsmMinValueSize: 2 max: 12>
GSM48Classmark3 class >> createDefault [
<category: 'creation'>
^ self new
data: self defaultValue; yourself
]
GSM48Classmark3 class >> defaultValue [
<category: 'default'>
^ #(16r60 16r14 16r4C 16r8F 16r60 16r3B 16r88 16r00 16r90) asByteArray.
]
]
GSM48VariableSizedIE subclass: GSM48MIdentity [
| type id |
<category: 'OsmoGSM'>
<comment: 'I am MobileIdentity of 10.5.1.4'>
<gsmElementId: 23>
<gsmName: 'mi'>
<gsmMinValueSize: 1 max: 8>
GSM48MIdentity class >> createDefault [
<category: 'creation'>
^ (self new)
imsi: '000000000000';
yourself
]
GSM48MIdentity class >> parseFrom: aStream [
^ self parseFrom: aStream length: aStream next
]
GSM48MIdentity class >> parseFrom: aStream length: len [
| head type id |
head := aStream next.
type := head bitAnd: 16r7.
id := type = GSM48IdentityType typeTMSI
ifTrue: [self parseTMSI: aStream length: len head: head]
ifFalse: [self parseBCDId: aStream length: len head: head].
^ self new
type: type;
id: id;
yourself
]
GSM48MIdentity class >> parseTMSI: aStream length: aLength head: aHead [
aLength = 5
ifFalse: [^self error: 'MI should be five bytes'].
^ aStream next: 4.
]
GSM48MIdentity class >> parseBCDId: aStream length: aLength head: aHead [
| digits odd |
digits := OrderedCollection new.
odd := (aHead bitShift: -3) bitAnd: 16r1.
digits add: ((aHead bitShift: -4) bitAnd: 16rF).
3 to: (1 + aLength) do: [:each | | val |
val := aStream next.
digits add: (val bitAnd: 16rF).
digits add: ((val bitShift: -4) bitAnd: 16rF).
].
"The last was just a dummy value"
odd = 1 ifFalse: [
digits removeLast.
].
^ (BCD decode: digits) asString.
]
imsi: anImsi [
<category: 'creation'>
type := GSM48IdentityType typeIMSI.
self id: anImsi.
]
imsi [
<category: 'access'>
self type = GSM48IdentityType typeIMSI
ifFalse: [^self error: 'Underlying type is not an IMSI'].
^ id
]
imei: anImei [
<category: 'creation'>
type := GSM48IdentityType typeIMEI.
self id: anImei.
]
imei [
<category: 'query'>
self type = GSM48IdentityType typeIMEI
ifFalse: [^self error: 'Underlying type is not an IMEI'].
^ id
]
tmsi: aTmsi [
<category: 'query'>
aTmsi size = 4
ifFalse: [^self error: 'TMSI must be four bytes'].
type := GSM48IdentityType typeTMSI.
self id: aTmsi.
]
tmsi [
<category: 'query'>
self type = GSM48IdentityType typeTMSI
ifFalse: [^self error: 'Underlying type is not a TMSI'].
^ id
]
id: anId [
<category: 'creation'>
id := anId
]
type: aType [
<category: 'creation'>
type := aType
]
type [
<category: 'access'>
^ type bitAnd: 2r111
]
writeOnDirect: aMsg [
<category: 'creation'>
type = GSM48IdentityType typeTMSI
ifTrue: [self storeTMSIOn: aMsg]
ifFalse: [self storeBCDIdentityOn: aMsg].
]
storeTMSIOn: aMsg [
aMsg
putByte: 5;
putByte: (type bitOr: 16rF0);
putByteArray: id.
]
storeBCDIdentityOn: aMsg [
| odd len head encoded bcds |
<category: 'private'>
odd := id size odd.
"Calculate the length. We can fit two digits into one byte"
len := odd
ifTrue: [ (id size + 1) / 2 ]
ifFalse: [ (id size / 2) + 1 ].
aMsg putByte: len.
"Create the first data"
head := ((id at: 1) digitValue) bitShift: 4.
odd ifTrue: [
head := head bitOr: (1 bitShift: 3).
].
head := head bitOr: self type.
aMsg putByte: head.
"Encode everything from 2..n into a ByteArray of len - 1"
bcds := OrderedCollection new.
2 to: id size do: [:pos |
bcds add: (id at: pos) digitValue.
].
odd ifFalse: [
bcds add: 16r0F.
].
"now fold the bcds into and encoded array"
encoded := OrderedCollection new.
1 to: bcds size by: 2 do: [:pos |
| lower upper |
lower := bcds at: pos.
upper := bcds at: pos + 1.
encoded add: ((upper bitShift: 4) bitOr: lower).
].
aMsg putByteArray: encoded asByteArray.
]
]
GSM48SimpleData subclass: GSM48RejectCause [
<category: 'OsmoGSM'>
<gsmName: 'cause'>
<gsmValueLength: 1>
GSM48RejectCause class [
causeImsiUnknownInHlr [ <category: 'cause'> ^ 2r00000010 ]
causeIllegalMS [ <category: 'cause'> ^ 2r00000011 ]
causeImsiUnknownInVLR [ <category: 'cause'> ^ 2r00000100 ]
causeIMEINotAccepted [ <category: 'cause'> ^ 2r00000101 ]
causeIllegalME [ <category: 'cause'> ^ 2r00000110 ]
causePLMNNotAllowed [ <category: 'cause'> ^ 2r00001011 ]
causeLocationAreaNotAllowed [ <category: 'cause'> ^ 2r00001100 ]
causeRoamingNotAllowedInLAC [ <category: 'cause'> ^ 2r00001101 ]
cuaseNetworkFailure [ <category: 'cause'> ^ 2r00010001 ]
causeCongestion [ <category: 'cause'> ^ 2r00010110 ]
cuaseServiceOptionNotSupported [ <category: 'cause'> ^ 2r00100000 ]
causeRequestedServiceOptionNotSubscribed [ <category: 'cause'> ^ 2r00100001 ]
causeServiceOptionTemporarilyOutOfOrder [ <category: 'cause'> ^ 2r00100010 ]
causeCallCannotBeIdentified [ <category: 'cause'> ^ 2r00100110 ]
causeSemanticallyIncorrectMessage [ <category: 'cause'> ^ 2r01011111 ]
causeInvalidMandatoryInformation [ <category: 'cause'> ^ 2r01100000 ]
causeMessageTypeNonExistentOrNotImplemented [ <category: 'cause'> ^ 2r01100001 ]
causeMessageTypeNotCompatibleWithProtocolState [ <category: 'cause'> ^ 2r01100010 ]
causeInformationElementNonExistentOrNotImplemented [ <category: 'cause'> ^ 2r01100011 ]
causeConditionalIEError [ <category: 'cause'> ^ 2r01100100 ]
causeMessageNotCompatibleWithProtocolState [ <category: 'cause'> ^ 2r01100101 ]
causeProtocolErrorUnspecified [ <category: 'cause'> ^ 2r01101111 ]
]
GSM48RejectCause class >> createDefault [
<category: 'creation'>
^ self new
cause: 11;
yourself.
]
cause [
^ self data at: 1
]
cause: aCause [
self data: (ByteArray with: aCause).
]
]
GSM48SimpleData subclass: GSM48AuthRand [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.3.1 Authentication parameter RAND'>
<gsmName: 'auth'>
<gsmValueLength: 16>
]
GSM48SimpleData subclass: GSM48AuthSRES [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.3.2 Auth. parameter SRES'>
<gsmName: 'sres'>
<gsmValueLength: 4>
]
GSM48SimpleTag subclass: GSM48FollowOn [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.3.7. A simple tag value'>
<gsmIeMask: 16rFF>
<gsmElementId: 16rA1>
<gsmName: 'follow'>
]
GSM48SimpleTag subclass: GSM48CTSPermission [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.3.7. A simple tag value'>
<gsmIeMask: 16rFF>
<gsmElementId: 16rA2>
<gsmName: 'cts'>
]
GSM48SimpleTag subclass: GSM48GroupCipherKeyNumber [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.1.10'>
<gsmIeMask: 16rF0>
<gsmElementId: 16r80>
<gsmName: 'groupCipherKey'>
]
GSM48SimpleTag subclass: GSM48GPRSResumption [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.2.14c'>
<gsmIeMask: 16rF0>
<gsmElementId: 16rC0>
<gsmName: 'gprsResumption'>
]
GSM48SimpleData subclass: GSM48IdentityType [
<category: 'OsmoGSM'>
<comment: 'I represent the 10.5.3.4. Identity Type'>
"Ignore the spare values"
<gsmName: 'idType'>
<gsmValueLength: 1>
GSM48IdentityType class >> typeIMSI [ <category: 'types'> ^ 2r001 ]
GSM48IdentityType class >> typeIMEI [ <category: 'types'> ^ 2r010 ]
GSM48IdentityType class >> typeIMEISV [ <category: 'types'> ^ 2r011 ]
GSM48IdentityType class >> typeTMSI [ <category: 'types'> ^ 2r100 ]
GSM48IdentityType class >> typeNone [ <category: 'types'> ^ 2r000 ]
GSM48IdentityType class >> defaultValue [
^ ByteArray with: self typeIMSI
]
isIMSI [
<category: 'query'>
^ self data first = self class typeIMSI
]
isIMEI [
<category: 'query'>
^ self data first = self class typeIMEI
]
isIMEISV [
<category: 'query'>
^ self data first = self class typeIMEISV
]
type: aType [
self data: (ByteArray with: aType)
]
]
GSM48SimpleTag subclass: GSMRepeatInd [
<category: 'OsmoGSM'>
<gsmElementId: 16rD0>
<gsmName: 'repeatInd'>
]
GSM48SimpleTag subclass: GSMPriorityLevel [
<category: 'OsmoGSM'>
<gsmElementId: 16r80>
<gsmName: 'prio'>
]
Object subclass: GSMBitField [
| byte |
<category: 'OsmoGSM'>
<comment: 'I am a 7bit bitfield and provide nice access. I am
commonly used with the GSM fields where the 8th indicate if things
continue or not. I can automatically generate accessors based on
a bit definition class'>
GSMBitField class >> fromByte: aByte [
<category: 'creation'>
^ self new
byte: aByte;
yourself
]
GSMBitField class >> initialize [
<category: 'protected'>
self bitDefinition do: [:each |
self compile: '%1 [ ^ self bitsFrom: (%2 to: %3) ]'
% {each first. each second. each third};
compile: '%1: aVal [ self atBits: (%2 to: %3) put: aVal]'
% {each first. each second. each third}.
]
]
data [
<category: 'access'>
^ byte
]
byte: aByte [
<category: 'private'>
byte := aByte
]
bitsFrom: interval [
| res mask |
<category: 'private'>
"Build the mask"
mask := 0.
interval do: [:each |
mask := mask bitAt: each put: 1].
"And with the value and shift"
res := (byte bitAnd: mask) bitShift: (interval first - 1) negated.
^ res
]
atBits: interval put: aVal [
| shifted |
aVal highBit > interval last ifTrue: [
^ self error: 'Value bigger than interval'.
].
shifted := aVal bitShift: interval first - 1.
interval do: [:each |
byte := byte bitAt: each put: (shifted bitAt: each)].
]
]
GSMBitField subclass: GSMBearerCapOctet3 [
<category: 'OsmoGSM'>
<comment: '10.5.4.5 Octet3'>
GSMBearerCapOctet3 class [
radioChReqReserved [ ^ 2r00 ]
radioChReqFullRateOnly [ ^ 2r01 ]
radioChReqDualHalfPref [ ^ 2r10 ]
radioChReqDualFullPref [ ^ 2r11 ]
radioCodStdGSM [ ^ 2r0 ]
radioCodStdReserved [ ^ 2r1 ]
transferModeCircuit [ ^ 2r0 ]
transferModePacket [ ^ 2r1 ]
transferCapSpeech [ ^ 2r000 ]
transferCapUnrest [ ^ 2r001 ]
transferCap31khzPlmn [ ^ 2r010 ]
transferCapFacsimileGroup3 [ ^ 2r011 ]
transferCapOtherITC [ ^ 2r101 ] "see Octet 5a"
transferCapReserved [ ^ 2r111 ]
bitDefinition [
"Bit definition of Octet3"
^ OrderedCollection new
add: #('informationTransferCapability' 1 3);
add: #('transferMode' 4 4);
add: #('codingStandard' 5 5);
add: #('radioChannelRequirement' 6 7);
yourself
]
]
]
GSMBitField subclass: GSMBearerCapOctet3a [
<category: 'OsmoGSM'>
<comment: '10.5.4.5 Octet3a MS to network'>
GSMBearerCapOctet3a class [
codingForTransferCapability [ ^ 2r0 ]
codingForOtherExtensions [ ^ 2r1 ]
ctmTextTelephonyNotSupported [ ^ 2r0 ]
ctmTextTelephonySupported [ ^ 2r1 ]
speechFullRateVersion1 [ ^ 2r0000 ]
speechFullRateVersion2 [ ^ 2r0010 ]
speechFullRateVersion3 [ ^ 2r0100 ]
speechHalfRateVersion1 [ ^ 2r0001 ]
speechHalfRateVersion3 [ ^ 2r0101 ]
bitDefinition [
^ OrderedCollection new
add: #('speechVersionIndication' 1 4);
add: #('spare' 5 5);
add: #('ctm' 6 6);
add: #('coding' 7 7);
yourself
]
]
]
GSMBearerCapOctet3a subclass: GSMBearerCapOctet3b [
<category: 'OsmoGSM'>
<comment: '10.5.4.5 Octet3b network to MS'>
GSMBearerCapOctet3b class [
bitDefinition [
"There is no CTM in this directtion"
^ OrderedCollection new
add: #('speechVersionIndication' 1 4);
add: #('spare' 5 6);
add: #('coding' 7 7);
yourself
]
]
]
Object subclass: GSMBearerCapDecoderBase [
| octet3 |
<category: 'OsmoGSM'>
<comment: 'I am the base of BearerCapDecoder parsing. My children
can parse the 10.5.4.5 bearer caps.'>
GSMBearerCapDecoderBase class >> parse: aStream [
^ self new
parse: aStream;
checkEndOfStream: aStream;
yourself
]
octet3 [
^ octet3
]
parse: aStream [
<category: 'protected'>
^ self parseOctet3: aStream
]
parseOctet3: aStream [
| byte |
"I return true if there is more for octet3"
<category: 'protected'>
octet3 := nil.
"nothing left to read"
aStream atEnd ifTrue: [
^ false].
octet3 := GSMBearerCapOctet3 fromByte: aStream next.
^ (octet3 data bitAt: 8) = 0.
]
parseOctets: aStream do: aBlock [
<category: 'protected'>
[aStream atEnd] whileFalse: [
| byte |
byte := aStream next.
aBlock value: byte.
"Check if we are at an end here"
(byte bitAt: 8) = 1 ifTrue: [
^ self
]
]
]
checkEndOfStream: aStream [
<category: 'private'>
aStream atEnd ifFalse: [
^ self error: 'Bearercaps not fully consumed.'
].
]
]
GSMBearerCapDecoderBase subclass: GSMBearerCapFromNetwork [
| octet3b |
<category: 'OsmoGSM'>
parse: aStream [
<category: 'private'>
octet3b := nil.
(self parseOctet3: aStream) ifTrue: [
self parseOctets: aStream do: [:each |
self octet3b add: (GSMBearerCapOctet3b fromByte: each)]
].
]
octet3b [
<category: 'accessing'>
^ octet3b ifNil: [octet3b := OrderedCollection new]
]
]
GSMBearerCapDecoderBase subclass: GSMBearerCapFromMS [
| octet3a |
<category: 'OsmoGSM'>
parse: aStream [
<category: 'private'>
octet3a := nil.
(self parseOctet3: aStream) ifTrue:[
self parseOctets: aStream do: [:each |
self octet3a add: (GSMBearerCapOctet3a fromByte: each)].
]
]
octet3a [
<category: 'accessing'>
^ octet3a ifNil: [octet3a := OrderedCollection new]
]
]
GSM48DataHolder subclass: GSMBearerCap [
<category: 'OsmoGSM'>
<comment: '10.5.4.5'>
<gsmElementId: 16r04>
<gsmName: 'bearer'>
<gsmMinValueSize: 1 max: 13>
"GSM 04.08 Table 10.5.102. Strings depend on other attributes"
]
GSM48DataHolder subclass: GSMFacility [
<category: 'OsmoGSM'>
<comment: '10.5.4.15'>
<gsmElementId: 16r1C>
<gsmName: 'facility'>
<gsmMinValueSize: 1 max: 254>
]
GSM48DataHolder subclass: GSMProgress [
<category: 'OsmoGSM'>
<comment: '10.5.4.21 Progress indicator'>
<gsmElementId: 16r1E>
<gsmName: 'progress'>
<gsmMinValueSize: 2 max: 2>
GSMProgress class [
codingStandardMask [ <category: 'Coding standard'> ^ 2r11 ]
codingStandardQ931 [ <category: 'Coding standard'> ^ 2r00 ]
codingStandardReservedInternational [ <category: 'Coding standard'> ^ 2r01 ]
codingStandardNational [ <category: 'Coding standard'> ^ 2r10 ]
codingStandardGSMToPLMNS [ <category: 'Coding standard'> ^ 2r11 ]
locationMask [ <category: 'Location'> ^ 2r1111 ]
locationUser [ <category: 'Location'> ^ 2r0000 ]
locationPrivateNetLocalUser [ <category: 'Location'> ^ 2r0001 ]
locationPublicNetLocalUser [ <category: 'Location'> ^ 2r0010 ]
locationPublicNetRemoteUser [ <category: 'Location'> ^ 2r0100 ]
locationPrivateNetRemoteUser [ <category: 'Location'> ^ 2r0101 ]
locationNetBeyondInterworkingPoint [ <category: 'Location'> ^ 2r1010 ]
progressMask [ <category: 'Progress'> ^ 2r1111111 ]
progressCallNotEndToEnd [ <category: 'Progress'> ^ 2r0000001 ]
progressDestNotInISDN [ <category: 'Progress'> ^ 2r0000010 ]
progressOrigNotInISDN [ <category: 'Progress'> ^ 2r0001000 ]
progressCallReturnedToISDN [ <category: 'Progress'> ^ 2r0100000 ]
progressQueueing [ <category: 'Progress'> ^ 2r1000000 ]
]
GSMProgress class >> createDefault [
^ self new
data: #(2r11101010 2r10000001) asByteArray;
yourself
]
isGSMToPLMNS [
<category: 'query'>
^ self coding = self class codingStandardGSMToPLMNS.
]
coding [
<category: 'accessing'>
^ ((data at: 1) bitShift: -5) bitAnd: 2r11
]
coding: aCode [
| code |
<category: 'manipulate'>
code := data first bitClear: self class codingStandardMask.
code := code bitOr: ((aCode bitAnd: 2r11) bitShift: 5).
data at: 1 put: code.
]
location [
<category: 'accessing'>
^ (data at: 1) bitAnd: 2r1111.
]
location: aLoc [
| loc |
<category: 'manipulate'>
loc := data first bitClear: self class locationMask.
loc := loc bitOr: (aLoc bitAnd: 2r11).
data at: 1 put: loc
]
progress [
<category: 'accessing'>
^ (data at: 2) bitAnd: 2r1111111
]
progress: aProgress [
| prog |
<category: 'manipulate'>
prog := data second bitClear: self class progressMask.
prog := prog bitOr: (aProgress bitAnd: 2r1111111).
data at: 2 put: prog.
]
]
GSM48SimpleData subclass: GSMSignal [
| signal |
<category: 'OsmoGSM'>
<gsmElementId: 16r34>
<gsmName: 'signal'>
<gsmValueLength: 1>
]
Object subclass: GSMNumberingPlan [
<category: 'OsmoGSM'>
<comment: 'I represent table 10.5.1.118'>
GSMNumberingPlan class >> planUnknown [ ^ 0 ]
GSMNumberingPlan class >> planISDN [ ^ 1 ]
GSMNumberingPlan class >> planData [ ^ 3 ]
GSMNumberingPlan class >> planTelex [ ^ 4 ]
GSMNumberingPlan class >> planNational [ ^ 8 ]
GSMNumberingPlan class >> planPrivate [ ^ 9 ]
GSMNumberingPlan class >> planReserved [ ^ 15 ]
]
Object subclass: GSMNumberDigits [
<category: 'OsmoGSM'>
<comment: 'I represent table 10.5.118 continued'>
GSMNumberDigits class [
| digitMap reverseMap |
]
GSMNumberDigits class >> mapDigit: aBinary [
^ self digitMap at: aBinary asInteger + 1.
]
GSMNumberDigits class >> digitMap: aDigit [
^ self reverseMap at: aDigit.
]
GSMNumberDigits class >> digitMap [
^ digitMap ifNil: [
digitMap := Dictionary new.
1 to: 10 do: [:each |
digitMap at: each put: (each + 48 - 1) asCharacter.
].
digitMap at: 11 put: $*.
digitMap at: 12 put: $#.
digitMap at: 13 put: $a.
digitMap at: 14 put: $b.
digitMap at: 15 put: $c.
digitMap at: 16 put: $Z.
digitMap yourself.
].
]
GSMNumberDigits class >> reverseMap [
^ reverseMap ifNil: [
reverseMap := Dictionary new.
self digitMap associationsDo: [:each |
reverseMap at: each value put: (each key - 1).
].
reverseMap yourself.
].
]
GSMNumberDigits class >> decodeFrom: anArray [
<category: 'decoding'>
^ self decodeFromStream: anArray readStream.
]
GSMNumberDigits class >> decodeFromStream: aStream [
| str |
<category: 'decoding'>
str := WriteStream on: String new.
[aStream atEnd] whileFalse: [
| in tmp char |
in := aStream next.
tmp := in bitAnd: 16r0F.
str nextPut: (self mapDigit: tmp).
tmp := (in bitAnd: 16rF0) bitShift: -4.
char := (self mapDigit: tmp).
char = $Z
ifFalse: [
str nextPut: char.
].
].
^ str contents
]
GSMNumberDigits class >> encodeFrom: aNumber [
| str |
<category: 'encoding'>
str := WriteStream on: (ByteArray new).
self encodeData: aNumber on: str.
^ str contents
]
GSMNumberDigits class >> encodeData: aNumber on: aStr [
| digits |
<category: 'encoding'>
digits := OrderedCollection new.
aNumber do: [:digit |
digits add: (self digitMap: digit).
].
digits size odd
ifTrue: [
digits add: 16rF.
].
"Create the binary structure"
1 to: digits size by: 2 do: [:each |
| low high |
low := digits at: each.
high := digits at: each + 1.
aStr nextPut: (low bitOr: (high bitShift: 4)).
].
]
]
GSM48DataHolder subclass: GSMCalledBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.7'>
<gsmElementId: 16r5E>
<gsmName: 'called'>
"For PCS1900 it is 19 in total, in theory up to 43. It
depends on the direction as well"
<gsmMinValueSize: 1 max: 17>
GSMCalledBCDNumber class >> spec [ ^ '10.5.4.7' ]
GSMCalledBCDNumber class [
typeUnknown [ <category: 'TypeOfNumber'> ^ 2r000 ]
typeInternational [ <category: 'TypeOfNumber'> ^ 2r001 ]
typeNational [ <category: 'TypeOfNumber'> ^ 2r010 ]
typeNetworkSpecific [ <category: 'TypeOfNumber'> ^ 2r011 ]
typeDedicatedAccess [ <category: 'TypeOfNumber'> ^ 2r100 ]
planUnknown [ <category: 'NumberingPlan'> ^ 2r0000 ]
planISDN [ <category: 'NumberingPlan'> ^ 2r0001 ]
planData [ <category: 'NumberingPlan'> ^ 2r0011 ]
planTelex [ <category: 'NumberingPlan'> ^ 2r0100 ]
planNational [ <category: 'NumberingPlan'> ^ 2r1000 ]
planPrivate [ <category: 'NumberingPlan'> ^ 2r1001 ]
]
numberType [
<category: 'extract'>
^ ((data at: 1) bitAnd: 16r70) bitShift: -4.
]
numberPlan [
<category: 'extract'>
^ (data at: 1) bitAnd: 16r0F
]
number [
<category: 'extract'>
^ GSMNumberDigits decodeFromStream: (data readStream skip: 1).
]
encode: aType plan: aPlan nr: aNr [
| str tmp |
<category: 'encode'>
str := WriteStream on: ByteArray new.
tmp := 16r80.
tmp := tmp bitOr: ((aType bitAnd: 16r7) bitShift: 4).
tmp := tmp bitOr: ((aPlan bitAnd: 16rF) bitShift: 0).
str nextPut: tmp.
GSMNumberDigits encodeData: aNr on: str.
self data: str contents.
]
]
GSM48DataHolder subclass: GSMCalledSubBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.8'>
<gsmElementId: 16r6D>
<gsmName: 'calledSub'>
<gsmMinValueSize: 0 max: 21>
]
GSM48DataHolder subclass: GSMCallingBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.9'>
<gsmElementId: 16r5C>
<gsmName: 'calling'>
<gsmMinValueSize: 1 max: 12>
]
GSM48DataHolder subclass: GSMCallingSubBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.10'>
<gsmElementId: 16r5D>
<gsmName: 'callingSub'>
<gsmMinValueSize: 0 max: 21>
]
GSM48DataHolder subclass: GSMRedirectingBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.21a'>
<gsmElementId: 16r74>
<gsmName: 'redirect'>
<gsmMinValueSize: 1 max: 17>
]
GSM48DataHolder subclass: GSMRedirectingSubBCDNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.21b'>
<gsmElementId: 16r75>
<gsmName: 'redirectSub'>
<gsmMinValueSize: 1 max: 21>
]
GSM48DataHolder subclass: GSMLLCompability [
<category: 'OsmoGSM'>
<comment: '10.5.4.18'>
<gsmElementId: 16r7C>
<gsmMinValueSize: 0 max: 13>
]
GSM48DataHolder subclass: GSMHLCompability [
<category: 'OsmoGSM'>
<comment: '10.5.4.16'>
<gsmElementId: 16r7D>
<gsmMinValueSize: 0 max: 3>
]
GSM48DataHolder subclass: GSMUserUser [
<category: 'OsmoGSM'>
<comment: '10.5.4.25'>
<gsmElementId: 16r7E>
<gsmName: 'useruser'>
<gsmMinValueSize: 1 max: 33>
]
GSM48DataHolder subclass: GSMSSVersionInd [
<category: 'OsmoGSM'>
<comment: '10.5.4.24'>
<gsmElementId: 16r7F>
<gsmName: 'ssVersion'>
<gsmMinValueSize: 0 max: 1>
]
GSM48SimpleTag subclass: GSMClirSuppression [
<category: 'OsmoGSM'>
<gsmIeMask: 16rFF>
<gsmElementId: 16rA1>
<gsmName: 'clirSuppr'>
]
GSM48SimpleTag subclass: GSMClirInvocation [
<category: 'OsmoGSM'>
<gsmIeMask: 16rFF>
<gsmElementId: 16rA2>
<gsmName: 'clirInvoc'>
]
GSM48DataHolder subclass: GSMCCCapabilities [
<category: 'OsmoGSM'>
<comment: '10.5.4.5a'>
<gsmElementId: 16r15>
<gsmName: 'ccCapabil'>
<gsmMinValueSize: 1 max: 2>
"TODO: How to handle things that are specified like this but different in
reality? The code should be able to be uses as both validation and real world
parsing code."
GSMCCCapabilities class >> strictlyValidSizes [ ^ 1 to: 1 ]
]
GSM48DataHolder subclass: GSMConnectedNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.13'>
<gsmElementId: 16r4C>
<gsmName: 'connected'>
<gsmMinValueSize: 1 max: 12>
]
GSM48DataHolder subclass: GSMConnectedSubNumber [
<category: 'OsmoGSM'>
<comment: '10.5.4.14'>
<gsmElementId: 16r4D>
<gsmName: 'connectedSub'>
<gsmMinValueSize: 0 max: 21>
]
GSM48DataHolder subclass: GSMAllowedActions [
<category: 'OsmoGSM'>
<comment: '10.5.4.27'>
<gsmElementId: 16r7B>
<gsmName: 'allowedActions'>
<gsmMinValueSize: 1 max: 1>
]
GSM48DataHolder subclass: GSM48Cause [
<category: 'OsmoGSM'>
<comment: '10.5.4.11'>
<gsmElementId: 16r8>
<gsmName: 'cause'>
<gsmMinValueSize: 2 max: 30>
]
GSM48DataHolder subclass: GSMAlertingPattern [
<category: 'OsmoGSM'>
<comment: '10.5.4.26'>
<gsmElementId: 16r19>
<gsmName: 'alert'>
<gsmMinValueSize: 1 max: 1>
]
GSM48SimpleData subclass: GSM48Callstate [
<category: 'OsmoGSM'>
<comment: '10.5.4.6'>
<gsmName: 'callState'>
<gsmValueLength: 1>
]
GSM48DataHolder subclass: GSM48AuxillaryStates [
<category: 'OsmoGSM'>
<comment: '10.5.4.4'>
<gsmElementId: 16r24>
<gsmName: 'auxStates'>
<gsmMinValueSize: 1 max: 1>
]
GSM48SimpleData subclass: GSMRRCause [
<category: 'OsmoGSM'>
<comment: '10.5.2.31'>
<gsmName: 'cause'>
<gsmValueLength: 1>
GSMRRCause class >> causeNormalEvent [ <category: 'cause'> ^ 2r00000000 ]
GSMRRCause class >> causeAbnormalRelUnspec [ <category: 'cause'> ^ 2r00000001 ]
GSMRRCause class >> causeAbnormalRelUnacc [ <category: 'cause'> ^ 2r00000010 ]
GSMRRCause class >> causeAbnormalRelTimer [ <category: 'cause'> ^ 2r00000011 ]
GSMRRCause class >> causeAbnormalRelInact [ <category: 'cause'> ^ 2r00000100 ]
GSMRRCause class >> causePreemptiveRelease [ <category: 'cause'> ^ 2r00000101 ]
GSMRRCause class >> causeHandoverImpossible [ <category: 'cause'> ^ 2r00001000 ]
GSMRRCause class >> causeChannelModeUnacc [ <category: 'cause'> ^ 2r00001001 ]
GSMRRCause class >> causeFrequencyNotImpl [ <category: 'cause'> ^ 2r00001010 ]
GSMRRCause class >> causeCallAlreadyCleared [ <category: 'cause'> ^ 2r01000001 ]
GSMRRCause class >> causeSemanticallyIncorr [ <category: 'cause'> ^ 2r01011111 ]
GSMRRCause class >> causeInvalidMandInfo [ <category: 'cause'> ^ 2r01100000 ]
GSMRRCause class >> causeMessageTypeNotExist [ <category: 'cause'> ^ 2r01100001 ]
GSMRRCause class >> causeMessageTypeIncompat [ <category: 'cause'> ^ 2r01100010 ]
GSMRRCause class >> causeConditionalIEError [ <category: 'cause'> ^ 2r01100100 ]
GSMRRCause class >> causeNoCellAllocAvail [ <category: 'cause'> ^ 2r01100101 ]
GSMRRCause class >> causeProtocolErrorUnspec [ <category: 'cause'> ^ 2r01101111 ]
GSMRRCause class >> defaultValue [
<category: 'default'>
^ ByteArray with: 0
]
]
GSM48SimpleData subclass: GSMStreamIdentifier [
<category: 'OsmoGSM'>
<comment: '10.5.4.28'>
<gsmElementId: 16r19>
<gsmName: 'streamIdentifier'>
<gsmValueLength: 1>
]
GSM48DataHolder subclass: GSMSupportedCodecs [
<category: 'OsmoGSM'>
<comment: '10.5.4.32'>
<gsmElementId: 16r40>
<gsmName: 'supportedCodecs'>
<gsmMinValueSize: 3 max: 254>
]
GSM48SimpleTag subclass: GSMRedial [
<category: 'OsmoGSM'>
<comment: '10.5.4.34'>
<gsmIeMask: 16rFF>
<gsmElementId: 16rA3>
<gsmName: 'redial'>
]
GSM48SimpleData subclass: GSMNetworkCallControlCap [
<category: 'OsmoGSM'>
<comment: '10.5.4.29'>
<gsmElementId: 16r2F>
<gsmName: 'networkCallControlCaps'>
<gsmValueLength: 1>
]
GSM48SimpleData subclass: GSMCauseNoCLI [
<category: 'OsmoGSM'>
<comment: '10.5.4.30'>
<gsmElementId: 16r3A>
<gsmName: 'causeNoCLI'>
<gsmValueLength: 1>
]
GSM48DataHolder subclass: GSMBackupBearerCapability [
<category: 'OsmoGSM'>
<comment: '10.5.4.4a'>
<gsmElementId: 16r41>
<gsmName: 'backupBearerCap'>
<gsmMinValueSize: 1 max: 13>
]
GSM48DataHolder subclass: GSM48BARange [
<category: 'OsmoGSM'>
<comment: '105.2.1a'>
<gsmElementId: 16r73>
<gsmName: 'baRange'>
<gsmMinValueSize: 4 max: 128>
]
GSM48DataHolder subclass: GSM48GroupChannelDescription [
<category: 'OsmoGSM'>
<comment: '10.5.2.14b'>
<gsmElementId: 16r74>
<gsmName: 'groupChannelDescription'>
<gsmMinValueSize: 2 max: 11>
]
GSM48SimpleData subclass: GSM48CellChanelDescription [
<category: 'OsmoGSM'>
<comment: 'I represent a 10.5.2.1b cell channel description'>
<gsmName: 'cellChannelDescription'>
<gsmElementId: 16r62>
<gsmValueLength: 16>
]
GSM48DataHolder subclass: GSM48BAListPref [
<category: 'OsmoGSM'>
<comment: '10.5.2.1c'>
<gsmElementId: 16r75>
<gsmName: 'baListPref'>
<gsmMinValueSize: 1 max: 128>
]
GSM48DataHolder subclass: GSM48NetworkName [
<category: 'OsmoGSM'>
<comment: '10.5.3.5a'>
<gsmElementId: 16r43>
<gsmName: 'fullNetworkName'>
<gsmMinValueSize: 1 max: 128>
]
GSM48NetworkName subclass: GSM48ShortName [
<category: 'OsmoGSM'>
<comment: '10.5.3.5a'>
<gsmElementId: 16r45>
<gsmName: 'shortNetworkName'>
<gsmMinValueSize: 1 max: 128>
]
GSM48SimpleData subclass: GSM48TimeZone [
<category: 'OsmoGSM'>
<comment: '10.5.3.8'>
<gsmElementId: 16r46>
<gsmValueLength: 1>
<gsmName: 'timeZone'>
]
GSM48SimpleData subclass: GSM48TimeZoneAndTime [
<category: 'OsmoGSM'>
<comment: '10.5.3.9'>
<gsmElementId: 16r47>
<gsmValueLength: 7>
<gsmName: 'timeZoneAndZone'>
]
GSM48DataHolder subclass: GSM48LSAIdentifier [
<category: 'OsmoGSM'>
<comment: '10.5.3.11'>
<gsmElementId: 16r48>
<gsmMinValueSize: 0 max: 3>
<gsmName: 'lsaIdentity'>
]
GSM48DataHolder subclass: GSM48DaylightSavingTime [
<category: 'OsmoGSM'>
<comment: '10.5.3.12'>
<gsmElementId: 16r49>
<gsmMinValueSize: 1 max: 1>
<gsmName: 'dst'>
]
Osmo.TLVParserBase subclass: GSM48MSG [
| seq ti |
<category: 'OsmoGSM'>
<comment: 'GSM48 has helper code for mandatory types'>
GSM48MSG class >> initialize [
<category: 'parsing'>
"Initialize all variables"
self tlvDescription do: [:each |
each instVarName isNil ifTrue: [
^ self error: '%1 unknown instVarName for parseClass: %2' %
{self name displayString. each parseClass name displayString.}].
each isOptional
ifFalse: [self addMandatory: each instVarName with: each parseClass]
ifTrue: [self addOptional: each instVarName with: each parseClass].
]
]
GSM48MSG class >> addVariable: aName [
"Check if the variable exists, otherwise add it"
(self instVarNames includes: aName)
ifFalse: [
self addInstVarName: aName.
].
]
GSM48MSG class >> addMandatory: aName with: aClass [
<category: 'creation'>
self addVariable: aName.
self compile: '%1 [ ^ %1 ifNil: [%1 := %2 createDefault.]]' % {aName asString. aClass}.
]
GSM48MSG class >> addOptional: aName with: aClass [
<category: 'creation'>
self addVariable: aName.
self compile: '%1 [ ^ %1 ]' % {aName asString}.
self compile: '%1OrDefault [ ^ %1 ifNil: [%1 := %2 createDefault.]]' % {aName asString. aClass}.
]
GSM48MSG class >> isCompatible: classType msgType: messageType [
| localType |
"Ignore the base classes."
self isGSMBaseclass ifTrue: [^false].
localType := classType bitAnd: 16r0F.
^ (self classType = localType) and: [self messageType = messageType].
]
GSM48MSG class >> decode: aStream [
| classType messageType |
classType := aStream next.
messageType := aStream next bitAnd: 16r3F.
aStream skip: -2.
GSM48MSG allSubclassesDo: [:each |
(each isCompatible: classType msgType: messageType)
ifTrue: [
^ each parseFrom: aStream.
].
].
^self error: 'No one handles: ', classType asString,
' and: ', messageType asString.
]
GSM48MSG class >> parseFrom: aStream [
| res dat |
res := self new.
res ti: (aStream next bitShift: -4).
res seq: (aStream next bitShift: -6).
"This is messy. The GSM04.80 spec had the great idea of adding
tagged mandatory items and we need to deal with it here."
self tlvDescription do: [:each |
each isMandatory
ifTrue: [res parseMandatory: aStream with: each].
each isOptional
ifTrue: [res parseOptional: aStream with: each].
].
"TODO: Complain if we have not consumed everything"
aStream atEnd ifFalse: [
self error: 'Every byte should be consumed: "%1"' % {aStream}.
].
^ res
]
parseMandatory: aStream with: tlvDescription [
<category: 'parsing'>
tlvDescription isForcedTag ifTrue: [
"TODO: elementId..."
aStream next = tlvDescription parseClass elementId ifFalse: [
^ self error: 'Mandatory Tagged Element %1 not present.'
% {tlvDescription instVarName asString->tlvDescription parseClass}.
].
].
"TODO: use doParse here...."
self instVarNamed: tlvDescription instVarName
put: (tlvDescription parseClass parseFrom: aStream).
]
parseOptional: aStream with: tlvDescription [
| tag clazz len |
<category: 'parsing'>
aStream atEnd ifTrue: [^nil].
clazz := tlvDescription parseClass.
tag := aStream peek bitAnd: clazz ieMask.
tag = clazz elementId
ifFalse: [^nil].
len := clazz length: aStream.
aStream skip: 1.
"treat the T only tags specially"
len = 0
ifTrue: [ self instVarNamed: tlvDescription instVarName
put: (clazz initWithData: len).]
ifFalse: [ self instVarNamed: tlvDescription instVarName
put: (clazz parseFrom: aStream).].
]
writeOn: aMsg [
| type classType |
type := self seq bitShift: 6.
type := type bitOr: self class messageType.
"Write the header. Skip Ind, Sequence are hardcoded"
classType := self ti bitShift: 4.
classType := classType bitOr: self class classType.
aMsg putByte: classType.
aMsg putByte: type.
"Write all Mandatory parts"
self class tlvDescription do: [:each |
each isMandatory ifTrue: [ | tmp |
tmp := self perform: each instVarName.
each isForcedTag
ifTrue: [tmp writeOn: aMsg]
ifFalse: [tmp writeOnDirect: aMsg]].
each isOptional ifTrue: [ | tmp |
tmp := self perform: each instVarName.
tmp ifNotNil: [
tmp writeOn: aMsg.
].
].
"TODO: Handle the Conditionals better here.."
each isConditional ifTrue: [ | tmp |
"Only write if it is already present"
tmp := self instVarNamed: each instVarName.
tmp ifNotNil: [
tmp writeOn: aMsg.
].
].
]
]
seq: aSeq [
seq := aSeq.
]
seq [
^ seq ifNil: [ 0 ]
]
ti: aTi [
ti := aTi.
]
ti [
"by default treat it like a spare"
^ 0
]
type [
^ self class messageType
]
]
GSM48MSG subclass: GSM48MMMessage [
<category: 'OsmoGSM'>
<comment: 'Baseclass for mobility managamenet'>
GSM48MMMessage class >> isGSMBaseclass [ <category: 'factory'> ^ self = GSM48MMMessage ]
GSM48MMMessage class >> classType [ ^ 16r5 ]
GSM48MMMessage class >> msgLUAcc [ ^ 16r02 ]
GSM48MMMessage class >> msgLURej [ ^ 16r04 ]
GSM48MMMessage class >> msgLUReq [ ^ 16r08 ]
GSM48MMMessage class >> msgIdRes [ ^ 16r19 ]
GSM48MMMessage class >> msgIdReq [ ^ 16r18 ]
GSM48MMMessage class >> msgAuRej [ ^ 16r11 ]
GSM48MMMessage class >> msgAuReq [ ^ 16r12 ]
GSM48MMMessage class >> msgAuRes [ ^ 16r14 ]
GSM48MMMessage class >> msgCMAccept [ ^ 16r21 ]
GSM48MMMessage class >> msgCMReject [ ^ 16r22 ]
GSM48MMMessage class >> msgCMReq [ ^ 16r24 ]
GSM48MMMessage class >> msgIMSIDetach [ ^ 16r01 ]
GSM48MMMessage class >> msgTMSIReallocationCommand [ ^ 2r11010 ]
GSM48MMMessage class >> msgTMSIReallocationComplete [ ^ 2r11011 ]
GSM48MMMessage class >> msgMMInfo [ ^ 2r110010 ]
]
GSM48MSG subclass: GSM48CCMessage [
<category: 'OsmoGSM'>
<comment: 'Baseclass for call control'>
GSM48CCMessage class >> isGSMBaseclass [ <category: 'factory'> ^ self = GSM48CCMessage ]
GSM48CCMessage class >> classType [ ^ 16r3 ]
GSM48CCMessage class >> msgAlerting [ <category: 'est'> ^ 2r000001 ]
GSM48CCMessage class >> msgConfirmed [ <category: 'est'> ^ 2r001000 ]
GSM48CCMessage class >> msgProceeding [ <category: 'est'> ^ 2r000010 ]
GSM48CCMessage class >> msgConnect [ <category: 'est'> ^ 2r000111 ]
GSM48CCMessage class >> msgConnectAck [ <category: 'est'> ^ 2r001111 ]
GSM48CCMessage class >> msgEmergencySetup [ <category: 'est'> ^ 2r001110 ]
GSM48CCMessage class >> msgProgress [ <category: 'est'> ^ 2r000011 ]
GSM48CCMessage class >> msgCCEst [ <category: 'est'> ^ 2r000100 ]
GSM48CCMessage class >> msgCCEstCnf [ <category: 'est'> ^ 2r000110 ]
GSM48CCMessage class >> msgRecall [ <category: 'est'> ^ 2r001011 ]
GSM48CCMessage class >> msgStartCC [ <category: 'est'> ^ 2r001001 ]
GSM48CCMessage class >> msgSetup [ <category: 'est'> ^ 2r000101 ]
GSM48CCMessage class >> msgModify [ <category: 'mod'> ^ 2r010111 ]
GSM48CCMessage class >> msgModifyComplete [ <category: 'mod'> ^ 2r011111 ]
GSM48CCMessage class >> msgModifyReject [ <category: 'mod'> ^ 2r010011 ]
GSM48CCMessage class >> msgUserInformation [ <category: 'mod'> ^ 2r010000 ]
GSM48CCMessage class >> msgHold [ <category: 'mod'> ^ 2r011000 ]
GSM48CCMessage class >> msgHoldAck [ <category: 'mod'> ^ 2r011001 ]
GSM48CCMessage class >> msgHoldReject [ <category: 'mod'> ^ 2r011010 ]
GSM48CCMessage class >> msgRetrieve [ <category: 'mod'> ^ 2r011100 ]
GSM48CCMessage class >> msgRetrieveAck [ <category: 'mod'> ^ 2r011101 ]
GSM48CCMessage class >> msgRetrieveReject [ <category: 'mod'> ^ 2r011110 ]
GSM48CCMessage class >> msgDisconnect [ <category: 'rel'> ^ 2r100101 ]
GSM48CCMessage class >> msgRelease [ <category: 'rel'> ^ 2r101101 ]
GSM48CCMessage class >> msgReleaseCompl [ <category: 'rel'> ^ 2r101010 ]
GSM48CCMessage class >> msgCongestionCtrl [ <category: 'misc'> ^ 2r111001 ]
GSM48CCMessage class >> msgNotify [ <category: 'misc'> ^ 2r111110 ]
GSM48CCMessage class >> msgStatus [ <category: 'misc'> ^ 2r111101 ]
GSM48CCMessage class >> msgStatusEnquiry [ <category: 'misc'> ^ 2r110100 ]
GSM48CCMessage class >> msgStartDTMF [ <category: 'misc'> ^ 2r110101 ]
GSM48CCMessage class >> msgStopDTMF [ <category: 'misc'> ^ 2r110001 ]
GSM48CCMessage class >> msgStopDTMFAck [ <category: 'misc'> ^ 2r110010 ]
GSM48CCMessage class >> msgStartDTMFAck [ <category: 'misc'> ^ 2r110110 ]
GSM48CCMessage class >> msgStartDTMFReject [ <category: 'misc'> ^ 2r110111 ]
GSM48CCMessage class >> msgFacility [ <category: 'misc'> ^ 2r111010 ]
ti [
^ ti ifNil: [ 0 ]
]
]
GSM48MSG subclass: GSM48RRMessage [
<category: 'OsmoGSM'>
<comment: 'Baseclass for radio resource handling'>
GSM48RRMessage class >> isGSMBaseclass [ <category: 'factory'> ^ self = GSM48RRMessage ]
GSM48RRMessage class >> classType [ ^ 16r6 ]
GSM48RRMessage class >> msgInitRequest [ <category: 'channel est.'> ^ 2r00111100 ]
GSM48RRMessage class >> msgAddAssignment [ <category: 'channel est.'> ^ 2r00111011 ]
GSM48RRMessage class >> msgImmAssignment [ <category: 'channel est.'> ^ 2r00111111 ]
GSM48RRMessage class >> msgImmAssignmentExt [ <category: 'channel est.'> ^ 2r00111010 ]
GSM48RRMessage class >> msgCipherModeCommand [ <category: 'ciphering'> ^ 2r00110101 ]
GSM48RRMessage class >> msgCipherModeComplete [ <category: 'ciphering'> ^ 2r00110010 ]
GSM48RRMessage class >> msgConfigChangeCommand [ <category: 'config'> ^ 2r00110000 ]
GSM48RRMessage class >> msgConfigChangeAck [ <category: 'config'> ^ 2r00110001 ]
GSM48RRMessage class >> msgConfigChangeReject [ <category: 'config'> ^ 2r00110011 ]
GSM48RRMessage class >> msgAssignmentCommand [ <category: 'handover'> ^ 2r00101110 ]
GSM48RRMessage class >> msgAssignmentComplete [ <category: 'handover'> ^ 2r00101001 ]
GSM48RRMessage class >> msgAssignmentFailure [ <category: 'handover'> ^ 2r00101111 ]
GSM48RRMessage class >> msgHandoverCommand [ <category: 'handover'> ^ 2r00101011 ]
GSM48RRMessage class >> msgHandoverComplete [ <category: 'handover'> ^ 2r00101100 ]
GSM48RRMessage class >> msgHandoverFailure [ <category: 'handover'> ^ 2r00101101 ]
GSM48RRMessage class >> msgCellChangeOrder [ <category: 'misc'> ^ 2r00001000 ]
GSM48RRMessage class >> msgPdchAssignmentCommand [ <category: 'misc'> ^ 2r00100011 ]
GSM48RRMessage class >> msgChannelRelease [ <category: 'release'> ^ 2r00001101 ]
GSM48RRMessage class >> msgPartialRelease [ <category: 'release'> ^ 2r00001010 ]
GSM48RRMessage class >> msgPartialReleaseComplete [ <category: 'release'> ^ 2r00001111 ]
GSM48RRMessage class >> msgPagingRequestType1 [ <category: 'paging'> ^ 2r00100001 ]
GSM48RRMessage class >> msgPagingRequestType2 [ <category: 'paging'> ^ 2r00100010 ]
GSM48RRMessage class >> msgPagingRequestType3 [ <category: 'paging'> ^ 2r00100100 ]
GSM48RRMessage class >> msgPagingResponse [ <category: 'paging'> ^ 2r00100111 ]
GSM48RRMessage class >> msgNotificationNch [ <category: 'paging'> ^ 2r00100000 ]
GSM48RRMessage class >> msgNotificationFacch [ <category: 'paging'> ^ 2r00100101 ]
GSM48RRMessage class >> msgNotificationResponse [ <category: 'paging'> ^ 2r00100110 ]
GSM48RRMessage class >> msgSystemInformation8 [ <category: 'si'> ^ 2r00011000 ]
GSM48RRMessage class >> msgSystemInformation1 [ <category: 'si'> ^ 2r00011001 ]
GSM48RRMessage class >> msgSystemInformation2 [ <category: 'si'> ^ 2r00011010 ]
GSM48RRMessage class >> msgSystemInformation3 [ <category: 'si'> ^ 2r00011011 ]
GSM48RRMessage class >> msgSystemInformation4 [ <category: 'si'> ^ 2r00011100 ]
GSM48RRMessage class >> msgSystemInformation5 [ <category: 'si'> ^ 2r00011101 ]
GSM48RRMessage class >> msgSystemInformation6 [ <category: 'si'> ^ 2r00011110 ]
GSM48RRMessage class >> msgSystemInformation7 [ <category: 'si'> ^ 2r00011111 ]
GSM48RRMessage class >> msgSystemInformation2bis [ <category: 'si'> ^ 2r00000010 ]
GSM48RRMessage class >> msgSystemInformation2ter [ <category: 'si'> ^ 2r00000011 ]
GSM48RRMessage class >> msgSystemInformation5bis [ <category: 'si'> ^ 2r00000101 ]
GSM48RRMessage class >> msgSystemInformation5ter [ <category: 'si'> ^ 2r00000110 ]
GSM48RRMessage class >> msgSystemInformation9 [ <category: 'si'> ^ 2r00000100 ]
GSM48RRMessage class >> msgSystemInformation13 [ <category: 'si'> ^ 2r00000000 ]
GSM48RRMessage class >> msgSystemInformation16 [ <category: 'si'> ^ 2r00111101 ]
GSM48RRMessage class >> msgSystemInformation17 [ <category: 'si'> ^ 2r00111110 ]
GSM48RRMessage class >> msgChannelModeModify [ <category: 'misc'> ^ 2r00010000 ]
GSM48RRMessage class >> msgRRStatus [ <category: 'misc'> ^ 2r00010010 ]
GSM48RRMessage class >> msgChannelModeModifyAck [ <category: 'misc'> ^ 2r00010111 ]
GSM48RRMessage class >> msgFrequencyRedefinition [ <category: 'misc'> ^ 2r00010100 ]
GSM48RRMessage class >> msgMeasurementReport [ <category: 'misc'> ^ 2r00010101 ]
GSM48RRMessage class >> msgClassmarkChange [ <category: 'misc'> ^ 2r00010110 ]
GSM48RRMessage class >> msgClassmarkEnquiry [ <category: 'misc'> ^ 2r00010011 ]
GSM48RRMessage class >> msgExtendedMeasurementReport [ <category: 'misc'> ^ 2r00110110 ]
GSM48RRMessage class >> msgExtendedMeasurementOrder [ <category: 'misc'> ^ 2r00110111 ]
GSM48RRMessage class >> msgGPRSSuspensionRequest [ <category: 'misc'> ^ 2r00110100 ]
GSM48RRMessage class >> msgVGCSUplinkGrant [ <category: 'vgcs'> ^ 2r00001001 ]
GSM48RRMessage class >> msgUplinkRelease [ <category: 'vgcs'> ^ 2r00001110 ]
GSM48RRMessage class >> msgUplinkFree [ <category: 'vgcs'> ^ 2r00001100 ]
GSM48RRMessage class >> msgTalkerIndication [ <category: 'vgcs'> ^ 2r00010001 ]
GSM48RRMessage class >> msgApplicationInformation [ <category: 'app'> ^ 2r00111000 ]
]
GSM48MSG subclass: GSM48SSMessage [
<category: 'OsmoGSM'>
<comment: 'I am here for GSM 04.80 and supplementary services'>
GSM48SSMessage class >> isGSMBaseclass [ <category: 'factory'> ^ self = GSM48SSMessage ]
GSM48SSMessage class >> classType [ ^ 2r1011 ]
GSM48SSMessage class >> msgReleaseCompl [ ^ 2r101010 ]
GSM48SSMessage class >> msgFacility [ ^ 2r111010 ]
GSM48SSMessage class >> msgRegister [ ^ 2r111011 ]
ti [
^ ti ifNil: [ 0 ]
]
]
GSM48MMMessage subclass: GSM48LURequest [
<category: 'OsmoGSM'>
GSM48LURequest class >> messageType [ ^ self msgLUReq ]
GSM48LURequest class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48KeySeqLuType asTLVDescription;
add: GSM48Lai asTLVDescription;
add: GSM48Classmark1 asTLVDescription;
add: GSM48MIdentity asTLVDescription;
yourself.
]
]
GSM48MMMessage subclass: GSM48LUAccept [
<category: 'OsmoGSM'>
GSM48LUAccept class >> messageType [ ^ self msgLUAcc ]
GSM48LUAccept class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48Lai asTLVDescription;
add: (GSM48MIdentity asTLVDescription beOptional; yourself);
add: (GSM48FollowOn asTLVDescription beOptional; yourself);
add: (GSM48CTSPermission asTLVDescription beOptional; yourself);
yourself
]
]
GSM48MMMessage subclass: GSM48LUReject [
<category: 'OsmoGSM'>
GSM48LUReject class >> messageType [ ^ self msgLURej ]
GSM48LUReject class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48RejectCause asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48AuthRej [
<category: 'OsmoGSM'>
GSM48AuthRej class >> messageType [ ^ self msgAuRej ]
GSM48AuthRej class >> tlvDescription [ <category: 'parsing'> ^ #() ]
]
GSM48MMMessage subclass: GSM48AuthReq [
<category: 'OsmoGSM'>
GSM48AuthReq class >> messageType [ ^ self msgAuReq ]
GSM48AuthReq class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48KeySeqLuType asTLVDescription;
add: GSM48AuthRand asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48AuthResp [
<category: 'OsmoGSM'>
GSM48AuthResp class >> messageType [ ^ self msgAuRes ]
GSM48AuthResp class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48AuthSRES asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48IdentityReq [
<category: 'OsmoGSM'>
GSM48IdentityReq class >> messageType [ ^ self msgIdReq ]
GSM48IdentityReq class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48IdentityType asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48IdentityResponse [
<category: 'OsmoGSM'>
GSM48IdentityResponse class >> messageType [ ^ self msgIdRes ]
GSM48IdentityResponse class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48MIdentity asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48CMServiceAccept [
<category: 'OsmoGSM'>
GSM48CMServiceAccept class >> messageType [ ^ self msgCMAccept ]
GSM48CMServiceAccept class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
]
]
GSM48MMMessage subclass: GSM48CMServiceReq [
<category: 'OsmoGSM'>
GSM48CMServiceReq class >> messageType [ ^ self msgCMReq ]
GSM48CMServiceReq class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48KeySeqLuType asTLVDescription;
add: GSM48Classmark2 asTLVDescription;
add: GSM48MIdentity asTLVDescription;
add: (GSMPriorityLevel asTLVDescription beOptional; yourself);
yourself
]
]
GSM48MMMessage subclass: GSM48CMServiceReject [
<category: 'OsmoGSM'>
GSM48CMServiceReject class >> messageType [ ^ self msgCMReject ]
GSM48CMServiceReject class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48RejectCause asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48IMSIDetachInd [
<category: 'OsmoGSM'>
GSM48IMSIDetachInd class >> messageType [ ^ self msgIMSIDetach ]
GSM48IMSIDetachInd class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48Classmark1 asTLVDescription;
add: GSM48MIdentity asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48TMSIReallocationCommand [
<category: 'OsmoGSM'>
GSM48TMSIReallocationCommand class >> messageType [
^ self msgTMSIReallocationCommand
]
GSM48TMSIReallocationCommand class >> tlvDescription [
<category:'parsing'>
^ OrderedCollection new
add: GSM48Lai asTLVDescription;
add: GSM48MIdentity asTLVDescription;
yourself
]
]
GSM48MMMessage subclass: GSM48TMSIReallocationComplete [
<category: 'OsmoGSM'>
GSM48TMSIReallocationComplete class >> messageType [
^ self msgTMSIReallocationComplete
]
GSM48TMSIReallocationComplete class >> tlvDescription [
^ OrderedCollection new
]
]
GSM48MMMessage subclass: GSM48MMInformation [
<category: 'OsmoGSM'>
GSM48MMInformation class >> messageType [ ^ self msgMMInfo ]
GSM48MMInformation class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSM48NetworkName asTLVDescription beOptional; yourself);
add: (GSM48ShortName asTLVDescription beOptional; yourself);
add: (GSM48TimeZone asTLVDescription beOptional; yourself);
add: (GSM48TimeZoneAndTime asTLVDescription beOptional; yourself);
add: (GSM48LSAIdentifier asTLVDescription beOptional; yourself);
add: (GSM48DaylightSavingTime asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCSetup [
<category: 'OsmoGSM'>
GSM48CCSetup class >> messageType [ ^ self msgSetup ]
GSM48CCSetup class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMRepeatInd asTLVDescription beOptional; yourself);
add: (GSMBearerCap asTLVDescription beOptional; instVarName: #bearer1; yourself);
add: (GSMBearerCap asTLVDescription beOptional; instVarName: #bearer2; yourself);
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMProgress asTLVDescription beOptional; yourself);
add: (GSMSignal asTLVDescription beOptional; yourself);
add: (GSMCallingBCDNumber asTLVDescription beOptional; yourself);
add: (GSMCallingSubBCDNumber asTLVDescription beOptional; yourself);
add: (GSMCalledBCDNumber asTLVDescription beOptional; yourself);
add: (GSMCalledSubBCDNumber asTLVDescription beOptional; yourself);
add: (GSMRedirectingBCDNumber asTLVDescription beOptional; yourself);
add: (GSMRedirectingSubBCDNumber asTLVDescription beOptional; yourself);
add: (GSMRepeatInd asTLVDescription beOptional; instVarName: #LLCInd; yourself);
add: (GSMLLCompability asTLVDescription beOptional; instVarName: #llc1; yourself);
add: (GSMLLCompability asTLVDescription beOptional; instVarName: #llc2; yourself);
add: (GSMRepeatInd asTLVDescription beOptional; instVarName: #HLCInd; yourself);
add: (GSMHLCompability asTLVDescription beOptional; instVarName: #hlc1; yourself);
add: (GSMHLCompability asTLVDescription beOptional; instVarName: #hlc2; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
"For MO call"
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
add: (GSMClirSuppression asTLVDescription beOptional; yourself);
add: (GSMClirInvocation asTLVDescription beOptional; yourself);
add: (GSMCCCapabilities asTLVDescription beOptional; yourself);
add: (GSMFacility asTLVDescription
beOptional; instVarName: #facilityCCBS; yourself);
add: (GSMFacility asTLVDescription
beOptional; instVarName: #facilityReca; yourself);
add: (GSMStreamIdentifier asTLVDescription beOptional; yourself);
add: (GSMSupportedCodecs asTLVDescription beOptional; yourself);
add: (GSMRedial asTLVDescription beOptional; yourself);
"For MT call"
add: (GSMPriorityLevel asTLVDescription beOptional; yourself);
add: (GSMAlertingPattern asTLVDescription beOptional; yourself);
add: (GSMNetworkCallControlCap asTLVDescription beOptional; yourself);
add: (GSMCauseNoCLI asTLVDescription beOptional; yourself);
add: (GSMBackupBearerCapability asTLVDescription beOptional; yourself);
yourself
]
writeOn: aMsg [
"TODO: these are incomplete and wrong"
"Implement the conditionals"
(self bearer1 ~= nil and: [self bearer2 ~= nil])
ifTrue: [
self instVarNamed: #repeatInd put: GSMRepeatInd new.
]
ifFalse: [
self instVarNamed: #repeatInd put: nil.
].
(self llc1 ~= nil and: [self llc2 ~= nil])
ifTrue: [
self instVarNamed: #LLCInd put: GSMRepeatInd new.
]
ifFalse: [
self instVarNamed: #LLCInd put: nil.
].
(self hlc1 ~= nil and: [self hlc2 ~= nil])
ifTrue: [
self instVarNamed: #HLCInd put: GSMRepeatInd new.
]
ifFalse: [
self instVarNamed: #HLCInd put: nil.
].
^ super writeOn: aMsg.
]
]
GSM48CCMessage subclass: GSM48CCProceeding [
<category: 'OsmoGSM'>
GSM48CCProceeding class >> messageType [ ^ self msgProceeding ]
GSM48CCProceeding class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMRepeatInd asTLVDescription
beOptional; yourself);
add: (GSMBearerCap asTLVDescription
beOptional; instVarName: #bearer1; yourself);
add: (GSMBearerCap asTLVDescription
beOptional; instVarName: #bearer2; yourself);
add: (GSMFacility asTLVDescription
beOptional; yourself);
add: (GSMProgress asTLVDescription
beOptional; yourself);
add: (GSMPriorityLevel asTLVDescription
beOptional; instVarName: #priorityGranted; yourself);
add: (GSMNetworkCallControlCap asTLVDescription
beOptional; instVarName: #networkCallControlCaps; yourself);
yourself
]
writeOn: aMsg [
(self bearer1 ~= nil and: [self bearer2 ~= nil])
ifTrue: [
self instVarNamed: #repeatInd put: GSMRepeatInd new.
]
ifFalse: [
self instVarNamed: #repeatInd put: nil.
].
^ super writeOn: aMsg.
]
]
GSM48CCMessage subclass: GSM48CCAlerting [
<category: 'OsmoGSM'>
GSM48CCAlerting class >> messageType [ ^ self msgAlerting ]
GSM48CCAlerting class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMProgress asTLVDescription beOptional; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
"mobile station to network"
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCCallConfirmed [
<category: 'OsmoGSM'>
GSM48CCCallConfirmed class >> messageType [
<category: 'factory'>
^ self msgConfirmed
]
GSM48CCCallConfirmed class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMRepeatInd asTLVDescription beOptional; yourself);
add: (GSMBearerCap asTLVDescription beOptional; instVarName: #bearer1; yourself);
add: (GSMBearerCap asTLVDescription beOptional; instVarName: #bearer2; yourself);
add: (GSM48Cause asTLVDescription beOptional; yourself);
add: (GSMCCCapabilities asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCConnect [
<category: 'OsmoGSM'>
GSM48CCConnect class >> messageType [ ^ self msgConnect ]
GSM48CCConnect class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMProgress asTLVDescription beOptional; yourself);
add: (GSMConnectedNumber asTLVDescription beOptional; yourself);
add: (GSMConnectedSubNumber asTLVDescription beOptional; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
add: (GSMStreamIdentifier asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCConnectAck [
<category: 'OsmoGSM'>
GSM48CCConnectAck class >> messageType [ ^ self msgConnectAck ]
GSM48CCConnectAck class >> tlvDescription [
<category: 'parsing'>
^ #()
]
]
GSM48CCMessage subclass: GSM48CCDisconnect [
<category: 'OsmoGSM'>
GSM48CCDisconnect class >> messageType [ ^ self msgDisconnect ]
GSM48CCDisconnect class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48Cause asTLVDescription;
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMProgress asTLVDescription beOptional; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
add: (GSMAllowedActions asTLVDescription beOptional; yourself);
"MO addition"
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCRelease [
<category: 'OsmoGSM'>
GSM48CCRelease class >> messageType [ ^ self msgRelease ]
GSM48CCRelease class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSM48Cause asTLVDescription beOptional; yourself);
add: (GSM48Cause asTLVDescription
beOptional; instVarName: #secondCause; yourself);
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCReleaseCompl [
<category: 'OsmoGSM'>
GSM48CCReleaseCompl class >> messageType [ ^ self msgReleaseCompl ]
GSM48CCReleaseCompl class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSM48Cause asTLVDescription beOptional; yourself);
add: (GSMFacility asTLVDescription beOptional; yourself);
add: (GSMUserUser asTLVDescription beOptional; yourself);
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCStatus [
<category: 'OsmoGSM'>
GSM48CCStatus class >> messageType [ ^ self msgStatus ]
GSM48CCStatus class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48Cause asTLVDescription;
add: GSM48Callstate asTLVDescription;
add: (GSM48AuxillaryStates asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCEmergencySetup [
<category: 'OsmoGSM'>
GSM48CCEmergencySetup class >> messageType [ ^ self msgEmergencySetup ]
GSM48CCEmergencySetup class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMBearerCap asTLVDescription beOptional; yourself);
yourself
]
]
GSM48CCMessage subclass: GSM48CCProgress [
<category: 'OsmoGSM'>
GSM48CCProgress class >> messageType [ ^self msgProgress ]
GSM48CCProgress class >> tlvDescription [
<category: 'parsing'>
^OrderedCollection new
add: GSMProgress asTLVDescription;
add: (GSMUserUser asTLVDescription
beOptional;
minSize: 1 maxSize: 129;
yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRAssignmentComplete [
<category: 'OsmoGSM'>
GSM48RRAssignmentComplete class >> messageType [
<category: 'factory'>
^ self msgAssignmentComplete
]
GSM48RRAssignmentComplete class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSMRRCause asTLVDescription;
yourself
]
]
GSM48RRMessage subclass: GSM48RRHandoverCommand [
<category: 'OsmoGSM'>
<comment: 'See Table 9.15 for details'>
GSM48RRHandoverCommand class >> messageType [
<category: 'factory'>
^ self msgHandoverCommand
]
GSM48RRHandoverCommand class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48CellDescription asTLVDescription;
add: GSM48ChannelDescription2 asTLVDescription;
add: GSM48HandoverReference asTLVDescription;
add: GSM48PowerCommandAndAccess asTLVDescription;
add: (GSM48SynchronizationInd asTLVDescription beOptional; yourself);
add: (GSM48FrequencyShortList asTLVDescription beConditional; yourself);
add: (GSM48FrequencyList asTLVDescription beConditional; yourself);
add: (GSM48CellChanelDescription asTLVDescription beConditional; yourself);
add: (GSM48MultislotAllocation asTLVDescription beConditional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet1; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet2; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet3; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet4; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet5; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet6; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet7; beOptional; yourself);
add: (GSM48ChannelMode asTLVDescription
instVarName: #channelSet8; beOptional; yourself);
add: (GSM48ChannelDescription asTLVDescription
instVarName: #secondDescription; beOptional; yourself);
add: (GSM48ChannelMode2 asTLVDescription
instVarName: #secondMode; beOptional; yourself);
add: (GSM48FrequencyChannelSequence asTLVDescription beConditional; yourself);
add: (GSM48MobileAllocation asTLVDescription beConditional; yourself);
add: (GSM48StartingTime asTLVDescription beOptional; yourself);
add: (GSM48TimingDifference asTLVDescription beConditional; yourself);
add: (GSM48TimingAdvance asTLVDescription beConditional; yourself);
add: (GSM48FrequencyShortList asTLVDescription
instVarName: #beforeTimeShort; beConditional; yourself);
add: (GSM48FrequencyList asTLVDescription
instVarName: #beforeTimeList; beConditional; yourself);
add: (GSM48ChannelDescription2 asTLVDescription
instVarName: #beforeTimeChannel; beOptional; yourself);
add: (GSM48ChannelDescription asTLVDescription
instVarName: #beforeTimeSecondChannel; beOptional; yourself);
add: (GSM48FrequencyChannelSequence asTLVDescription
instVarName: #beforeTimeFrequencySeq; beConditional; yourself);
add: (GSM48MobileAllocation asTLVDescription
instVarName: #beforeTimeTime; beConditional; yourself);
add: (GSM48CipherModeSetting asTLVDescription beOptional; yourself);
add: (GSM48VGCSTargetModeIndication asTLVDescription beOptional; yourself);
add: (GSM48MultiRateConfiguration asTLVDescription beOptional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRHandoverComplete [
<category: 'OsmoGSM'>
<comment: 'See table 9.16 for details'>
GSM48RRHandoverComplete class >> messageType [
<category: 'factory'>
^ self msgHandoverComplete
]
GSM48RRHandoverComplete class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSMRRCause asTLVDescription;
add: (GSM48TimingDifference asTLVDescription beOptional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRHandoverFailure [
<category: 'OsmoGSM'>
<comment: 'See table 9.17'>
GSM48RRHandoverFailure class >> messageType [
<category: 'factory'>
^ self msgHandoverFailure
]
GSM48RRHandoverFailure class >> tlvDescription [
^ OrderedCollection new
add: GSM48Cause asTLVDescription;
yourself
]
]
GSM48RRMessage subclass: GSM48RRImmediateAssignCommand [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 9.1.18 Immediate assignment'>
GSM48RRImmediateAssignCommand class [
messageType [ <category: 'parsing'> ^ self msgImmAssignment ]
]
GSM48RRImmediateAssignCommand class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48PageAndDedicatedMode asTLVDescription;
"TODO: properly handle conditionals"
add: GSM48ChannelOrPacketDescription asTLVDescription;
add: GSM48RequestReference asTLVDescription;
add: GSM48TimingAdvance asTLVDescription;
add: GSM48MobileAllocation asTLVDescription;
add: (GSM48StartingTime asTLVDescription beOptional; yourself);
add: GSM48IARestOctets asTLVDescription;
yourself
]
]
GSM48RRMessage subclass: GSM48RRChannelRelease [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 9.1.7 Channel Release'>
GSM48RRChannelRelease class [
messageType [ <category: 'parsing'> ^ self msgChannelRelease ]
]
GSM48RRChannelRelease class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSMRRCause asTLVDescription;
add: (GSM48BARange asTLVDescription beOptional; yourself);
add: (GSM48GroupChannelDescription asTLVDescription beOptional; yourself);
add: (GSM48GroupCipherKeyNumber asTLVDescription beConditional; yourself);
add: (GSM48GPRSResumption asTLVDescription beOptional; yourself);
add: (GSM48BAListPref asTLVDescription beOptional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRCipheringModeCommand [
<category: 'OsmoGSM'>
<comment: 'I represen a GSM 04.08 9.1.9 Ciphering Mode Command'>
GSM48RRCipheringModeCommand class >> messageType [
<category: 'parsing'>
^self msgCipherModeCommand
]
GSM48RRCipheringModeCommand class >> tlvDescription [
^OrderedCollection new
add: GSM48CipherModeSettingResponse asTLVDescription;
yourself
]
]
GSM48RRMessage subclass: GSM48RRCipheringModeComplete [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 9.1.10 Ciphering Mode Complete'>
GSM48RRCipheringModeComplete class >> messageType [
<category: 'parsing'>
^self msgCipherModeComplete
]
GSM48RRCipheringModeComplete class >> tlvDescription [
<category: 'parsing'>
^OrderedCollection new
add: (GSM48MIdentity asTLVDescription beOptional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRClassmarkChange [
<category: 'OsmoGSM'>
<comment: 'I represent a GSM 04.08 9.1.11 Classmark'>
GSM48RRClassmarkChange class >> messageType [
<category: 'parsing'>
^ self msgClassmarkChange
]
GSM48RRClassmarkChange class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48Classmark2 asTLVDescription;
add: (GSM48Classmark3 asTLVDescription beConditional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRPagingResponse [
<category: 'OsmoGSM'>
GSM48RRPagingResponse class >> messageType [
<category: 'factory'>
^ self msgPagingResponse
]
GSM48RRPagingResponse class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48KeySeqLuType asTLVDescription;
add: GSM48Classmark2 asTLVDescription;
add: GSM48MIdentity asTLVDescription;
yourself.
]
]
GSM48RRMessage subclass: GSM48RRChannelModeModify [
<category: 'OsmoGSM'>
GSM48RRChannelModeModify class >> messageType [
<category: 'factory'>
^ self msgChannelModeModify
]
GSM48RRChannelModeModify class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSM48ChannelDescription asTLVDescription;
add: GSM48ChannelMode asTLVDescription;
add: (GSM48VGCSTargetModeIndication asTLVDescription beOptional; yourself);
add: (GSM48MultiRateConfiguration asTLVDescription beOptional; yourself);
yourself
]
]
GSM48RRMessage subclass: GSM48RRChannelModeModifyAck [
<category: 'OsmoGSM'>
GSM48RRChannelModeModifyAck class >> messageType [
<category: 'factory'>
^ self msgChannelModeModifyAck
]
GSM48RRChannelModeModifyAck class >> tlvDescription [
^ OrderedCollection new
add: GSM48ChannelDescription asTLVDescription;
add: GSM48ChannelMode asTLVDescription;
yourself
]
]
GSM48SSMessage subclass: GSM48SSFacility [
<category: 'OsmoGSM'>
GSM48SSFacility class >> messageType [ ^ self msgFacility ]
GSM48SSFacility class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: GSMFacility asTLVDescription;
yourself
]
]
GSM48SSMessage subclass: GSM48SSRegister [
<category: 'OsmoGSM'>
GSM48SSRegister class >> messageType [ ^ self msgRegister ]
GSM48SSRegister class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSMFacility asTLVDescription beForceTagged; yourself);
"MS to mobile can contain this one"
add: (GSMSSVersionInd asTLVDescription beOptional; yourself);
yourself
]
]
GSM48SSMessage subclass: GSM48SSReleaseComplete [
<category: 'OsmoGSM'>
GSM48SSReleaseComplete class >> messageType [ ^ self msgReleaseCompl ]
GSM48SSReleaseComplete class >> tlvDescription [
<category: 'parsing'>
^ OrderedCollection new
add: (GSM48Cause asTLVDescription beOptional; yourself);
add: (GSMFacility asTLVDescription beOptional; yourself);
yourself
]
]
Eval [
GSM48LURequest initialize.
GSM48LUReject initialize.
GSM48LUAccept initialize.
GSM48AuthReq initialize.
GSM48AuthResp initialize.
GSM48IdentityReq initialize.
GSM48IdentityResponse initialize.
GSM48CMServiceAccept initialize.
GSM48CMServiceReq initialize.
GSM48CMServiceReject initialize.
GSM48IMSIDetachInd initialize.
GSM48TMSIReallocationCommand initialize.
GSM48TMSIReallocationComplete initialize.
GSM48MMInformation initialize.
GSM48CCSetup initialize.
GSM48CCCallConfirmed initialize.
GSM48CCProceeding initialize.
GSM48CCAlerting initialize.
GSM48CCConnect initialize.
GSM48CCConnectAck initialize.
GSM48CCDisconnect initialize.
GSM48CCRelease initialize.
GSM48CCReleaseCompl initialize.
GSM48CCStatus initialize.
GSM48CCEmergencySetup initialize.
GSM48CCProgress initialize.
GSM48RRAssignmentComplete initialize.
GSM48RRHandoverCommand initialize.
GSM48RRHandoverComplete initialize.
GSM48RRHandoverFailure initialize.
GSM48RRImmediateAssignCommand initialize.
GSM48RRChannelRelease initialize.
GSM48RRCipheringModeCommand initialize.
GSM48RRCipheringModeComplete initialize.
GSM48RRClassmarkChange initialize.
GSM48RRPagingResponse initialize.
GSM48RRChannelModeModify initialize.
GSM48RRChannelModeModifyAck initialize.
GSM48SSFacility initialize.
GSM48SSRegister initialize.
GSM48SSReleaseComplete initialize.
"single parts of the IEs"
GSMBearerCapOctet3 initialize.
GSMBearerCapOctet3a initialize.
GSMBearerCapOctet3b initialize.
]