1
0
Fork 0

nack: Test how the BSC will handle a NACK and that it does not drop the other BTS

Refactor the BTS and OMLInit code to allow to easily introduce
a NACK message at the required place. Implement the NACK for the
SetBTSAttributes in the OML code. Add the testcase and an the OpenBSC
NITB configuration needed
This commit is contained in:
Holger Hans Peter Freyther 2012-11-11 17:08:10 +01:00
parent bda9975da7
commit fecf0f68f9
6 changed files with 280 additions and 3 deletions

View File

@ -161,6 +161,10 @@ Object subclass: BTS [
<comment: 'A fake BTS to test the state machine and inject
RSL messages to test a network without RF.'>
BTS class >> omlInitClass [
^ OMLBTSInit
]
connect: anAddress [
<category: 'connect'>
self stop.
@ -210,7 +214,7 @@ Object subclass: BTS [
onData: [:each | self sendRSL: each].
"Start the OML init now in a new thread"
oml_init := OMLBTSInit initWith: self.
oml_init := self class omlInitClass initWith: self.
[[oml_init run ] ensure: [Transcript nextPutAll: 'OML-Init exited'; nl]] fork.
]

View File

@ -233,6 +233,10 @@ Object subclass: OMLBTSInit [
aSem signal.
]
initBtsInstance: bts withQueue: btsQueue [
^ OMLBTSInstanceInit on: bts withInit: self withQueue: btsQueue.
]
btsInit: aSem [
| btsQueue bts init trxProc trxSem rcProc rcSem |
btsQueue := SharedQueue new.
@ -241,7 +245,7 @@ Object subclass: OMLBTSInit [
"1. Activate the software"
self forwardOML: bts createSwActivateRequest toMessage.
init := OMLBTSInstanceInit on: bts withInit: self withQueue: btsQueue.
init := self initBtsInstance: bts withQueue: btsQueue.
"Get the SM into the enabled state"
trxSem := Semaphore new.

View File

@ -958,7 +958,8 @@ OMLMessageBase subclass: FOMMessage [
createNack [
<category: 'acking'>
^ self notImplementedYet
^ self class new
omDataField: om_field createNack.
]
createResponse: aResponse [
@ -1334,6 +1335,19 @@ OMLDataField subclass: OMLSetBTSAttributes [
ack instVarNamed: name put: (self instVarNamed: name)].
^ ack
]
createNack [
| nack |
<category: 'acking'>
nack := OMLSetBTSAttributesNack new
objectClass: self objectClass;
objectInstance: self objectInstance;
yourself.
self class instVarNames do: [:name |
nack instVarNamed: name put: (self instVarNamed: name)].
^ nack
]
]
OMLSetBTSAttributes subclass: OMLSetBTSAttributesAck [
@ -1346,6 +1360,16 @@ OMLSetBTSAttributes subclass: OMLSetBTSAttributesAck [
]
]
OMLSetBTSAttributes subclass: OMLSetBTSAttributesNack [
<category: 'BTS-OML'>
<comment: 'I construct a GSM 12.21 O&M Data field as of 8.6.1'>
OMLSetBTSAttributesNack class >> attributeType [
<category: 'parsing'>
^ FOMMessage msgSetBTSAttributesNack
]
]
OMLDataField subclass: OMLChangeAdminState [
| adm_state |

96
nack_test/NACKTest.st Normal file
View File

@ -0,0 +1,96 @@
"
(C) 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/>.
"
PackageLoader fileInPackage: #FakeBTS.
FakeBTS.OMLBTSInstanceInit subclass: NACKBTSInit [
<import: OsmoGSM>
<comment: 'I will respond with a nack...'>
waitForAttributes [
| msg res nack |
<category: 'protected'>
msg := queue next.
msg omDataField class = OMLSetBTSAttributes
ifFalse: [self error: 'Failed to get SetBTSAttributes'].
nack := msg createResponse: false.
omlInit forwardOML: nack toMessage.
]
]
FakeBTS.OMLBTSInit subclass: NACKInit [
<import: OsmoGSM>
<comment: 'I am an INIT that will nack the BTS Attributes to check
what OpenBSC will do'>
initBtsInstance: aBts withQueue: aQueue [
"Called to initialize the BTS Object"
^ NACKBTSInit on: aBts withInit: self withQueue: aQueue.
]
]
FakeBTS.BTS subclass: NACKBTS [
| oml_gone |
<import: OsmoGSM>
<comment: 'I am a BTS that will NACK the OML init and this should
cause this BTS to be dropped.'>
NACKBTS class >> omlInitClass [
^ NACKInit
]
connect: aHost [
self stop.
rsl := nil.
oml_gone := Semaphore new.
^ super connect: aHost.
]
omlStopped [
oml_gone signal.
]
waitForOMLGone [
"Wait until the OML connection is gone"
oml_gone wait.
]
]
Eval [
| btsAck btsNack test lchan |
"Connect and wait for the BTS to be ready."
btsAck := FakeBTS.BTS new
btsId: '1801/0/0'; connect: 'localhost';
waitForBTSReady; yourself.
"Now connect a NACK bts.."
btsNack := NACKBTS new
btsId: '1802/0/0'; connect: 'localhost';
waitForOMLGone; yourself.
"Verify that the first BTS is still connected"
test := FakeBTS.OpenBSCTest initWith: btsAck.
lchan := test requireAnyChannel.
lchan isNil
ifTrue: [Transcript nextPutAll: 'FAILED TO ALLOCATE A LCHAN'; nl.]
ifFalse: [Transcript nextPutAll: 'Test passed'; nl.].
]

2
nack_test/README Normal file
View File

@ -0,0 +1,2 @@
This should test two BTS connecting and the second one should NACK
some OML attributes while the first BTS remains connected.

147
nack_test/openbsc.cfg Normal file
View File

@ -0,0 +1,147 @@
!
! OpenBSC (0.12.0.18-1a6b8-dirty) configuration saved from vty
!!
password foo
!
log stderr
logging color 1
logging timestamp 0
!
line vty
no login
!
e1_input
e1_line 0 driver ipa
e1_line 0 port 0
network
network country code 1
mobile network code 1
short name OpenBSC
long name OpenBSC
auth policy closed
location updating reject cause 13
encryption a5 0
neci 1
paging any use tch 0
rrlp mode none
mm info 1
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 0
timer t3111 0
timer t3113 60
timer t3115 0
timer t3117 0
timer t3119 0
timer t3122 0
timer t3141 0
dtx-used 0
subscriber-keep-in-ram 0
bts 0
type nanobts
band DCS1800
cell_identity 0
location_area_code 1
training_sequence_code 7
base_station_id_code 63
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
channel allocator ascending
rach tx integer 9
rach max transmission 7
ip.access unit_id 1801 0
oml ip.access stream_id 255 line 0
neighbor-list mode automatic
gprs mode none
description BTS 1.. not nacked
trx 0
rf_locked 0
arfcn 809
nominal power 23
max_power_red 20
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
timeslot 1
phys_chan_config SDCCH8
hopping enabled 0
timeslot 2
phys_chan_config TCH/H
hopping enabled 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
bts 1
type nanobts
band DCS1800
cell_identity 0
location_area_code 1
training_sequence_code 7
base_station_id_code 63
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
channel allocator ascending
rach tx integer 9
rach max transmission 7
ip.access unit_id 1802 0
oml ip.access stream_id 255 line 0
neighbor-list mode automatic
gprs mode none
description BTS 1.. nacked
trx 0
rf_locked 0
arfcn 809
nominal power 23
max_power_red 20
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
timeslot 1
phys_chan_config SDCCH8
hopping enabled 0
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
mncc-int
default-codec tch-f efr
default-codec tch-h hr