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