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