blob: 2c2b489ee6c0ed93cd9fcc5fa4dd1cedcd2cd1c1 [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"
Andrea Campanella10426e22021-10-15 17:58:04 +020023 "github.com/opencord/omci-lib-go/v2"
24 me "github.com/opencord/omci-lib-go/v2/generated"
David K. Bainbridgec415efe2021-08-19 13:05:21 +000025 "github.com/opencord/voltha-protos/v5/go/openolt"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080026 "gotest.tools/assert"
Matteo Scandolo76f6b892021-11-15 16:13:06 -080027 "strconv"
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +020028 "testing"
Matteo Scandolo992a23e2021-02-04 15:35:04 -080029)
30
31var mockAttr = me.AttributeValueMap{
Matteo Scandolo992a23e2021-02-04 15:35:04 -080032 "PortId": 0,
33 "TContPointer": 0,
34 "Direction": 0,
35 "TrafficManagementPointerForUpstream": 0,
36 "TrafficDescriptorProfilePointerForUpstream": 0,
37 "PriorityQueuePointerForDownStream": 0,
38 "TrafficDescriptorProfilePointerForDownstream": 0,
39 "EncryptionKeyRing": 0,
40}
41
42func makeOmciCreateRequest(t *testing.T) []byte {
43 omciReq := &omci.CreateRequest{
44 MeBasePacket: omci.MeBasePacket{
45 EntityClass: me.GemPortNetworkCtpClassID,
46 EntityInstance: 12,
47 },
48 Attributes: mockAttr,
49 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080050
Matteo Scandolo992a23e2021-02-04 15:35:04 -080051 omciPkt, err := omcilib.Serialize(omci.CreateRequestType, omciReq, 66)
52 if err != nil {
53 t.Fatal(err.Error())
54 }
55
56 omciPkt, _ = omcilib.HexEncode(omciPkt)
57
58 return omciPkt
59}
60
61func makeOmciSetRequest(t *testing.T) []byte {
62 omciReq := &omci.SetRequest{
63 MeBasePacket: omci.MeBasePacket{
64 EntityClass: me.GemPortNetworkCtpClassID,
65 EntityInstance: 12,
66 },
67 Attributes: mockAttr,
68 }
69 omciPkt, err := omcilib.Serialize(omci.SetRequestType, omciReq, 66)
70 if err != nil {
71 t.Fatal(err.Error())
72 }
73
74 omciPkt, _ = omcilib.HexEncode(omciPkt)
75
76 return omciPkt
77}
78
79func makeOmciDeleteRequest(t *testing.T) []byte {
80 omciReq := &omci.DeleteRequest{
81 MeBasePacket: omci.MeBasePacket{
82 EntityClass: me.GemPortNetworkCtpClassID,
83 EntityInstance: 12,
84 },
85 }
86 omciPkt, err := omcilib.Serialize(omci.DeleteRequestType, omciReq, 66)
87 if err != nil {
88 t.Fatal(err.Error())
89 }
90
91 omciPkt, _ = omcilib.HexEncode(omciPkt)
92
93 return omciPkt
94}
95
96func makeOmciMibResetRequest(t *testing.T) []byte {
97 omciReq := &omci.MibResetRequest{
98 MeBasePacket: omci.MeBasePacket{
99 EntityClass: me.OnuDataClassID,
100 },
101 }
102 omciPkt, err := omcilib.Serialize(omci.MibResetRequestType, omciReq, 66)
103 if err != nil {
104 t.Fatal(err.Error())
105 }
106
107 omciPkt, _ = omcilib.HexEncode(omciPkt)
108
109 return omciPkt
110}
111
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700112func makeOmciStartSoftwareDownloadRequest(t *testing.T) []byte {
113 omciReq := &omci.StartSoftwareDownloadRequest{
114 MeBasePacket: omci.MeBasePacket{
115 EntityClass: me.SoftwareImageClassID,
116 },
117 ImageSize: 31,
118 NumberOfCircuitPacks: 1,
119 WindowSize: 31,
120 CircuitPacks: []uint16{0},
121 }
122 omciPkt, err := omcilib.Serialize(omci.StartSoftwareDownloadRequestType, omciReq, 66)
123 if err != nil {
124 t.Fatal(err.Error())
125 }
126
127 omciPkt, _ = omcilib.HexEncode(omciPkt)
128
129 return omciPkt
130}
131
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800132func makeOmciEndSoftwareDownloadRequest(t *testing.T, imageSize uint32, imageCrc uint32) []byte {
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700133 omciReq := &omci.EndSoftwareDownloadRequest{
134 MeBasePacket: omci.MeBasePacket{
135 EntityClass: me.SoftwareImageClassID,
136 },
137 NumberOfInstances: 1,
138 ImageInstances: []uint16{0},
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800139 ImageSize: imageSize,
140 CRC32: imageCrc,
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700141 }
142 omciPkt, err := omcilib.Serialize(omci.EndSoftwareDownloadRequestType, omciReq, 66)
143 if err != nil {
144 t.Fatal(err.Error())
145 }
146
147 omciPkt, _ = omcilib.HexEncode(omciPkt)
148
149 return omciPkt
150}
151
152func makeOmciActivateSoftwareRequest(t *testing.T) []byte {
153 omciReq := &omci.ActivateSoftwareRequest{
154 MeBasePacket: omci.MeBasePacket{
155 EntityClass: me.SoftwareImageClassID,
156 },
157 }
158 omciPkt, err := omcilib.Serialize(omci.ActivateSoftwareRequestType, omciReq, 66)
159 if err != nil {
160 t.Fatal(err.Error())
161 }
162
163 omciPkt, _ = omcilib.HexEncode(omciPkt)
164
165 return omciPkt
166}
167
168func makeOmciCommitSoftwareRequest(t *testing.T) []byte {
169 omciReq := &omci.CommitSoftwareRequest{
170 MeBasePacket: omci.MeBasePacket{
171 EntityClass: me.SoftwareImageClassID,
172 },
173 }
174 omciPkt, err := omcilib.Serialize(omci.CommitSoftwareRequestType, omciReq, 66)
175 if err != nil {
176 t.Fatal(err.Error())
177 }
178
179 omciPkt, _ = omcilib.HexEncode(omciPkt)
180
181 return omciPkt
182}
183
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800184func makeOmciMessage(t *testing.T, onu *Onu, pkt []byte) bbsim.OmciMessage {
Matteo Scandolob5913142021-03-19 16:10:18 -0700185 omciPkt, omciMsg, err := omcilib.ParseOpenOltOmciPacket(pkt)
186 if err != nil {
187 t.Fatal(err.Error())
188 }
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800189 return bbsim.OmciMessage{
Matteo Scandolob5913142021-03-19 16:10:18 -0700190 OnuSN: onu.SerialNumber,
191 OnuID: onu.ID,
192 OmciPkt: omciPkt,
193 OmciMsg: omciMsg,
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800194 }
195}
196
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800197func omciBytesToMsg(t *testing.T, data []byte) (*omci.OMCI, *gopacket.Packet) {
198 packet := gopacket.NewPacket(data, omci.LayerTypeOMCI, gopacket.NoCopy)
199 if packet == nil {
200 t.Fatal("could not decode rxMsg as OMCI")
201 }
202 omciLayer := packet.Layer(omci.LayerTypeOMCI)
203 if omciLayer == nil {
204 t.Fatal("could not decode omci layer")
205 }
206 omciMsg, ok := omciLayer.(*omci.OMCI)
207 if !ok {
208 t.Fatal("could not assign omci layer")
209 }
210 return omciMsg, &packet
211}
212
213func omciToCreateResponse(t *testing.T, omciPkt *gopacket.Packet) *omci.CreateResponse {
214 msgLayer := (*omciPkt).Layer(omci.LayerTypeCreateResponse)
215 if msgLayer == nil {
216 t.Fatal("omci Msg layer could not be detected for CreateResponse - handling of MibSyncChan stopped")
217 }
218 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
219 if !msgOk {
220 t.Fatal("omci Msg layer could not be assigned for CreateResponse - handling of MibSyncChan stopped")
221 }
222 return msgObj
223}
224
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800225func Test_MibDataSyncIncrease(t *testing.T) {
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700226 onu := createTestOnu()
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800227
228 assert.Equal(t, onu.MibDataSync, uint8(0))
229
230 stream := &mockStream{
231 Calls: make(map[int]*openolt.Indication),
232 }
233
234 // send a Create and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200235 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
236 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800237 assert.Equal(t, onu.MibDataSync, uint8(1))
238
239 // send a Set and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200240 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
241 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800242 assert.Equal(t, onu.MibDataSync, uint8(2))
243
244 // send a Delete and check that MDS has been increased
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200245 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
246 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800247 assert.Equal(t, onu.MibDataSync, uint8(3))
248
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700249 // Start software download
250 onu.InternalState.SetState(OnuStateEnabled)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200251 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciStartSoftwareDownloadRequest(t)), stream)
252 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700253 assert.Equal(t, onu.MibDataSync, uint8(4))
254
255 // End software download
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800256 onu.ImageSoftwareExpectedSections = 31
257 onu.ImageSoftwareReceivedSections = 31 // we fake that we have received all the download section we expect
258 onu.ImageSectionData = []byte{111, 114, 116, 116, 105, 116, 111, 114, 32, 113, 117, 105, 115, 46, 32, 86, 105, 118, 97, 109, 117, 115, 32, 110, 101, 99, 32, 108, 105, 98, 101}
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700259 onu.InternalState.SetState(OnuStateImageDownloadInProgress)
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800260 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 1523894119)), stream)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200261 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700262 assert.Equal(t, onu.MibDataSync, uint8(5))
263
264 // Activate software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200265 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciActivateSoftwareRequest(t)), stream)
266 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700267 assert.Equal(t, onu.MibDataSync, uint8(6))
268
269 // Commit software
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200270 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCommitSoftwareRequest(t)), stream)
271 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700272 assert.Equal(t, onu.MibDataSync, uint8(7))
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800273}
274
275func Test_MibDataSyncReset(t *testing.T) {
276 onu := createMockOnu(1, 1)
277 onu.MibDataSync = 192
278 assert.Equal(t, onu.MibDataSync, uint8(192))
279
280 stream := &mockStream{
281 Calls: make(map[int]*openolt.Indication),
282 }
283
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700284 // create a GemPort and an AllocId for this ONU
285 onu.PonPort.storeGemPort(1024, onu.SerialNumber)
286 onu.PonPort.storeAllocId(1024, onu.SerialNumber)
287
288 // send a MibReset
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200289 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciMibResetRequest(t)), stream)
290 assert.NilError(t, err)
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700291
292 // check that MDS has reset to 0
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800293 assert.Equal(t, onu.MibDataSync, uint8(0))
Matteo Scandolo2fdc3b82021-04-23 15:27:21 -0700294
295 // check that GemPort and AllocId have been removed
296 assert.Equal(t, len(onu.PonPort.AllocatedGemPorts), 0)
297 assert.Equal(t, len(onu.PonPort.AllocatedAllocIds), 0)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800298}
299
300func Test_MibDataSyncRotation(t *testing.T) {
301 onu := createMockOnu(1, 1)
302 onu.MibDataSync = 255
303 assert.Equal(t, onu.MibDataSync, uint8(255))
304
305 stream := &mockStream{
306 Calls: make(map[int]*openolt.Indication),
307 }
308
309 // 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 +0200310 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciDeleteRequest(t)), stream)
311 assert.NilError(t, err)
Matteo Scandolo992a23e2021-02-04 15:35:04 -0800312 assert.Equal(t, onu.MibDataSync, uint8(0))
313}
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800314
315func Test_GemPortValidation(t *testing.T) {
316
317 // setup
318 onu := createMockOnu(1, 1)
319
320 stream := &mockStream{
321 Calls: make(map[int]*openolt.Indication),
322 }
323
324 // create a gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200325 err := onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
326 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800327
328 // the first time we created the gemPort
329 // the MDS should be incremented
330 assert.Equal(t, stream.CallCount, 1)
331 assert.Equal(t, onu.MibDataSync, uint8(1))
332
333 // and the OMCI response status should be me.Success
334 indication := stream.Calls[1].GetOmciInd()
335 _, omciPkt := omciBytesToMsg(t, indication.Pkt)
336 responseLayer := omciToCreateResponse(t, omciPkt)
337 assert.Equal(t, responseLayer.Result, me.Success)
338
339 // send a request to create the same gem port via OMCI (gemPortId 12)
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200340 err = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciCreateRequest(t)), stream)
341 assert.NilError(t, err)
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800342
343 // this time the MDS should not be incremented
344 assert.Equal(t, stream.CallCount, 2)
345 assert.Equal(t, onu.MibDataSync, uint8(1))
346
347 // and the OMCI response status should be me.ProcessingError
348 _, omciPkt = omciBytesToMsg(t, stream.Calls[2].GetOmciInd().Pkt)
349 responseLayer = omciToCreateResponse(t, omciPkt)
350 assert.Equal(t, responseLayer.Result, me.ProcessingError)
351}
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000352
353func Test_OmciResponseRate(t *testing.T) {
354
355 onu := createMockOnu(1, 1)
356
357 for onu.OmciResponseRate = 0; onu.OmciResponseRate <= maxOmciMsgCounter; onu.OmciResponseRate++ {
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000358 stream := &mockStream{
359 Calls: make(map[int]*openolt.Indication),
360 }
361 //send ten OMCI requests and check if number of responses is only equal to onu.OmciResponseRate
362 for i := 0; i < 10; i++ {
Andrea Campanellabe1b7cf2021-04-30 09:53:40 +0200363 // we are not checking the error as we're expecting them (some messages should be skipped)
364 _ = onu.handleOmciRequest(makeOmciMessage(t, onu, makeOmciSetRequest(t)), stream)
Holger Hildebrandtc10bab12021-04-27 09:23:48 +0000365 }
366 assert.Equal(t, stream.CallCount, int(onu.OmciResponseRate))
367 }
368}
Matteo Scandolo76f6b892021-11-15 16:13:06 -0800369
370func Test_EndSoftwareDownloadRequestHandling(t *testing.T) {
371 onu := createTestOnu()
372
373 // test EndSoftwareDownloadRequest in case of abort
374 onu.ImageSoftwareReceivedSections = 2
375 imageCrc, _ := strconv.ParseInt("FFFFFFFF", 16, 64)
376 msg := makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 0, uint32(imageCrc)))
377 res := onu.handleEndSoftwareDownloadRequest(msg)
378 assert.Equal(t, res, true)
379 assert.Equal(t, onu.ImageSoftwareReceivedSections, 0)
380
381 // test EndSoftwareDownloadRequest if we received less sections than expected
382 onu.ImageSoftwareExpectedSections = 2
383 onu.ImageSoftwareReceivedSections = 1
384 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 2, 2))
385 res = onu.handleEndSoftwareDownloadRequest(msg)
386 assert.Equal(t, res, false)
387
388 // test CRC Mismatch
389 onu.ImageSectionData = []byte{111, 114, 116, 116, 105, 116, 111, 114, 32, 113, 117, 105, 115, 46, 32, 86, 105, 118, 97, 109, 117, 115, 32, 110, 101, 99, 32, 108, 105, 98, 101}
390 onu.ImageSoftwareExpectedSections = 2
391 onu.ImageSoftwareReceivedSections = 2
392 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 12))
393 res = onu.handleEndSoftwareDownloadRequest(msg)
394 assert.Equal(t, res, false)
395
396 // if it's a valid case then set the StandbyImageVersion
397 onu.InDownloadImageVersion = "DownloadedImage"
398 msg = makeOmciMessage(t, onu, makeOmciEndSoftwareDownloadRequest(t, 31, 1523894119))
399 res = onu.handleEndSoftwareDownloadRequest(msg)
400 assert.Equal(t, res, true)
401 assert.Equal(t, onu.StandbyImageVersion, "DownloadedImage")
402}