blob: 8cca4030c6ff3a964e9285ababfde164ae512f70 [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 (
32 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(byte(me.DownloadSection) | me.AR)
55 DownloadSectionResponseType = MessageType(byte(me.DownloadSection) | me.AK)
56 EndSoftwareDownloadRequestType = MessageType(byte(me.EndSoftwareDownload) | me.AR)
57 EndSoftwareDownloadResponseType = MessageType(byte(me.EndSoftwareDownload) | me.AK)
58 ActivateSoftwareRequestType = MessageType(byte(me.ActivateSoftware) | me.AR)
59 ActivateSoftwareResponseType = MessageType(byte(me.ActivateSoftware) | me.AK)
60 CommitSoftwareRequestType = MessageType(byte(me.CommitSoftware) | me.AR)
61 CommitSoftwareResponseType = MessageType(byte(me.CommitSoftware) | me.AK)
62 SynchronizeTimeRequestType = MessageType(byte(me.SynchronizeTime) | me.AR)
63 SynchronizeTimeResponseType = MessageType(byte(me.SynchronizeTime) | me.AK)
64 RebootRequestType = MessageType(byte(me.Reboot) | me.AR)
65 RebootResponseType = MessageType(byte(me.Reboot) | me.AK)
66 GetNextRequestType = MessageType(byte(me.GetNext) | me.AR)
67 GetNextResponseType = MessageType(byte(me.GetNext) | me.AK)
68 GetCurrentDataRequestType = MessageType(byte(me.GetCurrentData) | me.AR)
69 GetCurrentDataResponseType = MessageType(byte(me.GetCurrentData) | me.AK)
70 SetTableRequestType = MessageType(byte(me.SetTable) | me.AR)
71 SetTableResponseType = MessageType(byte(me.SetTable) | me.AK)
72 // Autonomous ONU messages
73 AlarmNotificationType = MessageType(byte(me.AlarmNotification))
74 AttributeValueChangeType = MessageType(byte(me.AttributeValueChange))
75 TestResultType = MessageType(byte(me.TestResult))
76)
77
78func (mt MessageType) String() string {
79 switch mt {
80 default:
81 return "Unknown"
82
83 case CreateRequestType:
84 return "Create Request"
85 case CreateResponseType:
86 return "Create Response"
87 case DeleteRequestType:
88 return "Delete Request"
89 case DeleteResponseType:
90 return "Delete Response"
91 case SetRequestType:
92 return "Set Request"
93 case SetResponseType:
94 return "Set Response"
95 case GetRequestType:
96 return "Get Request"
97 case GetResponseType:
98 return "Get Response"
99 case GetAllAlarmsRequestType:
100 return "Get All Alarms Request"
101 case GetAllAlarmsResponseType:
102 return "Get All Alarms Response"
103 case GetAllAlarmsNextRequestType:
104 return "Get All Alarms Next Request"
105 case GetAllAlarmsNextResponseType:
106 return "Get All Alarms Next Response"
107 case MibUploadRequestType:
108 return "MIB Upload Request"
109 case MibUploadResponseType:
110 return "MIB Upload Response"
111 case MibUploadNextRequestType:
112 return "MIB Upload Next Request"
113 case MibUploadNextResponseType:
114 return "MIB Upload Next Response"
115 case MibResetRequestType:
116 return "MIB Reset Request"
117 case MibResetResponseType:
118 return "MIB Reset Response"
119 case TestRequestType:
120 return "Test Request"
121 case TestResponseType:
122 return "Test Response"
123 case StartSoftwareDownloadRequestType:
124 return "Start Software Download Request"
125 case StartSoftwareDownloadResponseType:
126 return "Start Software Download Response"
127 case DownloadSectionRequestType:
128 return "Download Section Request"
129 case DownloadSectionResponseType:
130 return "Download Section Response"
131 case EndSoftwareDownloadRequestType:
132 return "End Software Download Request"
133 case EndSoftwareDownloadResponseType:
134 return "End Software Download Response"
135 case ActivateSoftwareRequestType:
136 return "Activate Software Request"
137 case ActivateSoftwareResponseType:
138 return "Activate Software Response"
139 case CommitSoftwareRequestType:
140 return "Commit Software Request"
141 case CommitSoftwareResponseType:
142 return "Commit Software Response"
143 case SynchronizeTimeRequestType:
144 return "Synchronize Time Request"
145 case SynchronizeTimeResponseType:
146 return "Synchronize Time Response"
147 case RebootRequestType:
148 return "Reboot Request"
149 case RebootResponseType:
150 return "Reboot Response"
151 case GetNextRequestType:
152 return "Get Next Request"
153 case GetNextResponseType:
154 return "Get Next Response"
155 case GetCurrentDataRequestType:
156 return "Get Current Data Request"
157 case GetCurrentDataResponseType:
158 return "Get Current Data Response"
159 case SetTableRequestType:
160 return "Set Table Request"
161 case SetTableResponseType:
162 return "Set Table Response"
163 case AlarmNotificationType:
164 return "Alarm Notification"
165 case AttributeValueChangeType:
166 return "Attribute Value Change"
167 case TestResultType:
168 return "Test Result"
169 }
170}
171
172/////////////////////////////////////////////////////////////////////////////
173// CreateRequest
174type CreateRequest struct {
175 MeBasePacket
176 Attributes me.AttributeValueMap
177}
178
179func (omci *CreateRequest) String() string {
180 return fmt.Sprintf("%v, attributes: %v", omci.MeBasePacket.String(), omci.Attributes)
181}
182
183// DecodeFromBytes decodes the given bytes of a Create Request into this layer
184func (omci *CreateRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
185 // Common ClassID/EntityID decode in msgBase
186 err := omci.MeBasePacket.DecodeFromBytes(data, p)
187 if err != nil {
188 return err
189 }
190 // Create attribute mask for all set-by-create entries
191 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
192 me.ParamData{EntityID: omci.EntityInstance})
193 if omciErr.StatusCode() != me.Success {
194 return omciErr.GetError()
195 }
196 // ME needs to support Create
197 if !me.SupportsMsgType(meDefinition, me.Create) {
198 return me.NewProcessingError("managed entity does not support Create Message-Type")
199 }
200 var sbcMask uint16
201 for index, attr := range meDefinition.GetAttributeDefinitions() {
202 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
203 if index == 0 {
204 continue // Skip Entity ID
205 }
206 sbcMask |= attr.Mask
207 }
208 }
209 // Attribute decode
210 omci.Attributes, err = meDefinition.DecodeAttributes(sbcMask, data[4:], p, byte(CreateRequestType))
211 if err != nil {
212 return err
213 }
214 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
215 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
216 return nil
217 }
218 panic("All Managed Entities have an EntityID attribute")
219}
220
221func decodeCreateRequest(data []byte, p gopacket.PacketBuilder) error {
222 omci := &CreateRequest{}
223 omci.MsgLayerType = LayerTypeCreateRequest
224 return decodingLayerDecoder(omci, data, p)
225}
226
227// SerializeTo provides serialization of an Create Request Message
228func (omci *CreateRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
229 // Basic (common) OMCI Header is 8 octets, 10
230 err := omci.MeBasePacket.SerializeTo(b)
231 if err != nil {
232 return err
233 }
234 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
235 me.ParamData{EntityID: omci.EntityInstance})
236 if omciErr.StatusCode() != me.Success {
237 return omciErr.GetError()
238 }
239 // Create attribute mask of SetByCreate attributes that should be present in the provided
240 // attributes.
241 var sbcMask uint16
242 for index, attr := range meDefinition.GetAttributeDefinitions() {
243 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
244 if index == 0 {
245 continue // Skip Entity ID
246 }
247 sbcMask |= attr.Mask
248 }
249 }
250 // Attribute serialization
251 // TODO: Only Baseline supported at this time
252 bytesAvailable := MaxBaselineLength - 8 - 8
253 err, _ = meDefinition.SerializeAttributes(omci.Attributes, sbcMask, b, byte(CreateRequestType), bytesAvailable, false)
254 return err
255}
256
257/////////////////////////////////////////////////////////////////////////////
258// CreateResponse
259type CreateResponse struct {
260 MeBasePacket
261 Result me.Results
262 AttributeExecutionMask uint16 // Used when Result == ParameterError
263}
264
265func (omci *CreateResponse) String() string {
266 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x",
267 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeExecutionMask)
268}
269
270// DecodeFromBytes decodes the given bytes of a Create Response into this layer
271func (omci *CreateResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
272 // Common ClassID/EntityID decode in msgBase
273 err := omci.MeBasePacket.DecodeFromBytes(data, p)
274 if err != nil {
275 return err
276 }
277 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
278 me.ParamData{EntityID: omci.EntityInstance})
279 if omciErr.StatusCode() != me.Success {
280 return omciErr.GetError()
281 }
282 // ME needs to support Create
283 if !me.SupportsMsgType(entity, me.Create) {
284 return me.NewProcessingError("managed entity does not support the Create Message-Type")
285 }
286 omci.Result = me.Results(data[4])
287 if omci.Result == me.ParameterError {
288 omci.AttributeExecutionMask = binary.BigEndian.Uint16(data[5:])
289 // TODO: validation that attributes set in mask are SetByCreate would be good here
290 }
291 return nil
292}
293
294func decodeCreateResponse(data []byte, p gopacket.PacketBuilder) error {
295 omci := &CreateResponse{}
296 omci.MsgLayerType = LayerTypeCreateResponse
297 return decodingLayerDecoder(omci, data, p)
298}
299
300// SerializeTo provides serialization of an Create Response message
301func (omci *CreateResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
302 // Basic (common) OMCI Header is 8 octets, 10
303 err := omci.MeBasePacket.SerializeTo(b)
304 if err != nil {
305 return err
306 }
307 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
308 me.ParamData{EntityID: omci.EntityInstance})
309 if omciErr.StatusCode() != me.Success {
310 return omciErr.GetError()
311 }
312 // ME needs to support Create
313 if !me.SupportsMsgType(entity, me.Create) {
314 return me.NewProcessingError("managed entity does not support the Create Message-Type")
315 }
316 bytes, err := b.AppendBytes(3)
317 if err != nil {
318 return err
319 }
320 bytes[0] = byte(omci.Result)
321 if omci.Result == me.ParameterError {
322 // TODO: validation that attributes set in mask are SetByCreate would be good here
323 binary.BigEndian.PutUint16(bytes[1:], omci.AttributeExecutionMask)
324 } else {
325 binary.BigEndian.PutUint16(bytes[1:], 0)
326 }
327 return nil
328}
329
330/////////////////////////////////////////////////////////////////////////////
331// DeleteRequest
332type DeleteRequest struct {
333 MeBasePacket
334}
335
336func (omci *DeleteRequest) String() string {
337 return fmt.Sprintf("%v", omci.MeBasePacket.String())
338}
339
340// DecodeFromBytes decodes the given bytes of a Delete Request into this layer
341func (omci *DeleteRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
342 // Common ClassID/EntityID decode in msgBase
343 err := omci.MeBasePacket.DecodeFromBytes(data, p)
344 if err != nil {
345 return err
346 }
347 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
348 me.ParamData{EntityID: omci.EntityInstance})
349 if omciErr.StatusCode() != me.Success {
350 return omciErr.GetError()
351 }
352 // ME needs to support Delete
353 if !me.SupportsMsgType(entity, me.Delete) {
354 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
355 }
356 return nil
357}
358
359func decodeDeleteRequest(data []byte, p gopacket.PacketBuilder) error {
360 omci := &DeleteRequest{}
361 omci.MsgLayerType = LayerTypeDeleteRequest
362 return decodingLayerDecoder(omci, data, p)
363}
364
365// SerializeTo provides serialization of an Delete Request message
366func (omci *DeleteRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
367 // Basic (common) OMCI Header is 8 octets, 10
368 err := omci.MeBasePacket.SerializeTo(b)
369 if err != nil {
370 return err
371 }
372 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
373 me.ParamData{EntityID: omci.EntityInstance})
374 if omciErr.StatusCode() != me.Success {
375 return omciErr.GetError()
376 }
377 // ME needs to support Delete
378 if !me.SupportsMsgType(entity, me.Delete) {
379 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
380 }
381 return nil
382}
383
384/////////////////////////////////////////////////////////////////////////////
385// DeleteResponse
386type DeleteResponse struct {
387 MeBasePacket
388 Result me.Results
389}
390
391func (omci *DeleteResponse) String() string {
392 return fmt.Sprintf("%v, Result: %d (%v)",
393 omci.MeBasePacket.String(), omci.Result, omci.Result)
394}
395
396// DecodeFromBytes decodes the given bytes of a Delete Response into this layer
397func (omci *DeleteResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
398 // Common ClassID/EntityID decode in msgBase
399 err := omci.MeBasePacket.DecodeFromBytes(data, p)
400 if err != nil {
401 return err
402 }
403 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
404 me.ParamData{EntityID: omci.EntityInstance})
405 if omciErr.StatusCode() != me.Success {
406 return omciErr.GetError()
407 }
408 // ME needs to support Delete
409 if !me.SupportsMsgType(entity, me.Delete) {
410 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
411 }
412 omci.Result = me.Results(data[4])
413 return nil
414}
415
416func decodeDeleteResponse(data []byte, p gopacket.PacketBuilder) error {
417 omci := &DeleteResponse{}
418 omci.MsgLayerType = LayerTypeDeleteResponse
419 return decodingLayerDecoder(omci, data, p)
420}
421
422// SerializeTo provides serialization of an Delete Response message
423func (omci *DeleteResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
424 // Basic (common) OMCI Header is 8 octets, 10
425 err := omci.MeBasePacket.SerializeTo(b)
426 if err != nil {
427 return err
428 }
429 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
430 me.ParamData{EntityID: omci.EntityInstance})
431 if omciErr.StatusCode() != me.Success {
432 return omciErr.GetError()
433 }
434 // ME needs to support Delete
435 if !me.SupportsMsgType(entity, me.Delete) {
436 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
437 }
438 bytes, err := b.AppendBytes(1)
439 if err != nil {
440 return err
441 }
442 bytes[0] = byte(omci.Result)
443 return nil
444}
445
446/////////////////////////////////////////////////////////////////////////////
447// SetRequest
448type SetRequest struct {
449 MeBasePacket
450 AttributeMask uint16
451 Attributes me.AttributeValueMap
452}
453
454func (omci *SetRequest) String() string {
455 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
456 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
457}
458
459// DecodeFromBytes decodes the given bytes of a Set Request into this layer
460func (omci *SetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
461 // Common ClassID/EntityID decode in msgBase
462 err := omci.MeBasePacket.DecodeFromBytes(data, p)
463 if err != nil {
464 return err
465 }
466 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
467 me.ParamData{EntityID: omci.EntityInstance})
468 if omciErr.StatusCode() != me.Success {
469 return omciErr.GetError()
470 }
471 // ME needs to support Set
472 if !me.SupportsMsgType(meDefinition, me.Set) {
473 return me.NewProcessingError("managed entity does not support Set Message-Type")
474 }
475 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
476
477 // Attribute decode
478 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(SetRequestType))
479 if err != nil {
480 return err
481 }
482 // Validate all attributes support write
483 for attrName := range omci.Attributes {
484 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
485 if err != nil {
486 return err
487 }
488 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
489 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
490 return me.NewProcessingError(msg)
491 }
492 }
493 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
494 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
495 return nil
496 }
497 panic("All Managed Entities have an EntityID attribute")
498}
499
500func decodeSetRequest(data []byte, p gopacket.PacketBuilder) error {
501 omci := &SetRequest{}
502 omci.MsgLayerType = LayerTypeSetRequest
503 return decodingLayerDecoder(omci, data, p)
504}
505
506// SerializeTo provides serialization of an Set Request message
507func (omci *SetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
508 // Basic (common) OMCI Header is 8 octets, 10
509 err := omci.MeBasePacket.SerializeTo(b)
510 if err != nil {
511 return err
512 }
513 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
514 me.ParamData{EntityID: omci.EntityInstance})
515 if omciErr.StatusCode() != me.Success {
516 return omciErr.GetError()
517 }
518 // ME needs to support Set
519 if !me.SupportsMsgType(meDefinition, me.Set) {
520 return me.NewProcessingError("managed entity does not support Set Message-Type")
521 }
522 // Validate all attributes support write
523 for attrName := range omci.Attributes {
524 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
525 if err != nil {
526 return err
527 }
528 // Do not test for write of Entity ID in the attribute list
529 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
530 // TODO: Check ITU spec to see if this should be listed as a failed
531 // attribute and not a processing error.
532 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
533 return me.NewProcessingError(msg)
534 }
535 }
536 bytes, err := b.AppendBytes(2)
537 if err != nil {
538 return err
539 }
540 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
541
542 // Attribute serialization
543 // TODO: Only Baseline supported at this time
544 bytesAvailable := MaxBaselineLength - 10 - 8
545
546 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
547 byte(SetRequestType), bytesAvailable, false)
548 return err
549}
550
551/////////////////////////////////////////////////////////////////////////////
552// SetResponse
553type SetResponse struct {
554 MeBasePacket
555 Result me.Results
556 UnsupportedAttributeMask uint16
557 FailedAttributeMask uint16
558}
559
560func (omci *SetResponse) String() string {
561 return fmt.Sprintf("%v, Result: %d (%v), Unsupported Mask: %#x, Failed Mask: %#x",
562 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.UnsupportedAttributeMask,
563 omci.FailedAttributeMask)
564}
565
566// DecodeFromBytes decodes the given bytes of a Set Response into this layer
567func (omci *SetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
568 // Common ClassID/EntityID decode in msgBase
569 err := omci.MeBasePacket.DecodeFromBytes(data, p)
570 if err != nil {
571 return err
572 }
573 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
574 me.ParamData{EntityID: omci.EntityInstance})
575 if omciErr.StatusCode() != me.Success {
576 return omciErr.GetError()
577 }
578 // ME needs to support Set
579 if !me.SupportsMsgType(entity, me.Set) {
580 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
581 }
582 omci.Result = me.Results(data[4])
583
584 if omci.Result == me.AttributeFailure {
585 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[5:7])
586 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[7:9])
587 }
588 return nil
589}
590
591func decodeSetResponse(data []byte, p gopacket.PacketBuilder) error {
592 omci := &SetResponse{}
593 omci.MsgLayerType = LayerTypeSetResponse
594 return decodingLayerDecoder(omci, data, p)
595}
596
597// SerializeTo provides serialization of an Set Response message
598func (omci *SetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
599 // Basic (common) OMCI Header is 8 octets, 10
600 err := omci.MeBasePacket.SerializeTo(b)
601 if err != nil {
602 return err
603 }
604 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
605 me.ParamData{EntityID: omci.EntityInstance})
606 if omciErr.StatusCode() != me.Success {
607 return omciErr.GetError()
608 }
609 // ME needs to support Set
610 if !me.SupportsMsgType(entity, me.Set) {
611 return me.NewProcessingError("managed entity does not support the Set Message-Type")
612 }
613 bytes, err := b.AppendBytes(5)
614 if err != nil {
615 return err
616 }
617 bytes[0] = byte(omci.Result)
618 binary.BigEndian.PutUint16(bytes[1:3], omci.UnsupportedAttributeMask)
619 binary.BigEndian.PutUint16(bytes[3:5], omci.FailedAttributeMask)
620 return nil
621}
622
623/////////////////////////////////////////////////////////////////////////////
624// GetRequest
625type GetRequest struct {
626 MeBasePacket
627 AttributeMask uint16
628}
629
630func (omci *GetRequest) String() string {
631 return fmt.Sprintf("%v, Mask: %#x",
632 omci.MeBasePacket.String(), omci.AttributeMask)
633}
634
635// DecodeFromBytes decodes the given bytes of a Get Request into this layer
636func (omci *GetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
637 // Common ClassID/EntityID decode in msgBase
638 err := omci.MeBasePacket.DecodeFromBytes(data, p)
639 if err != nil {
640 return err
641 }
642 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
643 me.ParamData{EntityID: omci.EntityInstance})
644 if omciErr.StatusCode() != me.Success {
645 return omciErr.GetError()
646 }
647 // ME needs to support Get
648 if !me.SupportsMsgType(meDefinition, me.Get) {
649 return me.NewProcessingError("managed entity does not support Get Message-Type")
650 }
651 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
652 return nil
653}
654
655func decodeGetRequest(data []byte, p gopacket.PacketBuilder) error {
656 omci := &GetRequest{}
657 omci.MsgLayerType = LayerTypeGetRequest
658 return decodingLayerDecoder(omci, data, p)
659}
660
661// SerializeTo provides serialization of an Get Request message
662func (omci *GetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
663 // Basic (common) OMCI Header is 8 octets, 10
664 err := omci.MeBasePacket.SerializeTo(b)
665 if err != nil {
666 return err
667 }
668 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
669 me.ParamData{EntityID: omci.EntityInstance})
670 if omciErr.StatusCode() != me.Success {
671 return omciErr.GetError()
672 }
673 // ME needs to support Set
674 if !me.SupportsMsgType(meDefinition, me.Get) {
675 return me.NewProcessingError("managed entity does not support Get Message-Type")
676 }
677 bytes, err := b.AppendBytes(2)
678 if err != nil {
679 return err
680 }
681 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
682 return nil
683}
684
685/////////////////////////////////////////////////////////////////////////////
686// GetResponse
687type GetResponse struct {
688 MeBasePacket
689 Result me.Results
690 AttributeMask uint16
691 Attributes me.AttributeValueMap
692 UnsupportedAttributeMask uint16
693 FailedAttributeMask uint16
694}
695
696func (omci *GetResponse) String() string {
697 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x, Unsupported: %#x, Failed: %#x, attributes: %v",
698 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask,
699 omci.UnsupportedAttributeMask, omci.FailedAttributeMask, omci.Attributes)
700}
701
702// DecodeFromBytes decodes the given bytes of a Get Response into this layer
703func (omci *GetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
704 // Common ClassID/EntityID decode in msgBase
705 err := omci.MeBasePacket.DecodeFromBytes(data, p)
706 if err != nil {
707 return err
708 }
709 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
710 me.ParamData{EntityID: omci.EntityInstance})
711 if omciErr.StatusCode() != me.Success {
712 return omciErr.GetError()
713 }
714 // ME needs to support Get
715 if !me.SupportsMsgType(meDefinition, me.Get) {
716 return me.NewProcessingError("managed entity does not support Get Message-Type")
717 }
718 omci.Result = me.Results(data[4])
719 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
720
721 // Attribute decode. Note that the ITU-T G.988 specification states that the
722 // Unsupported and Failed attribute masks are always present
723 // but only valid if the status code== 9. However some XGS
724 // ONUs (T&W and Alpha, perhaps more) will use these last 4
725 // octets for data if the status code == 0. So accommodate
726 // this behaviour in favor of greater interoperability.
727 lastOctet := 36
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530728
729 switch omci.Result {
730 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
731 return nil // Done (do not try and decode attributes)
732
733 case me.AttributeFailure:
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000734 lastOctet = 32
735 }
736 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:lastOctet], p, byte(GetResponseType))
737 if err != nil {
738 return err
739 }
740 // If Attribute failed or Unknown, decode optional attribute mask
741 if omci.Result == me.AttributeFailure {
742 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:34])
743 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:36])
744 }
745 // Validate all attributes support read
746 for attrName := range omci.Attributes {
747 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
748 if err != nil {
749 return err
750 }
751 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
752 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
753 return me.NewProcessingError(msg)
754 }
755 }
756 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
757 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
758 return nil
759 }
760 panic("All Managed Entities have an EntityID attribute")
761}
762
763func decodeGetResponse(data []byte, p gopacket.PacketBuilder) error {
764 omci := &GetResponse{}
765 omci.MsgLayerType = LayerTypeGetResponse
766 return decodingLayerDecoder(omci, data, p)
767}
768
769// SerializeTo provides serialization of an Get Response message
770func (omci *GetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
771 // Basic (common) OMCI Header is 8 octets, 10
772 if err := omci.MeBasePacket.SerializeTo(b); err != nil {
773 return err
774 }
775 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
776 me.ParamData{EntityID: omci.EntityInstance})
777
778 if omciErr.StatusCode() != me.Success {
779 return omciErr.GetError()
780 }
781 // ME needs to support Get
782 if !me.SupportsMsgType(meDefinition, me.Get) {
783 return me.NewProcessingError("managed entity does not support the Get Message-Type")
784 }
785 bytes, err := b.AppendBytes(3)
786 if err != nil {
787 return err
788 }
789 bytes[0] = byte(omci.Result)
790 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
791
792 // Validate all attributes support read
793 for attrName := range omci.Attributes {
794 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
795 if err != nil {
796 return err
797 }
798 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
799 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
800 return me.NewProcessingError(msg)
801 }
802 }
803 // Attribute serialization
804 switch omci.Result {
805 default:
806 break
807
808 case me.Success, me.AttributeFailure:
809 // TODO: Baseline only supported at this time)
810 available := MaxBaselineLength - 11 - 4 - 8
811
812 // Serialize to temporary buffer if we may need to reset values due to
813 // recoverable truncation errors
814 origBuffer := b
815 b := gopacket.NewSerializeBuffer()
816
817 err, failedMask := meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b, byte(GetResponseType),
818 available, opts.FixLengths)
819
820 if err == nil && failedMask != 0 && opts.FixLengths {
821 // Not all attributes would fit
822 omci.FailedAttributeMask |= failedMask
823 omci.AttributeMask &= ^failedMask
824 omci.Result = me.AttributeFailure
825
826 // Adjust already recorded values
827 bytes[0] = byte(omci.Result)
828 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
829 } else if err != nil {
830 return err
831 }
832 // Copy over attributes to the original serialization buffer
833 newSpace, err := origBuffer.AppendBytes(len(b.Bytes()))
834 if err != nil {
835 return err
836 }
837 copy(newSpace, b.Bytes())
838 b = origBuffer
839
840 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
841 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
842
843 remainingBytes, err := b.AppendBytes(bytesLeft + 4)
844 if err != nil {
845 return me.NewMessageTruncatedError(err.Error())
846 }
847 copy(remainingBytes, lotsOfZeros[:])
848
849 if omci.Result == me.AttributeFailure {
850 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
851 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
852 }
853 }
854 return nil
855}
856
857/////////////////////////////////////////////////////////////////////////////
858// GetAllAlarms
859type GetAllAlarmsRequest struct {
860 MeBasePacket
861 AlarmRetrievalMode byte
862}
863
864func (omci *GetAllAlarmsRequest) String() string {
865 return fmt.Sprintf("%v, Retrieval Mode: %v",
866 omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
867}
868
869// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
870func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
871 // Common ClassID/EntityID decode in msgBase
872 err := omci.MeBasePacket.DecodeFromBytes(data, p)
873 if err != nil {
874 return err
875 }
876 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
877 me.ParamData{EntityID: omci.EntityInstance})
878 if omciErr.StatusCode() != me.Success {
879 return omciErr.GetError()
880 }
881 // ME needs to support Get All Alarms
882 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
883 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
884 }
885 // Entity Class are always ONU DATA (2) and Entity Instance of 0
886 if omci.EntityClass != me.OnuDataClassID {
887 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
888 omci.EntityClass)
889 return me.NewProcessingError(msg)
890 }
891 if omci.EntityInstance != 0 {
892 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
893 omci.EntityInstance)
894 return me.NewUnknownInstanceError(msg)
895 }
896 omci.AlarmRetrievalMode = data[4]
897 if omci.AlarmRetrievalMode > 1 {
898 msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
899 omci.AlarmRetrievalMode)
900 return errors.New(msg)
901 }
902 return nil
903}
904
905func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
906 omci := &GetAllAlarmsRequest{}
907 omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
908 return decodingLayerDecoder(omci, data, p)
909}
910
911// SerializeTo provides serialization of an Get All Alarms Request message
912func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
913 // Basic (common) OMCI Header is 8 octets, 10
914 err := omci.MeBasePacket.SerializeTo(b)
915 if err != nil {
916 return err
917 }
918 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
919 me.ParamData{EntityID: omci.EntityInstance})
920 if omciErr.StatusCode() != me.Success {
921 return omciErr.GetError()
922 }
923 // ME needs to support Get All Alarms
924 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
925 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
926 }
927 bytes, err := b.AppendBytes(1)
928 if err != nil {
929 return err
930 }
931 bytes[0] = omci.AlarmRetrievalMode
932 return nil
933}
934
935/////////////////////////////////////////////////////////////////////////////
936// GetAllAlarms
937type GetAllAlarmsResponse struct {
938 MeBasePacket
939 NumberOfCommands uint16
940}
941
942func (omci *GetAllAlarmsResponse) String() string {
943 return fmt.Sprintf("%v, NumberOfCommands: %d",
944 omci.MeBasePacket.String(), omci.NumberOfCommands)
945}
946
947// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
948func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
949 // Common ClassID/EntityID decode in msgBase
950 err := omci.MeBasePacket.DecodeFromBytes(data, p)
951 if err != nil {
952 return err
953 }
954 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
955 me.ParamData{EntityID: omci.EntityInstance})
956 if omciErr.StatusCode() != me.Success {
957 return omciErr.GetError()
958 }
959 // ME needs to support Get All Alarms
960 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
961 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
962 }
963 // Entity Class are always ONU DATA (2) and Entity Instance of 0
964 if omci.EntityClass != me.OnuDataClassID {
965 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
966 omci.EntityClass)
967 return me.NewProcessingError(msg)
968 }
969 if omci.EntityInstance != 0 {
970 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
971 omci.EntityInstance)
972 return me.NewUnknownInstanceError(msg)
973 }
974 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
975 return nil
976}
977
978func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
979 omci := &GetAllAlarmsResponse{}
980 omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
981 return decodingLayerDecoder(omci, data, p)
982}
983
984// SerializeTo provides serialization of an Get All Alarms Response message
985func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
986 // Basic (common) OMCI Header is 8 octets, 10
987 err := omci.MeBasePacket.SerializeTo(b)
988 if err != nil {
989 return err
990 }
991 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
992 me.ParamData{EntityID: omci.EntityInstance})
993 if omciErr.StatusCode() != me.Success {
994 return omciErr.GetError()
995 }
996 // ME needs to support Get All Alarms
997 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
998 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
999 }
1000 bytes, err := b.AppendBytes(2)
1001 if err != nil {
1002 return err
1003 }
1004 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1005 return nil
1006}
1007
1008/////////////////////////////////////////////////////////////////////////////
1009// GetAllAlarms
1010type GetAllAlarmsNextRequest struct {
1011 MeBasePacket
1012 CommandSequenceNumber uint16
1013}
1014
1015func (omci *GetAllAlarmsNextRequest) String() string {
1016 return fmt.Sprintf("%v, Sequence Number: %d",
1017 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1018}
1019
1020// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
1021func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1022 // Common ClassID/EntityID decode in msgBase
1023 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1024 if err != nil {
1025 return err
1026 }
1027 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1028 me.ParamData{EntityID: omci.EntityInstance})
1029 if omciErr.StatusCode() != me.Success {
1030 return omciErr.GetError()
1031 }
1032 // ME needs to support Get All Alarms
1033 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1034 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1035 }
1036 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1037 if omci.EntityClass != me.OnuDataClassID {
1038 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
1039 omci.EntityClass)
1040 return me.NewProcessingError(msg)
1041 }
1042 if omci.EntityInstance != 0 {
1043 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
1044 omci.EntityInstance)
1045 return me.NewUnknownInstanceError(msg)
1046 }
1047 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1048 return nil
1049}
1050
1051func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
1052 omci := &GetAllAlarmsNextRequest{}
1053 omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
1054 return decodingLayerDecoder(omci, data, p)
1055}
1056
1057// SerializeTo provides serialization of an Get All Alarms Next Request message
1058func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1059 // Basic (common) OMCI Header is 8 octets, 10
1060 err := omci.MeBasePacket.SerializeTo(b)
1061 if err != nil {
1062 return err
1063 }
1064 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1065 me.ParamData{EntityID: omci.EntityInstance})
1066 if omciErr.StatusCode() != me.Success {
1067 return omciErr.GetError()
1068 }
1069 // ME needs to support Get All Alarms Next
1070 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1071 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1072 }
1073 bytes, err := b.AppendBytes(2)
1074 if err != nil {
1075 return err
1076 }
1077 binary.BigEndian.PutUint16(bytes, omci.CommandSequenceNumber)
1078 return nil
1079}
1080
1081/////////////////////////////////////////////////////////////////////////////
1082// GetAllAlarms
1083type GetAllAlarmsNextResponse struct {
1084 MeBasePacket
1085 AlarmEntityClass me.ClassID
1086 AlarmEntityInstance uint16
1087 AlarmBitMap [28]byte // 224 bits
1088}
1089
1090func (omci *GetAllAlarmsNextResponse) String() string {
1091 return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
1092 omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
1093 omci.AlarmEntityInstance, omci.AlarmBitMap)
1094}
1095
1096// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
1097func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1098 // Common ClassID/EntityID decode in msgBase
1099 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1100 if err != nil {
1101 return err
1102 }
1103 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1104 me.ParamData{EntityID: omci.EntityInstance})
1105 if omciErr.StatusCode() != me.Success {
1106 return omciErr.GetError()
1107 }
1108 // ME needs to support Get All Alarms Next
1109 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1110 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1111 }
1112 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1113 if omci.EntityClass != me.OnuDataClassID {
1114 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
1115 omci.EntityClass)
1116 return me.NewProcessingError(msg)
1117 }
1118 if omci.EntityInstance != 0 {
1119 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
1120 omci.EntityInstance)
1121 return me.NewUnknownInstanceError(msg)
1122 }
1123 omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4:6]))
1124 omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6:8])
1125
1126 copy(omci.AlarmBitMap[:], data[8:36])
1127 return nil
1128}
1129
1130func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
1131 omci := &GetAllAlarmsNextResponse{}
1132 omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
1133 return decodingLayerDecoder(omci, data, p)
1134}
1135
1136// SerializeTo provides serialization of an Get All Alarms Next Response message
1137func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1138 // Basic (common) OMCI Header is 8 octets, 10
1139 err := omci.MeBasePacket.SerializeTo(b)
1140 if err != nil {
1141 return err
1142 }
1143 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1144 me.ParamData{EntityID: omci.EntityInstance})
1145 if omciErr.StatusCode() != me.Success {
1146 return omciErr.GetError()
1147 }
1148 // ME needs to support Get All Alarms Next
1149 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1150 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1151 }
1152 bytes, err := b.AppendBytes(2 + 2 + 28)
1153 if err != nil {
1154 return err
1155 }
1156 binary.BigEndian.PutUint16(bytes[0:], uint16(omci.AlarmEntityClass))
1157 binary.BigEndian.PutUint16(bytes[2:], omci.AlarmEntityInstance)
1158 copy(bytes[4:], omci.AlarmBitMap[:])
1159 return nil
1160}
1161
1162/////////////////////////////////////////////////////////////////////////////
1163// MibUploadRequest
1164type MibUploadRequest struct {
1165 MeBasePacket
1166}
1167
1168func (omci *MibUploadRequest) String() string {
1169 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1170}
1171
1172// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
1173func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1174 // Common ClassID/EntityID decode in msgBase
1175 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1176 if err != nil {
1177 return err
1178 }
1179 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1180 me.ParamData{EntityID: omci.EntityInstance})
1181 if omciErr.StatusCode() != me.Success {
1182 return omciErr.GetError()
1183 }
1184 // ME needs to support MIB Upload
1185 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1186 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1187 }
1188 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1189 if omci.EntityClass != me.OnuDataClassID {
1190 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
1191 omci.EntityClass)
1192 return me.NewProcessingError(msg)
1193 }
1194 if omci.EntityInstance != 0 {
1195 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
1196 omci.EntityInstance)
1197 return me.NewUnknownInstanceError(msg)
1198 }
1199 return nil
1200}
1201
1202func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
1203 omci := &MibUploadRequest{}
1204 omci.MsgLayerType = LayerTypeMibUploadRequest
1205 return decodingLayerDecoder(omci, data, p)
1206}
1207
1208// SerializeTo provides serialization of an MIB Upload Request message
1209func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1210 // Basic (common) OMCI Header is 8 octets, 10
1211 err := omci.MeBasePacket.SerializeTo(b)
1212 if err != nil {
1213 return err
1214 }
1215 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1216 me.ParamData{EntityID: omci.EntityInstance})
1217 if omciErr.StatusCode() != me.Success {
1218 return omciErr.GetError()
1219 }
1220 // ME needs to support Get
1221 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1222 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1223 }
1224 return nil
1225}
1226
1227/////////////////////////////////////////////////////////////////////////////
1228// MibUploadResponse
1229type MibUploadResponse struct {
1230 MeBasePacket
1231 NumberOfCommands uint16
1232}
1233
1234func (omci *MibUploadResponse) String() string {
1235 return fmt.Sprintf("%v, NumberOfCommands: %#v",
1236 omci.MeBasePacket.String(), omci.NumberOfCommands)
1237}
1238
1239// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
1240func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1241 // Common ClassID/EntityID decode in msgBase
1242 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1243 if err != nil {
1244 return err
1245 }
1246 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1247 me.ParamData{EntityID: omci.EntityInstance})
1248 if omciErr.StatusCode() != me.Success {
1249 return omciErr.GetError()
1250 }
1251 // ME needs to support MIB Upload
1252 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1253 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1254 }
1255 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1256 if omci.EntityClass != me.OnuDataClassID {
1257 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
1258 omci.EntityClass)
1259 return me.NewProcessingError(msg)
1260 }
1261 if omci.EntityInstance != 0 {
1262 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
1263 omci.EntityInstance)
1264 return me.NewUnknownInstanceError(msg)
1265 }
1266 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1267 return nil
1268}
1269
1270func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
1271 omci := &MibUploadResponse{}
1272 omci.MsgLayerType = LayerTypeMibUploadResponse
1273 return decodingLayerDecoder(omci, data, p)
1274}
1275
1276// SerializeTo provides serialization of an MIB Upload Response message
1277func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1278 // Basic (common) OMCI Header is 8 octets, 10
1279 err := omci.MeBasePacket.SerializeTo(b)
1280 if err != nil {
1281 return err
1282 }
1283 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1284 me.ParamData{EntityID: omci.EntityInstance})
1285 if omciErr.StatusCode() != me.Success {
1286 return omciErr.GetError()
1287 }
1288 // ME needs to support MIB Upload
1289 if !me.SupportsMsgType(entity, me.MibUpload) {
1290 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1291 }
1292 bytes, err := b.AppendBytes(2)
1293 if err != nil {
1294 return err
1295 }
1296 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1297 return nil
1298}
1299
1300/////////////////////////////////////////////////////////////////////////////
1301//
1302type MibUploadNextRequest struct {
1303 MeBasePacket
1304 CommandSequenceNumber uint16
1305}
1306
1307func (omci *MibUploadNextRequest) String() string {
1308 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
1309 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1310}
1311
1312// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
1313func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1314 // Common ClassID/EntityID decode in msgBase
1315 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1316 if err != nil {
1317 return err
1318 }
1319 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1320 me.ParamData{EntityID: omci.EntityInstance})
1321 if omciErr.StatusCode() != me.Success {
1322 return omciErr.GetError()
1323 }
1324 // ME needs to support Get All Alarms
1325 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1326 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1327 }
1328 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1329 if omci.EntityClass != me.OnuDataClassID {
1330 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
1331 omci.EntityClass)
1332 return me.NewProcessingError(msg)
1333 }
1334 if omci.EntityInstance != 0 {
1335 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
1336 omci.EntityInstance)
1337 return me.NewUnknownInstanceError(msg)
1338 }
1339 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1340 return nil
1341}
1342
1343func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
1344 omci := &MibUploadNextRequest{}
1345 omci.MsgLayerType = LayerTypeMibUploadNextRequest
1346 return decodingLayerDecoder(omci, data, p)
1347}
1348
1349// SerializeTo provides serialization of an MIB Upload Next Request message
1350func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1351 // Basic (common) OMCI Header is 8 octets, 10
1352 err := omci.MeBasePacket.SerializeTo(b)
1353 if err != nil {
1354 return err
1355 }
1356 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1357 me.ParamData{EntityID: omci.EntityInstance})
1358 if omciErr.StatusCode() != me.Success {
1359 return omciErr.GetError()
1360 }
1361 // ME needs to support MIB upload
1362 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1363 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1364 }
1365 bytes, err := b.AppendBytes(2)
1366 if err != nil {
1367 return err
1368 }
1369 binary.BigEndian.PutUint16(bytes[0:2], omci.CommandSequenceNumber)
1370 return nil
1371}
1372
1373/////////////////////////////////////////////////////////////////////////////
1374//
1375type MibUploadNextResponse struct {
1376 MeBasePacket
1377 ReportedME me.ManagedEntity
1378}
1379
1380func (omci *MibUploadNextResponse) String() string {
1381 return fmt.Sprintf("%v, ReportedME: [%v]",
1382 omci.MeBasePacket.String(), omci.ReportedME.String())
1383}
1384
1385// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
1386func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1387 // Common ClassID/EntityID decode in msgBase
1388 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1389 if err != nil {
1390 return err
1391 }
1392 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1393 me.ParamData{EntityID: omci.EntityInstance})
1394 if omciErr.StatusCode() != me.Success {
1395 return omciErr.GetError()
1396 }
1397 // ME needs to support MibUploadNext
1398 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1399 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1400 }
1401 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1402 if omci.EntityClass != me.OnuDataClassID {
1403 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
1404 omci.EntityClass)
1405 return me.NewProcessingError(msg)
1406 }
1407 if omci.EntityInstance != 0 {
1408 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
1409 omci.EntityInstance)
1410 return me.NewUnknownInstanceError(msg)
1411 }
1412 // Decode reported ME. If an out-of-range sequence number was sent, this will
1413 // contain an ME with class ID and entity ID of zero and you should get an
1414 // error of "managed entity definition not found" returned.
1415 return omci.ReportedME.DecodeFromBytes(data[4:], p, byte(MibUploadNextResponseType))
1416}
1417
1418func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
1419 omci := &MibUploadNextResponse{}
1420 omci.MsgLayerType = LayerTypeMibUploadNextResponse
1421 return decodingLayerDecoder(omci, data, p)
1422}
1423
1424// SerializeTo provides serialization of an MIB Upload Next Response message
1425func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1426 // Basic (common) OMCI Header is 8 octets, 10
1427 err := omci.MeBasePacket.SerializeTo(b)
1428 if err != nil {
1429 return err
1430 }
1431 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1432 me.ParamData{EntityID: omci.EntityInstance})
1433 if omciErr.StatusCode() != me.Success {
1434 return omciErr.GetError()
1435 }
1436 // ME needs to support MIB Upload
1437 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1438 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1439 }
1440 // TODO: Only Baseline supported at this time
1441 bytesAvailable := MaxBaselineLength - 8 - 8
1442
1443 return omci.ReportedME.SerializeTo(b, byte(MibUploadNextResponseType), bytesAvailable, opts)
1444}
1445
1446/////////////////////////////////////////////////////////////////////////////
1447// MibResetRequest
1448type MibResetRequest struct {
1449 MeBasePacket
1450}
1451
1452func (omci *MibResetRequest) String() string {
1453 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1454}
1455
1456// DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
1457func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1458 // Common ClassID/EntityID decode in msgBase
1459 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1460 if err != nil {
1461 return err
1462 }
1463 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1464 me.ParamData{EntityID: omci.EntityInstance})
1465 if omciErr.StatusCode() != me.Success {
1466 return omciErr.GetError()
1467 }
1468 // ME needs to support MIB reset
1469 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1470 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1471 }
1472 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1473 if omci.EntityClass != me.OnuDataClassID {
1474 msg := fmt.Sprintf("invalid Entity Class for MIB Reset request: %v",
1475 omci.EntityClass)
1476 return me.NewProcessingError(msg)
1477 }
1478 if omci.EntityInstance != 0 {
1479 msg := fmt.Sprintf("invalid Entity Instance for MIB Reset request: %v",
1480 omci.EntityInstance)
1481 return me.NewUnknownInstanceError(msg)
1482 }
1483 return nil
1484}
1485
1486func decodeMibResetRequest(data []byte, p gopacket.PacketBuilder) error {
1487 omci := &MibResetRequest{}
1488 omci.MsgLayerType = LayerTypeMibResetRequest
1489 return decodingLayerDecoder(omci, data, p)
1490}
1491
1492// SerializeTo provides serialization of an MIB Reset Request message
1493func (omci *MibResetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1494 // Add class ID and entity ID
1495 return omci.MeBasePacket.SerializeTo(b)
1496}
1497
1498/////////////////////////////////////////////////////////////////////////////
1499// MibResetResponse
1500type MibResetResponse struct {
1501 MeBasePacket
1502 Result me.Results
1503}
1504
1505func (omci *MibResetResponse) String() string {
1506 return fmt.Sprintf("%v, Result: %d (%v)",
1507 omci.MeBasePacket.String(), omci.Result, omci.Result)
1508}
1509
1510// DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
1511func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1512 // Common ClassID/EntityID decode in msgBase
1513 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1514 if err != nil {
1515 return err
1516 }
1517 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1518 me.ParamData{EntityID: omci.EntityInstance})
1519 if omciErr.StatusCode() != me.Success {
1520 return omciErr.GetError()
1521 }
1522 // ME needs to support MIB reset
1523 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1524 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1525 }
1526 // MIB Reset Response Entity Class always ONU DATA (2) and
1527 // Entity Instance of 0
1528 if omci.EntityClass != me.OnuDataClassID {
1529 return me.NewProcessingError("invalid Entity Class for MIB Reset Response")
1530 }
1531 if omci.EntityInstance != 0 {
1532 return me.NewUnknownInstanceError("invalid Entity Instance for MIB Reset Response")
1533 }
1534 omci.Result = me.Results(data[4])
1535 if omci.Result > me.DeviceBusy {
1536 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
1537 return errors.New(msg)
1538 }
1539 return nil
1540}
1541
1542func decodeMibResetResponse(data []byte, p gopacket.PacketBuilder) error {
1543 omci := &MibResetResponse{}
1544 omci.MsgLayerType = LayerTypeMibResetResponse
1545 return decodingLayerDecoder(omci, data, p)
1546}
1547
1548// SerializeTo provides serialization of an MIB Reset Response message
1549func (omci *MibResetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1550 // Basic (common) OMCI Header is 8 octets, 10
1551 err := omci.MeBasePacket.SerializeTo(b)
1552 if err != nil {
1553 return err
1554 }
1555 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1556 me.ParamData{EntityID: omci.EntityInstance})
1557 if omciErr.StatusCode() != me.Success {
1558 return omciErr.GetError()
1559 }
1560 // ME needs to support Set
1561 if !me.SupportsMsgType(entity, me.MibReset) {
1562 return me.NewProcessingError("managed entity does not support the MIB Reset Message-Type")
1563 }
1564 bytes, err := b.AppendBytes(1)
1565 if err != nil {
1566 return err
1567 }
1568 bytes[0] = byte(omci.Result)
1569 return nil
1570}
1571
1572/////////////////////////////////////////////////////////////////////////////
1573// AlarmNotificationMsg
1574const AlarmBitmapSize = 224
1575
1576type AlarmNotificationMsg struct {
1577 MeBasePacket
1578 AlarmBitmap [AlarmBitmapSize / 8]byte
1579 zeroPadding [3]byte
1580 AlarmSequenceNumber byte
1581}
1582
1583func (omci *AlarmNotificationMsg) String() string {
1584 return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
1585 omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
1586}
1587
1588func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
1589 if alarmNumber >= AlarmBitmapSize {
1590 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1591 return false, errors.New(msg)
1592 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301593 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1594 me.ParamData{EntityID: omci.EntityInstance})
1595 if omciErr.StatusCode() != me.Success {
1596 return false, omciErr.GetError()
1597 }
1598 alarmMap := entity.GetAlarmMap()
1599 if alarmMap == nil {
1600 msg := "Managed Entity does not support Alarm notifications"
1601 return false, errors.New(msg)
1602 }
1603 if _, ok := alarmMap[alarmNumber]; !ok {
1604 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1605 return false, errors.New(msg)
1606 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001607 octet := alarmNumber / 8
1608 bit := 7 - (alarmNumber % 8)
1609 return omci.AlarmBitmap[octet]>>bit == 1, nil
1610}
1611
1612func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
1613 if alarmNumber >= AlarmBitmapSize {
1614 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1615 return false, errors.New(msg)
1616 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301617 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1618 me.ParamData{EntityID: omci.EntityInstance})
1619 if omciErr.StatusCode() != me.Success {
1620 return false, omciErr.GetError()
1621 }
1622 alarmMap := entity.GetAlarmMap()
1623 if alarmMap == nil {
1624 return false, errors.New("Managed Entity does not support Alarm notifications")
1625 }
1626 if _, ok := alarmMap[alarmNumber]; !ok {
1627 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1628 return false, errors.New(msg)
1629 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001630 octet := alarmNumber / 8
1631 bit := 7 - (alarmNumber % 8)
1632 return omci.AlarmBitmap[octet]>>bit == 0, nil
1633}
1634
1635func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
1636 if alarmNumber >= AlarmBitmapSize {
1637 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1638 return errors.New(msg)
1639 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301640 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1641 me.ParamData{EntityID: omci.EntityInstance})
1642 if omciErr.StatusCode() != me.Success {
1643 return omciErr.GetError()
1644 }
1645 alarmMap := entity.GetAlarmMap()
1646 if alarmMap == nil {
1647 return errors.New("Managed Entity does not support Alarm notifications")
1648 }
1649 if _, ok := alarmMap[alarmNumber]; !ok {
1650 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1651 return errors.New(msg)
1652 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001653 octet := alarmNumber / 8
1654 bit := 7 - (alarmNumber % 8)
1655 omci.AlarmBitmap[octet] |= 1 << bit
1656 return nil
1657}
1658
1659func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
1660 if alarmNumber >= AlarmBitmapSize {
1661 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1662 return errors.New(msg)
1663 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301664 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1665 me.ParamData{EntityID: omci.EntityInstance})
1666 if omciErr.StatusCode() != me.Success {
1667 return omciErr.GetError()
1668 }
1669 alarmMap := entity.GetAlarmMap()
1670 if alarmMap == nil {
1671 return errors.New("Managed Entity does not support Alarm notifications")
1672 }
1673 if _, ok := alarmMap[alarmNumber]; !ok {
1674 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1675 return errors.New(msg)
1676 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001677 octet := alarmNumber / 8
1678 bit := 7 - (alarmNumber % 8)
1679 omci.AlarmBitmap[octet] &= ^(1 << bit)
1680 return nil
1681}
1682
1683// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
1684func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1685 // Common ClassID/EntityID decode in msgBase
1686 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1687 if err != nil {
1688 return err
1689 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301690 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1691 me.ParamData{EntityID: omci.EntityInstance})
1692 if omciErr.StatusCode() != me.Success {
1693 return omciErr.GetError()
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001694 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301695 // Is this an unsupported or vendor specific ME. If so, it is not an error to decode
1696 // the alarms. We just cannot provide any alarm names. Handle decode here.
1697 classSupport := meDefinition.GetClassSupport()
1698 isUnsupported := classSupport == me.UnsupportedManagedEntity ||
1699 classSupport == me.UnsupportedVendorSpecificManagedEntity
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001700
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301701 // Look for a non-nil/not empty Alarm Map to determine if this ME supports alarms
1702 if alarmMap := meDefinition.GetAlarmMap(); isUnsupported || (alarmMap != nil && len(alarmMap) > 0) {
1703 for index, octet := range data[4 : (AlarmBitmapSize/8)-4] {
1704 omci.AlarmBitmap[index] = octet
1705 }
1706 padOffset := 4 + (AlarmBitmapSize / 8)
1707 omci.zeroPadding[0] = data[padOffset]
1708 omci.zeroPadding[1] = data[padOffset+1]
1709 omci.zeroPadding[2] = data[padOffset+2]
1710
1711 omci.AlarmSequenceNumber = data[padOffset+3]
1712 return nil
1713 }
1714 return me.NewProcessingError("managed entity does not support alarm notifications")
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001715}
1716
1717func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
1718 omci := &AlarmNotificationMsg{}
1719 omci.MsgLayerType = LayerTypeAlarmNotification
1720 return decodingLayerDecoder(omci, data, p)
1721}
1722
1723// SerializeTo provides serialization of an Alarm Notification message
1724func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1725 // Basic (common) OMCI Header is 8 octets, 10
1726 err := omci.MeBasePacket.SerializeTo(b)
1727 if err != nil {
1728 return err
1729 }
1730 //var meDefinition me.IManagedEntityDefinition
1731 //meDefinition, err = me.LoadManagedEntityDefinition(omci.EntityClass,
1732 // me.ParamData{EntityID: omci.EntityInstance})
1733 //if err != nil {
1734 // return err
1735 //}
1736 // ME needs to support Alarms
1737 // TODO: Add attribute to ME to specify that alarm is allowed
1738 //if !me.SupportsMsgType(meDefinition, me.MibReset) {
1739 // return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1740 //}
1741 bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
1742 if err != nil {
1743 return err
1744 }
1745 for index, octet := range omci.AlarmBitmap {
1746 bytes[index] = octet
1747 }
1748 padOffset := AlarmBitmapSize / 8
1749 bytes[padOffset] = 0
1750 bytes[padOffset+1] = 0
1751 bytes[padOffset+2] = 0
1752 bytes[padOffset+3] = omci.AlarmSequenceNumber
1753 return nil
1754}
1755
1756/////////////////////////////////////////////////////////////////////////////
1757// AttributeValueChangeMsg
1758type AttributeValueChangeMsg struct {
1759 MeBasePacket
1760 AttributeMask uint16
1761 Attributes me.AttributeValueMap
1762}
1763
1764func (omci *AttributeValueChangeMsg) String() string {
1765 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
1766 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
1767}
1768
1769// DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
1770func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1771 // Common ClassID/EntityID decode in msgBase
1772 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1773 if err != nil {
1774 return err
1775 }
1776 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1777 me.ParamData{EntityID: omci.EntityInstance})
1778 if omciErr.StatusCode() != me.Success {
1779 return omciErr.GetError()
1780 }
1781 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
1782 // Attribute decode
1783 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:40], p, byte(AttributeValueChangeType))
1784 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1785 // Validate all attributes support AVC
1786 //for attrName := range omci.attributes {
1787 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1788 // if err != nil {
1789 // return err
1790 // }
1791 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1792 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1793 // return me.NewProcessingError(msg)
1794 // }
1795 //}
1796 return err
1797}
1798
1799func decodeAttributeValueChange(data []byte, p gopacket.PacketBuilder) error {
1800 omci := &AttributeValueChangeMsg{}
1801 omci.MsgLayerType = LayerTypeAttributeValueChange
1802 return decodingLayerDecoder(omci, data, p)
1803}
1804
1805// SerializeTo provides serialization of an Attribute Value Change Notification message
1806func (omci *AttributeValueChangeMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1807 // Basic (common) OMCI Header is 8 octets, 10
1808 err := omci.MeBasePacket.SerializeTo(b)
1809 if err != nil {
1810 return err
1811 }
1812 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1813 me.ParamData{EntityID: omci.EntityInstance})
1814 if omciErr.StatusCode() != me.Success {
1815 return omciErr.GetError()
1816 }
1817 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1818 // Validate all attributes support AVC
1819 //for attrName := range omci.attributes {
1820 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1821 // if err != nil {
1822 // return err
1823 // }
1824 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1825 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1826 // return me.NewProcessingError(msg)
1827 // }
1828 //}
1829 bytes, err := b.AppendBytes(2)
1830 if err != nil {
1831 return err
1832 }
1833 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
1834
1835 // Attribute serialization
1836 // TODO: Only Baseline supported at this time
1837 bytesAvailable := MaxBaselineLength - 10 - 8
1838
1839 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
1840 byte(AttributeValueChangeType), bytesAvailable, false)
1841 return err
1842}
1843
1844/////////////////////////////////////////////////////////////////////////////
1845// TestRequest: TODO: Not yet implemented
1846type TestRequest struct {
1847 MeBasePacket
1848}
1849
1850func (omci *TestRequest) String() string {
1851 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1852}
1853
1854// DecodeFromBytes decodes the given bytes of a Test Request into this layer
1855func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1856 // Common ClassID/EntityID decode in msgBase
1857 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1858 if err != nil {
1859 return err
1860 }
1861 return errors.New("need to implement") // TODO: Fix me) // return nil
1862}
1863
1864func decodeTestRequest(data []byte, p gopacket.PacketBuilder) error {
1865 omci := &TestRequest{}
1866 omci.MsgLayerType = LayerTypeTestRequest
1867 return decodingLayerDecoder(omci, data, p)
1868}
1869
1870// SerializeTo provides serialization of an Test Request message
1871func (omci *TestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1872 // Basic (common) OMCI Header is 8 octets, 10
1873 err := omci.MeBasePacket.SerializeTo(b)
1874 if err != nil {
1875 return err
1876 }
1877 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1878}
1879
1880/////////////////////////////////////////////////////////////////////////////
1881// TestResponse: TODO: Not yet implemented
1882type TestResponse struct {
1883 MeBasePacket
1884}
1885
1886func (omci *TestResponse) String() string {
1887 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1888}
1889
1890// DecodeFromBytes decodes the given bytes of a Test Response into this layer
1891func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1892 // Common ClassID/EntityID decode in msgBase
1893 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1894 if err != nil {
1895 return err
1896 }
1897 return errors.New("need to implement") // TODO: Fix me) // return nil
1898}
1899
1900func decodeTestResponse(data []byte, p gopacket.PacketBuilder) error {
1901 omci := &TestResponse{}
1902 omci.MsgLayerType = LayerTypeTestResponse
1903 return decodingLayerDecoder(omci, data, p)
1904}
1905
1906// SerializeTo provides serialization of an Test Response message
1907func (omci *TestResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1908 // Basic (common) OMCI Header is 8 octets, 10
1909 err := omci.MeBasePacket.SerializeTo(b)
1910 if err != nil {
1911 return err
1912 }
1913 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1914}
1915
1916/////////////////////////////////////////////////////////////////////////////
1917//
1918type StartSoftwareDownloadRequest struct {
1919 MeBasePacket // Note: EntityInstance for software download is two specific values
1920 WindowSize byte // Window Size -1
1921 ImageSize uint32 // Octets
1922 NumberOfCircuitPacks byte
1923 CircuitPacks []uint16 // MSB & LSB of software image instance
1924}
1925
1926func (omci *StartSoftwareDownloadRequest) String() string {
1927 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
1928 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
1929}
1930
1931// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
1932func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1933 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1934 if err != nil {
1935 return err
1936 }
1937 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1938 me.ParamData{EntityID: omci.EntityInstance})
1939 if omciErr.StatusCode() != me.Success {
1940 return omciErr.GetError()
1941 }
1942 // ME needs to support Start Software Download
1943 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
1944 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
1945 }
1946 // Software Image Entity Class are always use the Software Image
1947 if omci.EntityClass != me.SoftwareImageClassID {
1948 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1949 }
1950 omci.WindowSize = data[4]
1951 omci.ImageSize = binary.BigEndian.Uint32(data[5:9])
1952 omci.NumberOfCircuitPacks = data[9]
1953 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
1954 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1955 omci.NumberOfCircuitPacks))
1956 }
1957 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
1958 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
1959 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[10+(index*2):])
1960 }
1961 return nil
1962}
1963
1964func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
1965 omci := &StartSoftwareDownloadRequest{}
1966 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
1967 return decodingLayerDecoder(omci, data, p)
1968}
1969
1970// SerializeTo provides serialization of an Start Software Download Request message
1971func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1972 // Basic (common) OMCI Header is 8 octets, 10
1973 err := omci.MeBasePacket.SerializeTo(b)
1974 if err != nil {
1975 return err
1976 }
1977 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1978 me.ParamData{EntityID: omci.EntityInstance})
1979 if omciErr.StatusCode() != me.Success {
1980 return omciErr.GetError()
1981 }
1982 // ME needs to support Start Software Download
1983 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
1984 return me.NewProcessingError("managed entity does not support the SStart Software Download Message-Type")
1985 }
1986 // Software Image Entity Class are always use the Software Image
1987 if omci.EntityClass != me.SoftwareImageClassID {
1988 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1989 }
1990 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
1991 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1992 omci.NumberOfCircuitPacks))
1993 }
1994 bytes, err := b.AppendBytes(6 + (2 * int(omci.NumberOfCircuitPacks)))
1995 if err != nil {
1996 return err
1997 }
1998 bytes[0] = omci.WindowSize
1999 binary.BigEndian.PutUint32(bytes[1:], omci.ImageSize)
2000 bytes[5] = omci.NumberOfCircuitPacks
2001 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2002 binary.BigEndian.PutUint16(bytes[6+(index*2):], omci.CircuitPacks[index])
2003 }
2004 return nil
2005}
2006
2007/////////////////////////////////////////////////////////////////////////////
2008//
2009type downloadResults struct {
2010 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
2011 Result me.Results
2012}
2013
2014func (dr *downloadResults) String() string {
2015 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
2016 dr.Result, dr.Result)
2017}
2018
2019type StartSoftwareDownloadResponse struct {
2020 MeBasePacket // Note: EntityInstance for software download is two specific values
2021 Result me.Results
2022 WindowSize byte // Window Size -1
2023 NumberOfInstances byte
2024 MeResults []downloadResults
2025}
2026
2027func (omci *StartSoftwareDownloadResponse) String() string {
2028 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
2029 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
2030}
2031
2032// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
2033func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2034 // Common ClassID/EntityID decode in msgBase
2035 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2036 if err != nil {
2037 return err
2038 }
2039 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2040 me.ParamData{EntityID: omci.EntityInstance})
2041 if omciErr.StatusCode() != me.Success {
2042 return omciErr.GetError()
2043 }
2044 // ME needs to support Start Software Download
2045 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2046 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2047 }
2048 // Software Image Entity Class are always use the Software Image
2049 if omci.EntityClass != me.SoftwareImageClassID {
2050 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2051 }
2052 omci.Result = me.Results(data[4])
2053 if omci.Result > me.DeviceBusy {
2054 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2055 omci.Result)
2056 return errors.New(msg)
2057 }
2058 omci.WindowSize = data[5]
2059 omci.NumberOfInstances = data[6]
2060
2061 if omci.NumberOfInstances > 9 {
2062 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2063 omci.NumberOfInstances)
2064 return errors.New(msg)
2065 }
2066 if omci.NumberOfInstances > 0 {
2067 omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
2068
2069 for index := 0; index < int(omci.NumberOfInstances); index++ {
2070 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
2071 omci.MeResults[index].Result = me.Results(data[9+(index*3)])
2072 if omci.MeResults[index].Result > me.DeviceBusy {
2073 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2074 index, omci.MeResults[index])
2075 return errors.New(msg)
2076 }
2077 }
2078 }
2079 return nil
2080}
2081
2082func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2083 omci := &StartSoftwareDownloadResponse{}
2084 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
2085 return decodingLayerDecoder(omci, data, p)
2086}
2087
2088// SerializeTo provides serialization of an Start Software Download Response message
2089func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2090 // Basic (common) OMCI Header is 8 octets, 10
2091 err := omci.MeBasePacket.SerializeTo(b)
2092 if err != nil {
2093 return err
2094 }
2095 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2096 me.ParamData{EntityID: omci.EntityInstance})
2097 if omciErr.StatusCode() != me.Success {
2098 return omciErr.GetError()
2099 }
2100 // ME needs to support Start Software Download
2101 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2102 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2103 }
2104 // Software Image Entity Class are always use the Software Image
2105 if omci.EntityClass != me.SoftwareImageClassID {
2106 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2107 }
2108 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2109 if err != nil {
2110 return err
2111 }
2112 if omci.Result > me.DeviceBusy {
2113 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2114 omci.Result)
2115 return errors.New(msg)
2116 }
2117 bytes[0] = byte(omci.Result)
2118 bytes[1] = omci.WindowSize
2119 bytes[2] = omci.NumberOfInstances
2120
2121 if omci.NumberOfInstances > 9 {
2122 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2123 omci.NumberOfInstances)
2124 return errors.New(msg)
2125 }
2126 if omci.NumberOfInstances > 0 {
2127 for index := 0; index < int(omci.NumberOfInstances); index++ {
2128 binary.BigEndian.PutUint16(bytes[3+(3*index):], omci.MeResults[index].ManagedEntityID)
2129
2130 if omci.MeResults[index].Result > me.DeviceBusy {
2131 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2132 index, omci.MeResults[index])
2133 return errors.New(msg)
2134 }
2135 bytes[5+(3*index)] = byte(omci.MeResults[index].Result)
2136 }
2137 }
2138 return nil
2139}
2140
2141/////////////////////////////////////////////////////////////////////////////
2142//
2143type DownloadSectionRequest struct {
2144 MeBasePacket // Note: EntityInstance for software download is two specific values
2145 SectionNumber byte
2146 SectionData [29]byte // 0 padding if final transfer requires only a partial block
2147}
2148
2149func (omci *DownloadSectionRequest) String() string {
2150 return fmt.Sprintf("%v, Section #: %v",
2151 omci.MeBasePacket.String(), omci.SectionNumber)
2152}
2153
2154// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
2155func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2156 // Common ClassID/EntityID decode in msgBase
2157 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2158 if err != nil {
2159 return err
2160 }
2161 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2162 me.ParamData{EntityID: omci.EntityInstance})
2163 if omciErr.StatusCode() != me.Success {
2164 return omciErr.GetError()
2165 }
2166 // ME needs to support Download section
2167 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2168 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2169 }
2170 // Software Image Entity Class are always use the Software Image
2171 if omci.EntityClass != me.SoftwareImageClassID {
2172 return me.NewProcessingError("invalid Entity Class for Download Section request")
2173 }
2174 omci.SectionNumber = data[4]
2175 copy(omci.SectionData[0:], data[5:])
2176 return nil
2177}
2178
2179func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2180 omci := &DownloadSectionRequest{}
2181 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2182 return decodingLayerDecoder(omci, data, p)
2183}
2184
2185// SerializeTo provides serialization of an Download Section Request message
2186func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2187 // Basic (common) OMCI Header is 8 octets, 10
2188 err := omci.MeBasePacket.SerializeTo(b)
2189 if err != nil {
2190 return err
2191 }
2192 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2193 me.ParamData{EntityID: omci.EntityInstance})
2194 if omciErr.StatusCode() != me.Success {
2195 return omciErr.GetError()
2196 }
2197 // ME needs to support Download section
2198 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2199 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2200 }
2201 // Software Image Entity Class are always use the Software Image
2202 if omci.EntityClass != me.SoftwareImageClassID {
2203 return me.NewProcessingError("invalid Entity Class for Download Section response")
2204 }
2205 bytes, err := b.AppendBytes(1 + 29)
2206 if err != nil {
2207 return err
2208 }
2209 bytes[0] = omci.SectionNumber
2210 copy(bytes[1:], omci.SectionData[0:])
2211 return nil
2212}
2213
2214/////////////////////////////////////////////////////////////////////////////
2215//
2216type DownloadSectionResponse struct {
2217 MeBasePacket // Note: EntityInstance for software download is two specific values
2218 Result me.Results
2219 SectionNumber byte
2220}
2221
2222func (omci *DownloadSectionResponse) String() string {
2223 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2224 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2225}
2226
2227// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
2228func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2229 // Common ClassID/EntityID decode in msgBase
2230 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2231 if err != nil {
2232 return err
2233 }
2234 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2235 me.ParamData{EntityID: omci.EntityInstance})
2236 if omciErr.StatusCode() != me.Success {
2237 return omciErr.GetError()
2238 }
2239 // ME needs to support Download section
2240 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2241 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2242 }
2243 // Software Image Entity Class are always use the Software Image
2244 if omci.EntityClass != me.SoftwareImageClassID {
2245 return me.NewProcessingError("invalid Entity Class for Download Section response")
2246 }
2247 omci.Result = me.Results(data[4])
2248 if omci.Result > me.DeviceBusy {
2249 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2250 omci.Result)
2251 return errors.New(msg)
2252 }
2253 omci.SectionNumber = data[5]
2254 return nil
2255}
2256
2257func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2258 omci := &DownloadSectionResponse{}
2259 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2260 return decodingLayerDecoder(omci, data, p)
2261}
2262
2263// SerializeTo provides serialization of an Download Section Response message
2264func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2265 // Basic (common) OMCI Header is 8 octets, 10
2266 err := omci.MeBasePacket.SerializeTo(b)
2267 if err != nil {
2268 return err
2269 }
2270 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2271 me.ParamData{EntityID: omci.EntityInstance})
2272 if omciErr.StatusCode() != me.Success {
2273 return omciErr.GetError()
2274 }
2275 // ME needs to support Download section
2276 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2277 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2278 }
2279 // Software Image Entity Class are always use the Software Image
2280 if omci.EntityClass != me.SoftwareImageClassID {
2281 return me.NewProcessingError("invalid Entity Class for Download Section response")
2282 }
2283 bytes, err := b.AppendBytes(2)
2284 if err != nil {
2285 return err
2286 }
2287 bytes[0] = omci.SectionNumber
2288 if omci.Result > me.DeviceBusy {
2289 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2290 omci.Result)
2291 return errors.New(msg)
2292 }
2293 bytes[1] = byte(omci.Result)
2294 return nil
2295}
2296
2297/////////////////////////////////////////////////////////////////////////////
2298//
2299type EndSoftwareDownloadRequest struct {
2300 MeBasePacket // Note: EntityInstance for software download is two specific values
2301 CRC32 uint32
2302 ImageSize uint32
2303 NumberOfInstances byte
2304 ImageInstances []uint16
2305}
2306
2307func (omci *EndSoftwareDownloadRequest) String() string {
2308 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2309 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2310}
2311
2312// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
2313func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2314 // Common ClassID/EntityID decode in msgBase
2315 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2316 if err != nil {
2317 return err
2318 }
2319 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2320 me.ParamData{EntityID: omci.EntityInstance})
2321 if omciErr.StatusCode() != me.Success {
2322 return omciErr.GetError()
2323 }
2324 // ME needs to support End Software Download
2325 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2326 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2327 }
2328 // Software Image Entity Class are always use the Software Image
2329 if omci.EntityClass != me.SoftwareImageClassID {
2330 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2331 }
2332 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2333 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
2334 omci.NumberOfInstances = data[13]
2335
2336 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2337 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2338 omci.NumberOfInstances))
2339 }
2340 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2341
2342 for index := 0; index < int(omci.NumberOfInstances); index++ {
2343 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[14+(index*2):])
2344 }
2345 return nil
2346}
2347
2348func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2349 omci := &EndSoftwareDownloadRequest{}
2350 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2351 return decodingLayerDecoder(omci, data, p)
2352}
2353
2354// SerializeTo provides serialization of an End Software Download Request message
2355func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2356 // Basic (common) OMCI Header is 8 octets, 10
2357 err := omci.MeBasePacket.SerializeTo(b)
2358 if err != nil {
2359 return err
2360 }
2361 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2362 me.ParamData{EntityID: omci.EntityInstance})
2363 if omciErr.StatusCode() != me.Success {
2364 return omciErr.GetError()
2365 }
2366 // ME needs to support End Software Download
2367 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2368 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2369 }
2370 // Software Image Entity Class are always use the Software Image
2371 if omci.EntityClass != me.SoftwareImageClassID {
2372 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2373 }
2374 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2375 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2376 omci.NumberOfInstances))
2377 }
2378 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2379 if err != nil {
2380 return err
2381 }
2382 binary.BigEndian.PutUint32(bytes[4:8], omci.CRC32)
2383 binary.BigEndian.PutUint32(bytes[8:12], omci.ImageSize)
2384 bytes[13] = omci.NumberOfInstances
2385 for index := 0; index < int(omci.NumberOfInstances); index++ {
2386 binary.BigEndian.PutUint16(bytes[14+(index*2):], omci.ImageInstances[index])
2387 }
2388 return nil
2389}
2390
2391/////////////////////////////////////////////////////////////////////////////
2392//
2393type EndSoftwareDownloadResponse struct {
2394 MeBasePacket // Note: EntityInstance for software download is two specific values
2395 Result me.Results
2396 NumberOfInstances byte
2397 MeResults []downloadResults
2398}
2399
2400func (omci *EndSoftwareDownloadResponse) String() string {
2401 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2402 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2403}
2404
2405// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
2406func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2407 // Common ClassID/EntityID decode in msgBase
2408 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2409 if err != nil {
2410 return err
2411 }
2412 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2413 me.ParamData{EntityID: omci.EntityInstance})
2414 if omciErr.StatusCode() != me.Success {
2415 return omciErr.GetError()
2416 }
2417 // ME needs to support End Software Download
2418 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2419 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2420 }
2421 // Software Image Entity Class are always use the Software Image
2422 if omci.EntityClass != me.SoftwareImageClassID {
2423 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2424 }
2425 omci.Result = me.Results(data[4])
2426 if omci.Result > me.DeviceBusy {
2427 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2428 omci.Result)
2429 return errors.New(msg)
2430 }
2431 omci.NumberOfInstances = data[5]
2432
2433 if omci.NumberOfInstances > 9 {
2434 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2435 omci.NumberOfInstances)
2436 return errors.New(msg)
2437 }
2438 if omci.NumberOfInstances > 0 {
2439 omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
2440
2441 for index := 0; index < int(omci.NumberOfInstances); index++ {
2442 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2443 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2444 if omci.MeResults[index].Result > me.DeviceBusy {
2445 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2446 index, omci.MeResults[index])
2447 return errors.New(msg)
2448 }
2449 }
2450 }
2451 return nil
2452}
2453
2454func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2455 omci := &EndSoftwareDownloadResponse{}
2456 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2457 return decodingLayerDecoder(omci, data, p)
2458}
2459
2460// SerializeTo provides serialization of an End Software Download Response message
2461func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2462 // Basic (common) OMCI Header is 8 octets, 10
2463 err := omci.MeBasePacket.SerializeTo(b)
2464 if err != nil {
2465 return err
2466 }
2467 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2468 me.ParamData{EntityID: omci.EntityInstance})
2469 if omciErr.StatusCode() != me.Success {
2470 return omciErr.GetError()
2471 }
2472 // ME needs to support End Software Download
2473 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2474 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2475 }
2476 // Software Image Entity Class are always use the Software Image
2477 if omci.EntityClass != me.SoftwareImageClassID {
2478 return me.NewProcessingError("invalid Entity Class for End Download response")
2479 }
2480 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2481 if err != nil {
2482 return err
2483 }
2484 if omci.Result > me.DeviceBusy {
2485 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2486 omci.Result)
2487 return errors.New(msg)
2488 }
2489 bytes[0] = byte(omci.Result)
2490 bytes[1] = omci.NumberOfInstances
2491
2492 if omci.NumberOfInstances > 9 {
2493 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2494 omci.NumberOfInstances)
2495 return errors.New(msg)
2496 }
2497 if omci.NumberOfInstances > 0 {
2498 for index := 0; index < int(omci.NumberOfInstances); index++ {
2499 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2500
2501 if omci.MeResults[index].Result > me.DeviceBusy {
2502 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2503 index, omci.MeResults[index])
2504 return errors.New(msg)
2505 }
2506 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2507 }
2508 }
2509 return nil
2510}
2511
2512/////////////////////////////////////////////////////////////////////////////
2513//
2514type ActivateSoftwareRequest struct {
2515 MeBasePacket // Note: EntityInstance for software download is two specific values
2516 ActivateFlags byte
2517}
2518
2519func (omci *ActivateSoftwareRequest) String() string {
2520 return fmt.Sprintf("%v, Flags: %#x",
2521 omci.MeBasePacket.String(), omci.ActivateFlags)
2522}
2523
2524// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
2525func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2526 // Common ClassID/EntityID decode in msgBase
2527 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2528 if err != nil {
2529 return err
2530 }
2531 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2532 me.ParamData{EntityID: omci.EntityInstance})
2533 if omciErr.StatusCode() != me.Success {
2534 return omciErr.GetError()
2535 }
2536 // ME needs to support End Software Download
2537 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2538 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2539 }
2540 // Software Image Entity Class are always use the Software Image
2541 if omci.EntityClass != me.SoftwareImageClassID {
2542 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2543 }
2544 omci.ActivateFlags = data[4]
2545 if omci.ActivateFlags > 2 {
2546 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2547 omci.ActivateFlags))
2548 }
2549 return nil
2550}
2551
2552func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2553 omci := &ActivateSoftwareRequest{}
2554 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2555 return decodingLayerDecoder(omci, data, p)
2556}
2557
2558// SerializeTo provides serialization of an Activate Software message
2559func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2560 // Basic (common) OMCI Header is 8 octets, 10
2561 err := omci.MeBasePacket.SerializeTo(b)
2562 if err != nil {
2563 return err
2564 }
2565 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2566 me.ParamData{EntityID: omci.EntityInstance})
2567 if omciErr.StatusCode() != me.Success {
2568 return omciErr.GetError()
2569 }
2570 // ME needs to support End Software Download
2571 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2572 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2573 }
2574 // Software Image Entity Class are always use the Software Image
2575 if omci.EntityClass != me.SoftwareImageClassID {
2576 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2577 }
2578 bytes, err := b.AppendBytes(1)
2579 if err != nil {
2580 return err
2581 }
2582 bytes[0] = omci.ActivateFlags
2583 if omci.ActivateFlags > 2 {
2584 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2585 omci.ActivateFlags)
2586 return errors.New(msg)
2587 }
2588 return nil
2589}
2590
2591/////////////////////////////////////////////////////////////////////////////
2592//
2593type ActivateSoftwareResponse struct {
2594 MeBasePacket
2595 Result me.Results
2596}
2597
2598func (omci *ActivateSoftwareResponse) String() string {
2599 return fmt.Sprintf("%v, Result: %d (%v)",
2600 omci.MeBasePacket.String(), omci.Result, omci.Result)
2601}
2602
2603// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
2604func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2605 // Common ClassID/EntityID decode in msgBase
2606 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2607 if err != nil {
2608 return err
2609 }
2610 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2611 me.ParamData{EntityID: omci.EntityInstance})
2612 if omciErr.StatusCode() != me.Success {
2613 return omciErr.GetError()
2614 }
2615 // ME needs to support End Software Download
2616 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2617 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2618 }
2619 // Software Image Entity Class are always use the Software Image
2620 if omci.EntityClass != me.SoftwareImageClassID {
2621 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2622 }
2623 omci.Result = me.Results(data[4])
2624 if omci.Result > me.Results(6) {
2625 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2626 omci.Result)
2627 return errors.New(msg)
2628 }
2629 return nil
2630}
2631
2632func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2633 omci := &ActivateSoftwareResponse{}
2634 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2635 return decodingLayerDecoder(omci, data, p)
2636}
2637
2638// SerializeTo provides serialization of an Activate Software Response message
2639func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2640 // Basic (common) OMCI Header is 8 octets, 10
2641 err := omci.MeBasePacket.SerializeTo(b)
2642 if err != nil {
2643 return err
2644 }
2645 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2646 me.ParamData{EntityID: omci.EntityInstance})
2647 if omciErr.StatusCode() != me.Success {
2648 return omciErr.GetError()
2649 }
2650 // ME needs to support End Software Download
2651 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2652 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2653 }
2654 // Software Image Entity Class are always use the Software Image
2655 if omci.EntityClass != me.SoftwareImageClassID {
2656 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2657 }
2658 bytes, err := b.AppendBytes(1)
2659 if err != nil {
2660 return err
2661 }
2662 bytes[0] = byte(omci.Result)
2663 if omci.Result > me.Results(6) {
2664 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2665 omci.Result)
2666 return errors.New(msg)
2667 }
2668 return nil
2669}
2670
2671/////////////////////////////////////////////////////////////////////////////
2672//
2673type CommitSoftwareRequest struct {
2674 MeBasePacket
2675}
2676
2677func (omci *CommitSoftwareRequest) String() string {
2678 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2679}
2680
2681// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
2682func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2683 // Common ClassID/EntityID decode in msgBase
2684 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2685 if err != nil {
2686 return err
2687 }
2688 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2689 me.ParamData{EntityID: omci.EntityInstance})
2690 if omciErr.StatusCode() != me.Success {
2691 return omciErr.GetError()
2692 }
2693 // ME needs to support End Software Download
2694 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2695 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2696 }
2697 // Software Image Entity Class are always use the Software Image
2698 if omci.EntityClass != me.SoftwareImageClassID {
2699 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2700 }
2701 return nil
2702}
2703
2704func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2705 omci := &CommitSoftwareRequest{}
2706 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
2707 return decodingLayerDecoder(omci, data, p)
2708}
2709
2710// SerializeTo provides serialization of an Commit Software Request message
2711func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2712 // Basic (common) OMCI Header is 8 octets, 10
2713 err := omci.MeBasePacket.SerializeTo(b)
2714 if err != nil {
2715 return err
2716 }
2717 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2718 me.ParamData{EntityID: omci.EntityInstance})
2719 if omciErr.StatusCode() != me.Success {
2720 return omciErr.GetError()
2721 }
2722 // ME needs to support End Software Download
2723 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2724 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2725 }
2726 // Software Image Entity Class are always use the Software Image
2727 if omci.EntityClass != me.SoftwareImageClassID {
2728 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2729 }
2730 return nil
2731}
2732
2733/////////////////////////////////////////////////////////////////////////////
2734//
2735type CommitSoftwareResponse struct {
2736 MeBasePacket
2737}
2738
2739func (omci *CommitSoftwareResponse) String() string {
2740 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2741}
2742
2743// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
2744func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2745 // Common ClassID/EntityID decode in msgBase
2746 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2747 if err != nil {
2748 return err
2749 }
2750 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2751 me.ParamData{EntityID: omci.EntityInstance})
2752 if omciErr.StatusCode() != me.Success {
2753 return omciErr.GetError()
2754 }
2755 // ME needs to support End Software Download
2756 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2757 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2758 }
2759 // Software Image Entity Class are always use the Software Image
2760 if omci.EntityClass != me.SoftwareImageClassID {
2761 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2762 }
2763 return nil
2764}
2765
2766func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2767 omci := &CommitSoftwareResponse{}
2768 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
2769 return decodingLayerDecoder(omci, data, p)
2770}
2771
2772// SerializeTo provides serialization of an Commit Software Response message
2773func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2774 // Basic (common) OMCI Header is 8 octets, 10
2775 err := omci.MeBasePacket.SerializeTo(b)
2776 if err != nil {
2777 return err
2778 }
2779 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2780 me.ParamData{EntityID: omci.EntityInstance})
2781 if omciErr.StatusCode() != me.Success {
2782 return omciErr.GetError()
2783 }
2784 // ME needs to support End Software Download
2785 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2786 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2787 }
2788 // Software Image Entity Class are always use the Software Image
2789 if omci.EntityClass != me.SoftwareImageClassID {
2790 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2791 }
2792 return nil
2793}
2794
2795/////////////////////////////////////////////////////////////////////////////
2796//
2797type SynchronizeTimeRequest struct {
2798 MeBasePacket
2799 Year uint16
2800 Month uint8
2801 Day uint8
2802 Hour uint8
2803 Minute uint8
2804 Second uint8
2805}
2806
2807func (omci *SynchronizeTimeRequest) String() string {
2808 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
2809 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
2810}
2811
2812// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
2813func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2814 // Common ClassID/EntityID decode in msgBase
2815 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2816 if err != nil {
2817 return err
2818 }
2819 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2820 me.ParamData{EntityID: omci.EntityInstance})
2821 if omciErr.StatusCode() != me.Success {
2822 return omciErr.GetError()
2823 }
2824 // ME needs to support Synchronize Time
2825 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2826 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2827 }
2828 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
2829 if omci.EntityClass != me.OnuGClassID {
2830 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
2831 }
2832 if omci.EntityInstance != 0 {
2833 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
2834 }
2835 omci.Year = binary.BigEndian.Uint16(data[4:6])
2836 omci.Month = data[6]
2837 omci.Day = data[7]
2838 omci.Hour = data[8]
2839 omci.Minute = data[9]
2840 omci.Second = data[10]
2841 return nil
2842}
2843
2844func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
2845 omci := &SynchronizeTimeRequest{}
2846 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
2847 return decodingLayerDecoder(omci, data, p)
2848}
2849
2850// SerializeTo provides serialization of an Synchronize Time Request message
2851func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2852 // Basic (common) OMCI Header is 8 octets, 10
2853 err := omci.MeBasePacket.SerializeTo(b)
2854 if err != nil {
2855 return err
2856 }
2857 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2858 me.ParamData{EntityID: omci.EntityInstance})
2859 if omciErr.StatusCode() != me.Success {
2860 return omciErr.GetError()
2861 }
2862 // ME needs to support Synchronize Time
2863 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2864 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2865 }
2866 bytes, err := b.AppendBytes(7)
2867 if err != nil {
2868 return err
2869 }
2870 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
2871 bytes[2] = omci.Month
2872 bytes[3] = omci.Day
2873 bytes[4] = omci.Hour
2874 bytes[5] = omci.Minute
2875 bytes[6] = omci.Second
2876 return nil
2877}
2878
2879/////////////////////////////////////////////////////////////////////////////
2880//
2881type SynchronizeTimeResponse struct {
2882 MeBasePacket
2883 Result me.Results
2884 SuccessResults uint8 // Only if 'Result' is 0 -> success
2885}
2886
2887func (omci *SynchronizeTimeResponse) String() string {
2888 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
2889 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
2890}
2891
2892// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
2893func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2894 // Common ClassID/EntityID decode in msgBase
2895 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2896 if err != nil {
2897 return err
2898 }
2899 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2900 me.ParamData{EntityID: omci.EntityInstance})
2901 if omciErr.StatusCode() != me.Success {
2902 return omciErr.GetError()
2903 }
2904 // ME needs to support Synchronize Time
2905 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2906 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2907 }
2908 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
2909 if omci.EntityClass != me.OnuGClassID {
2910 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2911 }
2912 if omci.EntityInstance != 0 {
2913 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2914 }
2915 omci.Result = me.Results(data[4])
2916 if omci.Result > me.DeviceBusy {
2917 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
2918 return errors.New(msg)
2919 }
2920 omci.SuccessResults = data[5]
2921 return nil
2922}
2923
2924func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
2925 omci := &SynchronizeTimeResponse{}
2926 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
2927 return decodingLayerDecoder(omci, data, p)
2928}
2929
2930// SerializeTo provides serialization of an Synchronize Time Response message
2931func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2932 // Basic (common) OMCI Header is 8 octets, 10
2933 err := omci.MeBasePacket.SerializeTo(b)
2934 if err != nil {
2935 return err
2936 }
2937 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2938 me.ParamData{EntityID: omci.EntityInstance})
2939 if omciErr.StatusCode() != me.Success {
2940 return omciErr.GetError()
2941 }
2942 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
2943 if omci.EntityClass != me.OnuGClassID {
2944 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2945 }
2946 if omci.EntityInstance != 0 {
2947 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2948 }
2949 // ME needs to support Synchronize Time
2950 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2951 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2952 }
2953 numBytes := 2
2954 if omci.Result != me.Success {
2955 numBytes = 1
2956 }
2957 bytes, err := b.AppendBytes(numBytes)
2958 if err != nil {
2959 return err
2960 }
2961 bytes[0] = uint8(omci.Result)
2962 if omci.Result == me.Success {
2963 bytes[1] = omci.SuccessResults
2964 }
2965 return nil
2966}
2967
2968/////////////////////////////////////////////////////////////////////////////
2969//
2970type RebootRequest struct {
2971 MeBasePacket
2972 RebootCondition byte
2973}
2974
2975func (omci *RebootRequest) String() string {
2976 return fmt.Sprintf("%v, Reboot Condition: %v",
2977 omci.MeBasePacket.String(), omci.RebootCondition)
2978}
2979
2980// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
2981func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2982 // Common ClassID/EntityID decode in msgBase
2983 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2984 if err != nil {
2985 return err
2986 }
2987 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2988 me.ParamData{EntityID: omci.EntityInstance})
2989 if omciErr.StatusCode() != me.Success {
2990 return omciErr.GetError()
2991 }
2992 // ME needs to support Reboot
2993 if !me.SupportsMsgType(meDefinition, me.Reboot) {
2994 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
2995 }
2996 omci.RebootCondition = data[4]
2997 if omci.RebootCondition > 3 {
2998 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
2999 return errors.New(msg)
3000 }
3001 return nil
3002}
3003
3004func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
3005 omci := &RebootRequest{}
3006 omci.MsgLayerType = LayerTypeRebootRequest
3007 return decodingLayerDecoder(omci, data, p)
3008}
3009
3010// SerializeTo provides serialization of an Reboot Request message
3011func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3012 // Basic (common) OMCI Header is 8 octets, 10
3013 err := omci.MeBasePacket.SerializeTo(b)
3014 if err != nil {
3015 return err
3016 }
3017 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3018 me.ParamData{EntityID: omci.EntityInstance})
3019 if omciErr.StatusCode() != me.Success {
3020 return omciErr.GetError()
3021 }
3022 // ME needs to support Reboot
3023 if !me.SupportsMsgType(entity, me.Reboot) {
3024 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3025 }
3026 bytes, err := b.AppendBytes(1)
3027 if err != nil {
3028 return err
3029 }
3030 if omci.RebootCondition > 3 {
3031 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
3032 omci.RebootCondition))
3033 }
3034 bytes[0] = omci.RebootCondition
3035 return nil
3036}
3037
3038/////////////////////////////////////////////////////////////////////////////
3039//
3040type RebootResponse struct {
3041 MeBasePacket
3042 Result me.Results
3043}
3044
3045// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3046func (omci *RebootResponse) String() string {
3047 return fmt.Sprintf("%v, Result: %d (%v)",
3048 omci.MeBasePacket.String(), omci.Result, omci.Result)
3049}
3050
3051// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3052func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3053 // Common ClassID/EntityID decode in msgBase
3054 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3055 if err != nil {
3056 return err
3057 }
3058 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3059 me.ParamData{EntityID: omci.EntityInstance})
3060 if omciErr.StatusCode() != me.Success {
3061 return omciErr.GetError()
3062 }
3063 // ME needs to support Reboot
3064 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3065 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3066 }
3067 if omci.Result > 6 {
3068 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3069 return errors.New(msg)
3070 }
3071 omci.Result = me.Results(data[4])
3072 return nil
3073}
3074
3075func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3076 omci := &RebootResponse{}
3077 omci.MsgLayerType = LayerTypeRebootResponse
3078 return decodingLayerDecoder(omci, data, p)
3079}
3080
3081// SerializeTo provides serialization of an Reboot Response message
3082func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3083 // Basic (common) OMCI Header is 8 octets, 10
3084 err := omci.MeBasePacket.SerializeTo(b)
3085 if err != nil {
3086 return err
3087 }
3088 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3089 me.ParamData{EntityID: omci.EntityInstance})
3090 if omciErr.StatusCode() != me.Success {
3091 return omciErr.GetError()
3092 }
3093 // ME needs to support Reboot
3094 if !me.SupportsMsgType(entity, me.Reboot) {
3095 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3096 }
3097 bytes, err := b.AppendBytes(1)
3098 if err != nil {
3099 return err
3100 }
3101 if omci.Result > 6 {
3102 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3103 return errors.New(msg)
3104 }
3105 bytes[0] = byte(omci.Result)
3106 return nil
3107}
3108
3109/////////////////////////////////////////////////////////////////////////////
3110//
3111type GetNextRequest struct {
3112 MeBasePacket
3113 AttributeMask uint16
3114 SequenceNumber uint16
3115}
3116
3117func (omci *GetNextRequest) String() string {
3118 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3119 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3120}
3121
3122// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
3123func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3124 // Common ClassID/EntityID decode in msgBase
3125 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3126 if err != nil {
3127 return err
3128 }
3129 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3130 me.ParamData{EntityID: omci.EntityInstance})
3131 if omciErr.StatusCode() != me.Success {
3132 return omciErr.GetError()
3133 }
3134 // ME needs to support GetNext
3135 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3136 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3137 }
3138 // Note: G.988 specifies that an error code of (3) should result if more
3139 // than one attribute is requested
3140 // TODO: Return error. Have flag to optionally allow it to be encoded
3141 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3142 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3143 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3144 return nil
3145}
3146
3147func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3148 omci := &GetNextRequest{}
3149 omci.MsgLayerType = LayerTypeGetNextRequest
3150 return decodingLayerDecoder(omci, data, p)
3151}
3152
3153// SerializeTo provides serialization of an Get Next Message Type Request
3154func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3155 // Basic (common) OMCI Header is 8 octets, 10
3156 err := omci.MeBasePacket.SerializeTo(b)
3157 if err != nil {
3158 return err
3159 }
3160 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3161 me.ParamData{EntityID: omci.EntityInstance})
3162 if omciErr.StatusCode() != me.Success {
3163 return omciErr.GetError()
3164 }
3165 // ME needs to support GetNext
3166 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3167 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3168 }
3169 bytes, err := b.AppendBytes(4)
3170 if err != nil {
3171 return err
3172 }
3173 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3174 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3175 return nil
3176}
3177
3178/////////////////////////////////////////////////////////////////////////////
3179//
3180type GetNextResponse struct {
3181 MeBasePacket
3182 Result me.Results
3183 AttributeMask uint16
3184 Attributes me.AttributeValueMap
3185}
3186
3187// SerializeTo provides serialization of an Get Next Message Type Response
3188func (omci *GetNextResponse) String() string {
3189 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3190 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3191}
3192
3193// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
3194func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3195 // Common ClassID/EntityID decode in msgBase
3196 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3197 if err != nil {
3198 return err
3199 }
3200 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3201 me.ParamData{EntityID: omci.EntityInstance})
3202 if omciErr.StatusCode() != me.Success {
3203 return omciErr.GetError()
3204 }
3205 // ME needs to support Set
3206 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3207 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3208 }
3209 omci.Result = me.Results(data[4])
3210 if omci.Result > 6 {
3211 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3212 return errors.New(msg)
3213 }
3214 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3215
3216 // Attribute decode
3217 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3218 if err != nil {
3219 return err
3220 }
3221 // Validate all attributes support read
3222 for attrName := range omci.Attributes {
3223 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3224 if err != nil {
3225 return err
3226 }
3227 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3228 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3229 return me.NewProcessingError(msg)
3230 }
3231 }
3232 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
3233 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3234 return nil
3235 }
3236 panic("All Managed Entities have an EntityID attribute")
3237}
3238
3239func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3240 omci := &GetNextResponse{}
3241 omci.MsgLayerType = LayerTypeGetNextResponse
3242 return decodingLayerDecoder(omci, data, p)
3243}
3244
3245// SerializeTo provides serialization of an Get Next Message Type Response
3246func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3247 // Basic (common) OMCI Header is 8 octets, 10
3248 err := omci.MeBasePacket.SerializeTo(b)
3249 if err != nil {
3250 return err
3251 }
3252 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3253 me.ParamData{EntityID: omci.EntityInstance})
3254 if omciErr.StatusCode() != me.Success {
3255 return omciErr.GetError()
3256 }
3257 // ME needs to support Get
3258 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3259 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3260 }
3261 bytes, err := b.AppendBytes(3)
3262 if err != nil {
3263 return err
3264 }
3265 bytes[0] = byte(omci.Result)
3266 if omci.Result > 6 {
3267 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3268 return errors.New(msg)
3269 }
3270 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3271
3272 // Validate all attributes support read
3273 for attrName := range omci.Attributes {
3274 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3275 if err != nil {
3276 return err
3277 }
3278 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3279 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3280 return me.NewProcessingError(msg)
3281 }
3282 }
3283 // Attribute serialization
3284 switch omci.Result {
3285 default:
3286 break
3287
3288 case me.Success:
3289 // TODO: Only Baseline supported at this time
3290 bytesAvailable := MaxBaselineLength - 11 - 8
3291
3292 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3293 byte(GetNextResponseType), bytesAvailable, false)
3294 if err != nil {
3295 return err
3296 }
3297 }
3298 return nil
3299}
3300
3301/////////////////////////////////////////////////////////////////////////////
3302//
3303type TestResultMsg struct {
3304 MeBasePacket
3305}
3306
3307func (omci *TestResultMsg) String() string {
3308 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3309}
3310
3311// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
3312func (omci *TestResultMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3313 // Common ClassID/EntityID decode in msgBase
3314 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3315 if err != nil {
3316 return err
3317 }
3318 return errors.New("need to implement") // TODO: Fix me) // return nil
3319}
3320
3321func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3322 omci := &TestResultMsg{}
3323 omci.MsgLayerType = LayerTypeTestResult
3324 return decodingLayerDecoder(omci, data, p)
3325}
3326
3327// SerializeTo provides serialization of an Test Result notification message
3328func (omci *TestResultMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3329 // Basic (common) OMCI Header is 8 octets, 10
3330 err := omci.MeBasePacket.SerializeTo(b)
3331 if err != nil {
3332 return err
3333 }
3334 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
3335}
3336
3337/////////////////////////////////////////////////////////////////////////////
3338//
3339type GetCurrentDataRequest struct {
3340 MeBasePacket
3341 AttributeMask uint16
3342}
3343
3344func (omci *GetCurrentDataRequest) String() string {
3345 return fmt.Sprintf("%v, Attribute Mask: %#x",
3346 omci.MeBasePacket.String(), omci.AttributeMask)
3347}
3348
3349// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
3350func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3351 // Common ClassID/EntityID decode in msgBase
3352 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3353 if err != nil {
3354 return err
3355 }
3356 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3357 me.ParamData{EntityID: omci.EntityInstance})
3358 if omciErr.StatusCode() != me.Success {
3359 return omciErr.GetError()
3360 }
3361 // ME needs to support GetNext
3362 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3363 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3364 }
3365 // Note: G.988 specifies that an error code of (3) should result if more
3366 // than one attribute is requested
3367 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3368 return nil
3369}
3370
3371func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3372 omci := &GetCurrentDataRequest{}
3373 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3374 return decodingLayerDecoder(omci, data, p)
3375}
3376
3377// SerializeTo provides serialization of an Get Current Data Request message
3378func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3379 // Basic (common) OMCI Header is 8 octets, 10
3380 err := omci.MeBasePacket.SerializeTo(b)
3381 if err != nil {
3382 return err
3383 }
3384 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3385 me.ParamData{EntityID: omci.EntityInstance})
3386 if omciErr.StatusCode() != me.Success {
3387 return omciErr.GetError()
3388 }
3389 // ME needs to support GetNext
3390 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3391 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3392 }
3393 bytes, err := b.AppendBytes(2)
3394 if err != nil {
3395 return err
3396 }
3397 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3398 return nil
3399}
3400
3401/////////////////////////////////////////////////////////////////////////////
3402//
3403type GetCurrentDataResponse struct {
3404 MeBasePacket
3405 Result me.Results
3406 AttributeMask uint16
3407 Attributes me.AttributeValueMap
3408}
3409
3410func (omci *GetCurrentDataResponse) String() string {
3411 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
3412 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
3413}
3414
3415// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
3416func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3417 // Common ClassID/EntityID decode in msgBase
3418 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3419 if err != nil {
3420 return err
3421 }
3422 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3423 me.ParamData{EntityID: omci.EntityInstance})
3424 if omciErr.StatusCode() != me.Success {
3425 return omciErr.GetError()
3426 }
3427 // ME needs to support Set
3428 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3429 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3430 }
3431 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3432
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303433 switch omci.Result {
3434 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
3435 return nil // Done (do not try and decode attributes)
3436 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +00003437 // Attribute decode
3438 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(GetCurrentDataResponseType))
3439 if err != nil {
3440 return err
3441 }
3442 return nil
3443}
3444
3445func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
3446 omci := &GetCurrentDataResponse{}
3447 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
3448 return decodingLayerDecoder(omci, data, p)
3449}
3450
3451// SerializeTo provides serialization of an Get Current Data Message Type Response
3452func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3453 // Basic (common) OMCI Header is 8 octets, 10
3454 err := omci.MeBasePacket.SerializeTo(b)
3455 if err != nil {
3456 return err
3457 }
3458 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3459 me.ParamData{EntityID: omci.EntityInstance})
3460 if omciErr.StatusCode() != me.Success {
3461 return omciErr.GetError()
3462 }
3463 // ME needs to support Get
3464 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3465 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
3466 }
3467 bytes, err := b.AppendBytes(2)
3468 if err != nil {
3469 return err
3470 }
3471 binary.BigEndian.PutUint16(bytes[0:2], omci.AttributeMask)
3472
3473 // Attribute serialization
3474 // TODO: Only Baseline supported at this time
3475 bytesAvailable := MaxBaselineLength - 9 - 8
3476 var failedMask uint16
3477
3478 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3479 byte(GetCurrentDataResponseType), bytesAvailable, opts.FixLengths)
3480
3481 if failedMask != 0 {
3482 // TODO: See GetResponse serialization above for the steps here
3483 return me.NewMessageTruncatedError("getCurrentData attribute truncation not yet supported")
3484 }
3485 if err != nil {
3486 return err
3487 }
3488 return nil
3489}
3490
3491/////////////////////////////////////////////////////////////////////////////
3492//
3493type SetTableRequest struct {
3494 MeBasePacket
3495 // TODO: Fix me when extended messages supported)
3496}
3497
3498func (omci *SetTableRequest) String() string {
3499 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3500}
3501
3502// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
3503func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3504 // Common ClassID/EntityID decode in msgBase
3505 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3506 if err != nil {
3507 return err
3508 }
3509 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3510}
3511
3512func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
3513 omci := &SetTableRequest{}
3514 omci.MsgLayerType = LayerTypeSetTableRequest
3515 return decodingLayerDecoder(omci, data, p)
3516}
3517
3518// SerializeTo provides serialization of an Set Table Message Type Request
3519func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3520 // Basic (common) OMCI Header is 8 octets, 10
3521 err := omci.MeBasePacket.SerializeTo(b)
3522 if err != nil {
3523 return err
3524 }
3525 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
3526}
3527
3528/////////////////////////////////////////////////////////////////////////////
3529//
3530type SetTableResponse struct {
3531 MeBasePacket
3532 // TODO: Fix me when extended messages supported)
3533}
3534
3535func (omci *SetTableResponse) String() string {
3536 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3537}
3538
3539// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
3540func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3541 // Common ClassID/EntityID decode in msgBase
3542 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3543 if err != nil {
3544 return err
3545 }
3546 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3547}
3548
3549func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
3550 omci := &SetTableResponse{}
3551 omci.MsgLayerType = LayerTypeSetTableResponse
3552 return decodingLayerDecoder(omci, data, p)
3553}
3554
3555// SerializeTo provides serialization of an Set Table Message Type Response
3556func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3557 // Basic (common) OMCI Header is 8 octets, 10
3558 err := omci.MeBasePacket.SerializeTo(b)
3559 if err != nil {
3560 return err
3561 }
3562 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3563}
3564
3565/////////////////////////////////////////////////////////////////////////////
3566//
3567type UnsupportedMessageTypeResponse struct {
3568 MeBasePacket
3569 Result me.Results
3570}
3571
3572// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
3573func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3574 return errors.New("you should never really decode this")
3575}
3576
3577// SerializeTo provides serialization of an Unsupported Message Type Response
3578func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3579 // Basic (common) OMCI Header is 8 octets, 10
3580 err := omci.MeBasePacket.SerializeTo(b)
3581 if err != nil {
3582 return err
3583 }
3584 bytes, err := b.AppendBytes(1)
3585 if err != nil {
3586 return err
3587 }
3588 bytes[0] = byte(omci.Result)
3589 return nil
3590}