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