blob: 553b7f3128d0732bb63dca920db559bdd9ca4388 [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
3 * Copyright 2020-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package omci
19
20import (
21 "encoding/binary"
22 "errors"
23 "fmt"
24 me "github.com/opencord/omci-lib-go/generated"
25 "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
728 if omci.Result == me.AttributeFailure {
729 lastOctet = 32
730 }
731 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:lastOctet], p, byte(GetResponseType))
732 if err != nil {
733 return err
734 }
735 // If Attribute failed or Unknown, decode optional attribute mask
736 if omci.Result == me.AttributeFailure {
737 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:34])
738 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:36])
739 }
740 // Validate all attributes support read
741 for attrName := range omci.Attributes {
742 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
743 if err != nil {
744 return err
745 }
746 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
747 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
748 return me.NewProcessingError(msg)
749 }
750 }
751 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
752 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
753 return nil
754 }
755 panic("All Managed Entities have an EntityID attribute")
756}
757
758func decodeGetResponse(data []byte, p gopacket.PacketBuilder) error {
759 omci := &GetResponse{}
760 omci.MsgLayerType = LayerTypeGetResponse
761 return decodingLayerDecoder(omci, data, p)
762}
763
764// SerializeTo provides serialization of an Get Response message
765func (omci *GetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
766 // Basic (common) OMCI Header is 8 octets, 10
767 if err := omci.MeBasePacket.SerializeTo(b); err != nil {
768 return err
769 }
770 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
771 me.ParamData{EntityID: omci.EntityInstance})
772
773 if omciErr.StatusCode() != me.Success {
774 return omciErr.GetError()
775 }
776 // ME needs to support Get
777 if !me.SupportsMsgType(meDefinition, me.Get) {
778 return me.NewProcessingError("managed entity does not support the Get Message-Type")
779 }
780 bytes, err := b.AppendBytes(3)
781 if err != nil {
782 return err
783 }
784 bytes[0] = byte(omci.Result)
785 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
786
787 // Validate all attributes support read
788 for attrName := range omci.Attributes {
789 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
790 if err != nil {
791 return err
792 }
793 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
794 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
795 return me.NewProcessingError(msg)
796 }
797 }
798 // Attribute serialization
799 switch omci.Result {
800 default:
801 break
802
803 case me.Success, me.AttributeFailure:
804 // TODO: Baseline only supported at this time)
805 available := MaxBaselineLength - 11 - 4 - 8
806
807 // Serialize to temporary buffer if we may need to reset values due to
808 // recoverable truncation errors
809 origBuffer := b
810 b := gopacket.NewSerializeBuffer()
811
812 err, failedMask := meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b, byte(GetResponseType),
813 available, opts.FixLengths)
814
815 if err == nil && failedMask != 0 && opts.FixLengths {
816 // Not all attributes would fit
817 omci.FailedAttributeMask |= failedMask
818 omci.AttributeMask &= ^failedMask
819 omci.Result = me.AttributeFailure
820
821 // Adjust already recorded values
822 bytes[0] = byte(omci.Result)
823 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
824 } else if err != nil {
825 return err
826 }
827 // Copy over attributes to the original serialization buffer
828 newSpace, err := origBuffer.AppendBytes(len(b.Bytes()))
829 if err != nil {
830 return err
831 }
832 copy(newSpace, b.Bytes())
833 b = origBuffer
834
835 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
836 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
837
838 remainingBytes, err := b.AppendBytes(bytesLeft + 4)
839 if err != nil {
840 return me.NewMessageTruncatedError(err.Error())
841 }
842 copy(remainingBytes, lotsOfZeros[:])
843
844 if omci.Result == me.AttributeFailure {
845 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
846 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
847 }
848 }
849 return nil
850}
851
852/////////////////////////////////////////////////////////////////////////////
853// GetAllAlarms
854type GetAllAlarmsRequest struct {
855 MeBasePacket
856 AlarmRetrievalMode byte
857}
858
859func (omci *GetAllAlarmsRequest) String() string {
860 return fmt.Sprintf("%v, Retrieval Mode: %v",
861 omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
862}
863
864// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
865func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
866 // Common ClassID/EntityID decode in msgBase
867 err := omci.MeBasePacket.DecodeFromBytes(data, p)
868 if err != nil {
869 return err
870 }
871 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
872 me.ParamData{EntityID: omci.EntityInstance})
873 if omciErr.StatusCode() != me.Success {
874 return omciErr.GetError()
875 }
876 // ME needs to support Get All Alarms
877 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
878 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
879 }
880 // Entity Class are always ONU DATA (2) and Entity Instance of 0
881 if omci.EntityClass != me.OnuDataClassID {
882 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
883 omci.EntityClass)
884 return me.NewProcessingError(msg)
885 }
886 if omci.EntityInstance != 0 {
887 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
888 omci.EntityInstance)
889 return me.NewUnknownInstanceError(msg)
890 }
891 omci.AlarmRetrievalMode = data[4]
892 if omci.AlarmRetrievalMode > 1 {
893 msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
894 omci.AlarmRetrievalMode)
895 return errors.New(msg)
896 }
897 return nil
898}
899
900func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
901 omci := &GetAllAlarmsRequest{}
902 omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
903 return decodingLayerDecoder(omci, data, p)
904}
905
906// SerializeTo provides serialization of an Get All Alarms Request message
907func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
908 // Basic (common) OMCI Header is 8 octets, 10
909 err := omci.MeBasePacket.SerializeTo(b)
910 if err != nil {
911 return err
912 }
913 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
914 me.ParamData{EntityID: omci.EntityInstance})
915 if omciErr.StatusCode() != me.Success {
916 return omciErr.GetError()
917 }
918 // ME needs to support Get All Alarms
919 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
920 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
921 }
922 bytes, err := b.AppendBytes(1)
923 if err != nil {
924 return err
925 }
926 bytes[0] = omci.AlarmRetrievalMode
927 return nil
928}
929
930/////////////////////////////////////////////////////////////////////////////
931// GetAllAlarms
932type GetAllAlarmsResponse struct {
933 MeBasePacket
934 NumberOfCommands uint16
935}
936
937func (omci *GetAllAlarmsResponse) String() string {
938 return fmt.Sprintf("%v, NumberOfCommands: %d",
939 omci.MeBasePacket.String(), omci.NumberOfCommands)
940}
941
942// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
943func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
944 // Common ClassID/EntityID decode in msgBase
945 err := omci.MeBasePacket.DecodeFromBytes(data, p)
946 if err != nil {
947 return err
948 }
949 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
950 me.ParamData{EntityID: omci.EntityInstance})
951 if omciErr.StatusCode() != me.Success {
952 return omciErr.GetError()
953 }
954 // ME needs to support Get All Alarms
955 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
956 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
957 }
958 // Entity Class are always ONU DATA (2) and Entity Instance of 0
959 if omci.EntityClass != me.OnuDataClassID {
960 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
961 omci.EntityClass)
962 return me.NewProcessingError(msg)
963 }
964 if omci.EntityInstance != 0 {
965 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
966 omci.EntityInstance)
967 return me.NewUnknownInstanceError(msg)
968 }
969 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
970 return nil
971}
972
973func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
974 omci := &GetAllAlarmsResponse{}
975 omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
976 return decodingLayerDecoder(omci, data, p)
977}
978
979// SerializeTo provides serialization of an Get All Alarms Response message
980func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
981 // Basic (common) OMCI Header is 8 octets, 10
982 err := omci.MeBasePacket.SerializeTo(b)
983 if err != nil {
984 return err
985 }
986 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
987 me.ParamData{EntityID: omci.EntityInstance})
988 if omciErr.StatusCode() != me.Success {
989 return omciErr.GetError()
990 }
991 // ME needs to support Get All Alarms
992 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
993 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
994 }
995 bytes, err := b.AppendBytes(2)
996 if err != nil {
997 return err
998 }
999 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1000 return nil
1001}
1002
1003/////////////////////////////////////////////////////////////////////////////
1004// GetAllAlarms
1005type GetAllAlarmsNextRequest struct {
1006 MeBasePacket
1007 CommandSequenceNumber uint16
1008}
1009
1010func (omci *GetAllAlarmsNextRequest) String() string {
1011 return fmt.Sprintf("%v, Sequence Number: %d",
1012 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1013}
1014
1015// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
1016func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1017 // Common ClassID/EntityID decode in msgBase
1018 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1019 if err != nil {
1020 return err
1021 }
1022 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1023 me.ParamData{EntityID: omci.EntityInstance})
1024 if omciErr.StatusCode() != me.Success {
1025 return omciErr.GetError()
1026 }
1027 // ME needs to support Get All Alarms
1028 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1029 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1030 }
1031 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1032 if omci.EntityClass != me.OnuDataClassID {
1033 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
1034 omci.EntityClass)
1035 return me.NewProcessingError(msg)
1036 }
1037 if omci.EntityInstance != 0 {
1038 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
1039 omci.EntityInstance)
1040 return me.NewUnknownInstanceError(msg)
1041 }
1042 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1043 return nil
1044}
1045
1046func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
1047 omci := &GetAllAlarmsNextRequest{}
1048 omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
1049 return decodingLayerDecoder(omci, data, p)
1050}
1051
1052// SerializeTo provides serialization of an Get All Alarms Next Request message
1053func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1054 // Basic (common) OMCI Header is 8 octets, 10
1055 err := omci.MeBasePacket.SerializeTo(b)
1056 if err != nil {
1057 return err
1058 }
1059 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1060 me.ParamData{EntityID: omci.EntityInstance})
1061 if omciErr.StatusCode() != me.Success {
1062 return omciErr.GetError()
1063 }
1064 // ME needs to support Get All Alarms Next
1065 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1066 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1067 }
1068 bytes, err := b.AppendBytes(2)
1069 if err != nil {
1070 return err
1071 }
1072 binary.BigEndian.PutUint16(bytes, omci.CommandSequenceNumber)
1073 return nil
1074}
1075
1076/////////////////////////////////////////////////////////////////////////////
1077// GetAllAlarms
1078type GetAllAlarmsNextResponse struct {
1079 MeBasePacket
1080 AlarmEntityClass me.ClassID
1081 AlarmEntityInstance uint16
1082 AlarmBitMap [28]byte // 224 bits
1083}
1084
1085func (omci *GetAllAlarmsNextResponse) String() string {
1086 return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
1087 omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
1088 omci.AlarmEntityInstance, omci.AlarmBitMap)
1089}
1090
1091// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
1092func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1093 // Common ClassID/EntityID decode in msgBase
1094 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1095 if err != nil {
1096 return err
1097 }
1098 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1099 me.ParamData{EntityID: omci.EntityInstance})
1100 if omciErr.StatusCode() != me.Success {
1101 return omciErr.GetError()
1102 }
1103 // ME needs to support Get All Alarms Next
1104 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1105 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1106 }
1107 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1108 if omci.EntityClass != me.OnuDataClassID {
1109 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
1110 omci.EntityClass)
1111 return me.NewProcessingError(msg)
1112 }
1113 if omci.EntityInstance != 0 {
1114 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
1115 omci.EntityInstance)
1116 return me.NewUnknownInstanceError(msg)
1117 }
1118 omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4:6]))
1119 omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6:8])
1120
1121 copy(omci.AlarmBitMap[:], data[8:36])
1122 return nil
1123}
1124
1125func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
1126 omci := &GetAllAlarmsNextResponse{}
1127 omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
1128 return decodingLayerDecoder(omci, data, p)
1129}
1130
1131// SerializeTo provides serialization of an Get All Alarms Next Response message
1132func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1133 // Basic (common) OMCI Header is 8 octets, 10
1134 err := omci.MeBasePacket.SerializeTo(b)
1135 if err != nil {
1136 return err
1137 }
1138 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1139 me.ParamData{EntityID: omci.EntityInstance})
1140 if omciErr.StatusCode() != me.Success {
1141 return omciErr.GetError()
1142 }
1143 // ME needs to support Get All Alarms Next
1144 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1145 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1146 }
1147 bytes, err := b.AppendBytes(2 + 2 + 28)
1148 if err != nil {
1149 return err
1150 }
1151 binary.BigEndian.PutUint16(bytes[0:], uint16(omci.AlarmEntityClass))
1152 binary.BigEndian.PutUint16(bytes[2:], omci.AlarmEntityInstance)
1153 copy(bytes[4:], omci.AlarmBitMap[:])
1154 return nil
1155}
1156
1157/////////////////////////////////////////////////////////////////////////////
1158// MibUploadRequest
1159type MibUploadRequest struct {
1160 MeBasePacket
1161}
1162
1163func (omci *MibUploadRequest) String() string {
1164 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1165}
1166
1167// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
1168func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1169 // Common ClassID/EntityID decode in msgBase
1170 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1171 if err != nil {
1172 return err
1173 }
1174 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1175 me.ParamData{EntityID: omci.EntityInstance})
1176 if omciErr.StatusCode() != me.Success {
1177 return omciErr.GetError()
1178 }
1179 // ME needs to support MIB Upload
1180 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1181 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1182 }
1183 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1184 if omci.EntityClass != me.OnuDataClassID {
1185 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
1186 omci.EntityClass)
1187 return me.NewProcessingError(msg)
1188 }
1189 if omci.EntityInstance != 0 {
1190 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
1191 omci.EntityInstance)
1192 return me.NewUnknownInstanceError(msg)
1193 }
1194 return nil
1195}
1196
1197func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
1198 omci := &MibUploadRequest{}
1199 omci.MsgLayerType = LayerTypeMibUploadRequest
1200 return decodingLayerDecoder(omci, data, p)
1201}
1202
1203// SerializeTo provides serialization of an MIB Upload Request message
1204func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1205 // Basic (common) OMCI Header is 8 octets, 10
1206 err := omci.MeBasePacket.SerializeTo(b)
1207 if err != nil {
1208 return err
1209 }
1210 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1211 me.ParamData{EntityID: omci.EntityInstance})
1212 if omciErr.StatusCode() != me.Success {
1213 return omciErr.GetError()
1214 }
1215 // ME needs to support Get
1216 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1217 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1218 }
1219 return nil
1220}
1221
1222/////////////////////////////////////////////////////////////////////////////
1223// MibUploadResponse
1224type MibUploadResponse struct {
1225 MeBasePacket
1226 NumberOfCommands uint16
1227}
1228
1229func (omci *MibUploadResponse) String() string {
1230 return fmt.Sprintf("%v, NumberOfCommands: %#v",
1231 omci.MeBasePacket.String(), omci.NumberOfCommands)
1232}
1233
1234// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
1235func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1236 // Common ClassID/EntityID decode in msgBase
1237 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1238 if err != nil {
1239 return err
1240 }
1241 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1242 me.ParamData{EntityID: omci.EntityInstance})
1243 if omciErr.StatusCode() != me.Success {
1244 return omciErr.GetError()
1245 }
1246 // ME needs to support MIB Upload
1247 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1248 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1249 }
1250 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1251 if omci.EntityClass != me.OnuDataClassID {
1252 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
1253 omci.EntityClass)
1254 return me.NewProcessingError(msg)
1255 }
1256 if omci.EntityInstance != 0 {
1257 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
1258 omci.EntityInstance)
1259 return me.NewUnknownInstanceError(msg)
1260 }
1261 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1262 return nil
1263}
1264
1265func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
1266 omci := &MibUploadResponse{}
1267 omci.MsgLayerType = LayerTypeMibUploadResponse
1268 return decodingLayerDecoder(omci, data, p)
1269}
1270
1271// SerializeTo provides serialization of an MIB Upload Response message
1272func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1273 // Basic (common) OMCI Header is 8 octets, 10
1274 err := omci.MeBasePacket.SerializeTo(b)
1275 if err != nil {
1276 return err
1277 }
1278 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1279 me.ParamData{EntityID: omci.EntityInstance})
1280 if omciErr.StatusCode() != me.Success {
1281 return omciErr.GetError()
1282 }
1283 // ME needs to support MIB Upload
1284 if !me.SupportsMsgType(entity, me.MibUpload) {
1285 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1286 }
1287 bytes, err := b.AppendBytes(2)
1288 if err != nil {
1289 return err
1290 }
1291 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1292 return nil
1293}
1294
1295/////////////////////////////////////////////////////////////////////////////
1296//
1297type MibUploadNextRequest struct {
1298 MeBasePacket
1299 CommandSequenceNumber uint16
1300}
1301
1302func (omci *MibUploadNextRequest) String() string {
1303 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
1304 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1305}
1306
1307// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
1308func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1309 // Common ClassID/EntityID decode in msgBase
1310 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1311 if err != nil {
1312 return err
1313 }
1314 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1315 me.ParamData{EntityID: omci.EntityInstance})
1316 if omciErr.StatusCode() != me.Success {
1317 return omciErr.GetError()
1318 }
1319 // ME needs to support Get All Alarms
1320 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1321 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1322 }
1323 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1324 if omci.EntityClass != me.OnuDataClassID {
1325 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
1326 omci.EntityClass)
1327 return me.NewProcessingError(msg)
1328 }
1329 if omci.EntityInstance != 0 {
1330 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
1331 omci.EntityInstance)
1332 return me.NewUnknownInstanceError(msg)
1333 }
1334 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1335 return nil
1336}
1337
1338func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
1339 omci := &MibUploadNextRequest{}
1340 omci.MsgLayerType = LayerTypeMibUploadNextRequest
1341 return decodingLayerDecoder(omci, data, p)
1342}
1343
1344// SerializeTo provides serialization of an MIB Upload Next Request message
1345func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1346 // Basic (common) OMCI Header is 8 octets, 10
1347 err := omci.MeBasePacket.SerializeTo(b)
1348 if err != nil {
1349 return err
1350 }
1351 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1352 me.ParamData{EntityID: omci.EntityInstance})
1353 if omciErr.StatusCode() != me.Success {
1354 return omciErr.GetError()
1355 }
1356 // ME needs to support MIB upload
1357 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1358 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1359 }
1360 bytes, err := b.AppendBytes(2)
1361 if err != nil {
1362 return err
1363 }
1364 binary.BigEndian.PutUint16(bytes[0:2], omci.CommandSequenceNumber)
1365 return nil
1366}
1367
1368/////////////////////////////////////////////////////////////////////////////
1369//
1370type MibUploadNextResponse struct {
1371 MeBasePacket
1372 ReportedME me.ManagedEntity
1373}
1374
1375func (omci *MibUploadNextResponse) String() string {
1376 return fmt.Sprintf("%v, ReportedME: [%v]",
1377 omci.MeBasePacket.String(), omci.ReportedME.String())
1378}
1379
1380// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
1381func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1382 // Common ClassID/EntityID decode in msgBase
1383 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1384 if err != nil {
1385 return err
1386 }
1387 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1388 me.ParamData{EntityID: omci.EntityInstance})
1389 if omciErr.StatusCode() != me.Success {
1390 return omciErr.GetError()
1391 }
1392 // ME needs to support MibUploadNext
1393 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1394 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1395 }
1396 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1397 if omci.EntityClass != me.OnuDataClassID {
1398 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
1399 omci.EntityClass)
1400 return me.NewProcessingError(msg)
1401 }
1402 if omci.EntityInstance != 0 {
1403 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
1404 omci.EntityInstance)
1405 return me.NewUnknownInstanceError(msg)
1406 }
1407 // Decode reported ME. If an out-of-range sequence number was sent, this will
1408 // contain an ME with class ID and entity ID of zero and you should get an
1409 // error of "managed entity definition not found" returned.
1410 return omci.ReportedME.DecodeFromBytes(data[4:], p, byte(MibUploadNextResponseType))
1411}
1412
1413func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
1414 omci := &MibUploadNextResponse{}
1415 omci.MsgLayerType = LayerTypeMibUploadNextResponse
1416 return decodingLayerDecoder(omci, data, p)
1417}
1418
1419// SerializeTo provides serialization of an MIB Upload Next Response message
1420func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1421 // Basic (common) OMCI Header is 8 octets, 10
1422 err := omci.MeBasePacket.SerializeTo(b)
1423 if err != nil {
1424 return err
1425 }
1426 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1427 me.ParamData{EntityID: omci.EntityInstance})
1428 if omciErr.StatusCode() != me.Success {
1429 return omciErr.GetError()
1430 }
1431 // ME needs to support MIB Upload
1432 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1433 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1434 }
1435 // TODO: Only Baseline supported at this time
1436 bytesAvailable := MaxBaselineLength - 8 - 8
1437
1438 return omci.ReportedME.SerializeTo(b, byte(MibUploadNextResponseType), bytesAvailable, opts)
1439}
1440
1441/////////////////////////////////////////////////////////////////////////////
1442// MibResetRequest
1443type MibResetRequest struct {
1444 MeBasePacket
1445}
1446
1447func (omci *MibResetRequest) String() string {
1448 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1449}
1450
1451// DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
1452func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1453 // Common ClassID/EntityID decode in msgBase
1454 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1455 if err != nil {
1456 return err
1457 }
1458 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1459 me.ParamData{EntityID: omci.EntityInstance})
1460 if omciErr.StatusCode() != me.Success {
1461 return omciErr.GetError()
1462 }
1463 // ME needs to support MIB reset
1464 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1465 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1466 }
1467 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1468 if omci.EntityClass != me.OnuDataClassID {
1469 msg := fmt.Sprintf("invalid Entity Class for MIB Reset request: %v",
1470 omci.EntityClass)
1471 return me.NewProcessingError(msg)
1472 }
1473 if omci.EntityInstance != 0 {
1474 msg := fmt.Sprintf("invalid Entity Instance for MIB Reset request: %v",
1475 omci.EntityInstance)
1476 return me.NewUnknownInstanceError(msg)
1477 }
1478 return nil
1479}
1480
1481func decodeMibResetRequest(data []byte, p gopacket.PacketBuilder) error {
1482 omci := &MibResetRequest{}
1483 omci.MsgLayerType = LayerTypeMibResetRequest
1484 return decodingLayerDecoder(omci, data, p)
1485}
1486
1487// SerializeTo provides serialization of an MIB Reset Request message
1488func (omci *MibResetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1489 // Add class ID and entity ID
1490 return omci.MeBasePacket.SerializeTo(b)
1491}
1492
1493/////////////////////////////////////////////////////////////////////////////
1494// MibResetResponse
1495type MibResetResponse struct {
1496 MeBasePacket
1497 Result me.Results
1498}
1499
1500func (omci *MibResetResponse) String() string {
1501 return fmt.Sprintf("%v, Result: %d (%v)",
1502 omci.MeBasePacket.String(), omci.Result, omci.Result)
1503}
1504
1505// DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
1506func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1507 // Common ClassID/EntityID decode in msgBase
1508 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1509 if err != nil {
1510 return err
1511 }
1512 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1513 me.ParamData{EntityID: omci.EntityInstance})
1514 if omciErr.StatusCode() != me.Success {
1515 return omciErr.GetError()
1516 }
1517 // ME needs to support MIB reset
1518 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1519 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1520 }
1521 // MIB Reset Response Entity Class always ONU DATA (2) and
1522 // Entity Instance of 0
1523 if omci.EntityClass != me.OnuDataClassID {
1524 return me.NewProcessingError("invalid Entity Class for MIB Reset Response")
1525 }
1526 if omci.EntityInstance != 0 {
1527 return me.NewUnknownInstanceError("invalid Entity Instance for MIB Reset Response")
1528 }
1529 omci.Result = me.Results(data[4])
1530 if omci.Result > me.DeviceBusy {
1531 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
1532 return errors.New(msg)
1533 }
1534 return nil
1535}
1536
1537func decodeMibResetResponse(data []byte, p gopacket.PacketBuilder) error {
1538 omci := &MibResetResponse{}
1539 omci.MsgLayerType = LayerTypeMibResetResponse
1540 return decodingLayerDecoder(omci, data, p)
1541}
1542
1543// SerializeTo provides serialization of an MIB Reset Response message
1544func (omci *MibResetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1545 // Basic (common) OMCI Header is 8 octets, 10
1546 err := omci.MeBasePacket.SerializeTo(b)
1547 if err != nil {
1548 return err
1549 }
1550 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1551 me.ParamData{EntityID: omci.EntityInstance})
1552 if omciErr.StatusCode() != me.Success {
1553 return omciErr.GetError()
1554 }
1555 // ME needs to support Set
1556 if !me.SupportsMsgType(entity, me.MibReset) {
1557 return me.NewProcessingError("managed entity does not support the MIB Reset Message-Type")
1558 }
1559 bytes, err := b.AppendBytes(1)
1560 if err != nil {
1561 return err
1562 }
1563 bytes[0] = byte(omci.Result)
1564 return nil
1565}
1566
1567/////////////////////////////////////////////////////////////////////////////
1568// AlarmNotificationMsg
1569const AlarmBitmapSize = 224
1570
1571type AlarmNotificationMsg struct {
1572 MeBasePacket
1573 AlarmBitmap [AlarmBitmapSize / 8]byte
1574 zeroPadding [3]byte
1575 AlarmSequenceNumber byte
1576}
1577
1578func (omci *AlarmNotificationMsg) String() string {
1579 return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
1580 omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
1581}
1582
1583func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
1584 if alarmNumber >= AlarmBitmapSize {
1585 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1586 return false, errors.New(msg)
1587 }
1588 octet := alarmNumber / 8
1589 bit := 7 - (alarmNumber % 8)
1590 return omci.AlarmBitmap[octet]>>bit == 1, nil
1591}
1592
1593func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
1594 if alarmNumber >= AlarmBitmapSize {
1595 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1596 return false, errors.New(msg)
1597 }
1598 octet := alarmNumber / 8
1599 bit := 7 - (alarmNumber % 8)
1600 return omci.AlarmBitmap[octet]>>bit == 0, nil
1601}
1602
1603func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
1604 if alarmNumber >= AlarmBitmapSize {
1605 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1606 return errors.New(msg)
1607 }
1608 octet := alarmNumber / 8
1609 bit := 7 - (alarmNumber % 8)
1610 omci.AlarmBitmap[octet] |= 1 << bit
1611 return nil
1612}
1613
1614func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
1615 if alarmNumber >= AlarmBitmapSize {
1616 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1617 return errors.New(msg)
1618 }
1619 octet := alarmNumber / 8
1620 bit := 7 - (alarmNumber % 8)
1621 omci.AlarmBitmap[octet] &= ^(1 << bit)
1622 return nil
1623}
1624
1625// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
1626func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1627 // Common ClassID/EntityID decode in msgBase
1628 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1629 if err != nil {
1630 return err
1631 }
1632 //var meDefinition me.IManagedEntityDefinition
1633 //meDefinition, err = me.LoadManagedEntityDefinition(omci.EntityClass,
1634 // me.ParamData{EntityID: omci.EntityInstance})
1635 //if err != nil {
1636 // return err
1637 //}
1638 // ME needs to support Alarms
1639 // TODO: Add attribute to ME to specify that alarm is allowed
1640 //if !me.SupportsMsgType(meDefinition, me.MibReset) {
1641 // return me.NewProcesssingError("managed entity does not support MIB Reset Message-Type")
1642 //}
1643 for index, octet := range data[4 : (AlarmBitmapSize/8)-4] {
1644 omci.AlarmBitmap[index] = octet
1645 }
1646 padOffset := 4 + (AlarmBitmapSize / 8)
1647 omci.zeroPadding[0] = data[padOffset]
1648 omci.zeroPadding[1] = data[padOffset+1]
1649 omci.zeroPadding[2] = data[padOffset+2]
1650
1651 omci.AlarmSequenceNumber = data[padOffset+3]
1652 return nil
1653}
1654
1655func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
1656 omci := &AlarmNotificationMsg{}
1657 omci.MsgLayerType = LayerTypeAlarmNotification
1658 return decodingLayerDecoder(omci, data, p)
1659}
1660
1661// SerializeTo provides serialization of an Alarm Notification message
1662func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1663 // Basic (common) OMCI Header is 8 octets, 10
1664 err := omci.MeBasePacket.SerializeTo(b)
1665 if err != nil {
1666 return err
1667 }
1668 //var meDefinition me.IManagedEntityDefinition
1669 //meDefinition, err = me.LoadManagedEntityDefinition(omci.EntityClass,
1670 // me.ParamData{EntityID: omci.EntityInstance})
1671 //if err != nil {
1672 // return err
1673 //}
1674 // ME needs to support Alarms
1675 // TODO: Add attribute to ME to specify that alarm is allowed
1676 //if !me.SupportsMsgType(meDefinition, me.MibReset) {
1677 // return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1678 //}
1679 bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
1680 if err != nil {
1681 return err
1682 }
1683 for index, octet := range omci.AlarmBitmap {
1684 bytes[index] = octet
1685 }
1686 padOffset := AlarmBitmapSize / 8
1687 bytes[padOffset] = 0
1688 bytes[padOffset+1] = 0
1689 bytes[padOffset+2] = 0
1690 bytes[padOffset+3] = omci.AlarmSequenceNumber
1691 return nil
1692}
1693
1694/////////////////////////////////////////////////////////////////////////////
1695// AttributeValueChangeMsg
1696type AttributeValueChangeMsg struct {
1697 MeBasePacket
1698 AttributeMask uint16
1699 Attributes me.AttributeValueMap
1700}
1701
1702func (omci *AttributeValueChangeMsg) String() string {
1703 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
1704 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
1705}
1706
1707// DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
1708func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1709 // Common ClassID/EntityID decode in msgBase
1710 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1711 if err != nil {
1712 return err
1713 }
1714 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1715 me.ParamData{EntityID: omci.EntityInstance})
1716 if omciErr.StatusCode() != me.Success {
1717 return omciErr.GetError()
1718 }
1719 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
1720 // Attribute decode
1721 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:40], p, byte(AttributeValueChangeType))
1722 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1723 // Validate all attributes support AVC
1724 //for attrName := range omci.attributes {
1725 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1726 // if err != nil {
1727 // return err
1728 // }
1729 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1730 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1731 // return me.NewProcessingError(msg)
1732 // }
1733 //}
1734 return err
1735}
1736
1737func decodeAttributeValueChange(data []byte, p gopacket.PacketBuilder) error {
1738 omci := &AttributeValueChangeMsg{}
1739 omci.MsgLayerType = LayerTypeAttributeValueChange
1740 return decodingLayerDecoder(omci, data, p)
1741}
1742
1743// SerializeTo provides serialization of an Attribute Value Change Notification message
1744func (omci *AttributeValueChangeMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1745 // Basic (common) OMCI Header is 8 octets, 10
1746 err := omci.MeBasePacket.SerializeTo(b)
1747 if err != nil {
1748 return err
1749 }
1750 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1751 me.ParamData{EntityID: omci.EntityInstance})
1752 if omciErr.StatusCode() != me.Success {
1753 return omciErr.GetError()
1754 }
1755 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1756 // Validate all attributes support AVC
1757 //for attrName := range omci.attributes {
1758 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1759 // if err != nil {
1760 // return err
1761 // }
1762 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1763 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1764 // return me.NewProcessingError(msg)
1765 // }
1766 //}
1767 bytes, err := b.AppendBytes(2)
1768 if err != nil {
1769 return err
1770 }
1771 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
1772
1773 // Attribute serialization
1774 // TODO: Only Baseline supported at this time
1775 bytesAvailable := MaxBaselineLength - 10 - 8
1776
1777 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
1778 byte(AttributeValueChangeType), bytesAvailable, false)
1779 return err
1780}
1781
1782/////////////////////////////////////////////////////////////////////////////
1783// TestRequest: TODO: Not yet implemented
1784type TestRequest struct {
1785 MeBasePacket
1786}
1787
1788func (omci *TestRequest) String() string {
1789 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1790}
1791
1792// DecodeFromBytes decodes the given bytes of a Test Request into this layer
1793func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1794 // Common ClassID/EntityID decode in msgBase
1795 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1796 if err != nil {
1797 return err
1798 }
1799 return errors.New("need to implement") // TODO: Fix me) // return nil
1800}
1801
1802func decodeTestRequest(data []byte, p gopacket.PacketBuilder) error {
1803 omci := &TestRequest{}
1804 omci.MsgLayerType = LayerTypeTestRequest
1805 return decodingLayerDecoder(omci, data, p)
1806}
1807
1808// SerializeTo provides serialization of an Test Request message
1809func (omci *TestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1810 // Basic (common) OMCI Header is 8 octets, 10
1811 err := omci.MeBasePacket.SerializeTo(b)
1812 if err != nil {
1813 return err
1814 }
1815 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1816}
1817
1818/////////////////////////////////////////////////////////////////////////////
1819// TestResponse: TODO: Not yet implemented
1820type TestResponse struct {
1821 MeBasePacket
1822}
1823
1824func (omci *TestResponse) String() string {
1825 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1826}
1827
1828// DecodeFromBytes decodes the given bytes of a Test Response into this layer
1829func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1830 // Common ClassID/EntityID decode in msgBase
1831 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1832 if err != nil {
1833 return err
1834 }
1835 return errors.New("need to implement") // TODO: Fix me) // return nil
1836}
1837
1838func decodeTestResponse(data []byte, p gopacket.PacketBuilder) error {
1839 omci := &TestResponse{}
1840 omci.MsgLayerType = LayerTypeTestResponse
1841 return decodingLayerDecoder(omci, data, p)
1842}
1843
1844// SerializeTo provides serialization of an Test Response message
1845func (omci *TestResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1846 // Basic (common) OMCI Header is 8 octets, 10
1847 err := omci.MeBasePacket.SerializeTo(b)
1848 if err != nil {
1849 return err
1850 }
1851 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1852}
1853
1854/////////////////////////////////////////////////////////////////////////////
1855//
1856type StartSoftwareDownloadRequest struct {
1857 MeBasePacket // Note: EntityInstance for software download is two specific values
1858 WindowSize byte // Window Size -1
1859 ImageSize uint32 // Octets
1860 NumberOfCircuitPacks byte
1861 CircuitPacks []uint16 // MSB & LSB of software image instance
1862}
1863
1864func (omci *StartSoftwareDownloadRequest) String() string {
1865 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
1866 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
1867}
1868
1869// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
1870func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1871 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1872 if err != nil {
1873 return err
1874 }
1875 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1876 me.ParamData{EntityID: omci.EntityInstance})
1877 if omciErr.StatusCode() != me.Success {
1878 return omciErr.GetError()
1879 }
1880 // ME needs to support Start Software Download
1881 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
1882 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
1883 }
1884 // Software Image Entity Class are always use the Software Image
1885 if omci.EntityClass != me.SoftwareImageClassID {
1886 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1887 }
1888 omci.WindowSize = data[4]
1889 omci.ImageSize = binary.BigEndian.Uint32(data[5:9])
1890 omci.NumberOfCircuitPacks = data[9]
1891 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
1892 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1893 omci.NumberOfCircuitPacks))
1894 }
1895 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
1896 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
1897 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[10+(index*2):])
1898 }
1899 return nil
1900}
1901
1902func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
1903 omci := &StartSoftwareDownloadRequest{}
1904 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
1905 return decodingLayerDecoder(omci, data, p)
1906}
1907
1908// SerializeTo provides serialization of an Start Software Download Request message
1909func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1910 // Basic (common) OMCI Header is 8 octets, 10
1911 err := omci.MeBasePacket.SerializeTo(b)
1912 if err != nil {
1913 return err
1914 }
1915 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1916 me.ParamData{EntityID: omci.EntityInstance})
1917 if omciErr.StatusCode() != me.Success {
1918 return omciErr.GetError()
1919 }
1920 // ME needs to support Start Software Download
1921 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
1922 return me.NewProcessingError("managed entity does not support the SStart Software Download Message-Type")
1923 }
1924 // Software Image Entity Class are always use the Software Image
1925 if omci.EntityClass != me.SoftwareImageClassID {
1926 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1927 }
1928 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
1929 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1930 omci.NumberOfCircuitPacks))
1931 }
1932 bytes, err := b.AppendBytes(6 + (2 * int(omci.NumberOfCircuitPacks)))
1933 if err != nil {
1934 return err
1935 }
1936 bytes[0] = omci.WindowSize
1937 binary.BigEndian.PutUint32(bytes[1:], omci.ImageSize)
1938 bytes[5] = omci.NumberOfCircuitPacks
1939 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
1940 binary.BigEndian.PutUint16(bytes[6+(index*2):], omci.CircuitPacks[index])
1941 }
1942 return nil
1943}
1944
1945/////////////////////////////////////////////////////////////////////////////
1946//
1947type downloadResults struct {
1948 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
1949 Result me.Results
1950}
1951
1952func (dr *downloadResults) String() string {
1953 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
1954 dr.Result, dr.Result)
1955}
1956
1957type StartSoftwareDownloadResponse struct {
1958 MeBasePacket // Note: EntityInstance for software download is two specific values
1959 Result me.Results
1960 WindowSize byte // Window Size -1
1961 NumberOfInstances byte
1962 MeResults []downloadResults
1963}
1964
1965func (omci *StartSoftwareDownloadResponse) String() string {
1966 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
1967 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
1968}
1969
1970// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
1971func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1972 // Common ClassID/EntityID decode in msgBase
1973 err := omci.MeBasePacket.DecodeFromBytes(data, p)
1974 if err != nil {
1975 return err
1976 }
1977 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1978 me.ParamData{EntityID: omci.EntityInstance})
1979 if omciErr.StatusCode() != me.Success {
1980 return omciErr.GetError()
1981 }
1982 // ME needs to support Start Software Download
1983 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
1984 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
1985 }
1986 // Software Image Entity Class are always use the Software Image
1987 if omci.EntityClass != me.SoftwareImageClassID {
1988 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
1989 }
1990 omci.Result = me.Results(data[4])
1991 if omci.Result > me.DeviceBusy {
1992 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
1993 omci.Result)
1994 return errors.New(msg)
1995 }
1996 omci.WindowSize = data[5]
1997 omci.NumberOfInstances = data[6]
1998
1999 if omci.NumberOfInstances > 9 {
2000 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2001 omci.NumberOfInstances)
2002 return errors.New(msg)
2003 }
2004 if omci.NumberOfInstances > 0 {
2005 omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
2006
2007 for index := 0; index < int(omci.NumberOfInstances); index++ {
2008 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
2009 omci.MeResults[index].Result = me.Results(data[9+(index*3)])
2010 if omci.MeResults[index].Result > me.DeviceBusy {
2011 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2012 index, omci.MeResults[index])
2013 return errors.New(msg)
2014 }
2015 }
2016 }
2017 return nil
2018}
2019
2020func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2021 omci := &StartSoftwareDownloadResponse{}
2022 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
2023 return decodingLayerDecoder(omci, data, p)
2024}
2025
2026// SerializeTo provides serialization of an Start Software Download Response message
2027func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2028 // Basic (common) OMCI Header is 8 octets, 10
2029 err := omci.MeBasePacket.SerializeTo(b)
2030 if err != nil {
2031 return err
2032 }
2033 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2034 me.ParamData{EntityID: omci.EntityInstance})
2035 if omciErr.StatusCode() != me.Success {
2036 return omciErr.GetError()
2037 }
2038 // ME needs to support Start Software Download
2039 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2040 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2041 }
2042 // Software Image Entity Class are always use the Software Image
2043 if omci.EntityClass != me.SoftwareImageClassID {
2044 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2045 }
2046 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2047 if err != nil {
2048 return err
2049 }
2050 if omci.Result > me.DeviceBusy {
2051 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2052 omci.Result)
2053 return errors.New(msg)
2054 }
2055 bytes[0] = byte(omci.Result)
2056 bytes[1] = omci.WindowSize
2057 bytes[2] = omci.NumberOfInstances
2058
2059 if omci.NumberOfInstances > 9 {
2060 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2061 omci.NumberOfInstances)
2062 return errors.New(msg)
2063 }
2064 if omci.NumberOfInstances > 0 {
2065 for index := 0; index < int(omci.NumberOfInstances); index++ {
2066 binary.BigEndian.PutUint16(bytes[3+(3*index):], omci.MeResults[index].ManagedEntityID)
2067
2068 if omci.MeResults[index].Result > me.DeviceBusy {
2069 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2070 index, omci.MeResults[index])
2071 return errors.New(msg)
2072 }
2073 bytes[5+(3*index)] = byte(omci.MeResults[index].Result)
2074 }
2075 }
2076 return nil
2077}
2078
2079/////////////////////////////////////////////////////////////////////////////
2080//
2081type DownloadSectionRequest struct {
2082 MeBasePacket // Note: EntityInstance for software download is two specific values
2083 SectionNumber byte
2084 SectionData [29]byte // 0 padding if final transfer requires only a partial block
2085}
2086
2087func (omci *DownloadSectionRequest) String() string {
2088 return fmt.Sprintf("%v, Section #: %v",
2089 omci.MeBasePacket.String(), omci.SectionNumber)
2090}
2091
2092// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
2093func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2094 // Common ClassID/EntityID decode in msgBase
2095 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2096 if err != nil {
2097 return err
2098 }
2099 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2100 me.ParamData{EntityID: omci.EntityInstance})
2101 if omciErr.StatusCode() != me.Success {
2102 return omciErr.GetError()
2103 }
2104 // ME needs to support Download section
2105 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2106 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2107 }
2108 // Software Image Entity Class are always use the Software Image
2109 if omci.EntityClass != me.SoftwareImageClassID {
2110 return me.NewProcessingError("invalid Entity Class for Download Section request")
2111 }
2112 omci.SectionNumber = data[4]
2113 copy(omci.SectionData[0:], data[5:])
2114 return nil
2115}
2116
2117func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2118 omci := &DownloadSectionRequest{}
2119 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2120 return decodingLayerDecoder(omci, data, p)
2121}
2122
2123// SerializeTo provides serialization of an Download Section Request message
2124func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2125 // Basic (common) OMCI Header is 8 octets, 10
2126 err := omci.MeBasePacket.SerializeTo(b)
2127 if err != nil {
2128 return err
2129 }
2130 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2131 me.ParamData{EntityID: omci.EntityInstance})
2132 if omciErr.StatusCode() != me.Success {
2133 return omciErr.GetError()
2134 }
2135 // ME needs to support Download section
2136 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2137 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2138 }
2139 // Software Image Entity Class are always use the Software Image
2140 if omci.EntityClass != me.SoftwareImageClassID {
2141 return me.NewProcessingError("invalid Entity Class for Download Section response")
2142 }
2143 bytes, err := b.AppendBytes(1 + 29)
2144 if err != nil {
2145 return err
2146 }
2147 bytes[0] = omci.SectionNumber
2148 copy(bytes[1:], omci.SectionData[0:])
2149 return nil
2150}
2151
2152/////////////////////////////////////////////////////////////////////////////
2153//
2154type DownloadSectionResponse struct {
2155 MeBasePacket // Note: EntityInstance for software download is two specific values
2156 Result me.Results
2157 SectionNumber byte
2158}
2159
2160func (omci *DownloadSectionResponse) String() string {
2161 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2162 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2163}
2164
2165// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
2166func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2167 // Common ClassID/EntityID decode in msgBase
2168 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2169 if err != nil {
2170 return err
2171 }
2172 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2173 me.ParamData{EntityID: omci.EntityInstance})
2174 if omciErr.StatusCode() != me.Success {
2175 return omciErr.GetError()
2176 }
2177 // ME needs to support Download section
2178 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2179 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2180 }
2181 // Software Image Entity Class are always use the Software Image
2182 if omci.EntityClass != me.SoftwareImageClassID {
2183 return me.NewProcessingError("invalid Entity Class for Download Section response")
2184 }
2185 omci.Result = me.Results(data[4])
2186 if omci.Result > me.DeviceBusy {
2187 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2188 omci.Result)
2189 return errors.New(msg)
2190 }
2191 omci.SectionNumber = data[5]
2192 return nil
2193}
2194
2195func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2196 omci := &DownloadSectionResponse{}
2197 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2198 return decodingLayerDecoder(omci, data, p)
2199}
2200
2201// SerializeTo provides serialization of an Download Section Response message
2202func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2203 // Basic (common) OMCI Header is 8 octets, 10
2204 err := omci.MeBasePacket.SerializeTo(b)
2205 if err != nil {
2206 return err
2207 }
2208 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2209 me.ParamData{EntityID: omci.EntityInstance})
2210 if omciErr.StatusCode() != me.Success {
2211 return omciErr.GetError()
2212 }
2213 // ME needs to support Download section
2214 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2215 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2216 }
2217 // Software Image Entity Class are always use the Software Image
2218 if omci.EntityClass != me.SoftwareImageClassID {
2219 return me.NewProcessingError("invalid Entity Class for Download Section response")
2220 }
2221 bytes, err := b.AppendBytes(2)
2222 if err != nil {
2223 return err
2224 }
2225 bytes[0] = omci.SectionNumber
2226 if omci.Result > me.DeviceBusy {
2227 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2228 omci.Result)
2229 return errors.New(msg)
2230 }
2231 bytes[1] = byte(omci.Result)
2232 return nil
2233}
2234
2235/////////////////////////////////////////////////////////////////////////////
2236//
2237type EndSoftwareDownloadRequest struct {
2238 MeBasePacket // Note: EntityInstance for software download is two specific values
2239 CRC32 uint32
2240 ImageSize uint32
2241 NumberOfInstances byte
2242 ImageInstances []uint16
2243}
2244
2245func (omci *EndSoftwareDownloadRequest) String() string {
2246 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2247 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2248}
2249
2250// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
2251func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2252 // Common ClassID/EntityID decode in msgBase
2253 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2254 if err != nil {
2255 return err
2256 }
2257 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2258 me.ParamData{EntityID: omci.EntityInstance})
2259 if omciErr.StatusCode() != me.Success {
2260 return omciErr.GetError()
2261 }
2262 // ME needs to support End Software Download
2263 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2264 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2265 }
2266 // Software Image Entity Class are always use the Software Image
2267 if omci.EntityClass != me.SoftwareImageClassID {
2268 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2269 }
2270 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2271 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
2272 omci.NumberOfInstances = data[13]
2273
2274 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2275 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2276 omci.NumberOfInstances))
2277 }
2278 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2279
2280 for index := 0; index < int(omci.NumberOfInstances); index++ {
2281 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[14+(index*2):])
2282 }
2283 return nil
2284}
2285
2286func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2287 omci := &EndSoftwareDownloadRequest{}
2288 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2289 return decodingLayerDecoder(omci, data, p)
2290}
2291
2292// SerializeTo provides serialization of an End Software Download Request message
2293func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2294 // Basic (common) OMCI Header is 8 octets, 10
2295 err := omci.MeBasePacket.SerializeTo(b)
2296 if err != nil {
2297 return err
2298 }
2299 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2300 me.ParamData{EntityID: omci.EntityInstance})
2301 if omciErr.StatusCode() != me.Success {
2302 return omciErr.GetError()
2303 }
2304 // ME needs to support End Software Download
2305 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2306 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2307 }
2308 // Software Image Entity Class are always use the Software Image
2309 if omci.EntityClass != me.SoftwareImageClassID {
2310 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2311 }
2312 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2313 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2314 omci.NumberOfInstances))
2315 }
2316 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2317 if err != nil {
2318 return err
2319 }
2320 binary.BigEndian.PutUint32(bytes[4:8], omci.CRC32)
2321 binary.BigEndian.PutUint32(bytes[8:12], omci.ImageSize)
2322 bytes[13] = omci.NumberOfInstances
2323 for index := 0; index < int(omci.NumberOfInstances); index++ {
2324 binary.BigEndian.PutUint16(bytes[14+(index*2):], omci.ImageInstances[index])
2325 }
2326 return nil
2327}
2328
2329/////////////////////////////////////////////////////////////////////////////
2330//
2331type EndSoftwareDownloadResponse struct {
2332 MeBasePacket // Note: EntityInstance for software download is two specific values
2333 Result me.Results
2334 NumberOfInstances byte
2335 MeResults []downloadResults
2336}
2337
2338func (omci *EndSoftwareDownloadResponse) String() string {
2339 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2340 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2341}
2342
2343// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
2344func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2345 // Common ClassID/EntityID decode in msgBase
2346 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2347 if err != nil {
2348 return err
2349 }
2350 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2351 me.ParamData{EntityID: omci.EntityInstance})
2352 if omciErr.StatusCode() != me.Success {
2353 return omciErr.GetError()
2354 }
2355 // ME needs to support End Software Download
2356 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2357 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2358 }
2359 // Software Image Entity Class are always use the Software Image
2360 if omci.EntityClass != me.SoftwareImageClassID {
2361 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2362 }
2363 omci.Result = me.Results(data[4])
2364 if omci.Result > me.DeviceBusy {
2365 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2366 omci.Result)
2367 return errors.New(msg)
2368 }
2369 omci.NumberOfInstances = data[5]
2370
2371 if omci.NumberOfInstances > 9 {
2372 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2373 omci.NumberOfInstances)
2374 return errors.New(msg)
2375 }
2376 if omci.NumberOfInstances > 0 {
2377 omci.MeResults = make([]downloadResults, omci.NumberOfInstances)
2378
2379 for index := 0; index < int(omci.NumberOfInstances); index++ {
2380 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2381 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2382 if omci.MeResults[index].Result > me.DeviceBusy {
2383 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2384 index, omci.MeResults[index])
2385 return errors.New(msg)
2386 }
2387 }
2388 }
2389 return nil
2390}
2391
2392func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2393 omci := &EndSoftwareDownloadResponse{}
2394 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2395 return decodingLayerDecoder(omci, data, p)
2396}
2397
2398// SerializeTo provides serialization of an End Software Download Response message
2399func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2400 // Basic (common) OMCI Header is 8 octets, 10
2401 err := omci.MeBasePacket.SerializeTo(b)
2402 if err != nil {
2403 return err
2404 }
2405 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2406 me.ParamData{EntityID: omci.EntityInstance})
2407 if omciErr.StatusCode() != me.Success {
2408 return omciErr.GetError()
2409 }
2410 // ME needs to support End Software Download
2411 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2412 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2413 }
2414 // Software Image Entity Class are always use the Software Image
2415 if omci.EntityClass != me.SoftwareImageClassID {
2416 return me.NewProcessingError("invalid Entity Class for End Download response")
2417 }
2418 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2419 if err != nil {
2420 return err
2421 }
2422 if omci.Result > me.DeviceBusy {
2423 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2424 omci.Result)
2425 return errors.New(msg)
2426 }
2427 bytes[0] = byte(omci.Result)
2428 bytes[1] = omci.NumberOfInstances
2429
2430 if omci.NumberOfInstances > 9 {
2431 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2432 omci.NumberOfInstances)
2433 return errors.New(msg)
2434 }
2435 if omci.NumberOfInstances > 0 {
2436 for index := 0; index < int(omci.NumberOfInstances); index++ {
2437 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2438
2439 if omci.MeResults[index].Result > me.DeviceBusy {
2440 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2441 index, omci.MeResults[index])
2442 return errors.New(msg)
2443 }
2444 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2445 }
2446 }
2447 return nil
2448}
2449
2450/////////////////////////////////////////////////////////////////////////////
2451//
2452type ActivateSoftwareRequest struct {
2453 MeBasePacket // Note: EntityInstance for software download is two specific values
2454 ActivateFlags byte
2455}
2456
2457func (omci *ActivateSoftwareRequest) String() string {
2458 return fmt.Sprintf("%v, Flags: %#x",
2459 omci.MeBasePacket.String(), omci.ActivateFlags)
2460}
2461
2462// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
2463func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2464 // Common ClassID/EntityID decode in msgBase
2465 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2466 if err != nil {
2467 return err
2468 }
2469 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2470 me.ParamData{EntityID: omci.EntityInstance})
2471 if omciErr.StatusCode() != me.Success {
2472 return omciErr.GetError()
2473 }
2474 // ME needs to support End Software Download
2475 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2476 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2477 }
2478 // Software Image Entity Class are always use the Software Image
2479 if omci.EntityClass != me.SoftwareImageClassID {
2480 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2481 }
2482 omci.ActivateFlags = data[4]
2483 if omci.ActivateFlags > 2 {
2484 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2485 omci.ActivateFlags))
2486 }
2487 return nil
2488}
2489
2490func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2491 omci := &ActivateSoftwareRequest{}
2492 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2493 return decodingLayerDecoder(omci, data, p)
2494}
2495
2496// SerializeTo provides serialization of an Activate Software message
2497func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2498 // Basic (common) OMCI Header is 8 octets, 10
2499 err := omci.MeBasePacket.SerializeTo(b)
2500 if err != nil {
2501 return err
2502 }
2503 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2504 me.ParamData{EntityID: omci.EntityInstance})
2505 if omciErr.StatusCode() != me.Success {
2506 return omciErr.GetError()
2507 }
2508 // ME needs to support End Software Download
2509 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2510 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2511 }
2512 // Software Image Entity Class are always use the Software Image
2513 if omci.EntityClass != me.SoftwareImageClassID {
2514 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2515 }
2516 bytes, err := b.AppendBytes(1)
2517 if err != nil {
2518 return err
2519 }
2520 bytes[0] = omci.ActivateFlags
2521 if omci.ActivateFlags > 2 {
2522 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2523 omci.ActivateFlags)
2524 return errors.New(msg)
2525 }
2526 return nil
2527}
2528
2529/////////////////////////////////////////////////////////////////////////////
2530//
2531type ActivateSoftwareResponse struct {
2532 MeBasePacket
2533 Result me.Results
2534}
2535
2536func (omci *ActivateSoftwareResponse) String() string {
2537 return fmt.Sprintf("%v, Result: %d (%v)",
2538 omci.MeBasePacket.String(), omci.Result, omci.Result)
2539}
2540
2541// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
2542func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2543 // Common ClassID/EntityID decode in msgBase
2544 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2545 if err != nil {
2546 return err
2547 }
2548 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2549 me.ParamData{EntityID: omci.EntityInstance})
2550 if omciErr.StatusCode() != me.Success {
2551 return omciErr.GetError()
2552 }
2553 // ME needs to support End Software Download
2554 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2555 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2556 }
2557 // Software Image Entity Class are always use the Software Image
2558 if omci.EntityClass != me.SoftwareImageClassID {
2559 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2560 }
2561 omci.Result = me.Results(data[4])
2562 if omci.Result > me.Results(6) {
2563 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2564 omci.Result)
2565 return errors.New(msg)
2566 }
2567 return nil
2568}
2569
2570func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2571 omci := &ActivateSoftwareResponse{}
2572 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2573 return decodingLayerDecoder(omci, data, p)
2574}
2575
2576// SerializeTo provides serialization of an Activate Software Response message
2577func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2578 // Basic (common) OMCI Header is 8 octets, 10
2579 err := omci.MeBasePacket.SerializeTo(b)
2580 if err != nil {
2581 return err
2582 }
2583 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2584 me.ParamData{EntityID: omci.EntityInstance})
2585 if omciErr.StatusCode() != me.Success {
2586 return omciErr.GetError()
2587 }
2588 // ME needs to support End Software Download
2589 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2590 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2591 }
2592 // Software Image Entity Class are always use the Software Image
2593 if omci.EntityClass != me.SoftwareImageClassID {
2594 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2595 }
2596 bytes, err := b.AppendBytes(1)
2597 if err != nil {
2598 return err
2599 }
2600 bytes[0] = byte(omci.Result)
2601 if omci.Result > me.Results(6) {
2602 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2603 omci.Result)
2604 return errors.New(msg)
2605 }
2606 return nil
2607}
2608
2609/////////////////////////////////////////////////////////////////////////////
2610//
2611type CommitSoftwareRequest struct {
2612 MeBasePacket
2613}
2614
2615func (omci *CommitSoftwareRequest) String() string {
2616 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2617}
2618
2619// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
2620func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2621 // Common ClassID/EntityID decode in msgBase
2622 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2623 if err != nil {
2624 return err
2625 }
2626 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2627 me.ParamData{EntityID: omci.EntityInstance})
2628 if omciErr.StatusCode() != me.Success {
2629 return omciErr.GetError()
2630 }
2631 // ME needs to support End Software Download
2632 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2633 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2634 }
2635 // Software Image Entity Class are always use the Software Image
2636 if omci.EntityClass != me.SoftwareImageClassID {
2637 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2638 }
2639 return nil
2640}
2641
2642func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2643 omci := &CommitSoftwareRequest{}
2644 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
2645 return decodingLayerDecoder(omci, data, p)
2646}
2647
2648// SerializeTo provides serialization of an Commit Software Request message
2649func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2650 // Basic (common) OMCI Header is 8 octets, 10
2651 err := omci.MeBasePacket.SerializeTo(b)
2652 if err != nil {
2653 return err
2654 }
2655 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2656 me.ParamData{EntityID: omci.EntityInstance})
2657 if omciErr.StatusCode() != me.Success {
2658 return omciErr.GetError()
2659 }
2660 // ME needs to support End Software Download
2661 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2662 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2663 }
2664 // Software Image Entity Class are always use the Software Image
2665 if omci.EntityClass != me.SoftwareImageClassID {
2666 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2667 }
2668 return nil
2669}
2670
2671/////////////////////////////////////////////////////////////////////////////
2672//
2673type CommitSoftwareResponse struct {
2674 MeBasePacket
2675}
2676
2677func (omci *CommitSoftwareResponse) String() string {
2678 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2679}
2680
2681// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
2682func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2683 // Common ClassID/EntityID decode in msgBase
2684 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2685 if err != nil {
2686 return err
2687 }
2688 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2689 me.ParamData{EntityID: omci.EntityInstance})
2690 if omciErr.StatusCode() != me.Success {
2691 return omciErr.GetError()
2692 }
2693 // ME needs to support End Software Download
2694 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2695 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2696 }
2697 // Software Image Entity Class are always use the Software Image
2698 if omci.EntityClass != me.SoftwareImageClassID {
2699 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2700 }
2701 return nil
2702}
2703
2704func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2705 omci := &CommitSoftwareResponse{}
2706 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
2707 return decodingLayerDecoder(omci, data, p)
2708}
2709
2710// SerializeTo provides serialization of an Commit Software Response message
2711func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2712 // Basic (common) OMCI Header is 8 octets, 10
2713 err := omci.MeBasePacket.SerializeTo(b)
2714 if err != nil {
2715 return err
2716 }
2717 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2718 me.ParamData{EntityID: omci.EntityInstance})
2719 if omciErr.StatusCode() != me.Success {
2720 return omciErr.GetError()
2721 }
2722 // ME needs to support End Software Download
2723 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2724 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2725 }
2726 // Software Image Entity Class are always use the Software Image
2727 if omci.EntityClass != me.SoftwareImageClassID {
2728 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2729 }
2730 return nil
2731}
2732
2733/////////////////////////////////////////////////////////////////////////////
2734//
2735type SynchronizeTimeRequest struct {
2736 MeBasePacket
2737 Year uint16
2738 Month uint8
2739 Day uint8
2740 Hour uint8
2741 Minute uint8
2742 Second uint8
2743}
2744
2745func (omci *SynchronizeTimeRequest) String() string {
2746 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
2747 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
2748}
2749
2750// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
2751func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2752 // Common ClassID/EntityID decode in msgBase
2753 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2754 if err != nil {
2755 return err
2756 }
2757 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2758 me.ParamData{EntityID: omci.EntityInstance})
2759 if omciErr.StatusCode() != me.Success {
2760 return omciErr.GetError()
2761 }
2762 // ME needs to support Synchronize Time
2763 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2764 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2765 }
2766 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
2767 if omci.EntityClass != me.OnuGClassID {
2768 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
2769 }
2770 if omci.EntityInstance != 0 {
2771 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
2772 }
2773 omci.Year = binary.BigEndian.Uint16(data[4:6])
2774 omci.Month = data[6]
2775 omci.Day = data[7]
2776 omci.Hour = data[8]
2777 omci.Minute = data[9]
2778 omci.Second = data[10]
2779 return nil
2780}
2781
2782func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
2783 omci := &SynchronizeTimeRequest{}
2784 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
2785 return decodingLayerDecoder(omci, data, p)
2786}
2787
2788// SerializeTo provides serialization of an Synchronize Time Request message
2789func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2790 // Basic (common) OMCI Header is 8 octets, 10
2791 err := omci.MeBasePacket.SerializeTo(b)
2792 if err != nil {
2793 return err
2794 }
2795 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2796 me.ParamData{EntityID: omci.EntityInstance})
2797 if omciErr.StatusCode() != me.Success {
2798 return omciErr.GetError()
2799 }
2800 // ME needs to support Synchronize Time
2801 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2802 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2803 }
2804 bytes, err := b.AppendBytes(7)
2805 if err != nil {
2806 return err
2807 }
2808 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
2809 bytes[2] = omci.Month
2810 bytes[3] = omci.Day
2811 bytes[4] = omci.Hour
2812 bytes[5] = omci.Minute
2813 bytes[6] = omci.Second
2814 return nil
2815}
2816
2817/////////////////////////////////////////////////////////////////////////////
2818//
2819type SynchronizeTimeResponse struct {
2820 MeBasePacket
2821 Result me.Results
2822 SuccessResults uint8 // Only if 'Result' is 0 -> success
2823}
2824
2825func (omci *SynchronizeTimeResponse) String() string {
2826 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
2827 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
2828}
2829
2830// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
2831func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2832 // Common ClassID/EntityID decode in msgBase
2833 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2834 if err != nil {
2835 return err
2836 }
2837 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2838 me.ParamData{EntityID: omci.EntityInstance})
2839 if omciErr.StatusCode() != me.Success {
2840 return omciErr.GetError()
2841 }
2842 // ME needs to support Synchronize Time
2843 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2844 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2845 }
2846 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
2847 if omci.EntityClass != me.OnuGClassID {
2848 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2849 }
2850 if omci.EntityInstance != 0 {
2851 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2852 }
2853 omci.Result = me.Results(data[4])
2854 if omci.Result > me.DeviceBusy {
2855 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
2856 return errors.New(msg)
2857 }
2858 omci.SuccessResults = data[5]
2859 return nil
2860}
2861
2862func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
2863 omci := &SynchronizeTimeResponse{}
2864 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
2865 return decodingLayerDecoder(omci, data, p)
2866}
2867
2868// SerializeTo provides serialization of an Synchronize Time Response message
2869func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2870 // Basic (common) OMCI Header is 8 octets, 10
2871 err := omci.MeBasePacket.SerializeTo(b)
2872 if err != nil {
2873 return err
2874 }
2875 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2876 me.ParamData{EntityID: omci.EntityInstance})
2877 if omciErr.StatusCode() != me.Success {
2878 return omciErr.GetError()
2879 }
2880 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
2881 if omci.EntityClass != me.OnuGClassID {
2882 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2883 }
2884 if omci.EntityInstance != 0 {
2885 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2886 }
2887 // ME needs to support Synchronize Time
2888 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2889 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2890 }
2891 numBytes := 2
2892 if omci.Result != me.Success {
2893 numBytes = 1
2894 }
2895 bytes, err := b.AppendBytes(numBytes)
2896 if err != nil {
2897 return err
2898 }
2899 bytes[0] = uint8(omci.Result)
2900 if omci.Result == me.Success {
2901 bytes[1] = omci.SuccessResults
2902 }
2903 return nil
2904}
2905
2906/////////////////////////////////////////////////////////////////////////////
2907//
2908type RebootRequest struct {
2909 MeBasePacket
2910 RebootCondition byte
2911}
2912
2913func (omci *RebootRequest) String() string {
2914 return fmt.Sprintf("%v, Reboot Condition: %v",
2915 omci.MeBasePacket.String(), omci.RebootCondition)
2916}
2917
2918// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
2919func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2920 // Common ClassID/EntityID decode in msgBase
2921 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2922 if err != nil {
2923 return err
2924 }
2925 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2926 me.ParamData{EntityID: omci.EntityInstance})
2927 if omciErr.StatusCode() != me.Success {
2928 return omciErr.GetError()
2929 }
2930 // ME needs to support Reboot
2931 if !me.SupportsMsgType(meDefinition, me.Reboot) {
2932 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
2933 }
2934 omci.RebootCondition = data[4]
2935 if omci.RebootCondition > 3 {
2936 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
2937 return errors.New(msg)
2938 }
2939 return nil
2940}
2941
2942func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
2943 omci := &RebootRequest{}
2944 omci.MsgLayerType = LayerTypeRebootRequest
2945 return decodingLayerDecoder(omci, data, p)
2946}
2947
2948// SerializeTo provides serialization of an Reboot Request message
2949func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2950 // Basic (common) OMCI Header is 8 octets, 10
2951 err := omci.MeBasePacket.SerializeTo(b)
2952 if err != nil {
2953 return err
2954 }
2955 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2956 me.ParamData{EntityID: omci.EntityInstance})
2957 if omciErr.StatusCode() != me.Success {
2958 return omciErr.GetError()
2959 }
2960 // ME needs to support Reboot
2961 if !me.SupportsMsgType(entity, me.Reboot) {
2962 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2963 }
2964 bytes, err := b.AppendBytes(1)
2965 if err != nil {
2966 return err
2967 }
2968 if omci.RebootCondition > 3 {
2969 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
2970 omci.RebootCondition))
2971 }
2972 bytes[0] = omci.RebootCondition
2973 return nil
2974}
2975
2976/////////////////////////////////////////////////////////////////////////////
2977//
2978type RebootResponse struct {
2979 MeBasePacket
2980 Result me.Results
2981}
2982
2983// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
2984func (omci *RebootResponse) String() string {
2985 return fmt.Sprintf("%v, Result: %d (%v)",
2986 omci.MeBasePacket.String(), omci.Result, omci.Result)
2987}
2988
2989// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
2990func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2991 // Common ClassID/EntityID decode in msgBase
2992 err := omci.MeBasePacket.DecodeFromBytes(data, p)
2993 if err != nil {
2994 return err
2995 }
2996 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2997 me.ParamData{EntityID: omci.EntityInstance})
2998 if omciErr.StatusCode() != me.Success {
2999 return omciErr.GetError()
3000 }
3001 // ME needs to support Reboot
3002 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3003 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3004 }
3005 if omci.Result > 6 {
3006 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3007 return errors.New(msg)
3008 }
3009 omci.Result = me.Results(data[4])
3010 return nil
3011}
3012
3013func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3014 omci := &RebootResponse{}
3015 omci.MsgLayerType = LayerTypeRebootResponse
3016 return decodingLayerDecoder(omci, data, p)
3017}
3018
3019// SerializeTo provides serialization of an Reboot Response message
3020func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3021 // Basic (common) OMCI Header is 8 octets, 10
3022 err := omci.MeBasePacket.SerializeTo(b)
3023 if err != nil {
3024 return err
3025 }
3026 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3027 me.ParamData{EntityID: omci.EntityInstance})
3028 if omciErr.StatusCode() != me.Success {
3029 return omciErr.GetError()
3030 }
3031 // ME needs to support Reboot
3032 if !me.SupportsMsgType(entity, me.Reboot) {
3033 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3034 }
3035 bytes, err := b.AppendBytes(1)
3036 if err != nil {
3037 return err
3038 }
3039 if omci.Result > 6 {
3040 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3041 return errors.New(msg)
3042 }
3043 bytes[0] = byte(omci.Result)
3044 return nil
3045}
3046
3047/////////////////////////////////////////////////////////////////////////////
3048//
3049type GetNextRequest struct {
3050 MeBasePacket
3051 AttributeMask uint16
3052 SequenceNumber uint16
3053}
3054
3055func (omci *GetNextRequest) String() string {
3056 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3057 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3058}
3059
3060// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
3061func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3062 // Common ClassID/EntityID decode in msgBase
3063 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3064 if err != nil {
3065 return err
3066 }
3067 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3068 me.ParamData{EntityID: omci.EntityInstance})
3069 if omciErr.StatusCode() != me.Success {
3070 return omciErr.GetError()
3071 }
3072 // ME needs to support GetNext
3073 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3074 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3075 }
3076 // Note: G.988 specifies that an error code of (3) should result if more
3077 // than one attribute is requested
3078 // TODO: Return error. Have flag to optionally allow it to be encoded
3079 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3080 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3081 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3082 return nil
3083}
3084
3085func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3086 omci := &GetNextRequest{}
3087 omci.MsgLayerType = LayerTypeGetNextRequest
3088 return decodingLayerDecoder(omci, data, p)
3089}
3090
3091// SerializeTo provides serialization of an Get Next Message Type Request
3092func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3093 // Basic (common) OMCI Header is 8 octets, 10
3094 err := omci.MeBasePacket.SerializeTo(b)
3095 if err != nil {
3096 return err
3097 }
3098 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3099 me.ParamData{EntityID: omci.EntityInstance})
3100 if omciErr.StatusCode() != me.Success {
3101 return omciErr.GetError()
3102 }
3103 // ME needs to support GetNext
3104 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3105 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3106 }
3107 bytes, err := b.AppendBytes(4)
3108 if err != nil {
3109 return err
3110 }
3111 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3112 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3113 return nil
3114}
3115
3116/////////////////////////////////////////////////////////////////////////////
3117//
3118type GetNextResponse struct {
3119 MeBasePacket
3120 Result me.Results
3121 AttributeMask uint16
3122 Attributes me.AttributeValueMap
3123}
3124
3125// SerializeTo provides serialization of an Get Next Message Type Response
3126func (omci *GetNextResponse) String() string {
3127 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3128 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3129}
3130
3131// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
3132func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3133 // Common ClassID/EntityID decode in msgBase
3134 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3135 if err != nil {
3136 return err
3137 }
3138 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3139 me.ParamData{EntityID: omci.EntityInstance})
3140 if omciErr.StatusCode() != me.Success {
3141 return omciErr.GetError()
3142 }
3143 // ME needs to support Set
3144 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3145 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3146 }
3147 omci.Result = me.Results(data[4])
3148 if omci.Result > 6 {
3149 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3150 return errors.New(msg)
3151 }
3152 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3153
3154 // Attribute decode
3155 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3156 if err != nil {
3157 return err
3158 }
3159 // Validate all attributes support read
3160 for attrName := range omci.Attributes {
3161 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3162 if err != nil {
3163 return err
3164 }
3165 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3166 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3167 return me.NewProcessingError(msg)
3168 }
3169 }
3170 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
3171 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3172 return nil
3173 }
3174 panic("All Managed Entities have an EntityID attribute")
3175}
3176
3177func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3178 omci := &GetNextResponse{}
3179 omci.MsgLayerType = LayerTypeGetNextResponse
3180 return decodingLayerDecoder(omci, data, p)
3181}
3182
3183// SerializeTo provides serialization of an Get Next Message Type Response
3184func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3185 // Basic (common) OMCI Header is 8 octets, 10
3186 err := omci.MeBasePacket.SerializeTo(b)
3187 if err != nil {
3188 return err
3189 }
3190 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3191 me.ParamData{EntityID: omci.EntityInstance})
3192 if omciErr.StatusCode() != me.Success {
3193 return omciErr.GetError()
3194 }
3195 // ME needs to support Get
3196 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3197 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3198 }
3199 bytes, err := b.AppendBytes(3)
3200 if err != nil {
3201 return err
3202 }
3203 bytes[0] = byte(omci.Result)
3204 if omci.Result > 6 {
3205 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3206 return errors.New(msg)
3207 }
3208 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3209
3210 // Validate all attributes support read
3211 for attrName := range omci.Attributes {
3212 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3213 if err != nil {
3214 return err
3215 }
3216 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3217 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3218 return me.NewProcessingError(msg)
3219 }
3220 }
3221 // Attribute serialization
3222 switch omci.Result {
3223 default:
3224 break
3225
3226 case me.Success:
3227 // TODO: Only Baseline supported at this time
3228 bytesAvailable := MaxBaselineLength - 11 - 8
3229
3230 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3231 byte(GetNextResponseType), bytesAvailable, false)
3232 if err != nil {
3233 return err
3234 }
3235 }
3236 return nil
3237}
3238
3239/////////////////////////////////////////////////////////////////////////////
3240//
3241type TestResultMsg struct {
3242 MeBasePacket
3243}
3244
3245func (omci *TestResultMsg) String() string {
3246 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3247}
3248
3249// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
3250func (omci *TestResultMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3251 // Common ClassID/EntityID decode in msgBase
3252 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3253 if err != nil {
3254 return err
3255 }
3256 return errors.New("need to implement") // TODO: Fix me) // return nil
3257}
3258
3259func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3260 omci := &TestResultMsg{}
3261 omci.MsgLayerType = LayerTypeTestResult
3262 return decodingLayerDecoder(omci, data, p)
3263}
3264
3265// SerializeTo provides serialization of an Test Result notification message
3266func (omci *TestResultMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3267 // Basic (common) OMCI Header is 8 octets, 10
3268 err := omci.MeBasePacket.SerializeTo(b)
3269 if err != nil {
3270 return err
3271 }
3272 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
3273}
3274
3275/////////////////////////////////////////////////////////////////////////////
3276//
3277type GetCurrentDataRequest struct {
3278 MeBasePacket
3279 AttributeMask uint16
3280}
3281
3282func (omci *GetCurrentDataRequest) String() string {
3283 return fmt.Sprintf("%v, Attribute Mask: %#x",
3284 omci.MeBasePacket.String(), omci.AttributeMask)
3285}
3286
3287// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
3288func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3289 // Common ClassID/EntityID decode in msgBase
3290 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3291 if err != nil {
3292 return err
3293 }
3294 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3295 me.ParamData{EntityID: omci.EntityInstance})
3296 if omciErr.StatusCode() != me.Success {
3297 return omciErr.GetError()
3298 }
3299 // ME needs to support GetNext
3300 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3301 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3302 }
3303 // Note: G.988 specifies that an error code of (3) should result if more
3304 // than one attribute is requested
3305 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3306 return nil
3307}
3308
3309func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3310 omci := &GetCurrentDataRequest{}
3311 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3312 return decodingLayerDecoder(omci, data, p)
3313}
3314
3315// SerializeTo provides serialization of an Get Current Data Request message
3316func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3317 // Basic (common) OMCI Header is 8 octets, 10
3318 err := omci.MeBasePacket.SerializeTo(b)
3319 if err != nil {
3320 return err
3321 }
3322 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3323 me.ParamData{EntityID: omci.EntityInstance})
3324 if omciErr.StatusCode() != me.Success {
3325 return omciErr.GetError()
3326 }
3327 // ME needs to support GetNext
3328 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3329 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3330 }
3331 bytes, err := b.AppendBytes(2)
3332 if err != nil {
3333 return err
3334 }
3335 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3336 return nil
3337}
3338
3339/////////////////////////////////////////////////////////////////////////////
3340//
3341type GetCurrentDataResponse struct {
3342 MeBasePacket
3343 Result me.Results
3344 AttributeMask uint16
3345 Attributes me.AttributeValueMap
3346}
3347
3348func (omci *GetCurrentDataResponse) String() string {
3349 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
3350 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
3351}
3352
3353// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
3354func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3355 // Common ClassID/EntityID decode in msgBase
3356 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3357 if err != nil {
3358 return err
3359 }
3360 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3361 me.ParamData{EntityID: omci.EntityInstance})
3362 if omciErr.StatusCode() != me.Success {
3363 return omciErr.GetError()
3364 }
3365 // ME needs to support Set
3366 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3367 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3368 }
3369 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3370
3371 // Attribute decode
3372 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(GetCurrentDataResponseType))
3373 if err != nil {
3374 return err
3375 }
3376 return nil
3377}
3378
3379func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
3380 omci := &GetCurrentDataResponse{}
3381 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
3382 return decodingLayerDecoder(omci, data, p)
3383}
3384
3385// SerializeTo provides serialization of an Get Current Data Message Type Response
3386func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3387 // Basic (common) OMCI Header is 8 octets, 10
3388 err := omci.MeBasePacket.SerializeTo(b)
3389 if err != nil {
3390 return err
3391 }
3392 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3393 me.ParamData{EntityID: omci.EntityInstance})
3394 if omciErr.StatusCode() != me.Success {
3395 return omciErr.GetError()
3396 }
3397 // ME needs to support Get
3398 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3399 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
3400 }
3401 bytes, err := b.AppendBytes(2)
3402 if err != nil {
3403 return err
3404 }
3405 binary.BigEndian.PutUint16(bytes[0:2], omci.AttributeMask)
3406
3407 // Attribute serialization
3408 // TODO: Only Baseline supported at this time
3409 bytesAvailable := MaxBaselineLength - 9 - 8
3410 var failedMask uint16
3411
3412 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3413 byte(GetCurrentDataResponseType), bytesAvailable, opts.FixLengths)
3414
3415 if failedMask != 0 {
3416 // TODO: See GetResponse serialization above for the steps here
3417 return me.NewMessageTruncatedError("getCurrentData attribute truncation not yet supported")
3418 }
3419 if err != nil {
3420 return err
3421 }
3422 return nil
3423}
3424
3425/////////////////////////////////////////////////////////////////////////////
3426//
3427type SetTableRequest struct {
3428 MeBasePacket
3429 // TODO: Fix me when extended messages supported)
3430}
3431
3432func (omci *SetTableRequest) String() string {
3433 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3434}
3435
3436// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
3437func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3438 // Common ClassID/EntityID decode in msgBase
3439 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3440 if err != nil {
3441 return err
3442 }
3443 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3444}
3445
3446func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
3447 omci := &SetTableRequest{}
3448 omci.MsgLayerType = LayerTypeSetTableRequest
3449 return decodingLayerDecoder(omci, data, p)
3450}
3451
3452// SerializeTo provides serialization of an Set Table Message Type Request
3453func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3454 // Basic (common) OMCI Header is 8 octets, 10
3455 err := omci.MeBasePacket.SerializeTo(b)
3456 if err != nil {
3457 return err
3458 }
3459 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
3460}
3461
3462/////////////////////////////////////////////////////////////////////////////
3463//
3464type SetTableResponse struct {
3465 MeBasePacket
3466 // TODO: Fix me when extended messages supported)
3467}
3468
3469func (omci *SetTableResponse) String() string {
3470 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3471}
3472
3473// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
3474func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3475 // Common ClassID/EntityID decode in msgBase
3476 err := omci.MeBasePacket.DecodeFromBytes(data, p)
3477 if err != nil {
3478 return err
3479 }
3480 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3481}
3482
3483func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
3484 omci := &SetTableResponse{}
3485 omci.MsgLayerType = LayerTypeSetTableResponse
3486 return decodingLayerDecoder(omci, data, p)
3487}
3488
3489// SerializeTo provides serialization of an Set Table Message Type Response
3490func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3491 // Basic (common) OMCI Header is 8 octets, 10
3492 err := omci.MeBasePacket.SerializeTo(b)
3493 if err != nil {
3494 return err
3495 }
3496 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3497}
3498
3499/////////////////////////////////////////////////////////////////////////////
3500//
3501type UnsupportedMessageTypeResponse struct {
3502 MeBasePacket
3503 Result me.Results
3504}
3505
3506// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
3507func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3508 return errors.New("you should never really decode this")
3509}
3510
3511// SerializeTo provides serialization of an Unsupported Message Type Response
3512func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3513 // Basic (common) OMCI Header is 8 octets, 10
3514 err := omci.MeBasePacket.SerializeTo(b)
3515 if err != nil {
3516 return err
3517 }
3518 bytes, err := b.AppendBytes(1)
3519 if err != nil {
3520 return err
3521 }
3522 bytes[0] = byte(omci.Result)
3523 return nil
3524}