blob: 94fc257413d613ff3733b510166577b4f9b94f56 [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 Bolingd8637b02021-04-29 08:36:38 -050073
Chip Boling6e27b352020-02-14 09:10:01 -060074 // Autonomous ONU messages
75 AlarmNotificationType = MessageType(byte(me.AlarmNotification))
76 AttributeValueChangeType = MessageType(byte(me.AttributeValueChange))
77 TestResultType = MessageType(byte(me.TestResult))
Chip Boling157c9b92021-04-21 09:58:36 -050078
79 // Support mapping of extended format types (use MSB reserved bit)
80 ExtendedTypeDecodeOffset = MessageType(byte(0x80))
Chip Boling6e27b352020-02-14 09:10:01 -060081)
82
83func (mt MessageType) String() string {
84 switch mt {
85 default:
86 return "Unknown"
87
88 case CreateRequestType:
89 return "Create Request"
90 case CreateResponseType:
91 return "Create Response"
92 case DeleteRequestType:
93 return "Delete Request"
94 case DeleteResponseType:
95 return "Delete Response"
96 case SetRequestType:
97 return "Set Request"
98 case SetResponseType:
99 return "Set Response"
100 case GetRequestType:
101 return "Get Request"
102 case GetResponseType:
103 return "Get Response"
104 case GetAllAlarmsRequestType:
105 return "Get All Alarms Request"
106 case GetAllAlarmsResponseType:
107 return "Get All Alarms Response"
108 case GetAllAlarmsNextRequestType:
109 return "Get All Alarms Next Request"
110 case GetAllAlarmsNextResponseType:
111 return "Get All Alarms Next Response"
112 case MibUploadRequestType:
113 return "MIB Upload Request"
114 case MibUploadResponseType:
115 return "MIB Upload Response"
116 case MibUploadNextRequestType:
117 return "MIB Upload Next Request"
118 case MibUploadNextResponseType:
119 return "MIB Upload Next Response"
120 case MibResetRequestType:
121 return "MIB Reset Request"
122 case MibResetResponseType:
123 return "MIB Reset Response"
124 case TestRequestType:
125 return "Test Request"
126 case TestResponseType:
127 return "Test Response"
128 case StartSoftwareDownloadRequestType:
129 return "Start Software Download Request"
130 case StartSoftwareDownloadResponseType:
131 return "Start Software Download Response"
Chip Boling157c9b92021-04-21 09:58:36 -0500132 case DownloadSectionRequestType, DownloadSectionRequestWithResponseType:
Chip Boling6e27b352020-02-14 09:10:01 -0600133 return "Download Section Request"
134 case DownloadSectionResponseType:
135 return "Download Section Response"
136 case EndSoftwareDownloadRequestType:
137 return "End Software Download Request"
138 case EndSoftwareDownloadResponseType:
139 return "End Software Download Response"
140 case ActivateSoftwareRequestType:
141 return "Activate Software Request"
142 case ActivateSoftwareResponseType:
143 return "Activate Software Response"
144 case CommitSoftwareRequestType:
145 return "Commit Software Request"
146 case CommitSoftwareResponseType:
147 return "Commit Software Response"
148 case SynchronizeTimeRequestType:
149 return "Synchronize Time Request"
150 case SynchronizeTimeResponseType:
151 return "Synchronize Time Response"
152 case RebootRequestType:
153 return "Reboot Request"
154 case RebootResponseType:
155 return "Reboot Response"
156 case GetNextRequestType:
157 return "Get Next Request"
158 case GetNextResponseType:
159 return "Get Next Response"
160 case GetCurrentDataRequestType:
161 return "Get Current Data Request"
162 case GetCurrentDataResponseType:
163 return "Get Current Data Response"
164 case SetTableRequestType:
165 return "Set Table Request"
166 case SetTableResponseType:
167 return "Set Table Response"
168 case AlarmNotificationType:
169 return "Alarm Notification"
170 case AttributeValueChangeType:
171 return "Attribute Value Change"
172 case TestResultType:
173 return "Test Result"
174 }
175}
176
177/////////////////////////////////////////////////////////////////////////////
178// CreateRequest
179type CreateRequest struct {
180 MeBasePacket
181 Attributes me.AttributeValueMap
182}
183
184func (omci *CreateRequest) String() string {
185 return fmt.Sprintf("%v, attributes: %v", omci.MeBasePacket.String(), omci.Attributes)
186}
187
188// DecodeFromBytes decodes the given bytes of a Create Request into this layer
189func (omci *CreateRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
190 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -0600191 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -0600192 if err != nil {
193 return err
194 }
195 // Create attribute mask for all set-by-create entries
196 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
197 me.ParamData{EntityID: omci.EntityInstance})
198 if omciErr.StatusCode() != me.Success {
199 return omciErr.GetError()
200 }
201 // ME needs to support Create
202 if !me.SupportsMsgType(meDefinition, me.Create) {
203 return me.NewProcessingError("managed entity does not support Create Message-Type")
204 }
205 var sbcMask uint16
206 for index, attr := range meDefinition.GetAttributeDefinitions() {
207 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
208 if index == 0 {
209 continue // Skip Entity ID
210 }
211 sbcMask |= attr.Mask
212 }
213 }
214 // Attribute decode
215 omci.Attributes, err = meDefinition.DecodeAttributes(sbcMask, data[4:], p, byte(CreateRequestType))
216 if err != nil {
217 return err
218 }
219 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
220 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
221 return nil
222 }
223 panic("All Managed Entities have an EntityID attribute")
224}
225
226func decodeCreateRequest(data []byte, p gopacket.PacketBuilder) error {
227 omci := &CreateRequest{}
228 omci.MsgLayerType = LayerTypeCreateRequest
229 return decodingLayerDecoder(omci, data, p)
230}
231
232// SerializeTo provides serialization of an Create Request Message
233func (omci *CreateRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
234 // Basic (common) OMCI Header is 8 octets, 10
235 err := omci.MeBasePacket.SerializeTo(b)
236 if err != nil {
237 return err
238 }
239 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
240 me.ParamData{EntityID: omci.EntityInstance})
241 if omciErr.StatusCode() != me.Success {
242 return omciErr.GetError()
243 }
244 // Create attribute mask of SetByCreate attributes that should be present in the provided
245 // attributes.
246 var sbcMask uint16
247 for index, attr := range meDefinition.GetAttributeDefinitions() {
248 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
249 if index == 0 {
250 continue // Skip Entity ID
251 }
252 sbcMask |= attr.Mask
253 }
254 }
255 // Attribute serialization
256 // TODO: Only Baseline supported at this time
257 bytesAvailable := MaxBaselineLength - 8 - 8
258 err, _ = meDefinition.SerializeAttributes(omci.Attributes, sbcMask, b, byte(CreateRequestType), bytesAvailable, false)
259 return err
260}
261
262/////////////////////////////////////////////////////////////////////////////
263// CreateResponse
264type CreateResponse struct {
265 MeBasePacket
266 Result me.Results
267 AttributeExecutionMask uint16 // Used when Result == ParameterError
268}
269
270func (omci *CreateResponse) String() string {
271 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x",
272 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeExecutionMask)
273}
274
275// DecodeFromBytes decodes the given bytes of a Create Response into this layer
276func (omci *CreateResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
277 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600278 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -0600279 if err != nil {
280 return err
281 }
282 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
283 me.ParamData{EntityID: omci.EntityInstance})
284 if omciErr.StatusCode() != me.Success {
285 return omciErr.GetError()
286 }
287 // ME needs to support Create
288 if !me.SupportsMsgType(entity, me.Create) {
289 return me.NewProcessingError("managed entity does not support the Create Message-Type")
290 }
291 omci.Result = me.Results(data[4])
292 if omci.Result == me.ParameterError {
293 omci.AttributeExecutionMask = binary.BigEndian.Uint16(data[5:])
294 // TODO: validation that attributes set in mask are SetByCreate would be good here
295 }
296 return nil
297}
298
299func decodeCreateResponse(data []byte, p gopacket.PacketBuilder) error {
300 omci := &CreateResponse{}
301 omci.MsgLayerType = LayerTypeCreateResponse
302 return decodingLayerDecoder(omci, data, p)
303}
304
305// SerializeTo provides serialization of an Create Response message
306func (omci *CreateResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
307 // Basic (common) OMCI Header is 8 octets, 10
308 err := omci.MeBasePacket.SerializeTo(b)
309 if err != nil {
310 return err
311 }
312 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
313 me.ParamData{EntityID: omci.EntityInstance})
314 if omciErr.StatusCode() != me.Success {
315 return omciErr.GetError()
316 }
317 // ME needs to support Create
318 if !me.SupportsMsgType(entity, me.Create) {
319 return me.NewProcessingError("managed entity does not support the Create Message-Type")
320 }
321 bytes, err := b.AppendBytes(3)
322 if err != nil {
323 return err
324 }
325 bytes[0] = byte(omci.Result)
326 if omci.Result == me.ParameterError {
327 // TODO: validation that attributes set in mask are SetByCreate would be good here
328 binary.BigEndian.PutUint16(bytes[1:], omci.AttributeExecutionMask)
329 } else {
330 binary.BigEndian.PutUint16(bytes[1:], 0)
331 }
332 return nil
333}
334
335/////////////////////////////////////////////////////////////////////////////
336// DeleteRequest
337type DeleteRequest struct {
338 MeBasePacket
339}
340
341func (omci *DeleteRequest) String() string {
342 return fmt.Sprintf("%v", omci.MeBasePacket.String())
343}
344
345// DecodeFromBytes decodes the given bytes of a Delete Request into this layer
346func (omci *DeleteRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
347 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -0600348 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -0600349 if err != nil {
350 return err
351 }
352 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
353 me.ParamData{EntityID: omci.EntityInstance})
354 if omciErr.StatusCode() != me.Success {
355 return omciErr.GetError()
356 }
357 // ME needs to support Delete
358 if !me.SupportsMsgType(entity, me.Delete) {
359 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
360 }
361 return nil
362}
363
364func decodeDeleteRequest(data []byte, p gopacket.PacketBuilder) error {
365 omci := &DeleteRequest{}
366 omci.MsgLayerType = LayerTypeDeleteRequest
367 return decodingLayerDecoder(omci, data, p)
368}
369
370// SerializeTo provides serialization of an Delete Request message
371func (omci *DeleteRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
372 // Basic (common) OMCI Header is 8 octets, 10
373 err := omci.MeBasePacket.SerializeTo(b)
374 if err != nil {
375 return err
376 }
377 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
378 me.ParamData{EntityID: omci.EntityInstance})
379 if omciErr.StatusCode() != me.Success {
380 return omciErr.GetError()
381 }
382 // ME needs to support Delete
383 if !me.SupportsMsgType(entity, me.Delete) {
384 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
385 }
386 return nil
387}
388
389/////////////////////////////////////////////////////////////////////////////
390// DeleteResponse
391type DeleteResponse struct {
392 MeBasePacket
393 Result me.Results
394}
395
396func (omci *DeleteResponse) String() string {
397 return fmt.Sprintf("%v, Result: %d (%v)",
398 omci.MeBasePacket.String(), omci.Result, omci.Result)
399}
400
401// DecodeFromBytes decodes the given bytes of a Delete Response into this layer
402func (omci *DeleteResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
403 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600404 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -0600405 if err != nil {
406 return err
407 }
408 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
409 me.ParamData{EntityID: omci.EntityInstance})
410 if omciErr.StatusCode() != me.Success {
411 return omciErr.GetError()
412 }
413 // ME needs to support Delete
414 if !me.SupportsMsgType(entity, me.Delete) {
415 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
416 }
417 omci.Result = me.Results(data[4])
418 return nil
419}
420
421func decodeDeleteResponse(data []byte, p gopacket.PacketBuilder) error {
422 omci := &DeleteResponse{}
423 omci.MsgLayerType = LayerTypeDeleteResponse
424 return decodingLayerDecoder(omci, data, p)
425}
426
427// SerializeTo provides serialization of an Delete Response message
428func (omci *DeleteResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
429 // Basic (common) OMCI Header is 8 octets, 10
430 err := omci.MeBasePacket.SerializeTo(b)
431 if err != nil {
432 return err
433 }
434 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
435 me.ParamData{EntityID: omci.EntityInstance})
436 if omciErr.StatusCode() != me.Success {
437 return omciErr.GetError()
438 }
439 // ME needs to support Delete
440 if !me.SupportsMsgType(entity, me.Delete) {
441 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
442 }
443 bytes, err := b.AppendBytes(1)
444 if err != nil {
445 return err
446 }
447 bytes[0] = byte(omci.Result)
448 return nil
449}
450
451/////////////////////////////////////////////////////////////////////////////
452// SetRequest
453type SetRequest struct {
454 MeBasePacket
455 AttributeMask uint16
456 Attributes me.AttributeValueMap
457}
458
459func (omci *SetRequest) String() string {
460 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
461 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
462}
463
464// DecodeFromBytes decodes the given bytes of a Set Request into this layer
465func (omci *SetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
466 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600467 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -0600468 if err != nil {
469 return err
470 }
471 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
472 me.ParamData{EntityID: omci.EntityInstance})
473 if omciErr.StatusCode() != me.Success {
474 return omciErr.GetError()
475 }
476 // ME needs to support Set
477 if !me.SupportsMsgType(meDefinition, me.Set) {
478 return me.NewProcessingError("managed entity does not support Set Message-Type")
479 }
480 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
481
482 // Attribute decode
483 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(SetRequestType))
484 if err != nil {
485 return err
486 }
487 // Validate all attributes support write
488 for attrName := range omci.Attributes {
489 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
490 if err != nil {
491 return err
492 }
493 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
494 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
495 return me.NewProcessingError(msg)
496 }
497 }
498 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
499 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
500 return nil
501 }
502 panic("All Managed Entities have an EntityID attribute")
503}
504
505func decodeSetRequest(data []byte, p gopacket.PacketBuilder) error {
506 omci := &SetRequest{}
507 omci.MsgLayerType = LayerTypeSetRequest
508 return decodingLayerDecoder(omci, data, p)
509}
510
511// SerializeTo provides serialization of an Set Request message
512func (omci *SetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
513 // Basic (common) OMCI Header is 8 octets, 10
514 err := omci.MeBasePacket.SerializeTo(b)
515 if err != nil {
516 return err
517 }
518 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
519 me.ParamData{EntityID: omci.EntityInstance})
520 if omciErr.StatusCode() != me.Success {
521 return omciErr.GetError()
522 }
523 // ME needs to support Set
524 if !me.SupportsMsgType(meDefinition, me.Set) {
525 return me.NewProcessingError("managed entity does not support Set Message-Type")
526 }
527 // Validate all attributes support write
528 for attrName := range omci.Attributes {
529 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
530 if err != nil {
531 return err
532 }
533 // Do not test for write of Entity ID in the attribute list
534 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
535 // TODO: Check ITU spec to see if this should be listed as a failed
536 // attribute and not a processing error.
537 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
538 return me.NewProcessingError(msg)
539 }
540 }
541 bytes, err := b.AppendBytes(2)
542 if err != nil {
543 return err
544 }
545 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
546
547 // Attribute serialization
548 // TODO: Only Baseline supported at this time
549 bytesAvailable := MaxBaselineLength - 10 - 8
550
551 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
552 byte(SetRequestType), bytesAvailable, false)
553 return err
554}
555
556/////////////////////////////////////////////////////////////////////////////
557// SetResponse
558type SetResponse struct {
559 MeBasePacket
560 Result me.Results
561 UnsupportedAttributeMask uint16
562 FailedAttributeMask uint16
563}
564
565func (omci *SetResponse) String() string {
566 return fmt.Sprintf("%v, Result: %d (%v), Unsupported Mask: %#x, Failed Mask: %#x",
567 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.UnsupportedAttributeMask,
568 omci.FailedAttributeMask)
569}
570
571// DecodeFromBytes decodes the given bytes of a Set Response into this layer
572func (omci *SetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
573 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600574 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
Chip Boling6e27b352020-02-14 09:10:01 -0600575 if err != nil {
576 return err
577 }
578 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
579 me.ParamData{EntityID: omci.EntityInstance})
580 if omciErr.StatusCode() != me.Success {
581 return omciErr.GetError()
582 }
583 // ME needs to support Set
584 if !me.SupportsMsgType(entity, me.Set) {
585 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
586 }
587 omci.Result = me.Results(data[4])
588
589 if omci.Result == me.AttributeFailure {
590 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[5:7])
591 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[7:9])
592 }
593 return nil
594}
595
596func decodeSetResponse(data []byte, p gopacket.PacketBuilder) error {
597 omci := &SetResponse{}
598 omci.MsgLayerType = LayerTypeSetResponse
599 return decodingLayerDecoder(omci, data, p)
600}
601
602// SerializeTo provides serialization of an Set Response message
603func (omci *SetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
604 // Basic (common) OMCI Header is 8 octets, 10
605 err := omci.MeBasePacket.SerializeTo(b)
606 if err != nil {
607 return err
608 }
609 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
610 me.ParamData{EntityID: omci.EntityInstance})
611 if omciErr.StatusCode() != me.Success {
612 return omciErr.GetError()
613 }
614 // ME needs to support Set
615 if !me.SupportsMsgType(entity, me.Set) {
616 return me.NewProcessingError("managed entity does not support the Set Message-Type")
617 }
618 bytes, err := b.AppendBytes(5)
619 if err != nil {
620 return err
621 }
622 bytes[0] = byte(omci.Result)
623 binary.BigEndian.PutUint16(bytes[1:3], omci.UnsupportedAttributeMask)
624 binary.BigEndian.PutUint16(bytes[3:5], omci.FailedAttributeMask)
625 return nil
626}
627
628/////////////////////////////////////////////////////////////////////////////
629// GetRequest
630type GetRequest struct {
631 MeBasePacket
632 AttributeMask uint16
633}
634
635func (omci *GetRequest) String() string {
636 return fmt.Sprintf("%v, Mask: %#x",
637 omci.MeBasePacket.String(), omci.AttributeMask)
638}
639
640// DecodeFromBytes decodes the given bytes of a Get Request into this layer
641func (omci *GetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
642 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600643 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -0600644 if err != nil {
645 return err
646 }
647 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
648 me.ParamData{EntityID: omci.EntityInstance})
649 if omciErr.StatusCode() != me.Success {
650 return omciErr.GetError()
651 }
652 // ME needs to support Get
653 if !me.SupportsMsgType(meDefinition, me.Get) {
654 return me.NewProcessingError("managed entity does not support Get Message-Type")
655 }
Chip Boling157c9b92021-04-21 09:58:36 -0500656 if omci.Extended {
657 if len(data) < 8 {
658 p.SetTruncated()
659 return errors.New("frame too small")
660 }
661 omci.AttributeMask = binary.BigEndian.Uint16(data[6:])
662 } else {
663 omci.AttributeMask = binary.BigEndian.Uint16(data[4:])
664 }
Chip Boling6e27b352020-02-14 09:10:01 -0600665 return nil
666}
667
668func decodeGetRequest(data []byte, p gopacket.PacketBuilder) error {
669 omci := &GetRequest{}
670 omci.MsgLayerType = LayerTypeGetRequest
671 return decodingLayerDecoder(omci, data, p)
672}
673
Chip Boling157c9b92021-04-21 09:58:36 -0500674func decodeGetRequestExtended(data []byte, p gopacket.PacketBuilder) error {
675 omci := &GetRequest{}
676 omci.MsgLayerType = LayerTypeGetRequest
677 omci.Extended = true
678 return decodingLayerDecoder(omci, data, p)
679}
680
Chip Boling6e27b352020-02-14 09:10:01 -0600681// SerializeTo provides serialization of an Get Request message
682func (omci *GetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
683 // Basic (common) OMCI Header is 8 octets, 10
684 err := omci.MeBasePacket.SerializeTo(b)
685 if err != nil {
686 return err
687 }
688 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
689 me.ParamData{EntityID: omci.EntityInstance})
690 if omciErr.StatusCode() != me.Success {
691 return omciErr.GetError()
692 }
693 // ME needs to support Set
694 if !me.SupportsMsgType(meDefinition, me.Get) {
695 return me.NewProcessingError("managed entity does not support Get Message-Type")
696 }
Chip Boling157c9b92021-04-21 09:58:36 -0500697 maskOffset := 0
698 if omci.Extended {
699 maskOffset = 2
700 }
701 bytes, err := b.AppendBytes(2 + maskOffset)
Chip Boling6e27b352020-02-14 09:10:01 -0600702 if err != nil {
703 return err
704 }
Chip Boling157c9b92021-04-21 09:58:36 -0500705 if omci.Extended {
706 binary.BigEndian.PutUint16(bytes, uint16(2))
707 }
708 binary.BigEndian.PutUint16(bytes[maskOffset:], omci.AttributeMask)
709 return nil
710}
711
712func (omci *GetRequest) SerializeToExtended(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
Chip Boling6e27b352020-02-14 09:10:01 -0600713 return nil
714}
715
716/////////////////////////////////////////////////////////////////////////////
717// GetResponse
718type GetResponse struct {
719 MeBasePacket
720 Result me.Results
721 AttributeMask uint16
722 Attributes me.AttributeValueMap
723 UnsupportedAttributeMask uint16
724 FailedAttributeMask uint16
725}
726
727func (omci *GetResponse) String() string {
728 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x, Unsupported: %#x, Failed: %#x, attributes: %v",
729 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask,
730 omci.UnsupportedAttributeMask, omci.FailedAttributeMask, omci.Attributes)
731}
732
733// DecodeFromBytes decodes the given bytes of a Get Response into this layer
734func (omci *GetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
735 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600736 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -0600737 if err != nil {
738 return err
739 }
740 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
741 me.ParamData{EntityID: omci.EntityInstance})
742 if omciErr.StatusCode() != me.Success {
743 return omciErr.GetError()
744 }
745 // ME needs to support Get
746 if !me.SupportsMsgType(meDefinition, me.Get) {
747 return me.NewProcessingError("managed entity does not support Get Message-Type")
748 }
Chip Boling157c9b92021-04-21 09:58:36 -0500749 if omci.Extended {
750 if len(data) < 13 {
751 p.SetTruncated()
752 return errors.New("frame too small")
753 }
754 omci.Result = me.Results(data[6])
755 omci.AttributeMask = binary.BigEndian.Uint16(data[7:])
Chip Boling6e27b352020-02-14 09:10:01 -0600756
Chip Boling157c9b92021-04-21 09:58:36 -0500757 // If Attribute failed or Unknown, decode optional attribute mask
758 if omci.Result == me.AttributeFailure {
759 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[9:])
760 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[11:])
761 }
762 } else {
763 omci.Result = me.Results(data[4])
764 omci.AttributeMask = binary.BigEndian.Uint16(data[5:])
765
766 // If Attribute failed or Unknown, decode optional attribute mask
767 if omci.Result == me.AttributeFailure {
768 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:34])
769 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:36])
770 }
771 }
Chip Boling6e27b352020-02-14 09:10:01 -0600772 // Attribute decode. Note that the ITU-T G.988 specification states that the
773 // Unsupported and Failed attribute masks are always present
774 // but only valid if the status code== 9. However some XGS
775 // ONUs (T&W and Alpha, perhaps more) will use these last 4
776 // octets for data if the status code == 0. So accommodate
777 // this behaviour in favor of greater interoperability.
Chip Boling157c9b92021-04-21 09:58:36 -0500778 firstOctet := 7
Chip Boling6e27b352020-02-14 09:10:01 -0600779 lastOctet := 36
Chip Boling157c9b92021-04-21 09:58:36 -0500780 if omci.Extended {
781 firstOctet = 13
782 lastOctet = len(data)
783 }
Chip Boling4e0ac9a2021-01-20 14:23:09 -0600784
785 switch omci.Result {
786 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
787 return nil // Done (do not try and decode attributes)
788
789 case me.AttributeFailure:
Chip Boling157c9b92021-04-21 09:58:36 -0500790 if !omci.Extended {
791 lastOctet = 32
792 }
Chip Boling6e27b352020-02-14 09:10:01 -0600793 }
Chip Boling157c9b92021-04-21 09:58:36 -0500794 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask,
795 data[firstOctet:lastOctet], p, byte(GetResponseType))
Chip Boling6e27b352020-02-14 09:10:01 -0600796 if err != nil {
797 return err
798 }
Chip Boling6e27b352020-02-14 09:10:01 -0600799 // Validate all attributes support read
800 for attrName := range omci.Attributes {
801 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
802 if err != nil {
803 return err
804 }
805 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
806 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
807 return me.NewProcessingError(msg)
808 }
809 }
810 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
811 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
812 return nil
813 }
814 panic("All Managed Entities have an EntityID attribute")
815}
816
817func decodeGetResponse(data []byte, p gopacket.PacketBuilder) error {
818 omci := &GetResponse{}
819 omci.MsgLayerType = LayerTypeGetResponse
820 return decodingLayerDecoder(omci, data, p)
821}
822
Chip Boling157c9b92021-04-21 09:58:36 -0500823func decodeGetResponseExtended(data []byte, p gopacket.PacketBuilder) error {
824 omci := &GetResponse{}
825 omci.MsgLayerType = LayerTypeGetResponse
826 omci.Extended = true
827 return decodingLayerDecoder(omci, data, p)
828}
829
Chip Boling6e27b352020-02-14 09:10:01 -0600830// SerializeTo provides serialization of an Get Response message
831func (omci *GetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
832 // Basic (common) OMCI Header is 8 octets, 10
833 if err := omci.MeBasePacket.SerializeTo(b); err != nil {
834 return err
835 }
836 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
837 me.ParamData{EntityID: omci.EntityInstance})
838
839 if omciErr.StatusCode() != me.Success {
840 return omciErr.GetError()
841 }
842 // ME needs to support Get
843 if !me.SupportsMsgType(meDefinition, me.Get) {
844 return me.NewProcessingError("managed entity does not support the Get Message-Type")
845 }
Chip Boling157c9b92021-04-21 09:58:36 -0500846 resultOffset := 0
847 attributeErrExtra := 0
848
849 if omci.Extended {
850 resultOffset = 2
851 attributeErrExtra = 4 // Attribute mask + attribute error masks
852 }
853 // Space for result + mask (both types) + (len & error masks if extended)
854 buffer, err := b.AppendBytes(3 + resultOffset + attributeErrExtra)
Chip Boling6e27b352020-02-14 09:10:01 -0600855 if err != nil {
856 return err
857 }
Chip Boling157c9b92021-04-21 09:58:36 -0500858 // Save result and initial mask. Other header fields updated after
859 // attribute copy
860 buffer[resultOffset] = byte(omci.Result)
861 binary.BigEndian.PutUint16(buffer[resultOffset+1:], omci.AttributeMask)
Chip Boling6e27b352020-02-14 09:10:01 -0600862
863 // Validate all attributes support read
864 for attrName := range omci.Attributes {
Chip Boling157c9b92021-04-21 09:58:36 -0500865 var attr *me.AttributeDefinition
866 attr, err = me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
Chip Boling6e27b352020-02-14 09:10:01 -0600867 if err != nil {
868 return err
869 }
870 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
871 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
872 return me.NewProcessingError(msg)
873 }
874 }
875 // Attribute serialization
876 switch omci.Result {
877 default:
Chip Boling157c9b92021-04-21 09:58:36 -0500878 if omci.Extended {
879 // Minimum length is 7 for extended an need to write error masks
880 binary.BigEndian.PutUint16(buffer, uint16(7))
881 binary.BigEndian.PutUint32(buffer[resultOffset+3:], 0)
882 }
Chip Boling6e27b352020-02-14 09:10:01 -0600883 break
884
885 case me.Success, me.AttributeFailure:
886 // TODO: Baseline only supported at this time)
Chip Boling157c9b92021-04-21 09:58:36 -0500887 var available int
888 if omci.Extended {
889 available = MaxExtendedLength - 18 - 4 // Less: header, mic
890 } else {
891 available = MaxBaselineLength - 11 - 4 - 8 // Less: header, failed attributes, length, mic
892 }
Chip Boling6e27b352020-02-14 09:10:01 -0600893 // Serialize to temporary buffer if we may need to reset values due to
894 // recoverable truncation errors
Chip Boling157c9b92021-04-21 09:58:36 -0500895 attributeBuffer := gopacket.NewSerializeBuffer()
896 var failedMask uint16
897 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask,
898 attributeBuffer, byte(GetResponseType), available, opts.FixLengths)
Chip Boling6e27b352020-02-14 09:10:01 -0600899
Chip Boling157c9b92021-04-21 09:58:36 -0500900 if err != nil {
901 return err
902 }
903 if failedMask != 0 {
Chip Boling6e27b352020-02-14 09:10:01 -0600904 // Not all attributes would fit
905 omci.FailedAttributeMask |= failedMask
906 omci.AttributeMask &= ^failedMask
907 omci.Result = me.AttributeFailure
908
909 // Adjust already recorded values
Chip Boling157c9b92021-04-21 09:58:36 -0500910 buffer[resultOffset] = byte(omci.Result)
911 binary.BigEndian.PutUint16(buffer[resultOffset+1:], omci.AttributeMask)
912 }
913 if omci.Extended {
914 // Set length and any failure masks
915 binary.BigEndian.PutUint16(buffer, uint16(len(attributeBuffer.Bytes())+7))
916
917 if omci.Result == me.AttributeFailure {
918 binary.BigEndian.PutUint16(buffer[resultOffset+3:], omci.UnsupportedAttributeMask)
919 binary.BigEndian.PutUint16(buffer[resultOffset+5:], omci.FailedAttributeMask)
920 } else {
921 binary.BigEndian.PutUint32(buffer[resultOffset+3:], 0)
922 }
Chip Boling6e27b352020-02-14 09:10:01 -0600923 }
924 // Copy over attributes to the original serialization buffer
Chip Boling157c9b92021-04-21 09:58:36 -0500925 var newSpace []byte
926
927 newSpace, err = b.AppendBytes(len(attributeBuffer.Bytes()))
Chip Boling6e27b352020-02-14 09:10:01 -0600928 if err != nil {
929 return err
930 }
Chip Boling157c9b92021-04-21 09:58:36 -0500931 copy(newSpace, attributeBuffer.Bytes())
Chip Boling6e27b352020-02-14 09:10:01 -0600932
Chip Boling157c9b92021-04-21 09:58:36 -0500933 if !omci.Extended {
934 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
935 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
Chip Boling6e27b352020-02-14 09:10:01 -0600936
Chip Boling157c9b92021-04-21 09:58:36 -0500937 var remainingBytes []byte
938 remainingBytes, err = b.AppendBytes(bytesLeft + 4)
Chip Boling6e27b352020-02-14 09:10:01 -0600939
Chip Boling157c9b92021-04-21 09:58:36 -0500940 if err != nil {
941 return me.NewMessageTruncatedError(err.Error())
942 }
943 copy(remainingBytes, lotsOfZeros[:])
944
945 if omci.Result == me.AttributeFailure {
946 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
947 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
948 }
Chip Boling6e27b352020-02-14 09:10:01 -0600949 }
950 }
951 return nil
952}
953
954/////////////////////////////////////////////////////////////////////////////
955// GetAllAlarms
956type GetAllAlarmsRequest struct {
957 MeBasePacket
958 AlarmRetrievalMode byte
959}
960
961func (omci *GetAllAlarmsRequest) String() string {
962 return fmt.Sprintf("%v, Retrieval Mode: %v",
963 omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
964}
965
966// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
967func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
968 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -0600969 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -0600970 if err != nil {
971 return err
972 }
973 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
974 me.ParamData{EntityID: omci.EntityInstance})
975 if omciErr.StatusCode() != me.Success {
976 return omciErr.GetError()
977 }
978 // ME needs to support Get All Alarms
979 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
980 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
981 }
982 // Entity Class are always ONU DATA (2) and Entity Instance of 0
983 if omci.EntityClass != me.OnuDataClassID {
984 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
985 omci.EntityClass)
986 return me.NewProcessingError(msg)
987 }
988 if omci.EntityInstance != 0 {
989 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
990 omci.EntityInstance)
991 return me.NewUnknownInstanceError(msg)
992 }
993 omci.AlarmRetrievalMode = data[4]
994 if omci.AlarmRetrievalMode > 1 {
995 msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
996 omci.AlarmRetrievalMode)
997 return errors.New(msg)
998 }
999 return nil
1000}
1001
1002func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
1003 omci := &GetAllAlarmsRequest{}
1004 omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
1005 return decodingLayerDecoder(omci, data, p)
1006}
1007
1008// SerializeTo provides serialization of an Get All Alarms Request message
1009func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1010 // Basic (common) OMCI Header is 8 octets, 10
1011 err := omci.MeBasePacket.SerializeTo(b)
1012 if err != nil {
1013 return err
1014 }
1015 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1016 me.ParamData{EntityID: omci.EntityInstance})
1017 if omciErr.StatusCode() != me.Success {
1018 return omciErr.GetError()
1019 }
1020 // ME needs to support Get All Alarms
1021 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
1022 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
1023 }
1024 bytes, err := b.AppendBytes(1)
1025 if err != nil {
1026 return err
1027 }
1028 bytes[0] = omci.AlarmRetrievalMode
1029 return nil
1030}
1031
1032/////////////////////////////////////////////////////////////////////////////
1033// GetAllAlarms
1034type GetAllAlarmsResponse struct {
1035 MeBasePacket
1036 NumberOfCommands uint16
1037}
1038
1039func (omci *GetAllAlarmsResponse) String() string {
1040 return fmt.Sprintf("%v, NumberOfCommands: %d",
1041 omci.MeBasePacket.String(), omci.NumberOfCommands)
1042}
1043
1044// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
1045func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1046 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001047 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06001048 if err != nil {
1049 return err
1050 }
1051 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1052 me.ParamData{EntityID: omci.EntityInstance})
1053 if omciErr.StatusCode() != me.Success {
1054 return omciErr.GetError()
1055 }
1056 // ME needs to support Get All Alarms
1057 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
1058 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
1059 }
1060 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1061 if omci.EntityClass != me.OnuDataClassID {
1062 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
1063 omci.EntityClass)
1064 return me.NewProcessingError(msg)
1065 }
1066 if omci.EntityInstance != 0 {
1067 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
1068 omci.EntityInstance)
1069 return me.NewUnknownInstanceError(msg)
1070 }
1071 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1072 return nil
1073}
1074
1075func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
1076 omci := &GetAllAlarmsResponse{}
1077 omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
1078 return decodingLayerDecoder(omci, data, p)
1079}
1080
1081// SerializeTo provides serialization of an Get All Alarms Response message
1082func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1083 // Basic (common) OMCI Header is 8 octets, 10
1084 err := omci.MeBasePacket.SerializeTo(b)
1085 if err != nil {
1086 return err
1087 }
1088 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1089 me.ParamData{EntityID: omci.EntityInstance})
1090 if omciErr.StatusCode() != me.Success {
1091 return omciErr.GetError()
1092 }
1093 // ME needs to support Get All Alarms
1094 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
1095 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
1096 }
1097 bytes, err := b.AppendBytes(2)
1098 if err != nil {
1099 return err
1100 }
1101 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1102 return nil
1103}
1104
1105/////////////////////////////////////////////////////////////////////////////
1106// GetAllAlarms
1107type GetAllAlarmsNextRequest struct {
1108 MeBasePacket
1109 CommandSequenceNumber uint16
1110}
1111
1112func (omci *GetAllAlarmsNextRequest) String() string {
1113 return fmt.Sprintf("%v, Sequence Number: %d",
1114 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1115}
1116
1117// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
1118func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1119 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001120 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06001121 if err != nil {
1122 return err
1123 }
1124 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1125 me.ParamData{EntityID: omci.EntityInstance})
1126 if omciErr.StatusCode() != me.Success {
1127 return omciErr.GetError()
1128 }
1129 // ME needs to support Get All Alarms
1130 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1131 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1132 }
1133 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1134 if omci.EntityClass != me.OnuDataClassID {
1135 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
1136 omci.EntityClass)
1137 return me.NewProcessingError(msg)
1138 }
1139 if omci.EntityInstance != 0 {
1140 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
1141 omci.EntityInstance)
1142 return me.NewUnknownInstanceError(msg)
1143 }
1144 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1145 return nil
1146}
1147
1148func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
1149 omci := &GetAllAlarmsNextRequest{}
1150 omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
1151 return decodingLayerDecoder(omci, data, p)
1152}
1153
1154// SerializeTo provides serialization of an Get All Alarms Next Request message
1155func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1156 // Basic (common) OMCI Header is 8 octets, 10
1157 err := omci.MeBasePacket.SerializeTo(b)
1158 if err != nil {
1159 return err
1160 }
1161 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1162 me.ParamData{EntityID: omci.EntityInstance})
1163 if omciErr.StatusCode() != me.Success {
1164 return omciErr.GetError()
1165 }
1166 // ME needs to support Get All Alarms Next
1167 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1168 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1169 }
1170 bytes, err := b.AppendBytes(2)
1171 if err != nil {
1172 return err
1173 }
1174 binary.BigEndian.PutUint16(bytes, omci.CommandSequenceNumber)
1175 return nil
1176}
1177
1178/////////////////////////////////////////////////////////////////////////////
1179// GetAllAlarms
1180type GetAllAlarmsNextResponse struct {
1181 MeBasePacket
1182 AlarmEntityClass me.ClassID
1183 AlarmEntityInstance uint16
1184 AlarmBitMap [28]byte // 224 bits
1185}
1186
1187func (omci *GetAllAlarmsNextResponse) String() string {
1188 return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
1189 omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
1190 omci.AlarmEntityInstance, omci.AlarmBitMap)
1191}
1192
1193// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
1194func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1195 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001196 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4+28)
Chip Boling6e27b352020-02-14 09:10:01 -06001197 if err != nil {
1198 return err
1199 }
1200 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1201 me.ParamData{EntityID: omci.EntityInstance})
1202 if omciErr.StatusCode() != me.Success {
1203 return omciErr.GetError()
1204 }
1205 // ME needs to support Get All Alarms Next
1206 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1207 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1208 }
1209 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1210 if omci.EntityClass != me.OnuDataClassID {
1211 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
1212 omci.EntityClass)
1213 return me.NewProcessingError(msg)
1214 }
1215 if omci.EntityInstance != 0 {
1216 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
1217 omci.EntityInstance)
1218 return me.NewUnknownInstanceError(msg)
1219 }
1220 omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4:6]))
1221 omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6:8])
1222
1223 copy(omci.AlarmBitMap[:], data[8:36])
1224 return nil
1225}
1226
1227func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
1228 omci := &GetAllAlarmsNextResponse{}
1229 omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
1230 return decodingLayerDecoder(omci, data, p)
1231}
1232
1233// SerializeTo provides serialization of an Get All Alarms Next Response message
1234func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1235 // Basic (common) OMCI Header is 8 octets, 10
1236 err := omci.MeBasePacket.SerializeTo(b)
1237 if err != nil {
1238 return err
1239 }
1240 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1241 me.ParamData{EntityID: omci.EntityInstance})
1242 if omciErr.StatusCode() != me.Success {
1243 return omciErr.GetError()
1244 }
1245 // ME needs to support Get All Alarms Next
1246 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1247 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1248 }
1249 bytes, err := b.AppendBytes(2 + 2 + 28)
1250 if err != nil {
1251 return err
1252 }
1253 binary.BigEndian.PutUint16(bytes[0:], uint16(omci.AlarmEntityClass))
1254 binary.BigEndian.PutUint16(bytes[2:], omci.AlarmEntityInstance)
1255 copy(bytes[4:], omci.AlarmBitMap[:])
1256 return nil
1257}
1258
1259/////////////////////////////////////////////////////////////////////////////
1260// MibUploadRequest
1261type MibUploadRequest struct {
1262 MeBasePacket
1263}
1264
1265func (omci *MibUploadRequest) String() string {
1266 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1267}
1268
1269// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
1270func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1271 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06001272 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06001273 if err != nil {
1274 return err
1275 }
1276 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1277 me.ParamData{EntityID: omci.EntityInstance})
1278 if omciErr.StatusCode() != me.Success {
1279 return omciErr.GetError()
1280 }
1281 // ME needs to support MIB Upload
1282 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1283 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1284 }
1285 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1286 if omci.EntityClass != me.OnuDataClassID {
1287 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
1288 omci.EntityClass)
1289 return me.NewProcessingError(msg)
1290 }
1291 if omci.EntityInstance != 0 {
1292 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
1293 omci.EntityInstance)
1294 return me.NewUnknownInstanceError(msg)
1295 }
1296 return nil
1297}
1298
1299func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
1300 omci := &MibUploadRequest{}
1301 omci.MsgLayerType = LayerTypeMibUploadRequest
1302 return decodingLayerDecoder(omci, data, p)
1303}
1304
1305// SerializeTo provides serialization of an MIB Upload Request message
1306func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1307 // Basic (common) OMCI Header is 8 octets, 10
1308 err := omci.MeBasePacket.SerializeTo(b)
1309 if err != nil {
1310 return err
1311 }
1312 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1313 me.ParamData{EntityID: omci.EntityInstance})
1314 if omciErr.StatusCode() != me.Success {
1315 return omciErr.GetError()
1316 }
1317 // ME needs to support Get
1318 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1319 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1320 }
1321 return nil
1322}
1323
1324/////////////////////////////////////////////////////////////////////////////
1325// MibUploadResponse
1326type MibUploadResponse struct {
1327 MeBasePacket
1328 NumberOfCommands uint16
1329}
1330
1331func (omci *MibUploadResponse) String() string {
1332 return fmt.Sprintf("%v, NumberOfCommands: %#v",
1333 omci.MeBasePacket.String(), omci.NumberOfCommands)
1334}
1335
1336// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
1337func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1338 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001339 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06001340 if err != nil {
1341 return err
1342 }
1343 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1344 me.ParamData{EntityID: omci.EntityInstance})
1345 if omciErr.StatusCode() != me.Success {
1346 return omciErr.GetError()
1347 }
1348 // ME needs to support MIB Upload
1349 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1350 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1351 }
1352 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1353 if omci.EntityClass != me.OnuDataClassID {
1354 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
1355 omci.EntityClass)
1356 return me.NewProcessingError(msg)
1357 }
1358 if omci.EntityInstance != 0 {
1359 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
1360 omci.EntityInstance)
1361 return me.NewUnknownInstanceError(msg)
1362 }
1363 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1364 return nil
1365}
1366
1367func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
1368 omci := &MibUploadResponse{}
1369 omci.MsgLayerType = LayerTypeMibUploadResponse
1370 return decodingLayerDecoder(omci, data, p)
1371}
1372
1373// SerializeTo provides serialization of an MIB Upload Response message
1374func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1375 // Basic (common) OMCI Header is 8 octets, 10
1376 err := omci.MeBasePacket.SerializeTo(b)
1377 if err != nil {
1378 return err
1379 }
1380 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1381 me.ParamData{EntityID: omci.EntityInstance})
1382 if omciErr.StatusCode() != me.Success {
1383 return omciErr.GetError()
1384 }
1385 // ME needs to support MIB Upload
1386 if !me.SupportsMsgType(entity, me.MibUpload) {
1387 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1388 }
1389 bytes, err := b.AppendBytes(2)
1390 if err != nil {
1391 return err
1392 }
1393 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1394 return nil
1395}
1396
1397/////////////////////////////////////////////////////////////////////////////
1398//
1399type MibUploadNextRequest struct {
1400 MeBasePacket
1401 CommandSequenceNumber uint16
1402}
1403
1404func (omci *MibUploadNextRequest) String() string {
1405 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
1406 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1407}
1408
1409// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
1410func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1411 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001412 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06001413 if err != nil {
1414 return err
1415 }
1416 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1417 me.ParamData{EntityID: omci.EntityInstance})
1418 if omciErr.StatusCode() != me.Success {
1419 return omciErr.GetError()
1420 }
1421 // ME needs to support Get All Alarms
1422 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1423 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1424 }
1425 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1426 if omci.EntityClass != me.OnuDataClassID {
1427 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
1428 omci.EntityClass)
1429 return me.NewProcessingError(msg)
1430 }
1431 if omci.EntityInstance != 0 {
1432 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
1433 omci.EntityInstance)
1434 return me.NewUnknownInstanceError(msg)
1435 }
1436 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1437 return nil
1438}
1439
1440func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
1441 omci := &MibUploadNextRequest{}
1442 omci.MsgLayerType = LayerTypeMibUploadNextRequest
1443 return decodingLayerDecoder(omci, data, p)
1444}
1445
1446// SerializeTo provides serialization of an MIB Upload Next Request message
1447func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1448 // Basic (common) OMCI Header is 8 octets, 10
1449 err := omci.MeBasePacket.SerializeTo(b)
1450 if err != nil {
1451 return err
1452 }
1453 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1454 me.ParamData{EntityID: omci.EntityInstance})
1455 if omciErr.StatusCode() != me.Success {
1456 return omciErr.GetError()
1457 }
1458 // ME needs to support MIB upload
1459 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1460 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1461 }
1462 bytes, err := b.AppendBytes(2)
1463 if err != nil {
1464 return err
1465 }
1466 binary.BigEndian.PutUint16(bytes[0:2], omci.CommandSequenceNumber)
1467 return nil
1468}
1469
1470/////////////////////////////////////////////////////////////////////////////
1471//
1472type MibUploadNextResponse struct {
1473 MeBasePacket
1474 ReportedME me.ManagedEntity
1475}
1476
1477func (omci *MibUploadNextResponse) String() string {
1478 return fmt.Sprintf("%v, ReportedME: [%v]",
1479 omci.MeBasePacket.String(), omci.ReportedME.String())
1480}
1481
1482// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
1483func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1484 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001485 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+6)
Chip Boling6e27b352020-02-14 09:10:01 -06001486 if err != nil {
1487 return err
1488 }
1489 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1490 me.ParamData{EntityID: omci.EntityInstance})
1491 if omciErr.StatusCode() != me.Success {
1492 return omciErr.GetError()
1493 }
1494 // ME needs to support MibUploadNext
1495 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1496 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1497 }
1498 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1499 if omci.EntityClass != me.OnuDataClassID {
1500 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
1501 omci.EntityClass)
1502 return me.NewProcessingError(msg)
1503 }
1504 if omci.EntityInstance != 0 {
1505 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
1506 omci.EntityInstance)
1507 return me.NewUnknownInstanceError(msg)
1508 }
1509 // Decode reported ME. If an out-of-range sequence number was sent, this will
1510 // contain an ME with class ID and entity ID of zero and you should get an
1511 // error of "managed entity definition not found" returned.
1512 return omci.ReportedME.DecodeFromBytes(data[4:], p, byte(MibUploadNextResponseType))
1513}
1514
1515func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
1516 omci := &MibUploadNextResponse{}
1517 omci.MsgLayerType = LayerTypeMibUploadNextResponse
1518 return decodingLayerDecoder(omci, data, p)
1519}
1520
1521// SerializeTo provides serialization of an MIB Upload Next Response message
1522func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1523 // Basic (common) OMCI Header is 8 octets, 10
1524 err := omci.MeBasePacket.SerializeTo(b)
1525 if err != nil {
1526 return err
1527 }
1528 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1529 me.ParamData{EntityID: omci.EntityInstance})
1530 if omciErr.StatusCode() != me.Success {
1531 return omciErr.GetError()
1532 }
1533 // ME needs to support MIB Upload
1534 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1535 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1536 }
1537 // TODO: Only Baseline supported at this time
1538 bytesAvailable := MaxBaselineLength - 8 - 8
1539
1540 return omci.ReportedME.SerializeTo(b, byte(MibUploadNextResponseType), bytesAvailable, opts)
1541}
1542
1543/////////////////////////////////////////////////////////////////////////////
1544// MibResetRequest
1545type MibResetRequest struct {
1546 MeBasePacket
1547}
1548
1549func (omci *MibResetRequest) String() string {
1550 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1551}
1552
1553// DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
1554func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1555 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06001556 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06001557 if err != nil {
1558 return err
1559 }
1560 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1561 me.ParamData{EntityID: omci.EntityInstance})
1562 if omciErr.StatusCode() != me.Success {
1563 return omciErr.GetError()
1564 }
1565 // ME needs to support MIB reset
1566 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1567 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1568 }
1569 // Entity Class are always ONU DATA (2) and Entity Instance of 0
1570 if omci.EntityClass != me.OnuDataClassID {
1571 msg := fmt.Sprintf("invalid Entity Class for MIB Reset request: %v",
1572 omci.EntityClass)
1573 return me.NewProcessingError(msg)
1574 }
1575 if omci.EntityInstance != 0 {
1576 msg := fmt.Sprintf("invalid Entity Instance for MIB Reset request: %v",
1577 omci.EntityInstance)
1578 return me.NewUnknownInstanceError(msg)
1579 }
1580 return nil
1581}
1582
1583func decodeMibResetRequest(data []byte, p gopacket.PacketBuilder) error {
1584 omci := &MibResetRequest{}
1585 omci.MsgLayerType = LayerTypeMibResetRequest
1586 return decodingLayerDecoder(omci, data, p)
1587}
1588
1589// SerializeTo provides serialization of an MIB Reset Request message
1590func (omci *MibResetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1591 // Add class ID and entity ID
1592 return omci.MeBasePacket.SerializeTo(b)
1593}
1594
1595/////////////////////////////////////////////////////////////////////////////
1596// MibResetResponse
1597type MibResetResponse struct {
1598 MeBasePacket
1599 Result me.Results
1600}
1601
1602func (omci *MibResetResponse) String() string {
1603 return fmt.Sprintf("%v, Result: %d (%v)",
1604 omci.MeBasePacket.String(), omci.Result, omci.Result)
1605}
1606
1607// DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
1608func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1609 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001610 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06001611 if err != nil {
1612 return err
1613 }
1614 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1615 me.ParamData{EntityID: omci.EntityInstance})
1616 if omciErr.StatusCode() != me.Success {
1617 return omciErr.GetError()
1618 }
1619 // ME needs to support MIB reset
1620 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1621 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1622 }
1623 // MIB Reset Response Entity Class always ONU DATA (2) and
1624 // Entity Instance of 0
1625 if omci.EntityClass != me.OnuDataClassID {
1626 return me.NewProcessingError("invalid Entity Class for MIB Reset Response")
1627 }
1628 if omci.EntityInstance != 0 {
1629 return me.NewUnknownInstanceError("invalid Entity Instance for MIB Reset Response")
1630 }
1631 omci.Result = me.Results(data[4])
1632 if omci.Result > me.DeviceBusy {
Chip Bolingd8637b02021-04-29 08:36:38 -05001633 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
Chip Boling6e27b352020-02-14 09:10:01 -06001634 return errors.New(msg)
1635 }
1636 return nil
1637}
1638
1639func decodeMibResetResponse(data []byte, p gopacket.PacketBuilder) error {
1640 omci := &MibResetResponse{}
1641 omci.MsgLayerType = LayerTypeMibResetResponse
1642 return decodingLayerDecoder(omci, data, p)
1643}
1644
1645// SerializeTo provides serialization of an MIB Reset Response message
1646func (omci *MibResetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1647 // Basic (common) OMCI Header is 8 octets, 10
1648 err := omci.MeBasePacket.SerializeTo(b)
1649 if err != nil {
1650 return err
1651 }
1652 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1653 me.ParamData{EntityID: omci.EntityInstance})
1654 if omciErr.StatusCode() != me.Success {
1655 return omciErr.GetError()
1656 }
1657 // ME needs to support Set
1658 if !me.SupportsMsgType(entity, me.MibReset) {
1659 return me.NewProcessingError("managed entity does not support the MIB Reset Message-Type")
1660 }
1661 bytes, err := b.AppendBytes(1)
1662 if err != nil {
1663 return err
1664 }
1665 bytes[0] = byte(omci.Result)
1666 return nil
1667}
1668
1669/////////////////////////////////////////////////////////////////////////////
1670// AlarmNotificationMsg
1671const AlarmBitmapSize = 224
1672
1673type AlarmNotificationMsg struct {
1674 MeBasePacket
1675 AlarmBitmap [AlarmBitmapSize / 8]byte
1676 zeroPadding [3]byte
1677 AlarmSequenceNumber byte
1678}
1679
1680func (omci *AlarmNotificationMsg) String() string {
1681 return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
1682 omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
1683}
1684
1685func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
1686 if alarmNumber >= AlarmBitmapSize {
1687 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1688 return false, errors.New(msg)
1689 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001690 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1691 me.ParamData{EntityID: omci.EntityInstance})
1692 if omciErr.StatusCode() != me.Success {
1693 return false, omciErr.GetError()
1694 }
1695 alarmMap := entity.GetAlarmMap()
1696 if alarmMap == nil {
1697 msg := "Managed Entity does not support Alarm notifications"
1698 return false, errors.New(msg)
1699 }
1700 if _, ok := alarmMap[alarmNumber]; !ok {
1701 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1702 return false, errors.New(msg)
1703 }
Chip Boling6e27b352020-02-14 09:10:01 -06001704 octet := alarmNumber / 8
1705 bit := 7 - (alarmNumber % 8)
1706 return omci.AlarmBitmap[octet]>>bit == 1, nil
1707}
1708
1709func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
1710 if alarmNumber >= AlarmBitmapSize {
1711 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1712 return false, errors.New(msg)
1713 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001714 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1715 me.ParamData{EntityID: omci.EntityInstance})
1716 if omciErr.StatusCode() != me.Success {
1717 return false, omciErr.GetError()
1718 }
1719 alarmMap := entity.GetAlarmMap()
1720 if alarmMap == nil {
1721 return false, errors.New("Managed Entity does not support Alarm notifications")
1722 }
1723 if _, ok := alarmMap[alarmNumber]; !ok {
1724 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1725 return false, errors.New(msg)
1726 }
Chip Boling6e27b352020-02-14 09:10:01 -06001727 octet := alarmNumber / 8
1728 bit := 7 - (alarmNumber % 8)
1729 return omci.AlarmBitmap[octet]>>bit == 0, nil
1730}
1731
1732func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
1733 if alarmNumber >= AlarmBitmapSize {
1734 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1735 return errors.New(msg)
1736 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001737 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1738 me.ParamData{EntityID: omci.EntityInstance})
1739 if omciErr.StatusCode() != me.Success {
1740 return omciErr.GetError()
1741 }
1742 alarmMap := entity.GetAlarmMap()
1743 if alarmMap == nil {
1744 return errors.New("Managed Entity does not support Alarm notifications")
1745 }
1746 if _, ok := alarmMap[alarmNumber]; !ok {
1747 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1748 return errors.New(msg)
1749 }
Chip Boling6e27b352020-02-14 09:10:01 -06001750 octet := alarmNumber / 8
1751 bit := 7 - (alarmNumber % 8)
1752 omci.AlarmBitmap[octet] |= 1 << bit
1753 return nil
1754}
1755
1756func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
1757 if alarmNumber >= AlarmBitmapSize {
1758 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1759 return errors.New(msg)
1760 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001761 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1762 me.ParamData{EntityID: omci.EntityInstance})
1763 if omciErr.StatusCode() != me.Success {
1764 return omciErr.GetError()
1765 }
1766 alarmMap := entity.GetAlarmMap()
1767 if alarmMap == nil {
1768 return errors.New("Managed Entity does not support Alarm notifications")
1769 }
1770 if _, ok := alarmMap[alarmNumber]; !ok {
1771 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1772 return errors.New(msg)
1773 }
Chip Boling6e27b352020-02-14 09:10:01 -06001774 octet := alarmNumber / 8
1775 bit := 7 - (alarmNumber % 8)
1776 omci.AlarmBitmap[octet] &= ^(1 << bit)
1777 return nil
1778}
1779
1780// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
1781func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1782 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001783 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+28)
Chip Boling6e27b352020-02-14 09:10:01 -06001784 if err != nil {
1785 return err
1786 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001787 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1788 me.ParamData{EntityID: omci.EntityInstance})
1789 if omciErr.StatusCode() != me.Success {
1790 return omciErr.GetError()
Chip Boling6e27b352020-02-14 09:10:01 -06001791 }
Chip Boling34ebcb62021-02-02 12:13:58 -06001792 // Is this an unsupported or vendor specific ME. If so, it is not an error to decode
1793 // the alarms. We just cannot provide any alarm names. Handle decode here.
1794 classSupport := meDefinition.GetClassSupport()
1795 isUnsupported := classSupport == me.UnsupportedManagedEntity ||
1796 classSupport == me.UnsupportedVendorSpecificManagedEntity
Chip Boling6e27b352020-02-14 09:10:01 -06001797
Chip Boling34ebcb62021-02-02 12:13:58 -06001798 // Look for a non-nil/not empty Alarm Map to determine if this ME supports alarms
1799 if alarmMap := meDefinition.GetAlarmMap(); isUnsupported || (alarmMap != nil && len(alarmMap) > 0) {
1800 for index, octet := range data[4 : (AlarmBitmapSize/8)-4] {
1801 omci.AlarmBitmap[index] = octet
1802 }
1803 padOffset := 4 + (AlarmBitmapSize / 8)
1804 omci.zeroPadding[0] = data[padOffset]
1805 omci.zeroPadding[1] = data[padOffset+1]
1806 omci.zeroPadding[2] = data[padOffset+2]
1807
1808 omci.AlarmSequenceNumber = data[padOffset+3]
1809 return nil
1810 }
1811 return me.NewProcessingError("managed entity does not support alarm notifications")
Chip Boling6e27b352020-02-14 09:10:01 -06001812}
1813
1814func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
1815 omci := &AlarmNotificationMsg{}
1816 omci.MsgLayerType = LayerTypeAlarmNotification
1817 return decodingLayerDecoder(omci, data, p)
1818}
1819
1820// SerializeTo provides serialization of an Alarm Notification message
1821func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1822 // Basic (common) OMCI Header is 8 octets, 10
1823 err := omci.MeBasePacket.SerializeTo(b)
1824 if err != nil {
1825 return err
1826 }
1827 //var meDefinition me.IManagedEntityDefinition
1828 //meDefinition, err = me.LoadManagedEntityDefinition(omci.EntityClass,
1829 // me.ParamData{EntityID: omci.EntityInstance})
1830 //if err != nil {
1831 // return err
1832 //}
1833 // ME needs to support Alarms
1834 // TODO: Add attribute to ME to specify that alarm is allowed
1835 //if !me.SupportsMsgType(meDefinition, me.MibReset) {
1836 // return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1837 //}
1838 bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
1839 if err != nil {
1840 return err
1841 }
1842 for index, octet := range omci.AlarmBitmap {
1843 bytes[index] = octet
1844 }
1845 padOffset := AlarmBitmapSize / 8
1846 bytes[padOffset] = 0
1847 bytes[padOffset+1] = 0
1848 bytes[padOffset+2] = 0
1849 bytes[padOffset+3] = omci.AlarmSequenceNumber
1850 return nil
1851}
1852
1853/////////////////////////////////////////////////////////////////////////////
1854// AttributeValueChangeMsg
1855type AttributeValueChangeMsg struct {
1856 MeBasePacket
1857 AttributeMask uint16
1858 Attributes me.AttributeValueMap
1859}
1860
1861func (omci *AttributeValueChangeMsg) String() string {
1862 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
1863 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
1864}
1865
1866// DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
1867func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1868 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06001869 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06001870 if err != nil {
1871 return err
1872 }
1873 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1874 me.ParamData{EntityID: omci.EntityInstance})
1875 if omciErr.StatusCode() != me.Success {
1876 return omciErr.GetError()
1877 }
1878 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
1879 // Attribute decode
1880 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:40], p, byte(AttributeValueChangeType))
1881 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1882 // Validate all attributes support AVC
1883 //for attrName := range omci.attributes {
1884 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1885 // if err != nil {
1886 // return err
1887 // }
1888 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1889 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1890 // return me.NewProcessingError(msg)
1891 // }
1892 //}
1893 return err
1894}
1895
1896func decodeAttributeValueChange(data []byte, p gopacket.PacketBuilder) error {
1897 omci := &AttributeValueChangeMsg{}
1898 omci.MsgLayerType = LayerTypeAttributeValueChange
1899 return decodingLayerDecoder(omci, data, p)
1900}
1901
1902// SerializeTo provides serialization of an Attribute Value Change Notification message
1903func (omci *AttributeValueChangeMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1904 // Basic (common) OMCI Header is 8 octets, 10
1905 err := omci.MeBasePacket.SerializeTo(b)
1906 if err != nil {
1907 return err
1908 }
1909 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1910 me.ParamData{EntityID: omci.EntityInstance})
1911 if omciErr.StatusCode() != me.Success {
1912 return omciErr.GetError()
1913 }
1914 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1915 // Validate all attributes support AVC
1916 //for attrName := range omci.attributes {
1917 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1918 // if err != nil {
1919 // return err
1920 // }
1921 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1922 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1923 // return me.NewProcessingError(msg)
1924 // }
1925 //}
1926 bytes, err := b.AppendBytes(2)
1927 if err != nil {
1928 return err
1929 }
1930 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
1931
1932 // Attribute serialization
1933 // TODO: Only Baseline supported at this time
1934 bytesAvailable := MaxBaselineLength - 10 - 8
1935
1936 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
1937 byte(AttributeValueChangeType), bytesAvailable, false)
1938 return err
1939}
1940
Chip Bolingd8637b02021-04-29 08:36:38 -05001941func decodeTestRequest(data []byte, p gopacket.PacketBuilder) error {
1942 // Peek at Managed Entity Type
1943 if len(data) < 8 {
1944 p.SetTruncated()
1945 return errors.New("frame too small")
1946 }
1947 classID := binary.BigEndian.Uint16(data)
1948
1949 // Is it a Managed Entity class we support customized decode of?
1950 switch me.ClassID(classID) {
1951 default:
1952 omci := &TestRequest{}
1953 omci.MsgLayerType = LayerTypeTestResult
1954 return decodingLayerDecoder(omci, data, p)
1955
1956 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
1957 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
1958 omci := &OpticalLineSupervisionTestRequest{}
1959 omci.MsgLayerType = LayerTypeTestResult
1960 return decodingLayerDecoder(omci, data, p)
1961 }
1962}
1963
1964// TestRequest message
Chip Boling6e27b352020-02-14 09:10:01 -06001965type TestRequest struct {
1966 MeBasePacket
Chip Bolingd8637b02021-04-29 08:36:38 -05001967 Payload []byte
Chip Boling6e27b352020-02-14 09:10:01 -06001968}
1969
1970func (omci *TestRequest) String() string {
Chip Bolingd8637b02021-04-29 08:36:38 -05001971 return fmt.Sprintf("%v, Request: %v octets", omci.MeBasePacket.String(), len(omci.Payload))
1972}
1973
1974func (omci *TestRequest) TestRequest() []byte {
1975 return omci.Payload
Chip Boling6e27b352020-02-14 09:10:01 -06001976}
1977
1978// DecodeFromBytes decodes the given bytes of a Test Request into this layer
1979func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1980 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8637b02021-04-29 08:36:38 -05001981 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06001982 if err != nil {
1983 return err
1984 }
Chip Boling6e27b352020-02-14 09:10:01 -06001985
Chip Bolingd8637b02021-04-29 08:36:38 -05001986 omci.Payload = make([]byte, MaxTestRequestLength)
1987 copy(omci.Payload, omci.MeBasePacket.Payload)
1988 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06001989}
1990
1991// SerializeTo provides serialization of an Test Request message
1992func (omci *TestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1993 // Basic (common) OMCI Header is 8 octets, 10
1994 err := omci.MeBasePacket.SerializeTo(b)
1995 if err != nil {
1996 return err
1997 }
Chip Bolingd8637b02021-04-29 08:36:38 -05001998 if omci.Payload == nil {
1999 return errors.New("Test Results payload is missing")
2000 }
2001
2002 if len(omci.Payload) > MaxTestRequestLength {
2003 msg := fmt.Sprintf("Invalid Test Request payload size. Received %v bytes, expected %v",
2004 len(omci.Payload), MaxTestRequestLength)
2005 return errors.New(msg)
2006 }
2007 bytes, err := b.AppendBytes(len(omci.Payload))
2008 if err != nil {
2009 return err
2010 }
2011
2012 copy(bytes, omci.Payload)
2013 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06002014}
2015
Chip Bolingd8637b02021-04-29 08:36:38 -05002016type OpticalLineSupervisionTestRequest struct {
2017 MeBasePacket
2018 SelectTest uint8 // Bitfield
2019 GeneralPurposeBuffer uint16 // Pointer to General Purpose Buffer ME
2020 VendorSpecificParameters uint16 // Pointer to Octet String ME
2021}
2022
2023func (omci *OpticalLineSupervisionTestRequest) String() string {
2024 return fmt.Sprintf("Optical Line Supervision Test Result: SelectTest: %#x, Buffer: %#x, Params: %#x",
2025 omci.SelectTest, omci.GeneralPurposeBuffer, omci.VendorSpecificParameters)
2026}
2027
2028func (omci *OpticalLineSupervisionTestRequest) TestRequest() []byte {
2029 return omci.Payload
2030}
2031
2032// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
2033func (omci *OpticalLineSupervisionTestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2034 // Common ClassID/EntityID decode in msgBase
2035 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
2036 if err != nil {
2037 return err
2038 }
2039
2040 omci.SelectTest = data[4]
2041 omci.GeneralPurposeBuffer = binary.BigEndian.Uint16(data[5:])
2042 omci.VendorSpecificParameters = binary.BigEndian.Uint16(data[7:])
2043 return nil
2044}
2045
2046// SerializeTo provides serialization of an Test Result notification message
2047func (omci *OpticalLineSupervisionTestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2048 // Basic (common) OMCI Header is 8 octets, 10
2049 err := omci.MeBasePacket.SerializeTo(b)
2050 if err != nil {
2051 return err
2052 }
2053
2054 bytes, err := b.AppendBytes(8)
2055 if err != nil {
2056 return err
2057 }
2058
2059 bytes[0] = omci.SelectTest
2060 binary.BigEndian.PutUint16(bytes[1:], omci.GeneralPurposeBuffer)
2061 binary.BigEndian.PutUint16(bytes[3:], omci.VendorSpecificParameters)
2062 return nil
2063}
2064
2065// TestResponse message
Chip Boling6e27b352020-02-14 09:10:01 -06002066type TestResponse struct {
2067 MeBasePacket
Chip Bolingd8637b02021-04-29 08:36:38 -05002068 Result me.Results
Chip Boling6e27b352020-02-14 09:10:01 -06002069}
2070
2071func (omci *TestResponse) String() string {
Chip Bolingd8637b02021-04-29 08:36:38 -05002072 return fmt.Sprintf("%v, Results: %d (%v)", omci.MeBasePacket.String(), omci.Result, omci.Result)
Chip Boling6e27b352020-02-14 09:10:01 -06002073}
2074
2075// DecodeFromBytes decodes the given bytes of a Test Response into this layer
2076func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2077 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002078 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002079 if err != nil {
2080 return err
2081 }
Chip Bolingd8637b02021-04-29 08:36:38 -05002082 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2083 me.ParamData{EntityID: omci.EntityInstance})
2084 if omciErr.StatusCode() != me.Success {
2085 return omciErr.GetError()
2086 }
2087
2088 // ME needs to support Test requests
2089 if !me.SupportsMsgType(meDefinition, me.Test) {
2090 return me.NewProcessingError("managed entity does not support Test Message-Type")
2091 }
2092 omci.Result = me.Results(data[4])
2093 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06002094}
2095
2096func decodeTestResponse(data []byte, p gopacket.PacketBuilder) error {
2097 omci := &TestResponse{}
2098 omci.MsgLayerType = LayerTypeTestResponse
2099 return decodingLayerDecoder(omci, data, p)
2100}
2101
2102// SerializeTo provides serialization of an Test Response message
2103func (omci *TestResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2104 // Basic (common) OMCI Header is 8 octets, 10
2105 err := omci.MeBasePacket.SerializeTo(b)
2106 if err != nil {
2107 return err
2108 }
Chip Bolingd8637b02021-04-29 08:36:38 -05002109 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2110 me.ParamData{EntityID: omci.EntityInstance})
2111 if omciErr.StatusCode() != me.Success {
2112 return omciErr.GetError()
2113 }
2114 // ME needs to support Set
2115 if !me.SupportsMsgType(entity, me.Test) {
2116 return me.NewProcessingError("managed entity does not support the Test Message-Type")
2117 }
2118 bytes, err := b.AppendBytes(1)
2119 if err != nil {
2120 return err
2121 }
2122 bytes[0] = byte(omci.Result)
2123
2124 if omci.Result > me.DeviceBusy {
2125 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
2126 return errors.New(msg)
2127 }
2128 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06002129}
2130
2131/////////////////////////////////////////////////////////////////////////////
2132//
2133type StartSoftwareDownloadRequest struct {
2134 MeBasePacket // Note: EntityInstance for software download is two specific values
2135 WindowSize byte // Window Size -1
2136 ImageSize uint32 // Octets
2137 NumberOfCircuitPacks byte
2138 CircuitPacks []uint16 // MSB & LSB of software image instance
2139}
2140
2141func (omci *StartSoftwareDownloadRequest) String() string {
2142 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
2143 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
2144}
2145
2146// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
2147func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
Chip Boling58fc4d22021-03-10 13:23:53 -06002148 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Chip Boling6e27b352020-02-14 09:10:01 -06002149 if err != nil {
2150 return err
2151 }
2152 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2153 me.ParamData{EntityID: omci.EntityInstance})
2154 if omciErr.StatusCode() != me.Success {
2155 return omciErr.GetError()
2156 }
2157 // ME needs to support Start Software Download
2158 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2159 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2160 }
2161 // Software Image Entity Class are always use the Software Image
2162 if omci.EntityClass != me.SoftwareImageClassID {
2163 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
2164 }
2165 omci.WindowSize = data[4]
2166 omci.ImageSize = binary.BigEndian.Uint32(data[5:9])
2167 omci.NumberOfCircuitPacks = data[9]
2168 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
2169 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
2170 omci.NumberOfCircuitPacks))
2171 }
2172 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
2173 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2174 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[10+(index*2):])
2175 }
2176 return nil
2177}
2178
2179func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2180 omci := &StartSoftwareDownloadRequest{}
2181 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
2182 return decodingLayerDecoder(omci, data, p)
2183}
2184
2185// SerializeTo provides serialization of an Start Software Download Request message
2186func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2187 // Basic (common) OMCI Header is 8 octets, 10
2188 err := omci.MeBasePacket.SerializeTo(b)
2189 if err != nil {
2190 return err
2191 }
2192 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2193 me.ParamData{EntityID: omci.EntityInstance})
2194 if omciErr.StatusCode() != me.Success {
2195 return omciErr.GetError()
2196 }
2197 // ME needs to support Start Software Download
2198 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
2199 return me.NewProcessingError("managed entity does not support the SStart Software Download Message-Type")
2200 }
2201 // Software Image Entity Class are always use the Software Image
2202 if omci.EntityClass != me.SoftwareImageClassID {
2203 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
2204 }
2205 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
2206 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
2207 omci.NumberOfCircuitPacks))
2208 }
2209 bytes, err := b.AppendBytes(6 + (2 * int(omci.NumberOfCircuitPacks)))
2210 if err != nil {
2211 return err
2212 }
2213 bytes[0] = omci.WindowSize
2214 binary.BigEndian.PutUint32(bytes[1:], omci.ImageSize)
2215 bytes[5] = omci.NumberOfCircuitPacks
2216 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2217 binary.BigEndian.PutUint16(bytes[6+(index*2):], omci.CircuitPacks[index])
2218 }
2219 return nil
2220}
2221
2222/////////////////////////////////////////////////////////////////////////////
2223//
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002224type DownloadResults struct {
Chip Boling6e27b352020-02-14 09:10:01 -06002225 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
2226 Result me.Results
2227}
2228
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002229func (dr *DownloadResults) String() string {
Chip Boling6e27b352020-02-14 09:10:01 -06002230 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
2231 dr.Result, dr.Result)
2232}
2233
2234type StartSoftwareDownloadResponse struct {
2235 MeBasePacket // Note: EntityInstance for software download is two specific values
2236 Result me.Results
2237 WindowSize byte // Window Size -1
2238 NumberOfInstances byte
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002239 MeResults []DownloadResults
Chip Boling6e27b352020-02-14 09:10:01 -06002240}
2241
2242func (omci *StartSoftwareDownloadResponse) String() string {
2243 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
2244 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
2245}
2246
2247// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
2248func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2249 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002250 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -06002251 if err != nil {
2252 return err
2253 }
2254 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2255 me.ParamData{EntityID: omci.EntityInstance})
2256 if omciErr.StatusCode() != me.Success {
2257 return omciErr.GetError()
2258 }
2259 // ME needs to support Start Software Download
2260 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2261 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2262 }
2263 // Software Image Entity Class are always use the Software Image
2264 if omci.EntityClass != me.SoftwareImageClassID {
2265 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2266 }
2267 omci.Result = me.Results(data[4])
2268 if omci.Result > me.DeviceBusy {
2269 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2270 omci.Result)
2271 return errors.New(msg)
2272 }
2273 omci.WindowSize = data[5]
2274 omci.NumberOfInstances = data[6]
2275
2276 if omci.NumberOfInstances > 9 {
2277 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2278 omci.NumberOfInstances)
2279 return errors.New(msg)
2280 }
2281 if omci.NumberOfInstances > 0 {
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002282 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Chip Boling6e27b352020-02-14 09:10:01 -06002283
2284 for index := 0; index < int(omci.NumberOfInstances); index++ {
2285 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
2286 omci.MeResults[index].Result = me.Results(data[9+(index*3)])
2287 if omci.MeResults[index].Result > me.DeviceBusy {
2288 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2289 index, omci.MeResults[index])
2290 return errors.New(msg)
2291 }
2292 }
2293 }
2294 return nil
2295}
2296
2297func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2298 omci := &StartSoftwareDownloadResponse{}
2299 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
2300 return decodingLayerDecoder(omci, data, p)
2301}
2302
2303// SerializeTo provides serialization of an Start Software Download Response message
2304func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2305 // Basic (common) OMCI Header is 8 octets, 10
2306 err := omci.MeBasePacket.SerializeTo(b)
2307 if err != nil {
2308 return err
2309 }
2310 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2311 me.ParamData{EntityID: omci.EntityInstance})
2312 if omciErr.StatusCode() != me.Success {
2313 return omciErr.GetError()
2314 }
2315 // ME needs to support Start Software Download
2316 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2317 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2318 }
2319 // Software Image Entity Class are always use the Software Image
2320 if omci.EntityClass != me.SoftwareImageClassID {
2321 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2322 }
2323 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2324 if err != nil {
2325 return err
2326 }
2327 if omci.Result > me.DeviceBusy {
2328 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2329 omci.Result)
2330 return errors.New(msg)
2331 }
2332 bytes[0] = byte(omci.Result)
2333 bytes[1] = omci.WindowSize
2334 bytes[2] = omci.NumberOfInstances
2335
2336 if omci.NumberOfInstances > 9 {
2337 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2338 omci.NumberOfInstances)
2339 return errors.New(msg)
2340 }
2341 if omci.NumberOfInstances > 0 {
2342 for index := 0; index < int(omci.NumberOfInstances); index++ {
2343 binary.BigEndian.PutUint16(bytes[3+(3*index):], omci.MeResults[index].ManagedEntityID)
2344
2345 if omci.MeResults[index].Result > me.DeviceBusy {
2346 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2347 index, omci.MeResults[index])
2348 return errors.New(msg)
2349 }
2350 bytes[5+(3*index)] = byte(omci.MeResults[index].Result)
2351 }
2352 }
2353 return nil
2354}
2355
Chip Boling00a30d22021-05-04 13:31:52 -05002356// DownloadSectionRequest data is bound by the message set in use. For the
2357// Baseline message set use MaxDownloadSectionLength and for the Extended message
2358// set, MaxDownloadSectionExtendedLength is provided
Chip Boling6e27b352020-02-14 09:10:01 -06002359type DownloadSectionRequest struct {
2360 MeBasePacket // Note: EntityInstance for software download is two specific values
2361 SectionNumber byte
Chip Boling00a30d22021-05-04 13:31:52 -05002362 SectionData []byte // 0 padding if final transfer requires only a partial block for baseline set
Chip Boling6e27b352020-02-14 09:10:01 -06002363}
2364
2365func (omci *DownloadSectionRequest) String() string {
Chip Boling00a30d22021-05-04 13:31:52 -05002366 return fmt.Sprintf("%v, Section #: %v, Data Length: %v",
2367 omci.MeBasePacket.String(), omci.SectionNumber, len(omci.SectionData))
Chip Boling6e27b352020-02-14 09:10:01 -06002368}
2369
2370// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
2371func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2372 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002373 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002374 if err != nil {
2375 return err
2376 }
2377 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2378 me.ParamData{EntityID: omci.EntityInstance})
2379 if omciErr.StatusCode() != me.Success {
2380 return omciErr.GetError()
2381 }
2382 // ME needs to support Download section
2383 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2384 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2385 }
2386 // Software Image Entity Class are always use the Software Image
2387 if omci.EntityClass != me.SoftwareImageClassID {
2388 return me.NewProcessingError("invalid Entity Class for Download Section request")
2389 }
Chip Boling00a30d22021-05-04 13:31:52 -05002390 if omci.Extended {
2391 if len(data) < 7 {
2392 p.SetTruncated()
2393 return errors.New("frame too small")
2394 }
2395 if len(data[7:]) > MaxDownloadSectionExtendedLength {
2396 return errors.New(fmt.Sprintf("software image data too large. Received %v, Max: %v",
2397 len(data[7:]), MaxDownloadSectionExtendedLength))
2398 }
2399 omci.SectionData = make([]byte, len(data[7:]))
2400 omci.SectionNumber = data[6]
2401 copy(omci.SectionData, data[7:])
2402 } else {
2403 if len(data[5:]) != MaxDownloadSectionLength {
2404 p.SetTruncated()
2405 return errors.New(fmt.Sprintf("software image size invalid. Received %v, Expected: %v",
2406 len(data[5:]), MaxDownloadSectionLength))
2407 }
2408 omci.SectionData = make([]byte, MaxDownloadSectionLength)
2409 omci.SectionNumber = data[4]
2410 copy(omci.SectionData, data[5:])
2411 }
Chip Boling6e27b352020-02-14 09:10:01 -06002412 return nil
2413}
2414
2415func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2416 omci := &DownloadSectionRequest{}
2417 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2418 return decodingLayerDecoder(omci, data, p)
2419}
2420
Chip Boling00a30d22021-05-04 13:31:52 -05002421func decodeDownloadSectionRequestExtended(data []byte, p gopacket.PacketBuilder) error {
2422 omci := &DownloadSectionRequest{}
2423 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2424 omci.Extended = true
2425 return decodingLayerDecoder(omci, data, p)
2426}
2427
Chip Boling6e27b352020-02-14 09:10:01 -06002428// SerializeTo provides serialization of an Download Section Request message
2429func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2430 // Basic (common) OMCI Header is 8 octets, 10
2431 err := omci.MeBasePacket.SerializeTo(b)
2432 if err != nil {
2433 return err
2434 }
2435 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2436 me.ParamData{EntityID: omci.EntityInstance})
2437 if omciErr.StatusCode() != me.Success {
2438 return omciErr.GetError()
2439 }
2440 // ME needs to support Download section
2441 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2442 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2443 }
2444 // Software Image Entity Class are always use the Software Image
2445 if omci.EntityClass != me.SoftwareImageClassID {
2446 return me.NewProcessingError("invalid Entity Class for Download Section response")
2447 }
Chip Boling00a30d22021-05-04 13:31:52 -05002448 sectionLength := len(omci.SectionData)
2449 if omci.Extended {
2450 if sectionLength > MaxDownloadSectionExtendedLength {
2451 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
2452 MaxDownloadSectionExtendedLength, sectionLength)
2453 return me.NewProcessingError(msg)
2454 }
2455 // Append section data
2456 bytes, err := b.AppendBytes(3 + sectionLength)
2457 if err != nil {
2458 return err
2459 }
2460 binary.BigEndian.PutUint16(bytes, uint16(1+sectionLength))
2461 bytes[2] = omci.SectionNumber
2462 copy(bytes[3:], omci.SectionData)
2463 } else {
2464 if sectionLength > MaxDownloadSectionLength {
2465 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
2466 MaxDownloadSectionLength, sectionLength)
2467 return me.NewProcessingError(msg)
2468 }
2469 // Append section data
2470 bytes, err := b.AppendBytes(1 + MaxDownloadSectionLength)
2471 if err != nil {
2472 return err
2473 }
2474 bytes[0] = omci.SectionNumber
2475 copy(bytes[1:], omci.SectionData)
2476
2477 // Zero extended if needed
2478 if sectionLength < MaxDownloadSectionLength {
2479 copy(omci.SectionData[sectionLength:], lotsOfZeros[:MaxDownloadSectionLength-sectionLength])
2480 }
Chip Boling6e27b352020-02-14 09:10:01 -06002481 }
Chip Boling6e27b352020-02-14 09:10:01 -06002482 return nil
2483}
2484
2485/////////////////////////////////////////////////////////////////////////////
2486//
2487type DownloadSectionResponse struct {
2488 MeBasePacket // Note: EntityInstance for software download is two specific values
2489 Result me.Results
2490 SectionNumber byte
2491}
2492
2493func (omci *DownloadSectionResponse) String() string {
2494 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2495 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2496}
2497
2498// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
2499func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2500 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002501 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06002502 if err != nil {
2503 return err
2504 }
2505 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2506 me.ParamData{EntityID: omci.EntityInstance})
2507 if omciErr.StatusCode() != me.Success {
2508 return omciErr.GetError()
2509 }
2510 // ME needs to support Download section
2511 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2512 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2513 }
2514 // Software Image Entity Class are always use the Software Image
2515 if omci.EntityClass != me.SoftwareImageClassID {
2516 return me.NewProcessingError("invalid Entity Class for Download Section response")
2517 }
Chip Boling00a30d22021-05-04 13:31:52 -05002518 if omci.Extended {
2519 if len(data) < 8 {
2520 p.SetTruncated()
2521 return errors.New("frame too small")
2522 }
2523 omci.Result = me.Results(data[6])
2524 omci.SectionNumber = data[7]
2525 } else {
2526 omci.Result = me.Results(data[4])
2527 omci.SectionNumber = data[5]
2528 }
Chip Boling6e27b352020-02-14 09:10:01 -06002529 if omci.Result > me.DeviceBusy {
2530 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2531 omci.Result)
2532 return errors.New(msg)
2533 }
Chip Boling6e27b352020-02-14 09:10:01 -06002534 return nil
2535}
2536
2537func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2538 omci := &DownloadSectionResponse{}
2539 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2540 return decodingLayerDecoder(omci, data, p)
2541}
2542
Chip Boling00a30d22021-05-04 13:31:52 -05002543func decodeDownloadSectionResponseExtended(data []byte, p gopacket.PacketBuilder) error {
2544 omci := &DownloadSectionResponse{}
2545 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2546 omci.Extended = true
2547 return decodingLayerDecoder(omci, data, p)
2548}
2549
Chip Boling6e27b352020-02-14 09:10:01 -06002550// SerializeTo provides serialization of an Download Section Response message
2551func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2552 // Basic (common) OMCI Header is 8 octets, 10
2553 err := omci.MeBasePacket.SerializeTo(b)
2554 if err != nil {
2555 return err
2556 }
2557 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2558 me.ParamData{EntityID: omci.EntityInstance})
2559 if omciErr.StatusCode() != me.Success {
2560 return omciErr.GetError()
2561 }
2562 // ME needs to support Download section
2563 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2564 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2565 }
2566 // Software Image Entity Class are always use the Software Image
2567 if omci.EntityClass != me.SoftwareImageClassID {
2568 return me.NewProcessingError("invalid Entity Class for Download Section response")
2569 }
Chip Boling6e27b352020-02-14 09:10:01 -06002570 if omci.Result > me.DeviceBusy {
2571 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2572 omci.Result)
2573 return errors.New(msg)
2574 }
Chip Boling00a30d22021-05-04 13:31:52 -05002575 if omci.Extended {
2576 bytes, err := b.AppendBytes(4)
2577 if err != nil {
2578 return err
2579 }
2580 binary.BigEndian.PutUint16(bytes, uint16(2))
2581 bytes[2] = byte(omci.Result)
2582 bytes[3] = omci.SectionNumber
2583 } else {
2584 bytes, err := b.AppendBytes(2)
2585 if err != nil {
2586 return err
2587 }
2588 bytes[0] = byte(omci.Result)
2589 bytes[1] = omci.SectionNumber
2590 }
Chip Boling6e27b352020-02-14 09:10:01 -06002591 return nil
2592}
2593
2594/////////////////////////////////////////////////////////////////////////////
2595//
2596type EndSoftwareDownloadRequest struct {
2597 MeBasePacket // Note: EntityInstance for software download is two specific values
2598 CRC32 uint32
2599 ImageSize uint32
2600 NumberOfInstances byte
2601 ImageInstances []uint16
2602}
2603
2604func (omci *EndSoftwareDownloadRequest) String() string {
2605 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2606 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2607}
2608
2609// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
2610func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2611 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002612 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Chip Boling6e27b352020-02-14 09:10:01 -06002613 if err != nil {
2614 return err
2615 }
2616 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2617 me.ParamData{EntityID: omci.EntityInstance})
2618 if omciErr.StatusCode() != me.Success {
2619 return omciErr.GetError()
2620 }
2621 // ME needs to support End Software Download
2622 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2623 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2624 }
2625 // Software Image Entity Class are always use the Software Image
2626 if omci.EntityClass != me.SoftwareImageClassID {
2627 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2628 }
2629 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2630 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
Chip Boling2ccec852021-02-24 11:18:02 -06002631 omci.NumberOfInstances = data[12]
Chip Boling6e27b352020-02-14 09:10:01 -06002632
2633 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2634 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2635 omci.NumberOfInstances))
2636 }
2637 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2638
2639 for index := 0; index < int(omci.NumberOfInstances); index++ {
Chip Boling2ccec852021-02-24 11:18:02 -06002640 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[13+(index*2):])
Chip Boling6e27b352020-02-14 09:10:01 -06002641 }
2642 return nil
2643}
2644
2645func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2646 omci := &EndSoftwareDownloadRequest{}
2647 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2648 return decodingLayerDecoder(omci, data, p)
2649}
2650
2651// SerializeTo provides serialization of an End Software Download Request message
2652func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2653 // Basic (common) OMCI Header is 8 octets, 10
2654 err := omci.MeBasePacket.SerializeTo(b)
2655 if err != nil {
2656 return err
2657 }
2658 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2659 me.ParamData{EntityID: omci.EntityInstance})
2660 if omciErr.StatusCode() != me.Success {
2661 return omciErr.GetError()
2662 }
2663 // ME needs to support End Software Download
2664 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2665 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2666 }
2667 // Software Image Entity Class are always use the Software Image
2668 if omci.EntityClass != me.SoftwareImageClassID {
2669 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2670 }
2671 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2672 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2673 omci.NumberOfInstances))
2674 }
2675 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2676 if err != nil {
2677 return err
2678 }
Chip Boling2ccec852021-02-24 11:18:02 -06002679 binary.BigEndian.PutUint32(bytes[0:4], omci.CRC32)
2680 binary.BigEndian.PutUint32(bytes[4:8], omci.ImageSize)
2681 bytes[8] = omci.NumberOfInstances
Chip Boling6e27b352020-02-14 09:10:01 -06002682 for index := 0; index < int(omci.NumberOfInstances); index++ {
Chip Boling2ccec852021-02-24 11:18:02 -06002683 binary.BigEndian.PutUint16(bytes[9+(index*2):], omci.ImageInstances[index])
Chip Boling6e27b352020-02-14 09:10:01 -06002684 }
2685 return nil
2686}
2687
2688/////////////////////////////////////////////////////////////////////////////
2689//
2690type EndSoftwareDownloadResponse struct {
2691 MeBasePacket // Note: EntityInstance for software download is two specific values
2692 Result me.Results
2693 NumberOfInstances byte
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002694 MeResults []DownloadResults
Chip Boling6e27b352020-02-14 09:10:01 -06002695}
2696
2697func (omci *EndSoftwareDownloadResponse) String() string {
2698 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2699 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2700}
2701
2702// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
2703func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2704 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002705 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06002706 if err != nil {
2707 return err
2708 }
2709 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2710 me.ParamData{EntityID: omci.EntityInstance})
2711 if omciErr.StatusCode() != me.Success {
2712 return omciErr.GetError()
2713 }
2714 // ME needs to support End Software Download
2715 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2716 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2717 }
2718 // Software Image Entity Class are always use the Software Image
2719 if omci.EntityClass != me.SoftwareImageClassID {
2720 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2721 }
2722 omci.Result = me.Results(data[4])
2723 if omci.Result > me.DeviceBusy {
2724 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2725 omci.Result)
2726 return errors.New(msg)
2727 }
2728 omci.NumberOfInstances = data[5]
2729
2730 if omci.NumberOfInstances > 9 {
2731 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2732 omci.NumberOfInstances)
2733 return errors.New(msg)
2734 }
2735 if omci.NumberOfInstances > 0 {
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002736 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Chip Boling6e27b352020-02-14 09:10:01 -06002737
2738 for index := 0; index < int(omci.NumberOfInstances); index++ {
2739 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2740 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2741 if omci.MeResults[index].Result > me.DeviceBusy {
2742 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2743 index, omci.MeResults[index])
2744 return errors.New(msg)
2745 }
2746 }
2747 }
2748 return nil
2749}
2750
2751func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2752 omci := &EndSoftwareDownloadResponse{}
2753 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2754 return decodingLayerDecoder(omci, data, p)
2755}
2756
2757// SerializeTo provides serialization of an End Software Download Response message
2758func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2759 // Basic (common) OMCI Header is 8 octets, 10
2760 err := omci.MeBasePacket.SerializeTo(b)
2761 if err != nil {
2762 return err
2763 }
2764 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2765 me.ParamData{EntityID: omci.EntityInstance})
2766 if omciErr.StatusCode() != me.Success {
2767 return omciErr.GetError()
2768 }
2769 // ME needs to support End Software Download
2770 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2771 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2772 }
2773 // Software Image Entity Class are always use the Software Image
2774 if omci.EntityClass != me.SoftwareImageClassID {
2775 return me.NewProcessingError("invalid Entity Class for End Download response")
2776 }
Chip Boling2ccec852021-02-24 11:18:02 -06002777 bytes, err := b.AppendBytes(2 + (3 * int(omci.NumberOfInstances)))
Chip Boling6e27b352020-02-14 09:10:01 -06002778 if err != nil {
2779 return err
2780 }
2781 if omci.Result > me.DeviceBusy {
2782 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2783 omci.Result)
2784 return errors.New(msg)
2785 }
2786 bytes[0] = byte(omci.Result)
2787 bytes[1] = omci.NumberOfInstances
2788
2789 if omci.NumberOfInstances > 9 {
2790 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2791 omci.NumberOfInstances)
2792 return errors.New(msg)
2793 }
2794 if omci.NumberOfInstances > 0 {
2795 for index := 0; index < int(omci.NumberOfInstances); index++ {
2796 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2797
2798 if omci.MeResults[index].Result > me.DeviceBusy {
2799 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2800 index, omci.MeResults[index])
2801 return errors.New(msg)
2802 }
2803 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2804 }
2805 }
2806 return nil
2807}
2808
2809/////////////////////////////////////////////////////////////////////////////
2810//
2811type ActivateSoftwareRequest struct {
2812 MeBasePacket // Note: EntityInstance for software download is two specific values
2813 ActivateFlags byte
2814}
2815
2816func (omci *ActivateSoftwareRequest) String() string {
2817 return fmt.Sprintf("%v, Flags: %#x",
2818 omci.MeBasePacket.String(), omci.ActivateFlags)
2819}
2820
2821// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
2822func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2823 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002824 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002825 if err != nil {
2826 return err
2827 }
2828 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2829 me.ParamData{EntityID: omci.EntityInstance})
2830 if omciErr.StatusCode() != me.Success {
2831 return omciErr.GetError()
2832 }
2833 // ME needs to support End Software Download
2834 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2835 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2836 }
2837 // Software Image Entity Class are always use the Software Image
2838 if omci.EntityClass != me.SoftwareImageClassID {
2839 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2840 }
2841 omci.ActivateFlags = data[4]
2842 if omci.ActivateFlags > 2 {
2843 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2844 omci.ActivateFlags))
2845 }
2846 return nil
2847}
2848
2849func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2850 omci := &ActivateSoftwareRequest{}
2851 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2852 return decodingLayerDecoder(omci, data, p)
2853}
2854
2855// SerializeTo provides serialization of an Activate Software message
2856func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2857 // Basic (common) OMCI Header is 8 octets, 10
2858 err := omci.MeBasePacket.SerializeTo(b)
2859 if err != nil {
2860 return err
2861 }
2862 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2863 me.ParamData{EntityID: omci.EntityInstance})
2864 if omciErr.StatusCode() != me.Success {
2865 return omciErr.GetError()
2866 }
2867 // ME needs to support End Software Download
2868 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2869 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2870 }
2871 // Software Image Entity Class are always use the Software Image
2872 if omci.EntityClass != me.SoftwareImageClassID {
2873 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2874 }
2875 bytes, err := b.AppendBytes(1)
2876 if err != nil {
2877 return err
2878 }
2879 bytes[0] = omci.ActivateFlags
2880 if omci.ActivateFlags > 2 {
2881 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2882 omci.ActivateFlags)
2883 return errors.New(msg)
2884 }
2885 return nil
2886}
2887
2888/////////////////////////////////////////////////////////////////////////////
2889//
2890type ActivateSoftwareResponse struct {
2891 MeBasePacket
2892 Result me.Results
2893}
2894
2895func (omci *ActivateSoftwareResponse) String() string {
2896 return fmt.Sprintf("%v, Result: %d (%v)",
2897 omci.MeBasePacket.String(), omci.Result, omci.Result)
2898}
2899
2900// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
2901func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2902 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002903 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002904 if err != nil {
2905 return err
2906 }
2907 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2908 me.ParamData{EntityID: omci.EntityInstance})
2909 if omciErr.StatusCode() != me.Success {
2910 return omciErr.GetError()
2911 }
2912 // ME needs to support End Software Download
2913 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2914 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2915 }
2916 // Software Image Entity Class are always use the Software Image
2917 if omci.EntityClass != me.SoftwareImageClassID {
2918 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2919 }
2920 omci.Result = me.Results(data[4])
2921 if omci.Result > me.Results(6) {
2922 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2923 omci.Result)
2924 return errors.New(msg)
2925 }
2926 return nil
2927}
2928
2929func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2930 omci := &ActivateSoftwareResponse{}
2931 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2932 return decodingLayerDecoder(omci, data, p)
2933}
2934
2935// SerializeTo provides serialization of an Activate Software Response message
2936func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2937 // Basic (common) OMCI Header is 8 octets, 10
2938 err := omci.MeBasePacket.SerializeTo(b)
2939 if err != nil {
2940 return err
2941 }
2942 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2943 me.ParamData{EntityID: omci.EntityInstance})
2944 if omciErr.StatusCode() != me.Success {
2945 return omciErr.GetError()
2946 }
2947 // ME needs to support End Software Download
2948 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2949 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2950 }
2951 // Software Image Entity Class are always use the Software Image
2952 if omci.EntityClass != me.SoftwareImageClassID {
2953 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2954 }
2955 bytes, err := b.AppendBytes(1)
2956 if err != nil {
2957 return err
2958 }
2959 bytes[0] = byte(omci.Result)
2960 if omci.Result > me.Results(6) {
2961 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2962 omci.Result)
2963 return errors.New(msg)
2964 }
2965 return nil
2966}
2967
2968/////////////////////////////////////////////////////////////////////////////
2969//
2970type CommitSoftwareRequest struct {
2971 MeBasePacket
2972}
2973
2974func (omci *CommitSoftwareRequest) String() string {
2975 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2976}
2977
2978// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
2979func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2980 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06002981 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06002982 if err != nil {
2983 return err
2984 }
2985 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2986 me.ParamData{EntityID: omci.EntityInstance})
2987 if omciErr.StatusCode() != me.Success {
2988 return omciErr.GetError()
2989 }
2990 // ME needs to support End Software Download
2991 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2992 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2993 }
2994 // Software Image Entity Class are always use the Software Image
2995 if omci.EntityClass != me.SoftwareImageClassID {
2996 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2997 }
2998 return nil
2999}
3000
3001func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
3002 omci := &CommitSoftwareRequest{}
3003 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
3004 return decodingLayerDecoder(omci, data, p)
3005}
3006
3007// SerializeTo provides serialization of an Commit Software Request message
3008func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3009 // Basic (common) OMCI Header is 8 octets, 10
3010 err := omci.MeBasePacket.SerializeTo(b)
3011 if err != nil {
3012 return err
3013 }
3014 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3015 me.ParamData{EntityID: omci.EntityInstance})
3016 if omciErr.StatusCode() != me.Success {
3017 return omciErr.GetError()
3018 }
3019 // ME needs to support End Software Download
3020 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3021 return me.NewProcessingError("managed entity does not support Commit Message-Type")
3022 }
3023 // Software Image Entity Class are always use the Software Image
3024 if omci.EntityClass != me.SoftwareImageClassID {
3025 return me.NewProcessingError("invalid Entity Class for Commit Software request")
3026 }
3027 return nil
3028}
3029
3030/////////////////////////////////////////////////////////////////////////////
3031//
3032type CommitSoftwareResponse struct {
3033 MeBasePacket
Chip Boling58fc4d22021-03-10 13:23:53 -06003034 Result me.Results
Chip Boling6e27b352020-02-14 09:10:01 -06003035}
3036
3037func (omci *CommitSoftwareResponse) String() string {
3038 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3039}
3040
3041// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
3042func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3043 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003044 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003045 if err != nil {
3046 return err
3047 }
3048 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3049 me.ParamData{EntityID: omci.EntityInstance})
3050 if omciErr.StatusCode() != me.Success {
3051 return omciErr.GetError()
3052 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003053 // ME needs to support Commit Software
Chip Boling6e27b352020-02-14 09:10:01 -06003054 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3055 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
3056 }
3057 // Software Image Entity Class are always use the Software Image
3058 if omci.EntityClass != me.SoftwareImageClassID {
3059 return me.NewProcessingError("invalid Entity Class for Commit Software response")
3060 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003061 omci.Result = me.Results(data[4])
3062 if omci.Result > me.Results(6) {
3063 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
3064 omci.Result)
3065 return errors.New(msg)
3066 }
Chip Boling6e27b352020-02-14 09:10:01 -06003067 return nil
3068}
3069
3070func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
3071 omci := &CommitSoftwareResponse{}
3072 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
3073 return decodingLayerDecoder(omci, data, p)
3074}
3075
3076// SerializeTo provides serialization of an Commit Software Response message
3077func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3078 // Basic (common) OMCI Header is 8 octets, 10
3079 err := omci.MeBasePacket.SerializeTo(b)
3080 if err != nil {
3081 return err
3082 }
3083 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3084 me.ParamData{EntityID: omci.EntityInstance})
3085 if omciErr.StatusCode() != me.Success {
3086 return omciErr.GetError()
3087 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003088 // ME needs to support Commit Software
Chip Boling6e27b352020-02-14 09:10:01 -06003089 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3090 return me.NewProcessingError("managed entity does not support Commit Message-Type")
3091 }
3092 // Software Image Entity Class are always use the Software Image
3093 if omci.EntityClass != me.SoftwareImageClassID {
3094 return me.NewProcessingError("invalid Entity Class for Commit Software response")
3095 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003096 bytes, err := b.AppendBytes(1)
3097 if err != nil {
3098 return err
3099 }
3100 bytes[0] = byte(omci.Result)
3101 if omci.Result > me.Results(6) {
3102 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
3103 omci.Result)
3104 return errors.New(msg)
3105 }
Chip Boling6e27b352020-02-14 09:10:01 -06003106 return nil
3107}
3108
3109/////////////////////////////////////////////////////////////////////////////
3110//
3111type SynchronizeTimeRequest struct {
3112 MeBasePacket
3113 Year uint16
3114 Month uint8
3115 Day uint8
3116 Hour uint8
3117 Minute uint8
3118 Second uint8
3119}
3120
3121func (omci *SynchronizeTimeRequest) String() string {
3122 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
3123 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
3124}
3125
3126// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
3127func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3128 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003129 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Chip Boling6e27b352020-02-14 09:10:01 -06003130 if err != nil {
3131 return err
3132 }
3133 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3134 me.ParamData{EntityID: omci.EntityInstance})
3135 if omciErr.StatusCode() != me.Success {
3136 return omciErr.GetError()
3137 }
3138 // ME needs to support Synchronize Time
3139 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3140 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3141 }
3142 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3143 if omci.EntityClass != me.OnuGClassID {
3144 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
3145 }
3146 if omci.EntityInstance != 0 {
3147 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
3148 }
3149 omci.Year = binary.BigEndian.Uint16(data[4:6])
3150 omci.Month = data[6]
3151 omci.Day = data[7]
3152 omci.Hour = data[8]
3153 omci.Minute = data[9]
3154 omci.Second = data[10]
3155 return nil
3156}
3157
3158func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
3159 omci := &SynchronizeTimeRequest{}
3160 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
3161 return decodingLayerDecoder(omci, data, p)
3162}
3163
3164// SerializeTo provides serialization of an Synchronize Time Request message
3165func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3166 // Basic (common) OMCI Header is 8 octets, 10
3167 err := omci.MeBasePacket.SerializeTo(b)
3168 if err != nil {
3169 return err
3170 }
3171 entity, 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 Synchronize Time
3177 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3178 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3179 }
3180 bytes, err := b.AppendBytes(7)
3181 if err != nil {
3182 return err
3183 }
3184 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
3185 bytes[2] = omci.Month
3186 bytes[3] = omci.Day
3187 bytes[4] = omci.Hour
3188 bytes[5] = omci.Minute
3189 bytes[6] = omci.Second
3190 return nil
3191}
3192
3193/////////////////////////////////////////////////////////////////////////////
3194//
3195type SynchronizeTimeResponse struct {
3196 MeBasePacket
3197 Result me.Results
3198 SuccessResults uint8 // Only if 'Result' is 0 -> success
3199}
3200
3201func (omci *SynchronizeTimeResponse) String() string {
3202 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
3203 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
3204}
3205
3206// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
3207func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3208 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003209 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003210 if err != nil {
3211 return err
3212 }
3213 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3214 me.ParamData{EntityID: omci.EntityInstance})
3215 if omciErr.StatusCode() != me.Success {
3216 return omciErr.GetError()
3217 }
3218 // ME needs to support Synchronize Time
3219 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3220 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3221 }
3222 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3223 if omci.EntityClass != me.OnuGClassID {
3224 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3225 }
3226 if omci.EntityInstance != 0 {
3227 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3228 }
3229 omci.Result = me.Results(data[4])
3230 if omci.Result > me.DeviceBusy {
Chip Bolingd8637b02021-04-29 08:36:38 -05003231 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
Chip Boling6e27b352020-02-14 09:10:01 -06003232 return errors.New(msg)
3233 }
3234 omci.SuccessResults = data[5]
3235 return nil
3236}
3237
3238func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
3239 omci := &SynchronizeTimeResponse{}
3240 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
3241 return decodingLayerDecoder(omci, data, p)
3242}
3243
3244// SerializeTo provides serialization of an Synchronize Time Response message
3245func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3246 // Basic (common) OMCI Header is 8 octets, 10
3247 err := omci.MeBasePacket.SerializeTo(b)
3248 if err != nil {
3249 return err
3250 }
3251 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3252 me.ParamData{EntityID: omci.EntityInstance})
3253 if omciErr.StatusCode() != me.Success {
3254 return omciErr.GetError()
3255 }
3256 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
3257 if omci.EntityClass != me.OnuGClassID {
3258 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3259 }
3260 if omci.EntityInstance != 0 {
3261 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3262 }
3263 // ME needs to support Synchronize Time
3264 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3265 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3266 }
3267 numBytes := 2
3268 if omci.Result != me.Success {
3269 numBytes = 1
3270 }
3271 bytes, err := b.AppendBytes(numBytes)
3272 if err != nil {
3273 return err
3274 }
3275 bytes[0] = uint8(omci.Result)
3276 if omci.Result == me.Success {
3277 bytes[1] = omci.SuccessResults
3278 }
3279 return nil
3280}
3281
3282/////////////////////////////////////////////////////////////////////////////
3283//
3284type RebootRequest struct {
3285 MeBasePacket
3286 RebootCondition byte
3287}
3288
3289func (omci *RebootRequest) String() string {
3290 return fmt.Sprintf("%v, Reboot Condition: %v",
3291 omci.MeBasePacket.String(), omci.RebootCondition)
3292}
3293
3294// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
3295func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3296 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003297 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003298 if err != nil {
3299 return err
3300 }
3301 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3302 me.ParamData{EntityID: omci.EntityInstance})
3303 if omciErr.StatusCode() != me.Success {
3304 return omciErr.GetError()
3305 }
3306 // ME needs to support Reboot
3307 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3308 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3309 }
3310 omci.RebootCondition = data[4]
3311 if omci.RebootCondition > 3 {
3312 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
3313 return errors.New(msg)
3314 }
3315 return nil
3316}
3317
3318func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
3319 omci := &RebootRequest{}
3320 omci.MsgLayerType = LayerTypeRebootRequest
3321 return decodingLayerDecoder(omci, data, p)
3322}
3323
3324// SerializeTo provides serialization of an Reboot Request message
3325func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3326 // Basic (common) OMCI Header is 8 octets, 10
3327 err := omci.MeBasePacket.SerializeTo(b)
3328 if err != nil {
3329 return err
3330 }
3331 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3332 me.ParamData{EntityID: omci.EntityInstance})
3333 if omciErr.StatusCode() != me.Success {
3334 return omciErr.GetError()
3335 }
3336 // ME needs to support Reboot
3337 if !me.SupportsMsgType(entity, me.Reboot) {
3338 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3339 }
3340 bytes, err := b.AppendBytes(1)
3341 if err != nil {
3342 return err
3343 }
3344 if omci.RebootCondition > 3 {
3345 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
3346 omci.RebootCondition))
3347 }
3348 bytes[0] = omci.RebootCondition
3349 return nil
3350}
3351
3352/////////////////////////////////////////////////////////////////////////////
3353//
3354type RebootResponse struct {
3355 MeBasePacket
3356 Result me.Results
3357}
3358
3359// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3360func (omci *RebootResponse) String() string {
3361 return fmt.Sprintf("%v, Result: %d (%v)",
3362 omci.MeBasePacket.String(), omci.Result, omci.Result)
3363}
3364
3365// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3366func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3367 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003368 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003369 if err != nil {
3370 return err
3371 }
3372 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3373 me.ParamData{EntityID: omci.EntityInstance})
3374 if omciErr.StatusCode() != me.Success {
3375 return omciErr.GetError()
3376 }
3377 // ME needs to support Reboot
3378 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3379 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3380 }
3381 if omci.Result > 6 {
3382 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3383 return errors.New(msg)
3384 }
3385 omci.Result = me.Results(data[4])
3386 return nil
3387}
3388
3389func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3390 omci := &RebootResponse{}
3391 omci.MsgLayerType = LayerTypeRebootResponse
3392 return decodingLayerDecoder(omci, data, p)
3393}
3394
3395// SerializeTo provides serialization of an Reboot Response message
3396func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3397 // Basic (common) OMCI Header is 8 octets, 10
3398 err := omci.MeBasePacket.SerializeTo(b)
3399 if err != nil {
3400 return err
3401 }
3402 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3403 me.ParamData{EntityID: omci.EntityInstance})
3404 if omciErr.StatusCode() != me.Success {
3405 return omciErr.GetError()
3406 }
3407 // ME needs to support Reboot
3408 if !me.SupportsMsgType(entity, me.Reboot) {
3409 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3410 }
3411 bytes, err := b.AppendBytes(1)
3412 if err != nil {
3413 return err
3414 }
3415 if omci.Result > 6 {
3416 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3417 return errors.New(msg)
3418 }
3419 bytes[0] = byte(omci.Result)
3420 return nil
3421}
3422
3423/////////////////////////////////////////////////////////////////////////////
3424//
3425type GetNextRequest struct {
3426 MeBasePacket
3427 AttributeMask uint16
3428 SequenceNumber uint16
3429}
3430
3431func (omci *GetNextRequest) String() string {
3432 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3433 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3434}
3435
3436// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
3437func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3438 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003439 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Chip Boling6e27b352020-02-14 09:10:01 -06003440 if err != nil {
3441 return err
3442 }
3443 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3444 me.ParamData{EntityID: omci.EntityInstance})
3445 if omciErr.StatusCode() != me.Success {
3446 return omciErr.GetError()
3447 }
3448 // ME needs to support GetNext
3449 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3450 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3451 }
3452 // Note: G.988 specifies that an error code of (3) should result if more
3453 // than one attribute is requested
3454 // TODO: Return error. Have flag to optionally allow it to be encoded
3455 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3456 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3457 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3458 return nil
3459}
3460
3461func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3462 omci := &GetNextRequest{}
3463 omci.MsgLayerType = LayerTypeGetNextRequest
3464 return decodingLayerDecoder(omci, data, p)
3465}
3466
3467// SerializeTo provides serialization of an Get Next Message Type Request
3468func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3469 // Basic (common) OMCI Header is 8 octets, 10
3470 err := omci.MeBasePacket.SerializeTo(b)
3471 if err != nil {
3472 return err
3473 }
3474 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3475 me.ParamData{EntityID: omci.EntityInstance})
3476 if omciErr.StatusCode() != me.Success {
3477 return omciErr.GetError()
3478 }
3479 // ME needs to support GetNext
3480 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3481 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3482 }
3483 bytes, err := b.AppendBytes(4)
3484 if err != nil {
3485 return err
3486 }
3487 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3488 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3489 return nil
3490}
3491
3492/////////////////////////////////////////////////////////////////////////////
3493//
3494type GetNextResponse struct {
3495 MeBasePacket
3496 Result me.Results
3497 AttributeMask uint16
3498 Attributes me.AttributeValueMap
3499}
3500
3501// SerializeTo provides serialization of an Get Next Message Type Response
3502func (omci *GetNextResponse) String() string {
3503 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3504 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3505}
3506
3507// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
3508func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3509 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003510 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -06003511 if err != nil {
3512 return err
3513 }
3514 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3515 me.ParamData{EntityID: omci.EntityInstance})
3516 if omciErr.StatusCode() != me.Success {
3517 return omciErr.GetError()
3518 }
3519 // ME needs to support Set
3520 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3521 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3522 }
3523 omci.Result = me.Results(data[4])
3524 if omci.Result > 6 {
3525 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3526 return errors.New(msg)
3527 }
3528 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3529
3530 // Attribute decode
3531 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3532 if err != nil {
3533 return err
3534 }
3535 // Validate all attributes support read
3536 for attrName := range omci.Attributes {
3537 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3538 if err != nil {
3539 return err
3540 }
3541 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3542 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3543 return me.NewProcessingError(msg)
3544 }
3545 }
3546 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
3547 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3548 return nil
3549 }
3550 panic("All Managed Entities have an EntityID attribute")
3551}
3552
3553func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3554 omci := &GetNextResponse{}
3555 omci.MsgLayerType = LayerTypeGetNextResponse
3556 return decodingLayerDecoder(omci, data, p)
3557}
3558
3559// SerializeTo provides serialization of an Get Next Message Type Response
3560func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3561 // Basic (common) OMCI Header is 8 octets, 10
3562 err := omci.MeBasePacket.SerializeTo(b)
3563 if err != nil {
3564 return err
3565 }
3566 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3567 me.ParamData{EntityID: omci.EntityInstance})
3568 if omciErr.StatusCode() != me.Success {
3569 return omciErr.GetError()
3570 }
3571 // ME needs to support Get
3572 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3573 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3574 }
3575 bytes, err := b.AppendBytes(3)
3576 if err != nil {
3577 return err
3578 }
3579 bytes[0] = byte(omci.Result)
3580 if omci.Result > 6 {
3581 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3582 return errors.New(msg)
3583 }
3584 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3585
3586 // Validate all attributes support read
3587 for attrName := range omci.Attributes {
3588 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3589 if err != nil {
3590 return err
3591 }
3592 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3593 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3594 return me.NewProcessingError(msg)
3595 }
3596 }
3597 // Attribute serialization
3598 switch omci.Result {
3599 default:
3600 break
3601
3602 case me.Success:
3603 // TODO: Only Baseline supported at this time
3604 bytesAvailable := MaxBaselineLength - 11 - 8
3605
3606 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3607 byte(GetNextResponseType), bytesAvailable, false)
3608 if err != nil {
3609 return err
3610 }
3611 }
3612 return nil
3613}
3614
Chip Bolingd8637b02021-04-29 08:36:38 -05003615func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3616 // Peek at Managed Entity Type
3617 if len(data) < 8 {
3618 p.SetTruncated()
3619 return errors.New("frame too small")
3620 }
3621 classID := binary.BigEndian.Uint16(data)
3622
3623 // Is it a Managed Entity class we support customized decode of?
3624 switch me.ClassID(classID) {
3625 default:
3626 omci := &TestResultNotification{}
3627 omci.MsgLayerType = LayerTypeTestResult
3628 return decodingLayerDecoder(omci, data, p)
3629
3630 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
3631 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
3632 omci := &OpticalLineSupervisionTestResult{}
3633 omci.MsgLayerType = LayerTypeTestResult
3634 return decodingLayerDecoder(omci, data, p)
3635 }
Chip Boling6e27b352020-02-14 09:10:01 -06003636}
3637
Chip Bolingd8637b02021-04-29 08:36:38 -05003638type TestResultNotification struct {
3639 MeBasePacket
3640 Payload []byte
3641}
3642
3643func (omci *TestResultNotification) TestResults() []byte {
3644 return omci.Payload
3645}
3646
3647func (omci *TestResultNotification) String() string {
3648 return fmt.Sprintf("%v, Payload: %v octets", omci.MeBasePacket.String(), len(omci.Payload))
Chip Boling6e27b352020-02-14 09:10:01 -06003649}
3650
3651// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
Chip Bolingd8637b02021-04-29 08:36:38 -05003652func (omci *TestResultNotification) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
Chip Boling6e27b352020-02-14 09:10:01 -06003653 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06003654 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06003655 if err != nil {
3656 return err
3657 }
Chip Boling6e27b352020-02-14 09:10:01 -06003658
Chip Bolingd8637b02021-04-29 08:36:38 -05003659 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3660 me.ParamData{EntityID: omci.EntityInstance})
3661 if omciErr.StatusCode() != me.Success {
3662 return omciErr.GetError()
3663 }
3664
3665 // ME needs to support Test requests
3666 if !me.SupportsMsgType(meDefinition, me.Test) {
3667 return me.NewProcessingError("managed entity does not support Test Message-Type")
3668 }
3669 omci.Payload = make([]byte, MaxTestResultsLength)
3670 copy(omci.Payload, omci.MeBasePacket.Payload)
3671 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06003672}
3673
3674// SerializeTo provides serialization of an Test Result notification message
Chip Bolingd8637b02021-04-29 08:36:38 -05003675func (omci *TestResultNotification) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3676 // Basic (common) OMCI Header is 8 octets
3677 err := omci.MeBasePacket.SerializeTo(b)
3678 if err != nil {
3679 return err
3680 }
3681
3682 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3683 me.ParamData{EntityID: omci.EntityInstance})
3684 if omciErr.StatusCode() != me.Success {
3685 return omciErr.GetError()
3686 }
3687
3688 // ME needs to support Test requests
3689 if !me.SupportsMsgType(meDefinition, me.Test) {
3690 return me.NewProcessingError("managed entity does not support Test Message-Type")
3691 }
3692 if omci.Payload == nil {
3693 return errors.New("Test Results payload is missing")
3694 }
3695 if len(omci.Payload) > MaxTestResultsLength {
3696 msg := fmt.Sprintf("Invalid Test Results payload size. Received %v bytes, expected %v",
3697 len(omci.Payload), MaxTestResultsLength)
3698 return errors.New(msg)
3699 }
3700 bytes, err := b.AppendBytes(len(omci.Payload))
3701 if err != nil {
3702 return err
3703 }
3704
3705 copy(bytes, omci.Payload)
3706 return nil
3707}
3708
3709// OpticalLineSupervisionTestResult provides a Optical Specific test results
3710// message decode for the associated Managed Entities
3711type OpticalLineSupervisionTestResult struct {
3712 MeBasePacket
3713 PowerFeedVoltageType uint8 // Type = 1
3714 PowerFeedVoltage uint16 // value
3715 ReceivedOpticalPowerType uint8 // Type = 3
3716 ReceivedOpticalPower uint16 // value
3717 MeanOpticalLaunchType uint8 // Type = 5
3718 MeanOpticalLaunch uint16 // value
3719 LaserBiasCurrentType uint8 // Type = 9
3720 LaserBiasCurrent uint16 // value
3721 TemperatureType uint8 // Type = 12
3722 Temperature uint16 // value
3723
3724 GeneralPurposeBuffer uint16 // Pointer to General Purpose Buffer ME
3725}
3726
3727func (omci *OpticalLineSupervisionTestResult) String() string {
3728 return fmt.Sprintf("Optical Line Supervision Test Result")
3729}
3730
3731func (omci *OpticalLineSupervisionTestResult) TestResults() []byte {
3732 return omci.MeBasePacket.Payload
3733}
3734
3735// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
3736func (omci *OpticalLineSupervisionTestResult) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3737 // Common ClassID/EntityID decode in msgBase
3738 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+17)
3739 if err != nil {
3740 return err
3741 }
3742
3743 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3744 me.ParamData{EntityID: omci.EntityInstance})
3745 if omciErr.StatusCode() != me.Success {
3746 return omciErr.GetError()
3747 }
3748
3749 // ME needs to support Test requests
3750 if !me.SupportsMsgType(meDefinition, me.Test) {
3751 return me.NewProcessingError("managed entity does not support Test Message-Type")
3752 }
3753 // Note: Unsupported tests will have a type = 0 and the value should be zero
3754 // as well, but that constraint is not enforced at this time.
3755 // Type = 1
3756 omci.PowerFeedVoltageType = data[4]
3757 omci.PowerFeedVoltage = binary.BigEndian.Uint16(data[5:])
3758
3759 // Type = 3
3760 omci.ReceivedOpticalPowerType = data[7]
3761 omci.ReceivedOpticalPower = binary.BigEndian.Uint16(data[8:])
3762
3763 // Type = 5
3764 omci.MeanOpticalLaunchType = data[10]
3765 omci.MeanOpticalLaunch = binary.BigEndian.Uint16(data[11:])
3766
3767 // Type = 9
3768 omci.LaserBiasCurrentType = data[13]
3769 omci.LaserBiasCurrent = binary.BigEndian.Uint16(data[14:])
3770
3771 // Type = 12
3772 omci.TemperatureType = data[16]
3773 omci.Temperature = binary.BigEndian.Uint16(data[17:])
3774
3775 omci.GeneralPurposeBuffer = binary.BigEndian.Uint16(data[19:])
3776 return nil
3777}
3778
3779// SerializeTo provides serialization of an Test Result notification message
3780func (omci *OpticalLineSupervisionTestResult) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
Chip Boling6e27b352020-02-14 09:10:01 -06003781 // Basic (common) OMCI Header is 8 octets, 10
3782 err := omci.MeBasePacket.SerializeTo(b)
3783 if err != nil {
3784 return err
3785 }
Chip Bolingd8637b02021-04-29 08:36:38 -05003786 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3787 me.ParamData{EntityID: omci.EntityInstance})
3788 if omciErr.StatusCode() != me.Success {
3789 return omciErr.GetError()
3790 }
3791
3792 // ME needs to support Test requests
3793 if !me.SupportsMsgType(meDefinition, me.Test) {
3794 return me.NewProcessingError("managed entity does not support Test Message-Type")
3795 }
3796 bytes, err := b.AppendBytes(17)
3797 if err != nil {
3798 return err
3799 }
3800
3801 bytes[0] = omci.PowerFeedVoltageType
3802 binary.BigEndian.PutUint16(bytes[1:], omci.PowerFeedVoltage)
3803 bytes[3] = omci.ReceivedOpticalPowerType
3804 binary.BigEndian.PutUint16(bytes[4:], omci.ReceivedOpticalPower)
3805 bytes[6] = omci.MeanOpticalLaunchType
3806 binary.BigEndian.PutUint16(bytes[7:], omci.MeanOpticalLaunch)
3807 bytes[9] = omci.LaserBiasCurrentType
3808 binary.BigEndian.PutUint16(bytes[10:], omci.LaserBiasCurrent)
3809 bytes[12] = omci.TemperatureType
3810 binary.BigEndian.PutUint16(bytes[13:], omci.Temperature)
3811 binary.BigEndian.PutUint16(bytes[15:], omci.GeneralPurposeBuffer)
3812 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06003813}
3814
3815/////////////////////////////////////////////////////////////////////////////
3816//
3817type GetCurrentDataRequest struct {
3818 MeBasePacket
3819 AttributeMask uint16
3820}
3821
3822func (omci *GetCurrentDataRequest) String() string {
3823 return fmt.Sprintf("%v, Attribute Mask: %#x",
3824 omci.MeBasePacket.String(), omci.AttributeMask)
3825}
3826
3827// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
3828func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3829 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003830 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003831 if err != nil {
3832 return err
3833 }
3834 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3835 me.ParamData{EntityID: omci.EntityInstance})
3836 if omciErr.StatusCode() != me.Success {
3837 return omciErr.GetError()
3838 }
3839 // ME needs to support GetNext
3840 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3841 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3842 }
3843 // Note: G.988 specifies that an error code of (3) should result if more
3844 // than one attribute is requested
3845 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3846 return nil
3847}
3848
3849func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3850 omci := &GetCurrentDataRequest{}
3851 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3852 return decodingLayerDecoder(omci, data, p)
3853}
3854
3855// SerializeTo provides serialization of an Get Current Data Request message
3856func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3857 // Basic (common) OMCI Header is 8 octets, 10
3858 err := omci.MeBasePacket.SerializeTo(b)
3859 if err != nil {
3860 return err
3861 }
3862 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3863 me.ParamData{EntityID: omci.EntityInstance})
3864 if omciErr.StatusCode() != me.Success {
3865 return omciErr.GetError()
3866 }
3867 // ME needs to support GetNext
3868 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3869 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3870 }
3871 bytes, err := b.AppendBytes(2)
3872 if err != nil {
3873 return err
3874 }
3875 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3876 return nil
3877}
3878
3879/////////////////////////////////////////////////////////////////////////////
3880//
3881type GetCurrentDataResponse struct {
3882 MeBasePacket
3883 Result me.Results
3884 AttributeMask uint16
3885 Attributes me.AttributeValueMap
3886}
3887
3888func (omci *GetCurrentDataResponse) String() string {
3889 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
3890 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
3891}
3892
3893// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
3894func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3895 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003896 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -06003897 if err != nil {
3898 return err
3899 }
3900 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3901 me.ParamData{EntityID: omci.EntityInstance})
3902 if omciErr.StatusCode() != me.Success {
3903 return omciErr.GetError()
3904 }
3905 // ME needs to support Set
3906 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3907 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3908 }
3909 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3910
Chip Boling4e0ac9a2021-01-20 14:23:09 -06003911 switch omci.Result {
3912 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
3913 return nil // Done (do not try and decode attributes)
3914 }
Chip Boling6e27b352020-02-14 09:10:01 -06003915 // Attribute decode
3916 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(GetCurrentDataResponseType))
3917 if err != nil {
3918 return err
3919 }
3920 return nil
3921}
3922
3923func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
3924 omci := &GetCurrentDataResponse{}
3925 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
3926 return decodingLayerDecoder(omci, data, p)
3927}
3928
3929// SerializeTo provides serialization of an Get Current Data Message Type Response
3930func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3931 // Basic (common) OMCI Header is 8 octets, 10
3932 err := omci.MeBasePacket.SerializeTo(b)
3933 if err != nil {
3934 return err
3935 }
3936 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3937 me.ParamData{EntityID: omci.EntityInstance})
3938 if omciErr.StatusCode() != me.Success {
3939 return omciErr.GetError()
3940 }
3941 // ME needs to support Get
3942 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3943 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
3944 }
3945 bytes, err := b.AppendBytes(2)
3946 if err != nil {
3947 return err
3948 }
3949 binary.BigEndian.PutUint16(bytes[0:2], omci.AttributeMask)
3950
3951 // Attribute serialization
3952 // TODO: Only Baseline supported at this time
3953 bytesAvailable := MaxBaselineLength - 9 - 8
3954 var failedMask uint16
3955
3956 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3957 byte(GetCurrentDataResponseType), bytesAvailable, opts.FixLengths)
3958
3959 if failedMask != 0 {
3960 // TODO: See GetResponse serialization above for the steps here
3961 return me.NewMessageTruncatedError("getCurrentData attribute truncation not yet supported")
3962 }
3963 if err != nil {
3964 return err
3965 }
3966 return nil
3967}
3968
3969/////////////////////////////////////////////////////////////////////////////
3970//
3971type SetTableRequest struct {
3972 MeBasePacket
3973 // TODO: Fix me when extended messages supported)
3974}
3975
3976func (omci *SetTableRequest) String() string {
3977 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3978}
3979
3980// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
3981func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3982 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003983 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003984 if err != nil {
3985 return err
3986 }
3987 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3988}
3989
3990func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
3991 omci := &SetTableRequest{}
3992 omci.MsgLayerType = LayerTypeSetTableRequest
3993 return decodingLayerDecoder(omci, data, p)
3994}
3995
3996// SerializeTo provides serialization of an Set Table Message Type Request
3997func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3998 // Basic (common) OMCI Header is 8 octets, 10
3999 err := omci.MeBasePacket.SerializeTo(b)
4000 if err != nil {
4001 return err
4002 }
4003 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
4004}
4005
4006/////////////////////////////////////////////////////////////////////////////
4007//
4008type SetTableResponse struct {
4009 MeBasePacket
4010 // TODO: Fix me when extended messages supported)
4011}
4012
4013func (omci *SetTableResponse) String() string {
4014 return fmt.Sprintf("%v", omci.MeBasePacket.String())
4015}
4016
4017// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
4018func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4019 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06004020 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+1)
Chip Boling6e27b352020-02-14 09:10:01 -06004021 if err != nil {
4022 return err
4023 }
4024 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
4025}
4026
4027func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
4028 omci := &SetTableResponse{}
4029 omci.MsgLayerType = LayerTypeSetTableResponse
4030 return decodingLayerDecoder(omci, data, p)
4031}
4032
4033// SerializeTo provides serialization of an Set Table Message Type Response
4034func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4035 // Basic (common) OMCI Header is 8 octets, 10
4036 err := omci.MeBasePacket.SerializeTo(b)
4037 if err != nil {
4038 return err
4039 }
4040 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
4041}
4042
4043/////////////////////////////////////////////////////////////////////////////
4044//
4045type UnsupportedMessageTypeResponse struct {
4046 MeBasePacket
4047 Result me.Results
4048}
4049
4050// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
4051func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
4052 return errors.New("you should never really decode this")
4053}
4054
4055// SerializeTo provides serialization of an Unsupported Message Type Response
4056func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
4057 // Basic (common) OMCI Header is 8 octets, 10
4058 err := omci.MeBasePacket.SerializeTo(b)
4059 if err != nil {
4060 return err
4061 }
4062 bytes, err := b.AppendBytes(1)
4063 if err != nil {
4064 return err
4065 }
4066 bytes[0] = byte(omci.Result)
4067 return nil
4068}