blob: 50a3fa550bede151c02985749779afcc3e5b04c6 [file] [log] [blame]
Matteo Scandolo992a23e2021-02-04 15:35:04 -08001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package devices
18
19import (
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080020 "github.com/google/gopacket"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080021 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
22 omcilib "github.com/opencord/bbsim/internal/common/omci"
23 "github.com/opencord/omci-lib-go"
24 me "github.com/opencord/omci-lib-go/generated"
25 "github.com/opencord/voltha-protos/v4/go/openolt"
26 "gotest.tools/assert"
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +020027 "testing"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080028)
29
30var mockAttr = me.AttributeValueMap{
Matteo Scandolo992a23e2021-02-04 15:35:04 -080031 "PortId": 0,
32 "TContPointer": 0,
33 "Direction": 0,
34 "TrafficManagementPointerForUpstream": 0,
35 "TrafficDescriptorProfilePointerForUpstream": 0,
36 "PriorityQueuePointerForDownStream": 0,
37 "TrafficDescriptorProfilePointerForDownstream": 0,
38 "EncryptionKeyRing": 0,
39}
40
41func makeOmciCreateRequest(t *testing.T) []byte {
42 omciReq := &omci.CreateRequest{
43 MeBasePacket: omci.MeBasePacket{
44 EntityClass: me.GemPortNetworkCtpClassID,
45 EntityInstance: 12,
46 },
47 Attributes: mockAttr,
48 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080049
Matteo Scandolo992a23e2021-02-04 15:35:04 -080050 omciPkt, err := omcilib.Serialize(omci.CreateRequestType, omciReq, 66)
51 if err != nil {
52 t.Fatal(err.Error())
53 }
54
55 omciPkt, _ = omcilib.HexEncode(omciPkt)
56
57 return omciPkt
58}
59
60func makeOmciSetRequest(t *testing.T) []byte {
61 omciReq := &omci.SetRequest{
62 MeBasePacket: omci.MeBasePacket{
63 EntityClass: me.GemPortNetworkCtpClassID,
64 EntityInstance: 12,
65 },
66 Attributes: mockAttr,
67 }
68 omciPkt, err := omcilib.Serialize(omci.SetRequestType, omciReq, 66)
69 if err != nil {
70 t.Fatal(err.Error())
71 }
72
73 omciPkt, _ = omcilib.HexEncode(omciPkt)
74
75 return omciPkt
76}
77
78func makeOmciDeleteRequest(t *testing.T) []byte {
79 omciReq := &omci.DeleteRequest{
80 MeBasePacket: omci.MeBasePacket{
81 EntityClass: me.GemPortNetworkCtpClassID,
82 EntityInstance: 12,
83 },
84 }
85 omciPkt, err := omcilib.Serialize(omci.DeleteRequestType, omciReq, 66)
86 if err != nil {
87 t.Fatal(err.Error())
88 }
89
90 omciPkt, _ = omcilib.HexEncode(omciPkt)
91
92 return omciPkt
93}
94
95func makeOmciMibResetRequest(t *testing.T) []byte {
96 omciReq := &omci.MibResetRequest{
97 MeBasePacket: omci.MeBasePacket{
98 EntityClass: me.OnuDataClassID,
99 },
100 }
101 omciPkt, err := omcilib.Serialize(omci.MibResetRequestType, omciReq, 66)
102 if err != nil {
103 t.Fatal(err.Error())
104 }
105
106 omciPkt, _ = omcilib.HexEncode(omciPkt)
107
108 return omciPkt
109}
110
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700111func makeOmciStartSoftwareDownloadRequest(t *testing.T) []byte {
112 omciReq := &omci.StartSoftwareDownloadRequest{
113 MeBasePacket: omci.MeBasePacket{
114 EntityClass: me.SoftwareImageClassID,
115 },
116 ImageSize: 31,
117 NumberOfCircuitPacks: 1,
118 WindowSize: 31,
119 CircuitPacks: []uint16{0},
120 }
121 omciPkt, err := omcilib.Serialize(omci.StartSoftwareDownloadRequestType, omciReq, 66)
122 if err != nil {
123 t.Fatal(err.Error())
124 }
125
126 omciPkt, _ = omcilib.HexEncode(omciPkt)
127
128 return omciPkt
129}
130
131func makeOmciEndSoftwareDownloadRequest(t *testing.T) []byte {
132 omciReq := &omci.EndSoftwareDownloadRequest{
133 MeBasePacket: omci.MeBasePacket{
134 EntityClass: me.SoftwareImageClassID,
135 },
136 NumberOfInstances: 1,
137 ImageInstances: []uint16{0},
138 }
139 omciPkt, err := omcilib.Serialize(omci.EndSoftwareDownloadRequestType, omciReq, 66)
140 if err != nil {
141 t.Fatal(err.Error())
142 }
143
144 omciPkt, _ = omcilib.HexEncode(omciPkt)
145
146 return omciPkt
147}
148
149func makeOmciActivateSoftwareRequest(t *testing.T) []byte {
150 omciReq := &omci.ActivateSoftwareRequest{
151 MeBasePacket: omci.MeBasePacket{
152 EntityClass: me.SoftwareImageClassID,
153 },
154 }
155 omciPkt, err := omcilib.Serialize(omci.ActivateSoftwareRequestType, omciReq, 66)
156 if err != nil {
157 t.Fatal(err.Error())
158 }
159
160 omciPkt, _ = omcilib.HexEncode(omciPkt)
161
162 return omciPkt
163}
164
165func makeOmciCommitSoftwareRequest(t *testing.T) []byte {
166 omciReq := &omci.CommitSoftwareRequest{
167 MeBasePacket: omci.MeBasePacket{
168 EntityClass: me.SoftwareImageClassID,
169 },
170 }
171 omciPkt, err := omcilib.Serialize(omci.CommitSoftwareRequestType, omciReq, 66)
172 if err != nil {
173 t.Fatal(err.Error())
174 }
175
176 omciPkt, _ = omcilib.HexEncode(omciPkt)
177
178 return omciPkt
179}
180
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800181func makeOmciMessage(t *testing.T, onu *Onu, pkt []byte) bbsim.OmciMessage {
Matteo Scandolob5913142021-03-19 16:10:18 -0700182 omciPkt, omciMsg, err := omcilib.ParseOpenOltOmciPacket(pkt)
183 if err != nil {
184 t.Fatal(err.Error())
185 }
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800186 return bbsim.OmciMessage{
Matteo Scandolob5913142021-03-19 16:10:18 -0700187 OnuSN: onu.SerialNumber,
188 OnuID: onu.ID,
189 OmciPkt: omciPkt,
190 OmciMsg: omciMsg,
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800191 }
192}
193
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800194func omciBytesToMsg(t *testing.T, data []byte) (*omci.OMCI, *gopacket.Packet) {
195 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.NoCopy)
196 if packet == nil {
197 t.Fatal("could not decode rxMsg as OMCI")
198 }
199 omciLayer := packet.Layer(omci.LayerTypeOMCI)
200 if omciLayer == nil {
201 t.Fatal("could not decode omci layer")
202 }
203 omciMsg, ok := omciLayer.(*omci.OMCI)
204 if !ok {
205 t.Fatal("could not assign omci layer")
206 }
207 return omciMsg, &packet
208}
209
210func omciToCreateResponse(t *testing.T, omciPkt *gopacket.Packet) *omci.CreateResponse {
211 msgLayer := (*omciPkt).Layer(omci.LayerTypeCreateResponse)
212 if msgLayer == nil {
213 t.Fatal("omci Msg layer could not be detected for CreateResponse - handling of MibSyncChan stopped")
214 }
215 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
216 if !msgOk {
217 t.Fatal("omci Msg layer could not be assigned for CreateResponse - handling of MibSyncChan stopped")
218 }
219 return msgObj
220}
221
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800222func Test_MibDataSyncIncrease(t *testing.T) {
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700223 onu := createTestOnu()
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800224
225 assert.Equal(t, onu.MibDataSync, uint8(0))
226
227 stream := &mockStream{
228 Calls: make(map[int]*openolt.Indication),
229 }
230
231 // send a Create and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200232 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
233 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800234 assert.Equal(t, onu.MibDataSync, uint8(1))
235
236 // send a Set and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200237 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
238 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800239 assert.Equal(t, onu.MibDataSync, uint8(2))
240
241 // send a Delete and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200242 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
243 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800244 assert.Equal(t, onu.MibDataSync, uint8(3))
245
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700246 // Start software download
247 onu.InternalState.SetState(OnuStateEnabled)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200248 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciStartSoftwareDownloadRequest(t)), stream)
249 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700250 assert.Equal(t, onu.MibDataSync, uint8(4))
251
252 // End software download
253 onu.ImageSoftwareReceivedSections = 1 // we fake that we have received the one download section we expect
254 onu.InternalState.SetState(OnuStateImageDownloadInProgress)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200255 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t)), stream)
256 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700257 assert.Equal(t, onu.MibDataSync, uint8(5))
258
259 // Activate software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200260 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciActivateSoftwareRequest(t)), stream)
261 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700262 assert.Equal(t, onu.MibDataSync, uint8(6))
263
264 // Commit software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200265 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCommitSoftwareRequest(t)), stream)
266 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700267 assert.Equal(t, onu.MibDataSync, uint8(7))
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800268}
269
270func Test_MibDataSyncReset(t *testing.T) {
271 onu := createMockOnu(1, 1)
272 onu.MibDataSync = 192
273 assert.Equal(t, onu.MibDataSync, uint8(192))
274
275 stream := &mockStream{
276 Calls: make(map[int]*openolt.Indication),
277 }
278
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700279 // create a GemPort and an AllocId for this ONU
280 onu.PonPort.storeGemPort(1024, onu.SerialNumber)
281 onu.PonPort.storeAllocId(1024, onu.SerialNumber)
282
283 // send a MibReset
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200284 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciMibResetRequest(t)), stream)
285 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700286
287 // check that MDS has reset to 0
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800288 assert.Equal(t, onu.MibDataSync, uint8(0))
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700289
290 // check that GemPort and AllocId have been removed
291 assert.Equal(t, len(onu.PonPort.AllocatedGemPorts), 0)
292 assert.Equal(t, len(onu.PonPort.AllocatedAllocIds), 0)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800293}
294
295func Test_MibDataSyncRotation(t *testing.T) {
296 onu := createMockOnu(1, 1)
297 onu.MibDataSync = 255
298 assert.Equal(t, onu.MibDataSync, uint8(255))
299
300 stream := &mockStream{
301 Calls: make(map[int]*openolt.Indication),
302 }
303
304 // send a request that increases the MDS, but once we're at 255 we should go back to 0 (8bit)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200305 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
306 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800307 assert.Equal(t, onu.MibDataSync, uint8(0))
308}
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800309
310func Test_GemPortValidation(t *testing.T) {
311
312 // setup
313 onu := createMockOnu(1, 1)
314
315 stream := &mockStream{
316 Calls: make(map[int]*openolt.Indication),
317 }
318
319 // create a gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200320 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
321 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800322
323 // the first time we created the gemPort
324 // the MDS should be incremented
325 assert.Equal(t, stream.CallCount, 1)
326 assert.Equal(t, onu.MibDataSync, uint8(1))
327
328 // and the OMCI response status should be me.Success
329 indication := stream.Calls[1].GetOmciInd()
330 _, omciPkt := omciBytesToMsg(t, indication.Pkt)
331 responseLayer := omciToCreateResponse(t, omciPkt)
332 assert.Equal(t, responseLayer.Result, me.Success)
333
334 // send a request to create the same gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200335 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
336 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800337
338 // this time the MDS should not be incremented
339 assert.Equal(t, stream.CallCount, 2)
340 assert.Equal(t, onu.MibDataSync, uint8(1))
341
342 // and the OMCI response status should be me.ProcessingError
343 _, omciPkt = omciBytesToMsg(t, stream.Calls[2].GetOmciInd().Pkt)
344 responseLayer = omciToCreateResponse(t, omciPkt)
345 assert.Equal(t, responseLayer.Result, me.ProcessingError)
346}
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000347
348func Test_OmciResponseRate(t *testing.T) {
349
350 onu := createMockOnu(1, 1)
351
352 for onu.OmciResponseRate = 0; onu.OmciResponseRate <= maxOmciMsgCounter; onu.OmciResponseRate++ {
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000353 stream := &mockStream{
354 Calls: make(map[int]*openolt.Indication),
355 }
356 //send ten OMCI requests and check if number of responses is only equal to onu.OmciResponseRate
357 for i := 0; i < 10; i++ {
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200358 // we are not checking the error as we're expecting them (some messages should be skipped)
359 _ = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000360 }
361 assert.Equal(t, stream.CallCount, int(onu.OmciResponseRate))
362 }
363}