blob: 5e5dd74e5dc0a20e0331c7a4b568c32473a8e14e [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
3 * Copyright 2020-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package omci
19
20import (
21 "encoding/binary"
22 "errors"
23 "fmt"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000024 "github.com/google/gopacket"
Himani Chawlaac1f5ad2021-02-04 21:21:54 +053025 me "github.com/opencord/omci-lib-go/generated"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000026)
27
28// MessageType is the OMCI Message Type or'ed with the AR/AK flags as appropriate.
29type MessageType byte
30
31const (
Girish Gowdra8a7b4562021-02-23 16:27:42 -080032 CreateRequestType = MessageType(byte(me.Create) | me.AR)
33 CreateResponseType = MessageType(byte(me.Create) | me.AK)
34 DeleteRequestType = MessageType(byte(me.Delete) | me.AR)
35 DeleteResponseType = MessageType(byte(me.Delete) | me.AK)
36 SetRequestType = MessageType(byte(me.Set) | me.AR)
37 SetResponseType = MessageType(byte(me.Set) | me.AK)
38 GetRequestType = MessageType(byte(me.Get) | me.AR)
39 GetResponseType = MessageType(byte(me.Get) | me.AK)
40 GetAllAlarmsRequestType = MessageType(byte(me.GetAllAlarms) | me.AR)
41 GetAllAlarmsResponseType = MessageType(byte(me.GetAllAlarms) | me.AK)
42 GetAllAlarmsNextRequestType = MessageType(byte(me.GetAllAlarmsNext) | me.AR)
43 GetAllAlarmsNextResponseType = MessageType(byte(me.GetAllAlarmsNext) | me.AK)
44 MibUploadRequestType = MessageType(byte(me.MibUpload) | me.AR)
45 MibUploadResponseType = MessageType(byte(me.MibUpload) | me.AK)
46 MibUploadNextRequestType = MessageType(byte(me.MibUploadNext) | me.AR)
47 MibUploadNextResponseType = MessageType(byte(me.MibUploadNext) | me.AK)
48 MibResetRequestType = MessageType(byte(me.MibReset) | me.AR)
49 MibResetResponseType = MessageType(byte(me.MibReset) | me.AK)
50 TestRequestType = MessageType(byte(me.Test) | me.AR)
51 TestResponseType = MessageType(byte(me.Test) | me.AK)
52 StartSoftwareDownloadRequestType = MessageType(byte(me.StartSoftwareDownload) | me.AR)
53 StartSoftwareDownloadResponseType = MessageType(byte(me.StartSoftwareDownload) | me.AK)
54 DownloadSectionRequestType = MessageType(me.DownloadSection) // me.AR is optional
55 DownloadSectionRequestWithResponseType = MessageType(byte(me.DownloadSection) | me.AR)
56 DownloadSectionResponseType = MessageType(byte(me.DownloadSection) | me.AK)
57 EndSoftwareDownloadRequestType = MessageType(byte(me.EndSoftwareDownload) | me.AR)
58 EndSoftwareDownloadResponseType = MessageType(byte(me.EndSoftwareDownload) | me.AK)
59 ActivateSoftwareRequestType = MessageType(byte(me.ActivateSoftware) | me.AR)
60 ActivateSoftwareResponseType = MessageType(byte(me.ActivateSoftware) | me.AK)
61 CommitSoftwareRequestType = MessageType(byte(me.CommitSoftware) | me.AR)
62 CommitSoftwareResponseType = MessageType(byte(me.CommitSoftware) | me.AK)
63 SynchronizeTimeRequestType = MessageType(byte(me.SynchronizeTime) | me.AR)
64 SynchronizeTimeResponseType = MessageType(byte(me.SynchronizeTime) | me.AK)
65 RebootRequestType = MessageType(byte(me.Reboot) | me.AR)
66 RebootResponseType = MessageType(byte(me.Reboot) | me.AK)
67 GetNextRequestType = MessageType(byte(me.GetNext) | me.AR)
68 GetNextResponseType = MessageType(byte(me.GetNext) | me.AK)
69 GetCurrentDataRequestType = MessageType(byte(me.GetCurrentData) | me.AR)
70 GetCurrentDataResponseType = MessageType(byte(me.GetCurrentData) | me.AK)
71 SetTableRequestType = MessageType(byte(me.SetTable) | me.AR)
72 SetTableResponseType = MessageType(byte(me.SetTable) | me.AK)
Girish Gowdra6afb56a2021-04-27 17:47:57 -070073
Holger Hildebrandtfa074992020-03-27 15:42:06 +000074 // Autonomous ONU messages
75 AlarmNotificationType = MessageType(byte(me.AlarmNotification))
76 AttributeValueChangeType = MessageType(byte(me.AttributeValueChange))
77 TestResultType = MessageType(byte(me.TestResult))
Girish Gowdra6afb56a2021-04-27 17:47:57 -070078
79 // Support mapping of extended format types (use MSB reserved bit)
80 ExtendedTypeDecodeOffset = MessageType(byte(0x80))
Holger Hildebrandtfa074992020-03-27 15:42:06 +000081)
82
83func (mt MessageType) String() string {
84 switch mt {
85 default:
86 return "Unknown"
87
88 case CreateRequestType:
89 return "Create Request"
90 case CreateResponseType:
91 return "Create Response"
92 case DeleteRequestType:
93 return "Delete Request"
94 case DeleteResponseType:
95 return "Delete Response"
96 case SetRequestType:
97 return "Set Request"
98 case SetResponseType:
99 return "Set Response"
100 case GetRequestType:
101 return "Get Request"
102 case GetResponseType:
103 return "Get Response"
104 case GetAllAlarmsRequestType:
105 return "Get All Alarms Request"
106 case GetAllAlarmsResponseType:
107 return "Get All Alarms Response"
108 case GetAllAlarmsNextRequestType:
109 return "Get All Alarms Next Request"
110 case GetAllAlarmsNextResponseType:
111 return "Get All Alarms Next Response"
112 case MibUploadRequestType:
113 return "MIB Upload Request"
114 case MibUploadResponseType:
115 return "MIB Upload Response"
116 case MibUploadNextRequestType:
117 return "MIB Upload Next Request"
118 case MibUploadNextResponseType:
119 return "MIB Upload Next Response"
120 case MibResetRequestType:
121 return "MIB Reset Request"
122 case MibResetResponseType:
123 return "MIB Reset Response"
124 case TestRequestType:
125 return "Test Request"
126 case TestResponseType:
127 return "Test Response"
128 case StartSoftwareDownloadRequestType:
129 return "Start Software Download Request"
130 case StartSoftwareDownloadResponseType:
131 return "Start Software Download Response"
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700132 case DownloadSectionRequestType, DownloadSectionRequestWithResponseType:
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000133 return "Download Section Request"
134 case DownloadSectionResponseType:
135 return "Download Section Response"
136 case EndSoftwareDownloadRequestType:
137 return "End Software Download Request"
138 case EndSoftwareDownloadResponseType:
139 return "End Software Download Response"
140 case ActivateSoftwareRequestType:
141 return "Activate Software Request"
142 case ActivateSoftwareResponseType:
143 return "Activate Software Response"
144 case CommitSoftwareRequestType:
145 return "Commit Software Request"
146 case CommitSoftwareResponseType:
147 return "Commit Software Response"
148 case SynchronizeTimeRequestType:
149 return "Synchronize Time Request"
150 case SynchronizeTimeResponseType:
151 return "Synchronize Time Response"
152 case RebootRequestType:
153 return "Reboot Request"
154 case RebootResponseType:
155 return "Reboot Response"
156 case GetNextRequestType:
157 return "Get Next Request"
158 case GetNextResponseType:
159 return "Get Next Response"
160 case GetCurrentDataRequestType:
161 return "Get Current Data Request"
162 case GetCurrentDataResponseType:
163 return "Get Current Data Response"
164 case SetTableRequestType:
165 return "Set Table Request"
166 case SetTableResponseType:
167 return "Set Table Response"
168 case AlarmNotificationType:
169 return "Alarm Notification"
170 case AttributeValueChangeType:
171 return "Attribute Value Change"
172 case TestResultType:
173 return "Test Result"
174 }
175}
176
177/////////////////////////////////////////////////////////////////////////////
178// CreateRequest
179type CreateRequest struct {
180 MeBasePacket
181 Attributes me.AttributeValueMap
182}
183
184func (omci *CreateRequest) String() string {
185 return fmt.Sprintf("%v, attributes: %v", omci.MeBasePacket.String(), omci.Attributes)
186}
187
188// DecodeFromBytes decodes the given bytes of a Create Request into this layer
189func (omci *CreateRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
190 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000191 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000192 if err != nil {
193 return err
194 }
195 // Create attribute mask for all set-by-create entries
196 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
197 me.ParamData{EntityID: omci.EntityInstance})
198 if omciErr.StatusCode() != me.Success {
199 return omciErr.GetError()
200 }
201 // ME needs to support Create
202 if !me.SupportsMsgType(meDefinition, me.Create) {
203 return me.NewProcessingError("managed entity does not support Create Message-Type")
204 }
205 var sbcMask uint16
206 for index, attr := range meDefinition.GetAttributeDefinitions() {
207 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
208 if index == 0 {
209 continue // Skip Entity ID
210 }
211 sbcMask |= attr.Mask
212 }
213 }
214 // Attribute decode
215 omci.Attributes, err = meDefinition.DecodeAttributes(sbcMask, data[4:], p, byte(CreateRequestType))
216 if err != nil {
217 return err
218 }
219 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
220 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
221 return nil
222 }
223 panic("All Managed Entities have an EntityID attribute")
224}
225
226func decodeCreateRequest(data []byte, p gopacket.PacketBuilder) error {
227 omci := &CreateRequest{}
228 omci.MsgLayerType = LayerTypeCreateRequest
229 return decodingLayerDecoder(omci, data, p)
230}
231
232// SerializeTo provides serialization of an Create Request Message
233func (omci *CreateRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
234 // Basic (common) OMCI Header is 8 octets, 10
235 err := omci.MeBasePacket.SerializeTo(b)
236 if err != nil {
237 return err
238 }
239 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
240 me.ParamData{EntityID: omci.EntityInstance})
241 if omciErr.StatusCode() != me.Success {
242 return omciErr.GetError()
243 }
244 // Create attribute mask of SetByCreate attributes that should be present in the provided
245 // attributes.
246 var sbcMask uint16
247 for index, attr := range meDefinition.GetAttributeDefinitions() {
248 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
249 if index == 0 {
250 continue // Skip Entity ID
251 }
252 sbcMask |= attr.Mask
253 }
254 }
255 // Attribute serialization
256 // TODO: Only Baseline supported at this time
257 bytesAvailable := MaxBaselineLength - 8 - 8
258 err, _ = meDefinition.SerializeAttributes(omci.Attributes, sbcMask, b, byte(CreateRequestType), bytesAvailable, false)
259 return err
260}
261
262/////////////////////////////////////////////////////////////////////////////
263// CreateResponse
264type CreateResponse struct {
265 MeBasePacket
266 Result me.Results
267 AttributeExecutionMask uint16 // Used when Result == ParameterError
268}
269
270func (omci *CreateResponse) String() string {
271 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x",
272 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeExecutionMask)
273}
274
275// DecodeFromBytes decodes the given bytes of a Create Response into this layer
276func (omci *CreateResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
277 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000278 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000279 if err != nil {
280 return err
281 }
282 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
283 me.ParamData{EntityID: omci.EntityInstance})
284 if omciErr.StatusCode() != me.Success {
285 return omciErr.GetError()
286 }
287 // ME needs to support Create
288 if !me.SupportsMsgType(entity, me.Create) {
289 return me.NewProcessingError("managed entity does not support the Create Message-Type")
290 }
291 omci.Result = me.Results(data[4])
292 if omci.Result == me.ParameterError {
293 omci.AttributeExecutionMask = binary.BigEndian.Uint16(data[5:])
294 // TODO: validation that attributes set in mask are SetByCreate would be good here
295 }
296 return nil
297}
298
299func decodeCreateResponse(data []byte, p gopacket.PacketBuilder) error {
300 omci := &CreateResponse{}
301 omci.MsgLayerType = LayerTypeCreateResponse
302 return decodingLayerDecoder(omci, data, p)
303}
304
305// SerializeTo provides serialization of an Create Response message
306func (omci *CreateResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
307 // Basic (common) OMCI Header is 8 octets, 10
308 err := omci.MeBasePacket.SerializeTo(b)
309 if err != nil {
310 return err
311 }
312 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
313 me.ParamData{EntityID: omci.EntityInstance})
314 if omciErr.StatusCode() != me.Success {
315 return omciErr.GetError()
316 }
317 // ME needs to support Create
318 if !me.SupportsMsgType(entity, me.Create) {
319 return me.NewProcessingError("managed entity does not support the Create Message-Type")
320 }
321 bytes, err := b.AppendBytes(3)
322 if err != nil {
323 return err
324 }
325 bytes[0] = byte(omci.Result)
326 if omci.Result == me.ParameterError {
327 // TODO: validation that attributes set in mask are SetByCreate would be good here
328 binary.BigEndian.PutUint16(bytes[1:], omci.AttributeExecutionMask)
329 } else {
330 binary.BigEndian.PutUint16(bytes[1:], 0)
331 }
332 return nil
333}
334
335/////////////////////////////////////////////////////////////////////////////
336// DeleteRequest
337type DeleteRequest struct {
338 MeBasePacket
339}
340
341func (omci *DeleteRequest) String() string {
342 return fmt.Sprintf("%v", omci.MeBasePacket.String())
343}
344
345// DecodeFromBytes decodes the given bytes of a Delete Request into this layer
346func (omci *DeleteRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
347 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000348 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000349 if err != nil {
350 return err
351 }
352 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
353 me.ParamData{EntityID: omci.EntityInstance})
354 if omciErr.StatusCode() != me.Success {
355 return omciErr.GetError()
356 }
357 // ME needs to support Delete
358 if !me.SupportsMsgType(entity, me.Delete) {
359 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
360 }
361 return nil
362}
363
364func decodeDeleteRequest(data []byte, p gopacket.PacketBuilder) error {
365 omci := &DeleteRequest{}
366 omci.MsgLayerType = LayerTypeDeleteRequest
367 return decodingLayerDecoder(omci, data, p)
368}
369
370// SerializeTo provides serialization of an Delete Request message
371func (omci *DeleteRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
372 // Basic (common) OMCI Header is 8 octets, 10
373 err := omci.MeBasePacket.SerializeTo(b)
374 if err != nil {
375 return err
376 }
377 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
378 me.ParamData{EntityID: omci.EntityInstance})
379 if omciErr.StatusCode() != me.Success {
380 return omciErr.GetError()
381 }
382 // ME needs to support Delete
383 if !me.SupportsMsgType(entity, me.Delete) {
384 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
385 }
386 return nil
387}
388
389/////////////////////////////////////////////////////////////////////////////
390// DeleteResponse
391type DeleteResponse struct {
392 MeBasePacket
393 Result me.Results
394}
395
396func (omci *DeleteResponse) String() string {
397 return fmt.Sprintf("%v, Result: %d (%v)",
398 omci.MeBasePacket.String(), omci.Result, omci.Result)
399}
400
401// DecodeFromBytes decodes the given bytes of a Delete Response into this layer
402func (omci *DeleteResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
403 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000404 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000405 if err != nil {
406 return err
407 }
408 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
409 me.ParamData{EntityID: omci.EntityInstance})
410 if omciErr.StatusCode() != me.Success {
411 return omciErr.GetError()
412 }
413 // ME needs to support Delete
414 if !me.SupportsMsgType(entity, me.Delete) {
415 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
416 }
417 omci.Result = me.Results(data[4])
418 return nil
419}
420
421func decodeDeleteResponse(data []byte, p gopacket.PacketBuilder) error {
422 omci := &DeleteResponse{}
423 omci.MsgLayerType = LayerTypeDeleteResponse
424 return decodingLayerDecoder(omci, data, p)
425}
426
427// SerializeTo provides serialization of an Delete Response message
428func (omci *DeleteResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
429 // Basic (common) OMCI Header is 8 octets, 10
430 err := omci.MeBasePacket.SerializeTo(b)
431 if err != nil {
432 return err
433 }
434 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
435 me.ParamData{EntityID: omci.EntityInstance})
436 if omciErr.StatusCode() != me.Success {
437 return omciErr.GetError()
438 }
439 // ME needs to support Delete
440 if !me.SupportsMsgType(entity, me.Delete) {
441 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
442 }
443 bytes, err := b.AppendBytes(1)
444 if err != nil {
445 return err
446 }
447 bytes[0] = byte(omci.Result)
448 return nil
449}
450
451/////////////////////////////////////////////////////////////////////////////
452// SetRequest
453type SetRequest struct {
454 MeBasePacket
455 AttributeMask uint16
456 Attributes me.AttributeValueMap
457}
458
459func (omci *SetRequest) String() string {
460 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
461 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
462}
463
464// DecodeFromBytes decodes the given bytes of a Set Request into this layer
465func (omci *SetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
466 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000467 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000468 if err != nil {
469 return err
470 }
471 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
472 me.ParamData{EntityID: omci.EntityInstance})
473 if omciErr.StatusCode() != me.Success {
474 return omciErr.GetError()
475 }
476 // ME needs to support Set
477 if !me.SupportsMsgType(meDefinition, me.Set) {
478 return me.NewProcessingError("managed entity does not support Set Message-Type")
479 }
480 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
481
482 // Attribute decode
483 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(SetRequestType))
484 if err != nil {
485 return err
486 }
487 // Validate all attributes support write
488 for attrName := range omci.Attributes {
489 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
490 if err != nil {
491 return err
492 }
493 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
494 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
495 return me.NewProcessingError(msg)
496 }
497 }
498 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
499 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
500 return nil
501 }
502 panic("All Managed Entities have an EntityID attribute")
503}
504
505func decodeSetRequest(data []byte, p gopacket.PacketBuilder) error {
506 omci := &SetRequest{}
507 omci.MsgLayerType = LayerTypeSetRequest
508 return decodingLayerDecoder(omci, data, p)
509}
510
511// SerializeTo provides serialization of an Set Request message
512func (omci *SetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
513 // Basic (common) OMCI Header is 8 octets, 10
514 err := omci.MeBasePacket.SerializeTo(b)
515 if err != nil {
516 return err
517 }
518 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
519 me.ParamData{EntityID: omci.EntityInstance})
520 if omciErr.StatusCode() != me.Success {
521 return omciErr.GetError()
522 }
523 // ME needs to support Set
524 if !me.SupportsMsgType(meDefinition, me.Set) {
525 return me.NewProcessingError("managed entity does not support Set Message-Type")
526 }
527 // Validate all attributes support write
528 for attrName := range omci.Attributes {
529 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
530 if err != nil {
531 return err
532 }
533 // Do not test for write of Entity ID in the attribute list
534 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
535 // TODO: Check ITU spec to see if this should be listed as a failed
536 // attribute and not a processing error.
537 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
538 return me.NewProcessingError(msg)
539 }
540 }
541 bytes, err := b.AppendBytes(2)
542 if err != nil {
543 return err
544 }
545 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
546
547 // Attribute serialization
548 // TODO: Only Baseline supported at this time
549 bytesAvailable := MaxBaselineLength - 10 - 8
550
551 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
552 byte(SetRequestType), bytesAvailable, false)
553 return err
554}
555
556/////////////////////////////////////////////////////////////////////////////
557// SetResponse
558type SetResponse struct {
559 MeBasePacket
560 Result me.Results
561 UnsupportedAttributeMask uint16
562 FailedAttributeMask uint16
563}
564
565func (omci *SetResponse) String() string {
566 return fmt.Sprintf("%v, Result: %d (%v), Unsupported Mask: %#x, Failed Mask: %#x",
567 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.UnsupportedAttributeMask,
568 omci.FailedAttributeMask)
569}
570
571// DecodeFromBytes decodes the given bytes of a Set Response into this layer
572func (omci *SetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
573 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000574 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000575 if err != nil {
576 return err
577 }
578 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
579 me.ParamData{EntityID: omci.EntityInstance})
580 if omciErr.StatusCode() != me.Success {
581 return omciErr.GetError()
582 }
583 // ME needs to support Set
584 if !me.SupportsMsgType(entity, me.Set) {
585 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
586 }
587 omci.Result = me.Results(data[4])
588
589 if omci.Result == me.AttributeFailure {
590 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[5:7])
591 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[7:9])
592 }
593 return nil
594}
595
596func decodeSetResponse(data []byte, p gopacket.PacketBuilder) error {
597 omci := &SetResponse{}
598 omci.MsgLayerType = LayerTypeSetResponse
599 return decodingLayerDecoder(omci, data, p)
600}
601
602// SerializeTo provides serialization of an Set Response message
603func (omci *SetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
604 // Basic (common) OMCI Header is 8 octets, 10
605 err := omci.MeBasePacket.SerializeTo(b)
606 if err != nil {
607 return err
608 }
609 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
610 me.ParamData{EntityID: omci.EntityInstance})
611 if omciErr.StatusCode() != me.Success {
612 return omciErr.GetError()
613 }
614 // ME needs to support Set
615 if !me.SupportsMsgType(entity, me.Set) {
616 return me.NewProcessingError("managed entity does not support the Set Message-Type")
617 }
618 bytes, err := b.AppendBytes(5)
619 if err != nil {
620 return err
621 }
622 bytes[0] = byte(omci.Result)
623 binary.BigEndian.PutUint16(bytes[1:3], omci.UnsupportedAttributeMask)
624 binary.BigEndian.PutUint16(bytes[3:5], omci.FailedAttributeMask)
625 return nil
626}
627
628/////////////////////////////////////////////////////////////////////////////
629// GetRequest
630type GetRequest struct {
631 MeBasePacket
632 AttributeMask uint16
633}
634
635func (omci *GetRequest) String() string {
636 return fmt.Sprintf("%v, Mask: %#x",
637 omci.MeBasePacket.String(), omci.AttributeMask)
638}
639
640// DecodeFromBytes decodes the given bytes of a Get Request into this layer
641func (omci *GetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
642 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000643 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000644 if err != nil {
645 return err
646 }
647 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
648 me.ParamData{EntityID: omci.EntityInstance})
649 if omciErr.StatusCode() != me.Success {
650 return omciErr.GetError()
651 }
652 // ME needs to support Get
653 if !me.SupportsMsgType(meDefinition, me.Get) {
654 return me.NewProcessingError("managed entity does not support Get Message-Type")
655 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700656 if omci.Extended {
657 if len(data) < 8 {
658 p.SetTruncated()
659 return errors.New("frame too small")
660 }
661 omci.AttributeMask = binary.BigEndian.Uint16(data[6:])
662 } else {
663 omci.AttributeMask = binary.BigEndian.Uint16(data[4:])
664 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000665 return nil
666}
667
668func decodeGetRequest(data []byte, p gopacket.PacketBuilder) error {
669 omci := &GetRequest{}
670 omci.MsgLayerType = LayerTypeGetRequest
671 return decodingLayerDecoder(omci, data, p)
672}
673
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700674func decodeGetRequestExtended(data []byte, p gopacket.PacketBuilder) error {
675 omci := &GetRequest{}
676 omci.MsgLayerType = LayerTypeGetRequest
677 omci.Extended = true
678 return decodingLayerDecoder(omci, data, p)
679}
680
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000681// SerializeTo provides serialization of an Get Request message
682func (omci *GetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
683 // Basic (common) OMCI Header is 8 octets, 10
684 err := omci.MeBasePacket.SerializeTo(b)
685 if err != nil {
686 return err
687 }
688 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
689 me.ParamData{EntityID: omci.EntityInstance})
690 if omciErr.StatusCode() != me.Success {
691 return omciErr.GetError()
692 }
693 // ME needs to support Set
694 if !me.SupportsMsgType(meDefinition, me.Get) {
695 return me.NewProcessingError("managed entity does not support Get Message-Type")
696 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700697 maskOffset := 0
698 if omci.Extended {
699 maskOffset = 2
700 }
701 bytes, err := b.AppendBytes(2 + maskOffset)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000702 if err != nil {
703 return err
704 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700705 if omci.Extended {
706 binary.BigEndian.PutUint16(bytes, uint16(2))
707 }
708 binary.BigEndian.PutUint16(bytes[maskOffset:], omci.AttributeMask)
709 return nil
710}
711
712func (omci *GetRequest) SerializeToExtended(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000713 return nil
714}
715
716/////////////////////////////////////////////////////////////////////////////
717// GetResponse
718type GetResponse struct {
719 MeBasePacket
720 Result me.Results
721 AttributeMask uint16
722 Attributes me.AttributeValueMap
723 UnsupportedAttributeMask uint16
724 FailedAttributeMask uint16
725}
726
727func (omci *GetResponse) String() string {
728 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x, Unsupported: %#x, Failed: %#x, attributes: %v",
729 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask,
730 omci.UnsupportedAttributeMask, omci.FailedAttributeMask, omci.Attributes)
731}
732
733// DecodeFromBytes decodes the given bytes of a Get Response into this layer
734func (omci *GetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
735 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000736 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000737 if err != nil {
738 return err
739 }
740 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
741 me.ParamData{EntityID: omci.EntityInstance})
742 if omciErr.StatusCode() != me.Success {
743 return omciErr.GetError()
744 }
745 // ME needs to support Get
746 if !me.SupportsMsgType(meDefinition, me.Get) {
747 return me.NewProcessingError("managed entity does not support Get Message-Type")
748 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700749 if omci.Extended {
750 if len(data) < 13 {
751 p.SetTruncated()
752 return errors.New("frame too small")
753 }
754 omci.Result = me.Results(data[6])
755 omci.AttributeMask = binary.BigEndian.Uint16(data[7:])
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000756
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700757 // If Attribute failed or Unknown, decode optional attribute mask
758 if omci.Result == me.AttributeFailure {
759 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[9:])
760 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[11:])
761 }
762 } else {
763 omci.Result = me.Results(data[4])
764 omci.AttributeMask = binary.BigEndian.Uint16(data[5:])
765
766 // If Attribute failed or Unknown, decode optional attribute mask
767 if omci.Result == me.AttributeFailure {
768 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:34])
769 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:36])
770 }
771 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000772 // Attribute decode. Note that the ITU-T G.988 specification states that the
773 // Unsupported and Failed attribute masks are always present
774 // but only valid if the status code== 9. However some XGS
775 // ONUs (T&W and Alpha, perhaps more) will use these last 4
776 // octets for data if the status code == 0. So accommodate
777 // this behaviour in favor of greater interoperability.
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700778 firstOctet := 7
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000779 lastOctet := 36
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700780 if omci.Extended {
781 firstOctet = 13
782 lastOctet = len(data)
783 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530784
785 switch omci.Result {
786 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
787 return nil // Done (do not try and decode attributes)
788
789 case me.AttributeFailure:
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700790 if !omci.Extended {
791 lastOctet = 32
792 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000793 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700794 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask,
795 data[firstOctet:lastOctet], p, byte(GetResponseType))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000796 if err != nil {
797 return err
798 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000799 // Validate all attributes support read
800 for attrName := range omci.Attributes {
801 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
802 if err != nil {
803 return err
804 }
805 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
806 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
807 return me.NewProcessingError(msg)
808 }
809 }
810 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
811 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
812 return nil
813 }
814 panic("All Managed Entities have an EntityID attribute")
815}
816
817func decodeGetResponse(data []byte, p gopacket.PacketBuilder) error {
818 omci := &GetResponse{}
819 omci.MsgLayerType = LayerTypeGetResponse
820 return decodingLayerDecoder(omci, data, p)
821}
822
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700823func decodeGetResponseExtended(data []byte, p gopacket.PacketBuilder) error {
824 omci := &GetResponse{}
825 omci.MsgLayerType = LayerTypeGetResponse
826 omci.Extended = true
827 return decodingLayerDecoder(omci, data, p)
828}
829
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000830// SerializeTo provides serialization of an Get Response message
831func (omci *GetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
832 // Basic (common) OMCI Header is 8 octets, 10
833 if err := omci.MeBasePacket.SerializeTo(b); err != nil {
834 return err
835 }
836 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
837 me.ParamData{EntityID: omci.EntityInstance})
838
839 if omciErr.StatusCode() != me.Success {
840 return omciErr.GetError()
841 }
842 // ME needs to support Get
843 if !me.SupportsMsgType(meDefinition, me.Get) {
844 return me.NewProcessingError("managed entity does not support the Get Message-Type")
845 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700846 resultOffset := 0
847 attributeErrExtra := 0
848
849 if omci.Extended {
850 resultOffset = 2
851 attributeErrExtra = 4 // Attribute mask + attribute error masks
852 }
853 // Space for result + mask (both types) + (len & error masks if extended)
854 buffer, err := b.AppendBytes(3 + resultOffset + attributeErrExtra)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000855 if err != nil {
856 return err
857 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700858 // Save result and initial mask. Other header fields updated after
859 // attribute copy
860 buffer[resultOffset] = byte(omci.Result)
861 binary.BigEndian.PutUint16(buffer[resultOffset+1:], omci.AttributeMask)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000862
863 // Validate all attributes support read
864 for attrName := range omci.Attributes {
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700865 var attr *me.AttributeDefinition
866 attr, err = me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000867 if err != nil {
868 return err
869 }
870 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
871 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
872 return me.NewProcessingError(msg)
873 }
874 }
875 // Attribute serialization
876 switch omci.Result {
877 default:
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700878 if omci.Extended {
879 // Minimum length is 7 for extended an need to write error masks
880 binary.BigEndian.PutUint16(buffer, uint16(7))
881 binary.BigEndian.PutUint32(buffer[resultOffset+3:], 0)
882 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000883 break
884
885 case me.Success, me.AttributeFailure:
886 // TODO: Baseline only supported at this time)
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700887 var available int
888 if omci.Extended {
889 available = MaxExtendedLength - 18 - 4 // Less: header, mic
890 } else {
891 available = MaxBaselineLength - 11 - 4 - 8 // Less: header, failed attributes, length, mic
892 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000893 // Serialize to temporary buffer if we may need to reset values due to
894 // recoverable truncation errors
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700895 attributeBuffer := gopacket.NewSerializeBuffer()
896 var failedMask uint16
897 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask,
898 attributeBuffer, byte(GetResponseType), available, opts.FixLengths)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000899
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700900 if err != nil {
901 return err
902 }
903 if failedMask != 0 {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000904 // Not all attributes would fit
905 omci.FailedAttributeMask |= failedMask
906 omci.AttributeMask &= ^failedMask
907 omci.Result = me.AttributeFailure
908
909 // Adjust already recorded values
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700910 buffer[resultOffset] = byte(omci.Result)
911 binary.BigEndian.PutUint16(buffer[resultOffset+1:], omci.AttributeMask)
912 }
913 if omci.Extended {
914 // Set length and any failure masks
915 binary.BigEndian.PutUint16(buffer, uint16(len(attributeBuffer.Bytes())+7))
916
917 if omci.Result == me.AttributeFailure {
918 binary.BigEndian.PutUint16(buffer[resultOffset+3:], omci.UnsupportedAttributeMask)
919 binary.BigEndian.PutUint16(buffer[resultOffset+5:], omci.FailedAttributeMask)
920 } else {
921 binary.BigEndian.PutUint32(buffer[resultOffset+3:], 0)
922 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000923 }
924 // Copy over attributes to the original serialization buffer
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700925 var newSpace []byte
926
927 newSpace, err = b.AppendBytes(len(attributeBuffer.Bytes()))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000928 if err != nil {
929 return err
930 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700931 copy(newSpace, attributeBuffer.Bytes())
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000932
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700933 if !omci.Extended {
934 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
935 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000936
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700937 var remainingBytes []byte
938 remainingBytes, err = b.AppendBytes(bytesLeft + 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000939
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700940 if err != nil {
941 return me.NewMessageTruncatedError(err.Error())
942 }
943 copy(remainingBytes, lotsOfZeros[:])
944
945 if omci.Result == me.AttributeFailure {
946 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
947 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
948 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000949 }
950 }
951 return nil
952}
953
954/////////////////////////////////////////////////////////////////////////////
955// GetAllAlarms
956type GetAllAlarmsRequest struct {
957 MeBasePacket
958 AlarmRetrievalMode byte
959}
960
961func (omci *GetAllAlarmsRequest) String() string {
962 return fmt.Sprintf("%v, Retrieval Mode: %v",
963 omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
964}
965
966// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
967func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
968 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +0000969 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000970 if err != nil {
971 return err
972 }
973 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
974 me.ParamData{EntityID: omci.EntityInstance})
975 if omciErr.StatusCode() != me.Success {
976 return omciErr.GetError()
977 }
978 // ME needs to support Get All Alarms
979 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
980 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
981 }
982 // Entity Class are always ONU DATA (2) and Entity Instance of 0
983 if omci.EntityClass != me.OnuDataClassID {
984 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
985 omci.EntityClass)
986 return me.NewProcessingError(msg)
987 }
988 if omci.EntityInstance != 0 {
989 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
990 omci.EntityInstance)
991 return me.NewUnknownInstanceError(msg)
992 }
993 omci.AlarmRetrievalMode = data[4]
994 if omci.AlarmRetrievalMode > 1 {
995 msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
996 omci.AlarmRetrievalMode)
997 return errors.New(msg)
998 }
999 return nil
1000}
1001
1002func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
1003 omci := &GetAllAlarmsRequest{}
1004 omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
1005 return decodingLayerDecoder(omci, data, p)
1006}
1007
1008// SerializeTo provides serialization of an Get All Alarms Request message
1009func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1010 // Basic (common) OMCI Header is 8 octets, 10
1011 err := omci.MeBasePacket.SerializeTo(b)
1012 if err != nil {
1013 return err
1014 }
1015 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1016 me.ParamData{EntityID: omci.EntityInstance})
1017 if omciErr.StatusCode() != me.Success {
1018 return omciErr.GetError()
1019 }
1020 // ME needs to support Get All Alarms
1021 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
1022 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
1023 }
1024 bytes, err := b.AppendBytes(1)
1025 if err != nil {
1026 return err
1027 }
1028 bytes[0] = omci.AlarmRetrievalMode
1029 return nil
1030}
1031
1032/////////////////////////////////////////////////////////////////////////////
1033// GetAllAlarms
1034type GetAllAlarmsResponse struct {
1035 MeBasePacket
1036 NumberOfCommands uint16
1037}
1038
1039func (omci *GetAllAlarmsResponse) String() string {
1040 return fmt.Sprintf("%v, NumberOfCommands: %d",
1041 omci.MeBasePacket.String(), omci.NumberOfCommands)
1042}
1043
1044// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
1045func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1046 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001047 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001048 if err != nil {
1049 return err
1050 }
1051 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1052 me.ParamData{EntityID: omci.EntityInstance})
1053 if omciErr.StatusCode() != me.Success {
1054 return omciErr.GetError()
1055 }
1056 // ME needs to support Get All Alarms
1057 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
1058 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
1059 }
1060 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1061 if omci.EntityClass != me.OnuDataClassID {
1062 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
1063 omci.EntityClass)
1064 return me.NewProcessingError(msg)
1065 }
1066 if omci.EntityInstance != 0 {
1067 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
1068 omci.EntityInstance)
1069 return me.NewUnknownInstanceError(msg)
1070 }
1071 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1072 return nil
1073}
1074
1075func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
1076 omci := &GetAllAlarmsResponse{}
1077 omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
1078 return decodingLayerDecoder(omci, data, p)
1079}
1080
1081// SerializeTo provides serialization of an Get All Alarms Response message
1082func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1083 // Basic (common) OMCI Header is 8 octets, 10
1084 err := omci.MeBasePacket.SerializeTo(b)
1085 if err != nil {
1086 return err
1087 }
1088 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1089 me.ParamData{EntityID: omci.EntityInstance})
1090 if omciErr.StatusCode() != me.Success {
1091 return omciErr.GetError()
1092 }
1093 // ME needs to support Get All Alarms
1094 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
1095 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
1096 }
1097 bytes, err := b.AppendBytes(2)
1098 if err != nil {
1099 return err
1100 }
1101 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1102 return nil
1103}
1104
1105/////////////////////////////////////////////////////////////////////////////
1106// GetAllAlarms
1107type GetAllAlarmsNextRequest struct {
1108 MeBasePacket
1109 CommandSequenceNumber uint16
1110}
1111
1112func (omci *GetAllAlarmsNextRequest) String() string {
1113 return fmt.Sprintf("%v, Sequence Number: %d",
1114 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1115}
1116
1117// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
1118func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1119 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001120 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001121 if err != nil {
1122 return err
1123 }
1124 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1125 me.ParamData{EntityID: omci.EntityInstance})
1126 if omciErr.StatusCode() != me.Success {
1127 return omciErr.GetError()
1128 }
1129 // ME needs to support Get All Alarms
1130 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1131 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1132 }
1133 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1134 if omci.EntityClass != me.OnuDataClassID {
1135 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
1136 omci.EntityClass)
1137 return me.NewProcessingError(msg)
1138 }
1139 if omci.EntityInstance != 0 {
1140 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
1141 omci.EntityInstance)
1142 return me.NewUnknownInstanceError(msg)
1143 }
1144 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1145 return nil
1146}
1147
1148func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
1149 omci := &GetAllAlarmsNextRequest{}
1150 omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
1151 return decodingLayerDecoder(omci, data, p)
1152}
1153
1154// SerializeTo provides serialization of an Get All Alarms Next Request message
1155func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1156 // Basic (common) OMCI Header is 8 octets, 10
1157 err := omci.MeBasePacket.SerializeTo(b)
1158 if err != nil {
1159 return err
1160 }
1161 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1162 me.ParamData{EntityID: omci.EntityInstance})
1163 if omciErr.StatusCode() != me.Success {
1164 return omciErr.GetError()
1165 }
1166 // ME needs to support Get All Alarms Next
1167 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1168 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1169 }
1170 bytes, err := b.AppendBytes(2)
1171 if err != nil {
1172 return err
1173 }
1174 binary.BigEndian.PutUint16(bytes, omci.CommandSequenceNumber)
1175 return nil
1176}
1177
1178/////////////////////////////////////////////////////////////////////////////
1179// GetAllAlarms
1180type GetAllAlarmsNextResponse struct {
1181 MeBasePacket
1182 AlarmEntityClass me.ClassID
1183 AlarmEntityInstance uint16
1184 AlarmBitMap [28]byte // 224 bits
1185}
1186
1187func (omci *GetAllAlarmsNextResponse) String() string {
1188 return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
1189 omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
1190 omci.AlarmEntityInstance, omci.AlarmBitMap)
1191}
1192
1193// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
1194func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1195 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001196 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4+28)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001197 if err != nil {
1198 return err
1199 }
1200 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1201 me.ParamData{EntityID: omci.EntityInstance})
1202 if omciErr.StatusCode() != me.Success {
1203 return omciErr.GetError()
1204 }
1205 // ME needs to support Get All Alarms Next
1206 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1207 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1208 }
1209 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1210 if omci.EntityClass != me.OnuDataClassID {
1211 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
1212 omci.EntityClass)
1213 return me.NewProcessingError(msg)
1214 }
1215 if omci.EntityInstance != 0 {
1216 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
1217 omci.EntityInstance)
1218 return me.NewUnknownInstanceError(msg)
1219 }
1220 omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4:6]))
1221 omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6:8])
1222
1223 copy(omci.AlarmBitMap[:], data[8:36])
1224 return nil
1225}
1226
1227func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
1228 omci := &GetAllAlarmsNextResponse{}
1229 omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
1230 return decodingLayerDecoder(omci, data, p)
1231}
1232
1233// SerializeTo provides serialization of an Get All Alarms Next Response message
1234func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1235 // Basic (common) OMCI Header is 8 octets, 10
1236 err := omci.MeBasePacket.SerializeTo(b)
1237 if err != nil {
1238 return err
1239 }
1240 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1241 me.ParamData{EntityID: omci.EntityInstance})
1242 if omciErr.StatusCode() != me.Success {
1243 return omciErr.GetError()
1244 }
1245 // ME needs to support Get All Alarms Next
1246 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1247 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1248 }
1249 bytes, err := b.AppendBytes(2 + 2 + 28)
1250 if err != nil {
1251 return err
1252 }
1253 binary.BigEndian.PutUint16(bytes[0:], uint16(omci.AlarmEntityClass))
1254 binary.BigEndian.PutUint16(bytes[2:], omci.AlarmEntityInstance)
1255 copy(bytes[4:], omci.AlarmBitMap[:])
1256 return nil
1257}
1258
1259/////////////////////////////////////////////////////////////////////////////
1260// MibUploadRequest
1261type MibUploadRequest struct {
1262 MeBasePacket
1263}
1264
1265func (omci *MibUploadRequest) String() string {
1266 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1267}
1268
1269// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
1270func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1271 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001272 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001273 if err != nil {
1274 return err
1275 }
1276 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1277 me.ParamData{EntityID: omci.EntityInstance})
1278 if omciErr.StatusCode() != me.Success {
1279 return omciErr.GetError()
1280 }
1281 // ME needs to support MIB Upload
1282 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1283 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1284 }
1285 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1286 if omci.EntityClass != me.OnuDataClassID {
1287 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
1288 omci.EntityClass)
1289 return me.NewProcessingError(msg)
1290 }
1291 if omci.EntityInstance != 0 {
1292 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
1293 omci.EntityInstance)
1294 return me.NewUnknownInstanceError(msg)
1295 }
1296 return nil
1297}
1298
1299func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
1300 omci := &MibUploadRequest{}
1301 omci.MsgLayerType = LayerTypeMibUploadRequest
1302 return decodingLayerDecoder(omci, data, p)
1303}
1304
1305// SerializeTo provides serialization of an MIB Upload Request message
1306func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1307 // Basic (common) OMCI Header is 8 octets, 10
1308 err := omci.MeBasePacket.SerializeTo(b)
1309 if err != nil {
1310 return err
1311 }
1312 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1313 me.ParamData{EntityID: omci.EntityInstance})
1314 if omciErr.StatusCode() != me.Success {
1315 return omciErr.GetError()
1316 }
1317 // ME needs to support Get
1318 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1319 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1320 }
1321 return nil
1322}
1323
1324/////////////////////////////////////////////////////////////////////////////
1325// MibUploadResponse
1326type MibUploadResponse struct {
1327 MeBasePacket
1328 NumberOfCommands uint16
1329}
1330
1331func (omci *MibUploadResponse) String() string {
1332 return fmt.Sprintf("%v, NumberOfCommands: %#v",
1333 omci.MeBasePacket.String(), omci.NumberOfCommands)
1334}
1335
1336// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
1337func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1338 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001339 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001340 if err != nil {
1341 return err
1342 }
1343 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1344 me.ParamData{EntityID: omci.EntityInstance})
1345 if omciErr.StatusCode() != me.Success {
1346 return omciErr.GetError()
1347 }
1348 // ME needs to support MIB Upload
1349 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1350 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1351 }
1352 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1353 if omci.EntityClass != me.OnuDataClassID {
1354 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
1355 omci.EntityClass)
1356 return me.NewProcessingError(msg)
1357 }
1358 if omci.EntityInstance != 0 {
1359 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
1360 omci.EntityInstance)
1361 return me.NewUnknownInstanceError(msg)
1362 }
1363 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1364 return nil
1365}
1366
1367func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
1368 omci := &MibUploadResponse{}
1369 omci.MsgLayerType = LayerTypeMibUploadResponse
1370 return decodingLayerDecoder(omci, data, p)
1371}
1372
1373// SerializeTo provides serialization of an MIB Upload Response message
1374func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1375 // Basic (common) OMCI Header is 8 octets, 10
1376 err := omci.MeBasePacket.SerializeTo(b)
1377 if err != nil {
1378 return err
1379 }
1380 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1381 me.ParamData{EntityID: omci.EntityInstance})
1382 if omciErr.StatusCode() != me.Success {
1383 return omciErr.GetError()
1384 }
1385 // ME needs to support MIB Upload
1386 if !me.SupportsMsgType(entity, me.MibUpload) {
1387 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1388 }
1389 bytes, err := b.AppendBytes(2)
1390 if err != nil {
1391 return err
1392 }
1393 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1394 return nil
1395}
1396
1397/////////////////////////////////////////////////////////////////////////////
1398//
1399type MibUploadNextRequest struct {
1400 MeBasePacket
1401 CommandSequenceNumber uint16
1402}
1403
1404func (omci *MibUploadNextRequest) String() string {
1405 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
1406 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1407}
1408
1409// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
1410func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1411 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001412 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001413 if err != nil {
1414 return err
1415 }
1416 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1417 me.ParamData{EntityID: omci.EntityInstance})
1418 if omciErr.StatusCode() != me.Success {
1419 return omciErr.GetError()
1420 }
1421 // ME needs to support Get All Alarms
1422 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1423 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1424 }
1425 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1426 if omci.EntityClass != me.OnuDataClassID {
1427 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
1428 omci.EntityClass)
1429 return me.NewProcessingError(msg)
1430 }
1431 if omci.EntityInstance != 0 {
1432 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
1433 omci.EntityInstance)
1434 return me.NewUnknownInstanceError(msg)
1435 }
1436 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1437 return nil
1438}
1439
1440func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
1441 omci := &MibUploadNextRequest{}
1442 omci.MsgLayerType = LayerTypeMibUploadNextRequest
1443 return decodingLayerDecoder(omci, data, p)
1444}
1445
1446// SerializeTo provides serialization of an MIB Upload Next Request message
1447func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1448 // Basic (common) OMCI Header is 8 octets, 10
1449 err := omci.MeBasePacket.SerializeTo(b)
1450 if err != nil {
1451 return err
1452 }
1453 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1454 me.ParamData{EntityID: omci.EntityInstance})
1455 if omciErr.StatusCode() != me.Success {
1456 return omciErr.GetError()
1457 }
1458 // ME needs to support MIB upload
1459 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1460 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1461 }
1462 bytes, err := b.AppendBytes(2)
1463 if err != nil {
1464 return err
1465 }
1466 binary.BigEndian.PutUint16(bytes[0:2], omci.CommandSequenceNumber)
1467 return nil
1468}
1469
1470/////////////////////////////////////////////////////////////////////////////
1471//
1472type MibUploadNextResponse struct {
1473 MeBasePacket
1474 ReportedME me.ManagedEntity
1475}
1476
1477func (omci *MibUploadNextResponse) String() string {
1478 return fmt.Sprintf("%v, ReportedME: [%v]",
1479 omci.MeBasePacket.String(), omci.ReportedME.String())
1480}
1481
1482// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
1483func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1484 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001485 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+6)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001486 if err != nil {
1487 return err
1488 }
1489 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1490 me.ParamData{EntityID: omci.EntityInstance})
1491 if omciErr.StatusCode() != me.Success {
1492 return omciErr.GetError()
1493 }
1494 // ME needs to support MibUploadNext
1495 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1496 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1497 }
1498 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1499 if omci.EntityClass != me.OnuDataClassID {
1500 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
1501 omci.EntityClass)
1502 return me.NewProcessingError(msg)
1503 }
1504 if omci.EntityInstance != 0 {
1505 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
1506 omci.EntityInstance)
1507 return me.NewUnknownInstanceError(msg)
1508 }
1509 // Decode reported ME. If an out-of-range sequence number was sent, this will
1510 // contain an ME with class ID and entity ID of zero and you should get an
1511 // error of "managed entity definition not found" returned.
1512 return omci.ReportedME.DecodeFromBytes(data[4:], p, byte(MibUploadNextResponseType))
1513}
1514
1515func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
1516 omci := &MibUploadNextResponse{}
1517 omci.MsgLayerType = LayerTypeMibUploadNextResponse
1518 return decodingLayerDecoder(omci, data, p)
1519}
1520
1521// SerializeTo provides serialization of an MIB Upload Next Response message
1522func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1523 // Basic (common) OMCI Header is 8 octets, 10
1524 err := omci.MeBasePacket.SerializeTo(b)
1525 if err != nil {
1526 return err
1527 }
1528 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1529 me.ParamData{EntityID: omci.EntityInstance})
1530 if omciErr.StatusCode() != me.Success {
1531 return omciErr.GetError()
1532 }
1533 // ME needs to support MIB Upload
1534 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1535 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1536 }
1537 // TODO: Only Baseline supported at this time
1538 bytesAvailable := MaxBaselineLength - 8 - 8
1539
1540 return omci.ReportedME.SerializeTo(b, byte(MibUploadNextResponseType), bytesAvailable, opts)
1541}
1542
1543/////////////////////////////////////////////////////////////////////////////
1544// MibResetRequest
1545type MibResetRequest struct {
1546 MeBasePacket
1547}
1548
1549func (omci *MibResetRequest) String() string {
1550 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1551}
1552
1553// DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
1554func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1555 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001556 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001557 if err != nil {
1558 return err
1559 }
1560 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1561 me.ParamData{EntityID: omci.EntityInstance})
1562 if omciErr.StatusCode() != me.Success {
1563 return omciErr.GetError()
1564 }
1565 // ME needs to support MIB reset
1566 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1567 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1568 }
1569 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1570 if omci.EntityClass != me.OnuDataClassID {
1571 msg := fmt.Sprintf("invalid Entity Class for MIB Reset request: %v",
1572 omci.EntityClass)
1573 return me.NewProcessingError(msg)
1574 }
1575 if omci.EntityInstance != 0 {
1576 msg := fmt.Sprintf("invalid Entity Instance for MIB Reset request: %v",
1577 omci.EntityInstance)
1578 return me.NewUnknownInstanceError(msg)
1579 }
1580 return nil
1581}
1582
1583func decodeMibResetRequest(data []byte, p gopacket.PacketBuilder) error {
1584 omci := &MibResetRequest{}
1585 omci.MsgLayerType = LayerTypeMibResetRequest
1586 return decodingLayerDecoder(omci, data, p)
1587}
1588
1589// SerializeTo provides serialization of an MIB Reset Request message
1590func (omci *MibResetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1591 // Add class ID and entity ID
1592 return omci.MeBasePacket.SerializeTo(b)
1593}
1594
1595/////////////////////////////////////////////////////////////////////////////
1596// MibResetResponse
1597type MibResetResponse struct {
1598 MeBasePacket
1599 Result me.Results
1600}
1601
1602func (omci *MibResetResponse) String() string {
1603 return fmt.Sprintf("%v, Result: %d (%v)",
1604 omci.MeBasePacket.String(), omci.Result, omci.Result)
1605}
1606
1607// DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
1608func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1609 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001610 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001611 if err != nil {
1612 return err
1613 }
1614 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1615 me.ParamData{EntityID: omci.EntityInstance})
1616 if omciErr.StatusCode() != me.Success {
1617 return omciErr.GetError()
1618 }
1619 // ME needs to support MIB reset
1620 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1621 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1622 }
1623 // MIB Reset Response Entity Class always ONU DATA (2) and
1624 // Entity Instance of 0
1625 if omci.EntityClass != me.OnuDataClassID {
1626 return me.NewProcessingError("invalid Entity Class for MIB Reset Response")
1627 }
1628 if omci.EntityInstance != 0 {
1629 return me.NewUnknownInstanceError("invalid Entity Instance for MIB Reset Response")
1630 }
1631 omci.Result = me.Results(data[4])
1632 if omci.Result > me.DeviceBusy {
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001633 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001634 return errors.New(msg)
1635 }
1636 return nil
1637}
1638
1639func decodeMibResetResponse(data []byte, p gopacket.PacketBuilder) error {
1640 omci := &MibResetResponse{}
1641 omci.MsgLayerType = LayerTypeMibResetResponse
1642 return decodingLayerDecoder(omci, data, p)
1643}
1644
1645// SerializeTo provides serialization of an MIB Reset Response message
1646func (omci *MibResetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1647 // Basic (common) OMCI Header is 8 octets, 10
1648 err := omci.MeBasePacket.SerializeTo(b)
1649 if err != nil {
1650 return err
1651 }
1652 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1653 me.ParamData{EntityID: omci.EntityInstance})
1654 if omciErr.StatusCode() != me.Success {
1655 return omciErr.GetError()
1656 }
1657 // ME needs to support Set
1658 if !me.SupportsMsgType(entity, me.MibReset) {
1659 return me.NewProcessingError("managed entity does not support the MIB Reset Message-Type")
1660 }
1661 bytes, err := b.AppendBytes(1)
1662 if err != nil {
1663 return err
1664 }
1665 bytes[0] = byte(omci.Result)
1666 return nil
1667}
1668
1669/////////////////////////////////////////////////////////////////////////////
1670// AlarmNotificationMsg
1671const AlarmBitmapSize = 224
1672
1673type AlarmNotificationMsg struct {
1674 MeBasePacket
1675 AlarmBitmap [AlarmBitmapSize / 8]byte
Himani Chawla43f95ff2021-06-03 00:24:12 +05301676 zeroPadding [3]byte // Note: This zero padding is not present in the Extended Message Set
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001677 AlarmSequenceNumber byte
1678}
1679
1680func (omci *AlarmNotificationMsg) String() string {
1681 return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
1682 omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
1683}
1684
1685func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
1686 if alarmNumber >= AlarmBitmapSize {
1687 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1688 return false, errors.New(msg)
1689 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301690 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1691 me.ParamData{EntityID: omci.EntityInstance})
1692 if omciErr.StatusCode() != me.Success {
1693 return false, omciErr.GetError()
1694 }
1695 alarmMap := entity.GetAlarmMap()
1696 if alarmMap == nil {
1697 msg := "Managed Entity does not support Alarm notifications"
1698 return false, errors.New(msg)
1699 }
1700 if _, ok := alarmMap[alarmNumber]; !ok {
1701 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1702 return false, errors.New(msg)
1703 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001704 octet := alarmNumber / 8
1705 bit := 7 - (alarmNumber % 8)
1706 return omci.AlarmBitmap[octet]>>bit == 1, nil
1707}
1708
1709func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
1710 if alarmNumber >= AlarmBitmapSize {
1711 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1712 return false, errors.New(msg)
1713 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301714 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1715 me.ParamData{EntityID: omci.EntityInstance})
1716 if omciErr.StatusCode() != me.Success {
1717 return false, omciErr.GetError()
1718 }
1719 alarmMap := entity.GetAlarmMap()
1720 if alarmMap == nil {
1721 return false, errors.New("Managed Entity does not support Alarm notifications")
1722 }
1723 if _, ok := alarmMap[alarmNumber]; !ok {
1724 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1725 return false, errors.New(msg)
1726 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001727 octet := alarmNumber / 8
1728 bit := 7 - (alarmNumber % 8)
1729 return omci.AlarmBitmap[octet]>>bit == 0, nil
1730}
1731
1732func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
1733 if alarmNumber >= AlarmBitmapSize {
1734 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1735 return errors.New(msg)
1736 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301737 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1738 me.ParamData{EntityID: omci.EntityInstance})
1739 if omciErr.StatusCode() != me.Success {
1740 return omciErr.GetError()
1741 }
1742 alarmMap := entity.GetAlarmMap()
1743 if alarmMap == nil {
1744 return errors.New("Managed Entity does not support Alarm notifications")
1745 }
1746 if _, ok := alarmMap[alarmNumber]; !ok {
1747 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1748 return errors.New(msg)
1749 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001750 octet := alarmNumber / 8
1751 bit := 7 - (alarmNumber % 8)
1752 omci.AlarmBitmap[octet] |= 1 << bit
1753 return nil
1754}
1755
1756func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
1757 if alarmNumber >= AlarmBitmapSize {
1758 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1759 return errors.New(msg)
1760 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301761 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1762 me.ParamData{EntityID: omci.EntityInstance})
1763 if omciErr.StatusCode() != me.Success {
1764 return omciErr.GetError()
1765 }
1766 alarmMap := entity.GetAlarmMap()
1767 if alarmMap == nil {
1768 return errors.New("Managed Entity does not support Alarm notifications")
1769 }
1770 if _, ok := alarmMap[alarmNumber]; !ok {
1771 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1772 return errors.New(msg)
1773 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001774 octet := alarmNumber / 8
1775 bit := 7 - (alarmNumber % 8)
1776 omci.AlarmBitmap[octet] &= ^(1 << bit)
1777 return nil
1778}
1779
1780// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
1781func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1782 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001783 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+28)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001784 if err != nil {
1785 return err
1786 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301787 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1788 me.ParamData{EntityID: omci.EntityInstance})
1789 if omciErr.StatusCode() != me.Success {
1790 return omciErr.GetError()
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001791 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301792 // Is this an unsupported or vendor specific ME. If so, it is not an error to decode
1793 // the alarms. We just cannot provide any alarm names. Handle decode here.
1794 classSupport := meDefinition.GetClassSupport()
1795 isUnsupported := classSupport == me.UnsupportedManagedEntity ||
1796 classSupport == me.UnsupportedVendorSpecificManagedEntity
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001797
Himani Chawla43f95ff2021-06-03 00:24:12 +05301798 mapOffset := 4
1799 if omci.Extended {
1800 mapOffset = 6
1801 if len(data) < 6+28+1 {
1802 p.SetTruncated()
1803 return errors.New("frame too small")
1804 }
1805 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301806 // Look for a non-nil/not empty Alarm Map to determine if this ME supports alarms
1807 if alarmMap := meDefinition.GetAlarmMap(); isUnsupported || (alarmMap != nil && len(alarmMap) > 0) {
Himani Chawla43f95ff2021-06-03 00:24:12 +05301808 for index, octet := range data[mapOffset : (AlarmBitmapSize/8)-mapOffset] {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301809 omci.AlarmBitmap[index] = octet
1810 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05301811 if omci.Extended {
1812 omci.AlarmSequenceNumber = data[mapOffset+(AlarmBitmapSize/8)]
1813 } else {
1814 padOffset := mapOffset + (AlarmBitmapSize / 8)
1815 omci.zeroPadding[0] = data[padOffset]
1816 omci.zeroPadding[1] = data[padOffset+1]
1817 omci.zeroPadding[2] = data[padOffset+2]
1818 omci.AlarmSequenceNumber = data[padOffset+3]
1819 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301820 return nil
1821 }
1822 return me.NewProcessingError("managed entity does not support alarm notifications")
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001823}
1824
1825func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
1826 omci := &AlarmNotificationMsg{}
1827 omci.MsgLayerType = LayerTypeAlarmNotification
1828 return decodingLayerDecoder(omci, data, p)
1829}
1830
Himani Chawla43f95ff2021-06-03 00:24:12 +05301831func decodeAlarmNotificationExtended(data []byte, p gopacket.PacketBuilder) error {
1832 omci := &AlarmNotificationMsg{}
1833 omci.MsgLayerType = LayerTypeAlarmNotification
1834 omci.Extended = true
1835 return decodingLayerDecoder(omci, data, p)
1836}
1837
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001838// SerializeTo provides serialization of an Alarm Notification message
1839func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1840 // Basic (common) OMCI Header is 8 octets, 10
1841 err := omci.MeBasePacket.SerializeTo(b)
1842 if err != nil {
1843 return err
1844 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05301845 // TODO: Support of encoding AlarmNotification into supported types not yet supported
1846 //meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001847 // me.ParamData{EntityID: omci.EntityInstance})
Himani Chawla43f95ff2021-06-03 00:24:12 +05301848 //if omciErr.StatusCode() != me.Success {
1849 // return omciErr.GetError()
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001850 //}
Himani Chawla43f95ff2021-06-03 00:24:12 +05301851 //if !me.SupportsMsgType(meDefinition, me.AlarmNotification) {
1852 // return me.NewProcessingError("managed entity does not support Alarm Notification Message-Type")
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001853 //}
Himani Chawla43f95ff2021-06-03 00:24:12 +05301854 if omci.Extended {
1855 bytes, err := b.AppendBytes(2 + (AlarmBitmapSize / 8) + 1)
1856 if err != nil {
1857 return err
1858 }
1859 binary.BigEndian.PutUint16(bytes, uint16((AlarmBitmapSize/8)+1))
1860
1861 for index, octet := range omci.AlarmBitmap {
1862 bytes[2+index] = octet
1863 }
1864 bytes[2+(AlarmBitmapSize/8)] = omci.AlarmSequenceNumber
1865 } else {
1866 bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
1867 if err != nil {
1868 return err
1869 }
1870 for index, octet := range omci.AlarmBitmap {
1871 bytes[index] = octet
1872 }
1873 padOffset := AlarmBitmapSize / 8
1874 bytes[padOffset] = 0
1875 bytes[padOffset+1] = 0
1876 bytes[padOffset+2] = 0
1877 bytes[padOffset+3] = omci.AlarmSequenceNumber
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001878 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001879 return nil
1880}
1881
1882/////////////////////////////////////////////////////////////////////////////
1883// AttributeValueChangeMsg
1884type AttributeValueChangeMsg struct {
1885 MeBasePacket
1886 AttributeMask uint16
1887 Attributes me.AttributeValueMap
1888}
1889
1890func (omci *AttributeValueChangeMsg) String() string {
1891 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
1892 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
1893}
1894
1895// DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
1896func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1897 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00001898 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001899 if err != nil {
1900 return err
1901 }
1902 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1903 me.ParamData{EntityID: omci.EntityInstance})
1904 if omciErr.StatusCode() != me.Success {
1905 return omciErr.GetError()
1906 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05301907 // TODO: Support for encoding AVC into message type support not yet supported
1908 //if !me.SupportsMsgType(meDefinition, me.AlarmNotification) {
1909 // return me.NewProcessingError("managed entity does not support Alarm Notification Message-Type")
1910 //}
1911 maskOffset := 4
1912 if omci.Extended {
1913 maskOffset = 6
1914 }
1915 omci.AttributeMask = binary.BigEndian.Uint16(data[maskOffset:])
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001916 // Attribute decode
Himani Chawla43f95ff2021-06-03 00:24:12 +05301917 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[maskOffset+2:],
1918 p, byte(AttributeValueChangeType))
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001919 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1920 // Validate all attributes support AVC
1921 //for attrName := range omci.attributes {
1922 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1923 // if err != nil {
1924 // return err
1925 // }
1926 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1927 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1928 // return me.NewProcessingError(msg)
1929 // }
1930 //}
1931 return err
1932}
1933
1934func decodeAttributeValueChange(data []byte, p gopacket.PacketBuilder) error {
1935 omci := &AttributeValueChangeMsg{}
1936 omci.MsgLayerType = LayerTypeAttributeValueChange
1937 return decodingLayerDecoder(omci, data, p)
1938}
1939
Himani Chawla43f95ff2021-06-03 00:24:12 +05301940func decodeAttributeValueChangeExtended(data []byte, p gopacket.PacketBuilder) error {
1941 omci := &AttributeValueChangeMsg{}
1942 omci.MsgLayerType = LayerTypeAttributeValueChange
1943 omci.Extended = true
1944 return decodingLayerDecoder(omci, data, p)
1945}
1946
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001947// SerializeTo provides serialization of an Attribute Value Change Notification message
1948func (omci *AttributeValueChangeMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1949 // Basic (common) OMCI Header is 8 octets, 10
1950 err := omci.MeBasePacket.SerializeTo(b)
1951 if err != nil {
1952 return err
1953 }
1954 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1955 me.ParamData{EntityID: omci.EntityInstance})
1956 if omciErr.StatusCode() != me.Success {
1957 return omciErr.GetError()
1958 }
1959 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1960 // Validate all attributes support AVC
1961 //for attrName := range omci.attributes {
1962 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1963 // if err != nil {
1964 // return err
1965 // }
1966 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1967 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1968 // return me.NewProcessingError(msg)
1969 // }
1970 //}
Himani Chawla43f95ff2021-06-03 00:24:12 +05301971 var maskOffset int
1972 var bytesAvailable int
1973 if omci.Extended {
1974 maskOffset = 2
1975 bytesAvailable = MaxExtendedLength - 12 - 4
1976 } else {
1977 maskOffset = 0
1978 bytesAvailable = MaxBaselineLength - 10 - 8
1979 }
1980 bytes, err := b.AppendBytes(maskOffset + 2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001981 if err != nil {
1982 return err
1983 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05301984 binary.BigEndian.PutUint16(bytes[maskOffset:], omci.AttributeMask)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001985
1986 // Attribute serialization
Himani Chawla43f95ff2021-06-03 00:24:12 +05301987 attributeBuffer := gopacket.NewSerializeBuffer()
1988 if err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask,
1989 attributeBuffer, byte(GetResponseType), bytesAvailable, false); err != nil {
1990 return err
1991 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001992
Himani Chawla43f95ff2021-06-03 00:24:12 +05301993 if omci.Extended {
1994 binary.BigEndian.PutUint16(bytes, uint16(len(attributeBuffer.Bytes())+2))
1995 }
1996 bytes, err = b.AppendBytes(len(attributeBuffer.Bytes()))
1997 if err != nil {
1998 return err
1999 }
2000 copy(bytes, attributeBuffer.Bytes())
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002001 return err
2002}
2003
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002004func decodeTestRequest(data []byte, p gopacket.PacketBuilder) error {
2005 // Peek at Managed Entity Type
2006 if len(data) < 8 {
2007 p.SetTruncated()
2008 return errors.New("frame too small")
2009 }
2010 classID := binary.BigEndian.Uint16(data)
2011
2012 // Is it a Managed Entity class we support customized decode of?
2013 switch me.ClassID(classID) {
2014 default:
2015 omci := &TestRequest{}
Himani Chawla43f95ff2021-06-03 00:24:12 +05302016 omci.MsgLayerType = LayerTypeTestRequest
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002017 return decodingLayerDecoder(omci, data, p)
2018
2019 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
2020 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
2021 omci := &OpticalLineSupervisionTestRequest{}
Himani Chawla43f95ff2021-06-03 00:24:12 +05302022 omci.MsgLayerType = LayerTypeTestRequest
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002023 return decodingLayerDecoder(omci, data, p)
2024 }
2025}
2026
2027// TestRequest message
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002028type TestRequest struct {
2029 MeBasePacket
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002030 Payload []byte
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002031}
2032
2033func (omci *TestRequest) String() string {
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002034 return fmt.Sprintf("%v, Request: %v octets", omci.MeBasePacket.String(), len(omci.Payload))
2035}
2036
2037func (omci *TestRequest) TestRequest() []byte {
2038 return omci.Payload
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002039}
2040
2041// DecodeFromBytes decodes the given bytes of a Test Request into this layer
2042func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2043 // Common ClassID/EntityID decode in msgBase
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002044 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002045 if err != nil {
2046 return err
2047 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002048
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002049 omci.Payload = make([]byte, MaxTestRequestLength)
2050 copy(omci.Payload, omci.MeBasePacket.Payload)
2051 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002052}
2053
2054// SerializeTo provides serialization of an Test Request message
2055func (omci *TestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2056 // Basic (common) OMCI Header is 8 octets, 10
2057 err := omci.MeBasePacket.SerializeTo(b)
2058 if err != nil {
2059 return err
2060 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002061 if omci.Payload == nil {
2062 return errors.New("Test Results payload is missing")
2063 }
2064
2065 if len(omci.Payload) > MaxTestRequestLength {
2066 msg := fmt.Sprintf("Invalid Test Request payload size. Received %v bytes, expected %v",
2067 len(omci.Payload), MaxTestRequestLength)
2068 return errors.New(msg)
2069 }
2070 bytes, err := b.AppendBytes(len(omci.Payload))
2071 if err != nil {
2072 return err
2073 }
2074
2075 copy(bytes, omci.Payload)
2076 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002077}
2078
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002079type OpticalLineSupervisionTestRequest struct {
2080 MeBasePacket
2081 SelectTest uint8 // Bitfield
2082 GeneralPurposeBuffer uint16 // Pointer to General Purpose Buffer ME
2083 VendorSpecificParameters uint16 // Pointer to Octet String ME
2084}
2085
2086func (omci *OpticalLineSupervisionTestRequest) String() string {
2087 return fmt.Sprintf("Optical Line Supervision Test Result: SelectTest: %#x, Buffer: %#x, Params: %#x",
2088 omci.SelectTest, omci.GeneralPurposeBuffer, omci.VendorSpecificParameters)
2089}
2090
2091func (omci *OpticalLineSupervisionTestRequest) TestRequest() []byte {
2092 return omci.Payload
2093}
2094
2095// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
2096func (omci *OpticalLineSupervisionTestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2097 // Common ClassID/EntityID decode in msgBase
2098 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
2099 if err != nil {
2100 return err
2101 }
2102
2103 omci.SelectTest = data[4]
2104 omci.GeneralPurposeBuffer = binary.BigEndian.Uint16(data[5:])
2105 omci.VendorSpecificParameters = binary.BigEndian.Uint16(data[7:])
2106 return nil
2107}
2108
2109// SerializeTo provides serialization of an Test Result notification message
2110func (omci *OpticalLineSupervisionTestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2111 // Basic (common) OMCI Header is 8 octets, 10
2112 err := omci.MeBasePacket.SerializeTo(b)
2113 if err != nil {
2114 return err
2115 }
2116
2117 bytes, err := b.AppendBytes(8)
2118 if err != nil {
2119 return err
2120 }
2121
2122 bytes[0] = omci.SelectTest
2123 binary.BigEndian.PutUint16(bytes[1:], omci.GeneralPurposeBuffer)
2124 binary.BigEndian.PutUint16(bytes[3:], omci.VendorSpecificParameters)
2125 return nil
2126}
2127
2128// TestResponse message
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002129type TestResponse struct {
2130 MeBasePacket
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002131 Result me.Results
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002132}
2133
2134func (omci *TestResponse) String() string {
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002135 return fmt.Sprintf("%v, Results: %d (%v)", omci.MeBasePacket.String(), omci.Result, omci.Result)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002136}
2137
2138// DecodeFromBytes decodes the given bytes of a Test Response into this layer
2139func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2140 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002141 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002142 if err != nil {
2143 return err
2144 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002145 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2146 me.ParamData{EntityID: omci.EntityInstance})
2147 if omciErr.StatusCode() != me.Success {
2148 return omciErr.GetError()
2149 }
2150
2151 // ME needs to support Test requests
2152 if !me.SupportsMsgType(meDefinition, me.Test) {
2153 return me.NewProcessingError("managed entity does not support Test Message-Type")
2154 }
2155 omci.Result = me.Results(data[4])
2156 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002157}
2158
2159func decodeTestResponse(data []byte, p gopacket.PacketBuilder) error {
2160 omci := &TestResponse{}
2161 omci.MsgLayerType = LayerTypeTestResponse
2162 return decodingLayerDecoder(omci, data, p)
2163}
2164
2165// SerializeTo provides serialization of an Test Response message
2166func (omci *TestResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2167 // Basic (common) OMCI Header is 8 octets, 10
2168 err := omci.MeBasePacket.SerializeTo(b)
2169 if err != nil {
2170 return err
2171 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002172 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2173 me.ParamData{EntityID: omci.EntityInstance})
2174 if omciErr.StatusCode() != me.Success {
2175 return omciErr.GetError()
2176 }
2177 // ME needs to support Set
2178 if !me.SupportsMsgType(entity, me.Test) {
2179 return me.NewProcessingError("managed entity does not support the Test Message-Type")
2180 }
2181 bytes, err := b.AppendBytes(1)
2182 if err != nil {
2183 return err
2184 }
2185 bytes[0] = byte(omci.Result)
2186
2187 if omci.Result > me.DeviceBusy {
2188 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
2189 return errors.New(msg)
2190 }
2191 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002192}
2193
2194/////////////////////////////////////////////////////////////////////////////
2195//
2196type StartSoftwareDownloadRequest struct {
2197 MeBasePacket // Note: EntityInstance for software download is two specific values
2198 WindowSize byte // Window Size -1
2199 ImageSize uint32 // Octets
2200 NumberOfCircuitPacks byte
2201 CircuitPacks []uint16 // MSB & LSB of software image instance
2202}
2203
2204func (omci *StartSoftwareDownloadRequest) String() string {
2205 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
2206 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
2207}
2208
2209// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
2210func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
mpagenkobf67a092021-03-17 09:52:28 +00002211 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002212 if err != nil {
2213 return err
2214 }
2215 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2216 me.ParamData{EntityID: omci.EntityInstance})
2217 if omciErr.StatusCode() != me.Success {
2218 return omciErr.GetError()
2219 }
2220 // ME needs to support Start Software Download
2221 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2222 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2223 }
2224 // Software Image Entity Class are always use the Software Image
2225 if omci.EntityClass != me.SoftwareImageClassID {
2226 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
2227 }
2228 omci.WindowSize = data[4]
2229 omci.ImageSize = binary.BigEndian.Uint32(data[5:9])
2230 omci.NumberOfCircuitPacks = data[9]
2231 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
2232 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
2233 omci.NumberOfCircuitPacks))
2234 }
2235 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
2236 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2237 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[10+(index*2):])
2238 }
2239 return nil
2240}
2241
2242func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2243 omci := &StartSoftwareDownloadRequest{}
2244 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
2245 return decodingLayerDecoder(omci, data, p)
2246}
2247
2248// SerializeTo provides serialization of an Start Software Download Request message
2249func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2250 // Basic (common) OMCI Header is 8 octets, 10
2251 err := omci.MeBasePacket.SerializeTo(b)
2252 if err != nil {
2253 return err
2254 }
2255 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2256 me.ParamData{EntityID: omci.EntityInstance})
2257 if omciErr.StatusCode() != me.Success {
2258 return omciErr.GetError()
2259 }
2260 // ME needs to support Start Software Download
2261 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
2262 return me.NewProcessingError("managed entity does not support the SStart Software Download Message-Type")
2263 }
2264 // Software Image Entity Class are always use the Software Image
2265 if omci.EntityClass != me.SoftwareImageClassID {
2266 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
2267 }
2268 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
2269 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
2270 omci.NumberOfCircuitPacks))
2271 }
2272 bytes, err := b.AppendBytes(6 + (2 * int(omci.NumberOfCircuitPacks)))
2273 if err != nil {
2274 return err
2275 }
2276 bytes[0] = omci.WindowSize
2277 binary.BigEndian.PutUint32(bytes[1:], omci.ImageSize)
2278 bytes[5] = omci.NumberOfCircuitPacks
2279 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2280 binary.BigEndian.PutUint16(bytes[6+(index*2):], omci.CircuitPacks[index])
2281 }
2282 return nil
2283}
2284
2285/////////////////////////////////////////////////////////////////////////////
2286//
mpagenkobf67a092021-03-17 09:52:28 +00002287type DownloadResults struct {
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002288 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
2289 Result me.Results
2290}
2291
mpagenkobf67a092021-03-17 09:52:28 +00002292func (dr *DownloadResults) String() string {
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002293 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
2294 dr.Result, dr.Result)
2295}
2296
2297type StartSoftwareDownloadResponse struct {
2298 MeBasePacket // Note: EntityInstance for software download is two specific values
2299 Result me.Results
2300 WindowSize byte // Window Size -1
2301 NumberOfInstances byte
mpagenkobf67a092021-03-17 09:52:28 +00002302 MeResults []DownloadResults
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002303}
2304
2305func (omci *StartSoftwareDownloadResponse) String() string {
2306 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
2307 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
2308}
2309
2310// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
2311func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2312 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002313 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002314 if err != nil {
2315 return err
2316 }
2317 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2318 me.ParamData{EntityID: omci.EntityInstance})
2319 if omciErr.StatusCode() != me.Success {
2320 return omciErr.GetError()
2321 }
2322 // ME needs to support Start Software Download
2323 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2324 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2325 }
2326 // Software Image Entity Class are always use the Software Image
2327 if omci.EntityClass != me.SoftwareImageClassID {
2328 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2329 }
2330 omci.Result = me.Results(data[4])
2331 if omci.Result > me.DeviceBusy {
2332 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2333 omci.Result)
2334 return errors.New(msg)
2335 }
2336 omci.WindowSize = data[5]
2337 omci.NumberOfInstances = data[6]
2338
2339 if omci.NumberOfInstances > 9 {
2340 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2341 omci.NumberOfInstances)
2342 return errors.New(msg)
2343 }
2344 if omci.NumberOfInstances > 0 {
mpagenkobf67a092021-03-17 09:52:28 +00002345 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002346
2347 for index := 0; index < int(omci.NumberOfInstances); index++ {
2348 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
2349 omci.MeResults[index].Result = me.Results(data[9+(index*3)])
2350 if omci.MeResults[index].Result > me.DeviceBusy {
2351 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2352 index, omci.MeResults[index])
2353 return errors.New(msg)
2354 }
2355 }
2356 }
2357 return nil
2358}
2359
2360func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2361 omci := &StartSoftwareDownloadResponse{}
2362 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
2363 return decodingLayerDecoder(omci, data, p)
2364}
2365
2366// SerializeTo provides serialization of an Start Software Download Response message
2367func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2368 // Basic (common) OMCI Header is 8 octets, 10
2369 err := omci.MeBasePacket.SerializeTo(b)
2370 if err != nil {
2371 return err
2372 }
2373 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2374 me.ParamData{EntityID: omci.EntityInstance})
2375 if omciErr.StatusCode() != me.Success {
2376 return omciErr.GetError()
2377 }
2378 // ME needs to support Start Software Download
2379 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2380 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2381 }
2382 // Software Image Entity Class are always use the Software Image
2383 if omci.EntityClass != me.SoftwareImageClassID {
2384 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2385 }
2386 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2387 if err != nil {
2388 return err
2389 }
2390 if omci.Result > me.DeviceBusy {
2391 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2392 omci.Result)
2393 return errors.New(msg)
2394 }
2395 bytes[0] = byte(omci.Result)
2396 bytes[1] = omci.WindowSize
2397 bytes[2] = omci.NumberOfInstances
2398
2399 if omci.NumberOfInstances > 9 {
2400 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2401 omci.NumberOfInstances)
2402 return errors.New(msg)
2403 }
2404 if omci.NumberOfInstances > 0 {
2405 for index := 0; index < int(omci.NumberOfInstances); index++ {
2406 binary.BigEndian.PutUint16(bytes[3+(3*index):], omci.MeResults[index].ManagedEntityID)
2407
2408 if omci.MeResults[index].Result > me.DeviceBusy {
2409 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2410 index, omci.MeResults[index])
2411 return errors.New(msg)
2412 }
2413 bytes[5+(3*index)] = byte(omci.MeResults[index].Result)
2414 }
2415 }
2416 return nil
2417}
2418
Himani Chawla43f95ff2021-06-03 00:24:12 +05302419// DownloadSectionRequest data is bound by the message set in use. For the
2420// Baseline message set use MaxDownloadSectionLength and for the Extended message
2421// set, MaxDownloadSectionExtendedLength is provided
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002422type DownloadSectionRequest struct {
2423 MeBasePacket // Note: EntityInstance for software download is two specific values
2424 SectionNumber byte
Himani Chawla43f95ff2021-06-03 00:24:12 +05302425 SectionData []byte // 0 padding if final transfer requires only a partial block for baseline set
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002426}
2427
2428func (omci *DownloadSectionRequest) String() string {
Himani Chawla43f95ff2021-06-03 00:24:12 +05302429 return fmt.Sprintf("%v, Section #: %v, Data Length: %v",
2430 omci.MeBasePacket.String(), omci.SectionNumber, len(omci.SectionData))
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002431}
2432
2433// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
2434func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2435 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002436 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002437 if err != nil {
2438 return err
2439 }
2440 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2441 me.ParamData{EntityID: omci.EntityInstance})
2442 if omciErr.StatusCode() != me.Success {
2443 return omciErr.GetError()
2444 }
2445 // ME needs to support Download section
2446 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2447 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2448 }
2449 // Software Image Entity Class are always use the Software Image
2450 if omci.EntityClass != me.SoftwareImageClassID {
2451 return me.NewProcessingError("invalid Entity Class for Download Section request")
2452 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05302453 if omci.Extended {
2454 if len(data) < 7 {
2455 p.SetTruncated()
2456 return errors.New("frame too small")
2457 }
2458 if len(data[7:]) > MaxDownloadSectionExtendedLength {
2459 return errors.New(fmt.Sprintf("software image data too large. Received %v, Max: %v",
2460 len(data[7:]), MaxDownloadSectionExtendedLength))
2461 }
2462 omci.SectionData = make([]byte, len(data[7:]))
2463 omci.SectionNumber = data[6]
2464 copy(omci.SectionData, data[7:])
2465 } else {
2466 if len(data[5:]) != MaxDownloadSectionLength {
2467 p.SetTruncated()
2468 return errors.New(fmt.Sprintf("software image size invalid. Received %v, Expected: %v",
2469 len(data[5:]), MaxDownloadSectionLength))
2470 }
2471 omci.SectionData = make([]byte, MaxDownloadSectionLength)
2472 omci.SectionNumber = data[4]
2473 copy(omci.SectionData, data[5:])
2474 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002475 return nil
2476}
2477
2478func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2479 omci := &DownloadSectionRequest{}
2480 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2481 return decodingLayerDecoder(omci, data, p)
2482}
2483
Himani Chawla43f95ff2021-06-03 00:24:12 +05302484func decodeDownloadSectionRequestExtended(data []byte, p gopacket.PacketBuilder) error {
2485 omci := &DownloadSectionRequest{}
2486 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2487 omci.Extended = true
2488 return decodingLayerDecoder(omci, data, p)
2489}
2490
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002491// SerializeTo provides serialization of an Download Section Request message
2492func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2493 // Basic (common) OMCI Header is 8 octets, 10
2494 err := omci.MeBasePacket.SerializeTo(b)
2495 if err != nil {
2496 return err
2497 }
2498 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2499 me.ParamData{EntityID: omci.EntityInstance})
2500 if omciErr.StatusCode() != me.Success {
2501 return omciErr.GetError()
2502 }
2503 // ME needs to support Download section
2504 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2505 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2506 }
2507 // Software Image Entity Class are always use the Software Image
2508 if omci.EntityClass != me.SoftwareImageClassID {
2509 return me.NewProcessingError("invalid Entity Class for Download Section response")
2510 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05302511 sectionLength := len(omci.SectionData)
2512 if omci.Extended {
2513 if sectionLength > MaxDownloadSectionExtendedLength {
2514 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
2515 MaxDownloadSectionExtendedLength, sectionLength)
2516 return me.NewProcessingError(msg)
2517 }
2518 // Append section data
2519 bytes, err := b.AppendBytes(3 + sectionLength)
2520 if err != nil {
2521 return err
2522 }
2523 binary.BigEndian.PutUint16(bytes, uint16(1+sectionLength))
2524 bytes[2] = omci.SectionNumber
2525 copy(bytes[3:], omci.SectionData)
2526 } else {
2527 if sectionLength > MaxDownloadSectionLength {
2528 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
2529 MaxDownloadSectionLength, sectionLength)
2530 return me.NewProcessingError(msg)
2531 }
2532 // Append section data
2533 bytes, err := b.AppendBytes(1 + MaxDownloadSectionLength)
2534 if err != nil {
2535 return err
2536 }
2537 bytes[0] = omci.SectionNumber
2538 copy(bytes[1:], omci.SectionData)
2539
2540 // Zero extended if needed
2541 if sectionLength < MaxDownloadSectionLength {
2542 copy(omci.SectionData[sectionLength:], lotsOfZeros[:MaxDownloadSectionLength-sectionLength])
2543 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002544 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002545 return nil
2546}
2547
2548/////////////////////////////////////////////////////////////////////////////
2549//
2550type DownloadSectionResponse struct {
2551 MeBasePacket // Note: EntityInstance for software download is two specific values
2552 Result me.Results
2553 SectionNumber byte
2554}
2555
2556func (omci *DownloadSectionResponse) String() string {
2557 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2558 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2559}
2560
2561// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
2562func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2563 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002564 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002565 if err != nil {
2566 return err
2567 }
2568 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2569 me.ParamData{EntityID: omci.EntityInstance})
2570 if omciErr.StatusCode() != me.Success {
2571 return omciErr.GetError()
2572 }
2573 // ME needs to support Download section
2574 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2575 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2576 }
2577 // Software Image Entity Class are always use the Software Image
2578 if omci.EntityClass != me.SoftwareImageClassID {
2579 return me.NewProcessingError("invalid Entity Class for Download Section response")
2580 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05302581 if omci.Extended {
2582 if len(data) < 8 {
2583 p.SetTruncated()
2584 return errors.New("frame too small")
2585 }
2586 omci.Result = me.Results(data[6])
2587 omci.SectionNumber = data[7]
2588 } else {
2589 omci.Result = me.Results(data[4])
2590 omci.SectionNumber = data[5]
2591 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002592 if omci.Result > me.DeviceBusy {
2593 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2594 omci.Result)
2595 return errors.New(msg)
2596 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002597 return nil
2598}
2599
2600func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2601 omci := &DownloadSectionResponse{}
2602 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2603 return decodingLayerDecoder(omci, data, p)
2604}
2605
Himani Chawla43f95ff2021-06-03 00:24:12 +05302606func decodeDownloadSectionResponseExtended(data []byte, p gopacket.PacketBuilder) error {
2607 omci := &DownloadSectionResponse{}
2608 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2609 omci.Extended = true
2610 return decodingLayerDecoder(omci, data, p)
2611}
2612
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002613// SerializeTo provides serialization of an Download Section Response message
2614func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2615 // Basic (common) OMCI Header is 8 octets, 10
2616 err := omci.MeBasePacket.SerializeTo(b)
2617 if err != nil {
2618 return err
2619 }
2620 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2621 me.ParamData{EntityID: omci.EntityInstance})
2622 if omciErr.StatusCode() != me.Success {
2623 return omciErr.GetError()
2624 }
2625 // ME needs to support Download section
2626 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2627 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2628 }
2629 // Software Image Entity Class are always use the Software Image
2630 if omci.EntityClass != me.SoftwareImageClassID {
2631 return me.NewProcessingError("invalid Entity Class for Download Section response")
2632 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002633 if omci.Result > me.DeviceBusy {
2634 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2635 omci.Result)
2636 return errors.New(msg)
2637 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05302638 if omci.Extended {
2639 bytes, err := b.AppendBytes(4)
2640 if err != nil {
2641 return err
2642 }
2643 binary.BigEndian.PutUint16(bytes, uint16(2))
2644 bytes[2] = byte(omci.Result)
2645 bytes[3] = omci.SectionNumber
2646 } else {
2647 bytes, err := b.AppendBytes(2)
2648 if err != nil {
2649 return err
2650 }
2651 bytes[0] = byte(omci.Result)
2652 bytes[1] = omci.SectionNumber
2653 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002654 return nil
2655}
2656
2657/////////////////////////////////////////////////////////////////////////////
2658//
2659type EndSoftwareDownloadRequest struct {
2660 MeBasePacket // Note: EntityInstance for software download is two specific values
2661 CRC32 uint32
2662 ImageSize uint32
2663 NumberOfInstances byte
2664 ImageInstances []uint16
2665}
2666
2667func (omci *EndSoftwareDownloadRequest) String() string {
2668 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2669 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2670}
2671
2672// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
2673func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2674 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002675 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002676 if err != nil {
2677 return err
2678 }
2679 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2680 me.ParamData{EntityID: omci.EntityInstance})
2681 if omciErr.StatusCode() != me.Success {
2682 return omciErr.GetError()
2683 }
2684 // ME needs to support End Software Download
2685 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2686 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2687 }
2688 // Software Image Entity Class are always use the Software Image
2689 if omci.EntityClass != me.SoftwareImageClassID {
2690 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2691 }
2692 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2693 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
mpagenko15ff4a52021-03-02 10:09:20 +00002694 omci.NumberOfInstances = data[12]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002695
2696 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2697 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2698 omci.NumberOfInstances))
2699 }
2700 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2701
2702 for index := 0; index < int(omci.NumberOfInstances); index++ {
mpagenko15ff4a52021-03-02 10:09:20 +00002703 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[13+(index*2):])
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002704 }
2705 return nil
2706}
2707
2708func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2709 omci := &EndSoftwareDownloadRequest{}
2710 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2711 return decodingLayerDecoder(omci, data, p)
2712}
2713
2714// SerializeTo provides serialization of an End Software Download Request message
2715func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2716 // Basic (common) OMCI Header is 8 octets, 10
2717 err := omci.MeBasePacket.SerializeTo(b)
2718 if err != nil {
2719 return err
2720 }
2721 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2722 me.ParamData{EntityID: omci.EntityInstance})
2723 if omciErr.StatusCode() != me.Success {
2724 return omciErr.GetError()
2725 }
2726 // ME needs to support End Software Download
2727 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2728 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2729 }
2730 // Software Image Entity Class are always use the Software Image
2731 if omci.EntityClass != me.SoftwareImageClassID {
2732 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2733 }
2734 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2735 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2736 omci.NumberOfInstances))
2737 }
2738 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2739 if err != nil {
2740 return err
2741 }
mpagenko15ff4a52021-03-02 10:09:20 +00002742 binary.BigEndian.PutUint32(bytes[0:4], omci.CRC32)
2743 binary.BigEndian.PutUint32(bytes[4:8], omci.ImageSize)
2744 bytes[8] = omci.NumberOfInstances
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002745 for index := 0; index < int(omci.NumberOfInstances); index++ {
mpagenko15ff4a52021-03-02 10:09:20 +00002746 binary.BigEndian.PutUint16(bytes[9+(index*2):], omci.ImageInstances[index])
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002747 }
2748 return nil
2749}
2750
2751/////////////////////////////////////////////////////////////////////////////
2752//
2753type EndSoftwareDownloadResponse struct {
2754 MeBasePacket // Note: EntityInstance for software download is two specific values
2755 Result me.Results
2756 NumberOfInstances byte
mpagenkobf67a092021-03-17 09:52:28 +00002757 MeResults []DownloadResults
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002758}
2759
2760func (omci *EndSoftwareDownloadResponse) String() string {
2761 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2762 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2763}
2764
2765// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
2766func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2767 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002768 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002769 if err != nil {
2770 return err
2771 }
2772 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2773 me.ParamData{EntityID: omci.EntityInstance})
2774 if omciErr.StatusCode() != me.Success {
2775 return omciErr.GetError()
2776 }
2777 // ME needs to support End Software Download
2778 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2779 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2780 }
2781 // Software Image Entity Class are always use the Software Image
2782 if omci.EntityClass != me.SoftwareImageClassID {
2783 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2784 }
2785 omci.Result = me.Results(data[4])
2786 if omci.Result > me.DeviceBusy {
2787 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2788 omci.Result)
2789 return errors.New(msg)
2790 }
2791 omci.NumberOfInstances = data[5]
2792
2793 if omci.NumberOfInstances > 9 {
2794 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2795 omci.NumberOfInstances)
2796 return errors.New(msg)
2797 }
2798 if omci.NumberOfInstances > 0 {
mpagenkobf67a092021-03-17 09:52:28 +00002799 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002800
2801 for index := 0; index < int(omci.NumberOfInstances); index++ {
2802 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2803 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2804 if omci.MeResults[index].Result > me.DeviceBusy {
2805 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2806 index, omci.MeResults[index])
2807 return errors.New(msg)
2808 }
2809 }
2810 }
2811 return nil
2812}
2813
2814func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2815 omci := &EndSoftwareDownloadResponse{}
2816 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2817 return decodingLayerDecoder(omci, data, p)
2818}
2819
2820// SerializeTo provides serialization of an End Software Download Response message
2821func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2822 // Basic (common) OMCI Header is 8 octets, 10
2823 err := omci.MeBasePacket.SerializeTo(b)
2824 if err != nil {
2825 return err
2826 }
2827 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2828 me.ParamData{EntityID: omci.EntityInstance})
2829 if omciErr.StatusCode() != me.Success {
2830 return omciErr.GetError()
2831 }
2832 // ME needs to support End Software Download
2833 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2834 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2835 }
2836 // Software Image Entity Class are always use the Software Image
2837 if omci.EntityClass != me.SoftwareImageClassID {
2838 return me.NewProcessingError("invalid Entity Class for End Download response")
2839 }
mpagenko15ff4a52021-03-02 10:09:20 +00002840 bytes, err := b.AppendBytes(2 + (3 * int(omci.NumberOfInstances)))
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002841 if err != nil {
2842 return err
2843 }
2844 if omci.Result > me.DeviceBusy {
2845 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2846 omci.Result)
2847 return errors.New(msg)
2848 }
2849 bytes[0] = byte(omci.Result)
2850 bytes[1] = omci.NumberOfInstances
2851
2852 if omci.NumberOfInstances > 9 {
2853 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2854 omci.NumberOfInstances)
2855 return errors.New(msg)
2856 }
2857 if omci.NumberOfInstances > 0 {
2858 for index := 0; index < int(omci.NumberOfInstances); index++ {
2859 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2860
2861 if omci.MeResults[index].Result > me.DeviceBusy {
2862 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2863 index, omci.MeResults[index])
2864 return errors.New(msg)
2865 }
2866 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2867 }
2868 }
2869 return nil
2870}
2871
2872/////////////////////////////////////////////////////////////////////////////
2873//
2874type ActivateSoftwareRequest struct {
2875 MeBasePacket // Note: EntityInstance for software download is two specific values
2876 ActivateFlags byte
2877}
2878
2879func (omci *ActivateSoftwareRequest) String() string {
2880 return fmt.Sprintf("%v, Flags: %#x",
2881 omci.MeBasePacket.String(), omci.ActivateFlags)
2882}
2883
2884// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
2885func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2886 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002887 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002888 if err != nil {
2889 return err
2890 }
2891 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2892 me.ParamData{EntityID: omci.EntityInstance})
2893 if omciErr.StatusCode() != me.Success {
2894 return omciErr.GetError()
2895 }
2896 // ME needs to support End Software Download
2897 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2898 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2899 }
2900 // Software Image Entity Class are always use the Software Image
2901 if omci.EntityClass != me.SoftwareImageClassID {
2902 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2903 }
2904 omci.ActivateFlags = data[4]
2905 if omci.ActivateFlags > 2 {
2906 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2907 omci.ActivateFlags))
2908 }
2909 return nil
2910}
2911
2912func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2913 omci := &ActivateSoftwareRequest{}
2914 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2915 return decodingLayerDecoder(omci, data, p)
2916}
2917
2918// SerializeTo provides serialization of an Activate Software message
2919func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2920 // Basic (common) OMCI Header is 8 octets, 10
2921 err := omci.MeBasePacket.SerializeTo(b)
2922 if err != nil {
2923 return err
2924 }
2925 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2926 me.ParamData{EntityID: omci.EntityInstance})
2927 if omciErr.StatusCode() != me.Success {
2928 return omciErr.GetError()
2929 }
2930 // ME needs to support End Software Download
2931 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2932 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2933 }
2934 // Software Image Entity Class are always use the Software Image
2935 if omci.EntityClass != me.SoftwareImageClassID {
2936 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2937 }
2938 bytes, err := b.AppendBytes(1)
2939 if err != nil {
2940 return err
2941 }
2942 bytes[0] = omci.ActivateFlags
2943 if omci.ActivateFlags > 2 {
2944 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2945 omci.ActivateFlags)
2946 return errors.New(msg)
2947 }
2948 return nil
2949}
2950
2951/////////////////////////////////////////////////////////////////////////////
2952//
2953type ActivateSoftwareResponse struct {
2954 MeBasePacket
2955 Result me.Results
2956}
2957
2958func (omci *ActivateSoftwareResponse) String() string {
2959 return fmt.Sprintf("%v, Result: %d (%v)",
2960 omci.MeBasePacket.String(), omci.Result, omci.Result)
2961}
2962
2963// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
2964func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2965 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00002966 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00002967 if err != nil {
2968 return err
2969 }
2970 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2971 me.ParamData{EntityID: omci.EntityInstance})
2972 if omciErr.StatusCode() != me.Success {
2973 return omciErr.GetError()
2974 }
2975 // ME needs to support End Software Download
2976 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2977 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2978 }
2979 // Software Image Entity Class are always use the Software Image
2980 if omci.EntityClass != me.SoftwareImageClassID {
2981 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2982 }
2983 omci.Result = me.Results(data[4])
2984 if omci.Result > me.Results(6) {
2985 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2986 omci.Result)
2987 return errors.New(msg)
2988 }
2989 return nil
2990}
2991
2992func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2993 omci := &ActivateSoftwareResponse{}
2994 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2995 return decodingLayerDecoder(omci, data, p)
2996}
2997
2998// SerializeTo provides serialization of an Activate Software Response message
2999func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3000 // Basic (common) OMCI Header is 8 octets, 10
3001 err := omci.MeBasePacket.SerializeTo(b)
3002 if err != nil {
3003 return err
3004 }
3005 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3006 me.ParamData{EntityID: omci.EntityInstance})
3007 if omciErr.StatusCode() != me.Success {
3008 return omciErr.GetError()
3009 }
3010 // ME needs to support End Software Download
3011 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
3012 return me.NewProcessingError("managed entity does not support Activate Message-Type")
3013 }
3014 // Software Image Entity Class are always use the Software Image
3015 if omci.EntityClass != me.SoftwareImageClassID {
3016 return me.NewProcessingError("invalid Entity Class for Activate Software response")
3017 }
3018 bytes, err := b.AppendBytes(1)
3019 if err != nil {
3020 return err
3021 }
3022 bytes[0] = byte(omci.Result)
3023 if omci.Result > me.Results(6) {
3024 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
3025 omci.Result)
3026 return errors.New(msg)
3027 }
3028 return nil
3029}
3030
3031/////////////////////////////////////////////////////////////////////////////
3032//
3033type CommitSoftwareRequest struct {
3034 MeBasePacket
3035}
3036
3037func (omci *CommitSoftwareRequest) String() string {
3038 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3039}
3040
3041// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
3042func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3043 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003044 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003045 if err != nil {
3046 return err
3047 }
3048 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3049 me.ParamData{EntityID: omci.EntityInstance})
3050 if omciErr.StatusCode() != me.Success {
3051 return omciErr.GetError()
3052 }
3053 // ME needs to support End Software Download
3054 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3055 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
3056 }
3057 // Software Image Entity Class are always use the Software Image
3058 if omci.EntityClass != me.SoftwareImageClassID {
3059 return me.NewProcessingError("invalid Entity Class for Commit Software request")
3060 }
3061 return nil
3062}
3063
3064func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
3065 omci := &CommitSoftwareRequest{}
3066 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
3067 return decodingLayerDecoder(omci, data, p)
3068}
3069
3070// SerializeTo provides serialization of an Commit Software Request message
3071func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3072 // Basic (common) OMCI Header is 8 octets, 10
3073 err := omci.MeBasePacket.SerializeTo(b)
3074 if err != nil {
3075 return err
3076 }
3077 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3078 me.ParamData{EntityID: omci.EntityInstance})
3079 if omciErr.StatusCode() != me.Success {
3080 return omciErr.GetError()
3081 }
3082 // ME needs to support End Software Download
3083 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3084 return me.NewProcessingError("managed entity does not support Commit Message-Type")
3085 }
3086 // Software Image Entity Class are always use the Software Image
3087 if omci.EntityClass != me.SoftwareImageClassID {
3088 return me.NewProcessingError("invalid Entity Class for Commit Software request")
3089 }
3090 return nil
3091}
3092
3093/////////////////////////////////////////////////////////////////////////////
3094//
3095type CommitSoftwareResponse struct {
3096 MeBasePacket
mpagenkobf67a092021-03-17 09:52:28 +00003097 Result me.Results
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003098}
3099
3100func (omci *CommitSoftwareResponse) String() string {
3101 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3102}
3103
3104// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
3105func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3106 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003107 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003108 if err != nil {
3109 return err
3110 }
3111 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3112 me.ParamData{EntityID: omci.EntityInstance})
3113 if omciErr.StatusCode() != me.Success {
3114 return omciErr.GetError()
3115 }
mpagenkobf67a092021-03-17 09:52:28 +00003116 // ME needs to support Commit Software
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003117 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3118 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
3119 }
3120 // Software Image Entity Class are always use the Software Image
3121 if omci.EntityClass != me.SoftwareImageClassID {
3122 return me.NewProcessingError("invalid Entity Class for Commit Software response")
3123 }
mpagenkobf67a092021-03-17 09:52:28 +00003124 omci.Result = me.Results(data[4])
3125 if omci.Result > me.Results(6) {
3126 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
3127 omci.Result)
3128 return errors.New(msg)
3129 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003130 return nil
3131}
3132
3133func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
3134 omci := &CommitSoftwareResponse{}
3135 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
3136 return decodingLayerDecoder(omci, data, p)
3137}
3138
3139// SerializeTo provides serialization of an Commit Software Response message
3140func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3141 // Basic (common) OMCI Header is 8 octets, 10
3142 err := omci.MeBasePacket.SerializeTo(b)
3143 if err != nil {
3144 return err
3145 }
3146 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3147 me.ParamData{EntityID: omci.EntityInstance})
3148 if omciErr.StatusCode() != me.Success {
3149 return omciErr.GetError()
3150 }
mpagenkobf67a092021-03-17 09:52:28 +00003151 // ME needs to support Commit Software
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003152 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3153 return me.NewProcessingError("managed entity does not support Commit Message-Type")
3154 }
3155 // Software Image Entity Class are always use the Software Image
3156 if omci.EntityClass != me.SoftwareImageClassID {
3157 return me.NewProcessingError("invalid Entity Class for Commit Software response")
3158 }
mpagenkobf67a092021-03-17 09:52:28 +00003159 bytes, err := b.AppendBytes(1)
3160 if err != nil {
3161 return err
3162 }
3163 bytes[0] = byte(omci.Result)
3164 if omci.Result > me.Results(6) {
3165 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
3166 omci.Result)
3167 return errors.New(msg)
3168 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003169 return nil
3170}
3171
3172/////////////////////////////////////////////////////////////////////////////
3173//
3174type SynchronizeTimeRequest struct {
3175 MeBasePacket
3176 Year uint16
3177 Month uint8
3178 Day uint8
3179 Hour uint8
3180 Minute uint8
3181 Second uint8
3182}
3183
3184func (omci *SynchronizeTimeRequest) String() string {
3185 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
3186 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
3187}
3188
3189// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
3190func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3191 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003192 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003193 if err != nil {
3194 return err
3195 }
3196 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3197 me.ParamData{EntityID: omci.EntityInstance})
3198 if omciErr.StatusCode() != me.Success {
3199 return omciErr.GetError()
3200 }
3201 // ME needs to support Synchronize Time
3202 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3203 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3204 }
3205 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3206 if omci.EntityClass != me.OnuGClassID {
3207 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
3208 }
3209 if omci.EntityInstance != 0 {
3210 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
3211 }
3212 omci.Year = binary.BigEndian.Uint16(data[4:6])
3213 omci.Month = data[6]
3214 omci.Day = data[7]
3215 omci.Hour = data[8]
3216 omci.Minute = data[9]
3217 omci.Second = data[10]
3218 return nil
3219}
3220
3221func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
3222 omci := &SynchronizeTimeRequest{}
3223 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
3224 return decodingLayerDecoder(omci, data, p)
3225}
3226
3227// SerializeTo provides serialization of an Synchronize Time Request message
3228func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3229 // Basic (common) OMCI Header is 8 octets, 10
3230 err := omci.MeBasePacket.SerializeTo(b)
3231 if err != nil {
3232 return err
3233 }
3234 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3235 me.ParamData{EntityID: omci.EntityInstance})
3236 if omciErr.StatusCode() != me.Success {
3237 return omciErr.GetError()
3238 }
3239 // ME needs to support Synchronize Time
3240 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3241 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3242 }
3243 bytes, err := b.AppendBytes(7)
3244 if err != nil {
3245 return err
3246 }
3247 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
3248 bytes[2] = omci.Month
3249 bytes[3] = omci.Day
3250 bytes[4] = omci.Hour
3251 bytes[5] = omci.Minute
3252 bytes[6] = omci.Second
3253 return nil
3254}
3255
3256/////////////////////////////////////////////////////////////////////////////
3257//
3258type SynchronizeTimeResponse struct {
3259 MeBasePacket
3260 Result me.Results
3261 SuccessResults uint8 // Only if 'Result' is 0 -> success
3262}
3263
3264func (omci *SynchronizeTimeResponse) String() string {
3265 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
3266 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
3267}
3268
3269// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
3270func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3271 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003272 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003273 if err != nil {
3274 return err
3275 }
3276 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3277 me.ParamData{EntityID: omci.EntityInstance})
3278 if omciErr.StatusCode() != me.Success {
3279 return omciErr.GetError()
3280 }
3281 // ME needs to support Synchronize Time
3282 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3283 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3284 }
3285 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3286 if omci.EntityClass != me.OnuGClassID {
3287 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3288 }
3289 if omci.EntityInstance != 0 {
3290 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3291 }
3292 omci.Result = me.Results(data[4])
3293 if omci.Result > me.DeviceBusy {
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003294 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003295 return errors.New(msg)
3296 }
3297 omci.SuccessResults = data[5]
3298 return nil
3299}
3300
3301func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
3302 omci := &SynchronizeTimeResponse{}
3303 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
3304 return decodingLayerDecoder(omci, data, p)
3305}
3306
3307// SerializeTo provides serialization of an Synchronize Time Response message
3308func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3309 // Basic (common) OMCI Header is 8 octets, 10
3310 err := omci.MeBasePacket.SerializeTo(b)
3311 if err != nil {
3312 return err
3313 }
3314 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3315 me.ParamData{EntityID: omci.EntityInstance})
3316 if omciErr.StatusCode() != me.Success {
3317 return omciErr.GetError()
3318 }
3319 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
3320 if omci.EntityClass != me.OnuGClassID {
3321 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3322 }
3323 if omci.EntityInstance != 0 {
3324 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3325 }
3326 // ME needs to support Synchronize Time
3327 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3328 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3329 }
3330 numBytes := 2
3331 if omci.Result != me.Success {
3332 numBytes = 1
3333 }
3334 bytes, err := b.AppendBytes(numBytes)
3335 if err != nil {
3336 return err
3337 }
3338 bytes[0] = uint8(omci.Result)
3339 if omci.Result == me.Success {
3340 bytes[1] = omci.SuccessResults
3341 }
3342 return nil
3343}
3344
3345/////////////////////////////////////////////////////////////////////////////
3346//
3347type RebootRequest struct {
3348 MeBasePacket
3349 RebootCondition byte
3350}
3351
3352func (omci *RebootRequest) String() string {
3353 return fmt.Sprintf("%v, Reboot Condition: %v",
3354 omci.MeBasePacket.String(), omci.RebootCondition)
3355}
3356
3357// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
3358func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3359 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003360 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003361 if err != nil {
3362 return err
3363 }
3364 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3365 me.ParamData{EntityID: omci.EntityInstance})
3366 if omciErr.StatusCode() != me.Success {
3367 return omciErr.GetError()
3368 }
3369 // ME needs to support Reboot
3370 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3371 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3372 }
3373 omci.RebootCondition = data[4]
3374 if omci.RebootCondition > 3 {
3375 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
3376 return errors.New(msg)
3377 }
3378 return nil
3379}
3380
3381func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
3382 omci := &RebootRequest{}
3383 omci.MsgLayerType = LayerTypeRebootRequest
3384 return decodingLayerDecoder(omci, data, p)
3385}
3386
3387// SerializeTo provides serialization of an Reboot Request message
3388func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3389 // Basic (common) OMCI Header is 8 octets, 10
3390 err := omci.MeBasePacket.SerializeTo(b)
3391 if err != nil {
3392 return err
3393 }
3394 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3395 me.ParamData{EntityID: omci.EntityInstance})
3396 if omciErr.StatusCode() != me.Success {
3397 return omciErr.GetError()
3398 }
3399 // ME needs to support Reboot
3400 if !me.SupportsMsgType(entity, me.Reboot) {
3401 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3402 }
3403 bytes, err := b.AppendBytes(1)
3404 if err != nil {
3405 return err
3406 }
3407 if omci.RebootCondition > 3 {
3408 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
3409 omci.RebootCondition))
3410 }
3411 bytes[0] = omci.RebootCondition
3412 return nil
3413}
3414
3415/////////////////////////////////////////////////////////////////////////////
3416//
3417type RebootResponse struct {
3418 MeBasePacket
3419 Result me.Results
3420}
3421
3422// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3423func (omci *RebootResponse) String() string {
3424 return fmt.Sprintf("%v, Result: %d (%v)",
3425 omci.MeBasePacket.String(), omci.Result, omci.Result)
3426}
3427
3428// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3429func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3430 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003431 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003432 if err != nil {
3433 return err
3434 }
3435 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3436 me.ParamData{EntityID: omci.EntityInstance})
3437 if omciErr.StatusCode() != me.Success {
3438 return omciErr.GetError()
3439 }
3440 // ME needs to support Reboot
3441 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3442 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3443 }
3444 if omci.Result > 6 {
3445 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3446 return errors.New(msg)
3447 }
3448 omci.Result = me.Results(data[4])
3449 return nil
3450}
3451
3452func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3453 omci := &RebootResponse{}
3454 omci.MsgLayerType = LayerTypeRebootResponse
3455 return decodingLayerDecoder(omci, data, p)
3456}
3457
3458// SerializeTo provides serialization of an Reboot Response message
3459func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3460 // Basic (common) OMCI Header is 8 octets, 10
3461 err := omci.MeBasePacket.SerializeTo(b)
3462 if err != nil {
3463 return err
3464 }
3465 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3466 me.ParamData{EntityID: omci.EntityInstance})
3467 if omciErr.StatusCode() != me.Success {
3468 return omciErr.GetError()
3469 }
3470 // ME needs to support Reboot
3471 if !me.SupportsMsgType(entity, me.Reboot) {
3472 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3473 }
3474 bytes, err := b.AppendBytes(1)
3475 if err != nil {
3476 return err
3477 }
3478 if omci.Result > 6 {
3479 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3480 return errors.New(msg)
3481 }
3482 bytes[0] = byte(omci.Result)
3483 return nil
3484}
3485
3486/////////////////////////////////////////////////////////////////////////////
3487//
3488type GetNextRequest struct {
3489 MeBasePacket
3490 AttributeMask uint16
3491 SequenceNumber uint16
3492}
3493
3494func (omci *GetNextRequest) String() string {
3495 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3496 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3497}
3498
3499// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
3500func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3501 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003502 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003503 if err != nil {
3504 return err
3505 }
3506 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3507 me.ParamData{EntityID: omci.EntityInstance})
3508 if omciErr.StatusCode() != me.Success {
3509 return omciErr.GetError()
3510 }
3511 // ME needs to support GetNext
3512 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3513 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3514 }
3515 // Note: G.988 specifies that an error code of (3) should result if more
3516 // than one attribute is requested
3517 // TODO: Return error. Have flag to optionally allow it to be encoded
3518 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3519 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3520 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3521 return nil
3522}
3523
3524func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3525 omci := &GetNextRequest{}
3526 omci.MsgLayerType = LayerTypeGetNextRequest
3527 return decodingLayerDecoder(omci, data, p)
3528}
3529
3530// SerializeTo provides serialization of an Get Next Message Type Request
3531func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3532 // Basic (common) OMCI Header is 8 octets, 10
3533 err := omci.MeBasePacket.SerializeTo(b)
3534 if err != nil {
3535 return err
3536 }
3537 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3538 me.ParamData{EntityID: omci.EntityInstance})
3539 if omciErr.StatusCode() != me.Success {
3540 return omciErr.GetError()
3541 }
3542 // ME needs to support GetNext
3543 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3544 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3545 }
3546 bytes, err := b.AppendBytes(4)
3547 if err != nil {
3548 return err
3549 }
3550 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3551 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3552 return nil
3553}
3554
3555/////////////////////////////////////////////////////////////////////////////
3556//
3557type GetNextResponse struct {
3558 MeBasePacket
3559 Result me.Results
3560 AttributeMask uint16
3561 Attributes me.AttributeValueMap
3562}
3563
3564// SerializeTo provides serialization of an Get Next Message Type Response
3565func (omci *GetNextResponse) String() string {
3566 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3567 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3568}
3569
3570// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
3571func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3572 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00003573 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003574 if err != nil {
3575 return err
3576 }
3577 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3578 me.ParamData{EntityID: omci.EntityInstance})
3579 if omciErr.StatusCode() != me.Success {
3580 return omciErr.GetError()
3581 }
3582 // ME needs to support Set
3583 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3584 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3585 }
3586 omci.Result = me.Results(data[4])
3587 if omci.Result > 6 {
3588 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3589 return errors.New(msg)
3590 }
3591 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3592
3593 // Attribute decode
3594 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3595 if err != nil {
3596 return err
3597 }
3598 // Validate all attributes support read
3599 for attrName := range omci.Attributes {
3600 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3601 if err != nil {
3602 return err
3603 }
3604 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3605 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3606 return me.NewProcessingError(msg)
3607 }
3608 }
3609 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
3610 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3611 return nil
3612 }
3613 panic("All Managed Entities have an EntityID attribute")
3614}
3615
3616func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3617 omci := &GetNextResponse{}
3618 omci.MsgLayerType = LayerTypeGetNextResponse
3619 return decodingLayerDecoder(omci, data, p)
3620}
3621
3622// SerializeTo provides serialization of an Get Next Message Type Response
3623func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3624 // Basic (common) OMCI Header is 8 octets, 10
3625 err := omci.MeBasePacket.SerializeTo(b)
3626 if err != nil {
3627 return err
3628 }
3629 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3630 me.ParamData{EntityID: omci.EntityInstance})
3631 if omciErr.StatusCode() != me.Success {
3632 return omciErr.GetError()
3633 }
3634 // ME needs to support Get
3635 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3636 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3637 }
3638 bytes, err := b.AppendBytes(3)
3639 if err != nil {
3640 return err
3641 }
3642 bytes[0] = byte(omci.Result)
3643 if omci.Result > 6 {
3644 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3645 return errors.New(msg)
3646 }
3647 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3648
3649 // Validate all attributes support read
3650 for attrName := range omci.Attributes {
3651 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3652 if err != nil {
3653 return err
3654 }
3655 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3656 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3657 return me.NewProcessingError(msg)
3658 }
3659 }
3660 // Attribute serialization
3661 switch omci.Result {
3662 default:
3663 break
3664
3665 case me.Success:
3666 // TODO: Only Baseline supported at this time
3667 bytesAvailable := MaxBaselineLength - 11 - 8
3668
3669 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3670 byte(GetNextResponseType), bytesAvailable, false)
3671 if err != nil {
3672 return err
3673 }
3674 }
3675 return nil
3676}
3677
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003678func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3679 // Peek at Managed Entity Type
3680 if len(data) < 8 {
3681 p.SetTruncated()
3682 return errors.New("frame too small")
3683 }
3684 classID := binary.BigEndian.Uint16(data)
3685
3686 // Is it a Managed Entity class we support customized decode of?
3687 switch me.ClassID(classID) {
3688 default:
3689 omci := &TestResultNotification{}
3690 omci.MsgLayerType = LayerTypeTestResult
3691 return decodingLayerDecoder(omci, data, p)
3692
3693 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
3694 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
3695 omci := &OpticalLineSupervisionTestResult{}
3696 omci.MsgLayerType = LayerTypeTestResult
3697 return decodingLayerDecoder(omci, data, p)
3698 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003699}
3700
Himani Chawla43f95ff2021-06-03 00:24:12 +05303701func decodeTestResultExtended(data []byte, p gopacket.PacketBuilder) error {
3702 // Peek at Managed Entity Type
3703 if len(data) < 8 {
3704 p.SetTruncated()
3705 return errors.New("frame too small")
3706 }
3707 classID := binary.BigEndian.Uint16(data)
3708
3709 // Is it a Managed Entity class we support customized decode of?
3710 switch me.ClassID(classID) {
3711 default:
3712 omci := &TestResultNotification{}
3713 omci.MsgLayerType = LayerTypeTestResult
3714 omci.Extended = true
3715 return decodingLayerDecoder(omci, data, p)
3716
3717 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
3718 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
3719 omci := &OpticalLineSupervisionTestResult{}
3720 omci.MsgLayerType = LayerTypeTestResult
3721 omci.Extended = true
3722 return decodingLayerDecoder(omci, data, p)
3723 }
3724}
3725
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003726type TestResultNotification struct {
3727 MeBasePacket
3728 Payload []byte
3729}
3730
3731func (omci *TestResultNotification) TestResults() []byte {
3732 return omci.Payload
3733}
3734
3735func (omci *TestResultNotification) String() string {
3736 return fmt.Sprintf("%v, Payload: %v octets", omci.MeBasePacket.String(), len(omci.Payload))
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003737}
3738
3739// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003740func (omci *TestResultNotification) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003741 // Common ClassID/EntityID decode in msgBase
Himani Chawla43f95ff2021-06-03 00:24:12 +05303742 payloadOffset := 4
3743 if omci.Extended {
3744 payloadOffset = 6
3745 }
3746 err := omci.MeBasePacket.DecodeFromBytes(data, p, payloadOffset)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003747 if err != nil {
3748 return err
3749 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003750
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003751 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3752 me.ParamData{EntityID: omci.EntityInstance})
3753 if omciErr.StatusCode() != me.Success {
3754 return omciErr.GetError()
3755 }
3756
3757 // ME needs to support Test requests
3758 if !me.SupportsMsgType(meDefinition, me.Test) {
3759 return me.NewProcessingError("managed entity does not support Test Message-Type")
3760 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05303761 if omci.Extended {
3762 if len(data) < 6 {
3763 p.SetTruncated()
3764 return errors.New("frame too small")
3765 }
3766 length := binary.BigEndian.Uint16(data[4:])
3767 if len(data) < 6+int(length) {
3768 p.SetTruncated()
3769 return errors.New("frame too small")
3770 }
3771 omci.Payload = make([]byte, length)
3772 copy(omci.Payload, data[6:])
3773 } else {
3774 omci.Payload = make([]byte, MaxTestResultsLength)
3775 copy(omci.Payload, omci.MeBasePacket.Payload)
3776 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003777 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003778}
3779
3780// SerializeTo provides serialization of an Test Result notification message
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003781func (omci *TestResultNotification) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3782 // Basic (common) OMCI Header is 8 octets
3783 err := omci.MeBasePacket.SerializeTo(b)
3784 if err != nil {
3785 return err
3786 }
3787
3788 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3789 me.ParamData{EntityID: omci.EntityInstance})
3790 if omciErr.StatusCode() != me.Success {
3791 return omciErr.GetError()
3792 }
3793
3794 // ME needs to support Test requests
3795 if !me.SupportsMsgType(meDefinition, me.Test) {
3796 return me.NewProcessingError("managed entity does not support Test Message-Type")
3797 }
3798 if omci.Payload == nil {
3799 return errors.New("Test Results payload is missing")
3800 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05303801
3802 payloadOffset := 0
3803 maxSize := MaxTestResultsLength
3804
3805 if omci.Extended {
3806 payloadOffset = 2
3807 maxSize = MaxExtendedLength - 10 - 4
3808 }
3809 if len(omci.Payload) > maxSize {
3810 msg := fmt.Sprintf("Invalid Test Results payload size. Received %v bytes, max expected %v",
3811 len(omci.Payload), maxSize)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003812 return errors.New(msg)
3813 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05303814 bytes, err := b.AppendBytes(len(omci.Payload) + payloadOffset)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003815 if err != nil {
3816 return err
3817 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05303818 if omci.Extended {
3819 binary.BigEndian.PutUint16(bytes, uint16(len(omci.Payload)))
3820 }
3821 copy(bytes[payloadOffset:], omci.Payload)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003822 return nil
3823}
3824
3825// OpticalLineSupervisionTestResult provides a Optical Specific test results
3826// message decode for the associated Managed Entities
3827type OpticalLineSupervisionTestResult struct {
3828 MeBasePacket
3829 PowerFeedVoltageType uint8 // Type = 1
3830 PowerFeedVoltage uint16 // value
3831 ReceivedOpticalPowerType uint8 // Type = 3
3832 ReceivedOpticalPower uint16 // value
3833 MeanOpticalLaunchType uint8 // Type = 5
3834 MeanOpticalLaunch uint16 // value
3835 LaserBiasCurrentType uint8 // Type = 9
3836 LaserBiasCurrent uint16 // value
3837 TemperatureType uint8 // Type = 12
3838 Temperature uint16 // value
3839
3840 GeneralPurposeBuffer uint16 // Pointer to General Purpose Buffer ME
3841}
3842
3843func (omci *OpticalLineSupervisionTestResult) String() string {
3844 return fmt.Sprintf("Optical Line Supervision Test Result")
3845}
3846
3847func (omci *OpticalLineSupervisionTestResult) TestResults() []byte {
3848 return omci.MeBasePacket.Payload
3849}
3850
3851// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
3852func (omci *OpticalLineSupervisionTestResult) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3853 // Common ClassID/EntityID decode in msgBase
Himani Chawla43f95ff2021-06-03 00:24:12 +05303854 payloadOffset := 4
3855 if omci.Extended {
3856 payloadOffset = 6
3857 }
3858 err := omci.MeBasePacket.DecodeFromBytes(data, p, payloadOffset+17)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003859 if err != nil {
3860 return err
3861 }
3862
3863 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3864 me.ParamData{EntityID: omci.EntityInstance})
3865 if omciErr.StatusCode() != me.Success {
3866 return omciErr.GetError()
3867 }
3868
3869 // ME needs to support Test requests
3870 if !me.SupportsMsgType(meDefinition, me.Test) {
3871 return me.NewProcessingError("managed entity does not support Test Message-Type")
3872 }
3873 // Note: Unsupported tests will have a type = 0 and the value should be zero
3874 // as well, but that constraint is not enforced at this time.
3875 // Type = 1
Himani Chawla43f95ff2021-06-03 00:24:12 +05303876 omci.PowerFeedVoltageType = data[payloadOffset]
3877 omci.PowerFeedVoltage = binary.BigEndian.Uint16(data[payloadOffset+1:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003878
3879 // Type = 3
Himani Chawla43f95ff2021-06-03 00:24:12 +05303880 omci.ReceivedOpticalPowerType = data[payloadOffset+3]
3881 omci.ReceivedOpticalPower = binary.BigEndian.Uint16(data[payloadOffset+4:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003882
3883 // Type = 5
Himani Chawla43f95ff2021-06-03 00:24:12 +05303884 omci.MeanOpticalLaunchType = data[payloadOffset+6]
3885 omci.MeanOpticalLaunch = binary.BigEndian.Uint16(data[payloadOffset+7:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003886
3887 // Type = 9
Himani Chawla43f95ff2021-06-03 00:24:12 +05303888 omci.LaserBiasCurrentType = data[payloadOffset+9]
3889 omci.LaserBiasCurrent = binary.BigEndian.Uint16(data[payloadOffset+10:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003890
3891 // Type = 12
Himani Chawla43f95ff2021-06-03 00:24:12 +05303892 omci.TemperatureType = data[payloadOffset+12]
3893 omci.Temperature = binary.BigEndian.Uint16(data[payloadOffset+13:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003894
Himani Chawla43f95ff2021-06-03 00:24:12 +05303895 omci.GeneralPurposeBuffer = binary.BigEndian.Uint16(data[payloadOffset+15:])
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003896 return nil
3897}
3898
3899// SerializeTo provides serialization of an Test Result notification message
3900func (omci *OpticalLineSupervisionTestResult) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003901 // Basic (common) OMCI Header is 8 octets, 10
3902 err := omci.MeBasePacket.SerializeTo(b)
3903 if err != nil {
3904 return err
3905 }
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003906 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3907 me.ParamData{EntityID: omci.EntityInstance})
3908 if omciErr.StatusCode() != me.Success {
3909 return omciErr.GetError()
3910 }
3911
3912 // ME needs to support Test requests
3913 if !me.SupportsMsgType(meDefinition, me.Test) {
3914 return me.NewProcessingError("managed entity does not support Test Message-Type")
3915 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05303916 payloadOffset := 0
3917
3918 if omci.Extended {
3919 payloadOffset = 2
3920 }
3921 bytes, err := b.AppendBytes(payloadOffset + 17)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003922 if err != nil {
3923 return err
3924 }
3925
Himani Chawla43f95ff2021-06-03 00:24:12 +05303926 if omci.Extended {
3927 binary.BigEndian.PutUint16(bytes, 17)
3928 }
3929 bytes[payloadOffset] = omci.PowerFeedVoltageType
3930 binary.BigEndian.PutUint16(bytes[payloadOffset+1:], omci.PowerFeedVoltage)
3931 bytes[payloadOffset+3] = omci.ReceivedOpticalPowerType
3932 binary.BigEndian.PutUint16(bytes[payloadOffset+4:], omci.ReceivedOpticalPower)
3933 bytes[payloadOffset+6] = omci.MeanOpticalLaunchType
3934 binary.BigEndian.PutUint16(bytes[payloadOffset+7:], omci.MeanOpticalLaunch)
3935 bytes[payloadOffset+9] = omci.LaserBiasCurrentType
3936 binary.BigEndian.PutUint16(bytes[payloadOffset+10:], omci.LaserBiasCurrent)
3937 bytes[payloadOffset+12] = omci.TemperatureType
3938 binary.BigEndian.PutUint16(bytes[payloadOffset+13:], omci.Temperature)
3939 binary.BigEndian.PutUint16(bytes[payloadOffset+15:], omci.GeneralPurposeBuffer)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07003940 return nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003941}
3942
3943/////////////////////////////////////////////////////////////////////////////
3944//
3945type GetCurrentDataRequest struct {
3946 MeBasePacket
3947 AttributeMask uint16
3948}
3949
3950func (omci *GetCurrentDataRequest) String() string {
3951 return fmt.Sprintf("%v, Attribute Mask: %#x",
3952 omci.MeBasePacket.String(), omci.AttributeMask)
3953}
3954
3955// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
3956func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3957 // Common ClassID/EntityID decode in msgBase
Himani Chawla43f95ff2021-06-03 00:24:12 +05303958 var offset int
3959 if omci.Extended {
3960 offset = 6
3961 } else {
3962 offset = 4
3963 }
3964 hdrSize := offset + 2
3965 if len(data) < hdrSize {
3966 p.SetTruncated()
3967 return errors.New("frame too small")
3968 }
3969 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003970 if err != nil {
3971 return err
3972 }
3973 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3974 me.ParamData{EntityID: omci.EntityInstance})
3975 if omciErr.StatusCode() != me.Success {
3976 return omciErr.GetError()
3977 }
3978 // ME needs to support GetNext
3979 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3980 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3981 }
3982 // Note: G.988 specifies that an error code of (3) should result if more
3983 // than one attribute is requested
Himani Chawla43f95ff2021-06-03 00:24:12 +05303984 omci.AttributeMask = binary.BigEndian.Uint16(data[offset:])
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003985 return nil
3986}
3987
3988func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3989 omci := &GetCurrentDataRequest{}
3990 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3991 return decodingLayerDecoder(omci, data, p)
3992}
3993
3994// SerializeTo provides serialization of an Get Current Data Request message
3995func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3996 // Basic (common) OMCI Header is 8 octets, 10
3997 err := omci.MeBasePacket.SerializeTo(b)
3998 if err != nil {
3999 return err
4000 }
4001 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
4002 me.ParamData{EntityID: omci.EntityInstance})
4003 if omciErr.StatusCode() != me.Success {
4004 return omciErr.GetError()
4005 }
4006 // ME needs to support GetNext
4007 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
4008 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
4009 }
4010 bytes, err := b.AppendBytes(2)
4011 if err != nil {
4012 return err
4013 }
4014 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
4015 return nil
4016}
4017
4018/////////////////////////////////////////////////////////////////////////////
4019//
4020type GetCurrentDataResponse struct {
4021 MeBasePacket
Himani Chawla43f95ff2021-06-03 00:24:12 +05304022 Result me.Results
4023 AttributeMask uint16
4024 UnsupportedAttributeMask uint16
4025 FailedAttributeMask uint16
4026 Attributes me.AttributeValueMap
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004027}
4028
4029func (omci *GetCurrentDataResponse) String() string {
4030 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
4031 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
4032}
4033
4034// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
4035func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4036 // Common ClassID/EntityID decode in msgBase
Himani Chawla43f95ff2021-06-03 00:24:12 +05304037 var offset, length int
4038 if omci.Extended {
4039 offset = 6
4040 length = 7
4041 } else {
4042 offset = 4
4043 length = 3
4044 }
4045 hdrSize := offset + length
4046 if len(data) < hdrSize {
4047 p.SetTruncated()
4048 return errors.New("frame too small")
4049 }
4050 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004051 if err != nil {
4052 return err
4053 }
4054 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
4055 me.ParamData{EntityID: omci.EntityInstance})
4056 if omciErr.StatusCode() != me.Success {
4057 return omciErr.GetError()
4058 }
4059 // ME needs to support Set
4060 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
4061 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
4062 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05304063 omci.Result = me.Results(data[offset])
4064 omci.AttributeMask = binary.BigEndian.Uint16(data[offset+1:])
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304065 switch omci.Result {
4066 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
4067 return nil // Done (do not try and decode attributes)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304068 case me.AttributeFailure:
4069 if omci.Extended {
4070 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[offset+3:])
4071 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[offset+5:])
4072 } else {
4073 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:])
4074 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:])
4075 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304076 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05304077 // Attribute decode. Note that the ITU-T G.988 specification states that the
4078 // Unsupported and Failed attribute masks are always present
4079 // but only valid if the status code== 9. However some XGS
4080 // ONUs (T&W and Alpha, perhaps more) will use these last 4
4081 // octets for data if the status code == 0 in a baseline GET
4082 // Response. So this behaviour is anticipated here as well
4083 // and will be allowed in favor of greater interoperability.
4084 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[hdrSize:], p, byte(GetCurrentDataResponseType))
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004085 if err != nil {
4086 return err
4087 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05304088 // Validate all attributes support read
4089 for attrName := range omci.Attributes {
4090 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
4091 if err != nil {
4092 return err
4093 }
4094 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
4095 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
4096 return me.NewProcessingError(msg)
4097 }
4098 }
4099 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
4100 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
4101 return nil
4102 }
4103 return errors.New("All Managed Entities have an EntityID attribute")
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004104}
4105
4106func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
4107 omci := &GetCurrentDataResponse{}
4108 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
4109 return decodingLayerDecoder(omci, data, p)
4110}
4111
4112// SerializeTo provides serialization of an Get Current Data Message Type Response
4113func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4114 // Basic (common) OMCI Header is 8 octets, 10
4115 err := omci.MeBasePacket.SerializeTo(b)
4116 if err != nil {
4117 return err
4118 }
4119 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
4120 me.ParamData{EntityID: omci.EntityInstance})
4121 if omciErr.StatusCode() != me.Success {
4122 return omciErr.GetError()
4123 }
4124 // ME needs to support Get
4125 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
4126 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
4127 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05304128 var resultOffset, hdrSize int
4129
4130 if omci.Extended {
4131 resultOffset = 2
4132 hdrSize = resultOffset + 1 + 2 + 2 + 2 // length + result + masks
4133 } else {
4134 resultOffset = 0
4135 hdrSize = resultOffset + 1 + 2 // length + result + attr-mask
4136 }
4137 bytes, err := b.AppendBytes(hdrSize)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004138 if err != nil {
4139 return err
4140 }
Himani Chawla43f95ff2021-06-03 00:24:12 +05304141 bytes[resultOffset] = byte(omci.Result)
4142 binary.BigEndian.PutUint16(bytes[resultOffset+1:], omci.AttributeMask)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004143
Himani Chawla43f95ff2021-06-03 00:24:12 +05304144 // Validate all attributes support read
4145 for attrName := range omci.Attributes {
4146 var attr *me.AttributeDefinition
4147 attr, err = me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
4148 if err != nil {
4149 return err
4150 }
4151 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
4152 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
4153 return me.NewProcessingError(msg)
4154 }
4155 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004156 // Attribute serialization
Himani Chawla43f95ff2021-06-03 00:24:12 +05304157 switch omci.Result {
4158 default:
4159 if omci.Extended {
4160 binary.BigEndian.PutUint16(bytes, 7) // Length
4161 binary.BigEndian.PutUint32(bytes[resultOffset+3:], 0)
4162 }
4163 break
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004164
Himani Chawla43f95ff2021-06-03 00:24:12 +05304165 case me.Success, me.AttributeFailure:
4166 var available int
4167 if omci.Extended {
4168 available = MaxExtendedLength - 10 - 3 - 4 - 4 // Less: header, result+mask, optional-masks mic
4169 } else {
4170 available = MaxBaselineLength - 8 - 3 - 4 - 8 // hdr, result+mask, optional-masks, trailer
4171 }
4172 // Serialize to temporary buffer if we may need to reset values due to
4173 // recoverable truncation errors
4174 attributeBuffer := gopacket.NewSerializeBuffer()
4175 var failedMask uint16
4176 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask,
4177 attributeBuffer, byte(GetCurrentDataResponseType), available, opts.FixLengths)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004178
Himani Chawla43f95ff2021-06-03 00:24:12 +05304179 if err != nil {
4180 return err
4181 }
4182 if failedMask != 0 {
4183 // Not all attributes would fit
4184 omci.FailedAttributeMask |= failedMask
4185 omci.AttributeMask &= ^failedMask
4186 omci.Result = me.AttributeFailure
4187
4188 // Adjust already recorded values
4189 bytes[resultOffset] = byte(omci.Result)
4190 binary.BigEndian.PutUint16(bytes[resultOffset+1:], omci.AttributeMask)
4191 }
4192 if omci.Extended {
4193 // Set length and any failure masks
4194 binary.BigEndian.PutUint16(bytes, uint16(len(attributeBuffer.Bytes())+7))
4195
4196 if omci.Result == me.AttributeFailure {
4197 binary.BigEndian.PutUint16(bytes[resultOffset+3:], omci.UnsupportedAttributeMask)
4198 binary.BigEndian.PutUint16(bytes[resultOffset+5:], omci.FailedAttributeMask)
4199 } else {
4200 binary.BigEndian.PutUint32(bytes[resultOffset+3:], 0)
4201 }
4202 }
4203 // Copy over attributes to the original serialization buffer
4204 var newSpace []byte
4205
4206 newSpace, err = b.AppendBytes(len(attributeBuffer.Bytes()))
4207 if err != nil {
4208 return err
4209 }
4210 copy(newSpace, attributeBuffer.Bytes())
4211
4212 if !omci.Extended {
4213 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
4214 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
4215
4216 var remainingBytes []byte
4217 remainingBytes, err = b.AppendBytes(bytesLeft + 4)
4218
4219 if err != nil {
4220 return me.NewMessageTruncatedError(err.Error())
4221 }
4222 copy(remainingBytes, lotsOfZeros[:])
4223
4224 if omci.Result == me.AttributeFailure {
4225 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
4226 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
4227 }
4228 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004229 }
4230 return nil
4231}
4232
4233/////////////////////////////////////////////////////////////////////////////
4234//
4235type SetTableRequest struct {
4236 MeBasePacket
4237 // TODO: Fix me when extended messages supported)
4238}
4239
4240func (omci *SetTableRequest) String() string {
4241 return fmt.Sprintf("%v", omci.MeBasePacket.String())
4242}
4243
4244// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
4245func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4246 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00004247 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+2)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004248 if err != nil {
4249 return err
4250 }
4251 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
4252}
4253
4254func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
4255 omci := &SetTableRequest{}
4256 omci.MsgLayerType = LayerTypeSetTableRequest
4257 return decodingLayerDecoder(omci, data, p)
4258}
4259
4260// SerializeTo provides serialization of an Set Table Message Type Request
4261func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4262 // Basic (common) OMCI Header is 8 octets, 10
4263 err := omci.MeBasePacket.SerializeTo(b)
4264 if err != nil {
4265 return err
4266 }
4267 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
4268}
4269
4270/////////////////////////////////////////////////////////////////////////////
4271//
4272type SetTableResponse struct {
4273 MeBasePacket
4274 // TODO: Fix me when extended messages supported)
4275}
4276
4277func (omci *SetTableResponse) String() string {
4278 return fmt.Sprintf("%v", omci.MeBasePacket.String())
4279}
4280
4281// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
4282func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4283 // Common ClassID/EntityID decode in msgBase
mpagenkobf67a092021-03-17 09:52:28 +00004284 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+1)
Holger Hildebrandtfa074992020-03-27 15:42:06 +00004285 if err != nil {
4286 return err
4287 }
4288 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
4289}
4290
4291func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
4292 omci := &SetTableResponse{}
4293 omci.MsgLayerType = LayerTypeSetTableResponse
4294 return decodingLayerDecoder(omci, data, p)
4295}
4296
4297// SerializeTo provides serialization of an Set Table Message Type Response
4298func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4299 // Basic (common) OMCI Header is 8 octets, 10
4300 err := omci.MeBasePacket.SerializeTo(b)
4301 if err != nil {
4302 return err
4303 }
4304 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
4305}
4306
4307/////////////////////////////////////////////////////////////////////////////
4308//
4309type UnsupportedMessageTypeResponse struct {
4310 MeBasePacket
4311 Result me.Results
4312}
4313
4314// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
4315func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4316 return errors.New("you should never really decode this")
4317}
4318
4319// SerializeTo provides serialization of an Unsupported Message Type Response
4320func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4321 // Basic (common) OMCI Header is 8 octets, 10
4322 err := omci.MeBasePacket.SerializeTo(b)
4323 if err != nil {
4324 return err
4325 }
4326 bytes, err := b.AppendBytes(1)
4327 if err != nil {
4328 return err
4329 }
4330 bytes[0] = byte(omci.Result)
4331 return nil
4332}