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