2982 lines
90 KiB
Smalltalk
2982 lines
90 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]
|
|
]
|
|
]
|
|
|
|
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
|
|
]
|
|
|
|
length: aStream [
|
|
<category: 'parsing'>
|
|
^ self gsmValueLength
|
|
]
|
|
|
|
length [
|
|
<category: 'parsing'>
|
|
"TODO: deprecate and remove"
|
|
^ self gsmValueLength
|
|
]
|
|
|
|
gsmValueLength [
|
|
<category: 'parsing'>
|
|
^ gsmValueLength ifNil: [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.
|
|
]
|
|
|
|
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>
|
|
]
|
|
|
|
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>
|
|
]
|
|
|
|
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: 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>
|
|
]
|
|
|
|
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'>
|
|
<gsmMinValueSize: 2 max: 6>
|
|
]
|
|
|
|
GSM48SimpleData subclass: GSM48KeySeqLuType [
|
|
<category: 'OsmoGSM'>
|
|
<comment: 'This byte is shared for two things'>
|
|
|
|
<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 >> createDefault [
|
|
<category: 'creation'>
|
|
^ (self new)
|
|
val: 16r70;
|
|
yourself
|
|
]
|
|
|
|
val [
|
|
^ 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>
|
|
]
|
|
|
|
GSM48VariableSizedIE subclass: GSM48MIdentity [
|
|
| type id |
|
|
|
|
<category: 'OsmoGSM'>
|
|
<comment: 'I am MobileIdentity of 10.5.1.4'>
|
|
|
|
<gsmElementId: 23>
|
|
<gsmName: 'mi'>
|
|
|
|
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 ]
|
|
"TODO: Range of causes for re-try 2r00110000 to 2r00111111"
|
|
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'>
|
|
|
|
DigitMap := nil.
|
|
ReverseMap := nil.
|
|
|
|
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: Character eof.
|
|
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 := OrderedCollection new.
|
|
|
|
[aStream atEnd] whileFalse: [
|
|
| in tmp char |
|
|
in := aStream next.
|
|
tmp := in bitAnd: 16r0F.
|
|
str add: (self mapDigit: tmp).
|
|
|
|
tmp := (in bitAnd: 16rF0) bitShift: -4.
|
|
char := (self mapDigit: tmp).
|
|
char = Character eof
|
|
ifFalse: [
|
|
str add: char.
|
|
].
|
|
].
|
|
|
|
^ str asString
|
|
]
|
|
|
|
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'>
|
|
^ 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'>
|
|
]
|
|
|
|
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'>
|
|
]
|
|
|
|
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.
|
|
].
|
|
].
|
|
|
|
Exception signal: '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 too"
|
|
]
|
|
]
|
|
|
|
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);
|
|
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
|
|
]
|
|
]
|
|
|
|
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: GSM48Cause asTLVDescription;
|
|
add: (GSM48TimingDifference asTLVDescription beOptional; yourself);
|
|
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: 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.
|
|
|
|
GSM48RRAssignmentComplete initialize.
|
|
GSM48RRHandoverCommand initialize.
|
|
GSM48RRHandoverComplete initialize.
|
|
GSM48RRImmediateAssignCommand initialize.
|
|
GSM48RRChannelRelease 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.
|
|
]
|