blob: 456bef8448e6cb8f5cb714b4942a5bcc02bd2d39 [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
2356/////////////////////////////////////////////////////////////////////////////
2357//
2358type DownloadSectionRequest struct {
2359 MeBasePacket // Note: EntityInstance for software download is two specific values
2360 SectionNumber byte
Chip Boling8c8018e2021-02-22 15:56:00 -06002361 SectionData [31]byte // 0 padding if final transfer requires only a partial block
Chip Boling6e27b352020-02-14 09:10:01 -06002362}
2363
2364func (omci *DownloadSectionRequest) String() string {
2365 return fmt.Sprintf("%v, Section #: %v",
2366 omci.MeBasePacket.String(), omci.SectionNumber)
2367}
2368
2369// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
2370func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2371 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002372 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002373 if err != nil {
2374 return err
2375 }
2376 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2377 me.ParamData{EntityID: omci.EntityInstance})
2378 if omciErr.StatusCode() != me.Success {
2379 return omciErr.GetError()
2380 }
2381 // ME needs to support Download section
2382 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2383 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2384 }
2385 // Software Image Entity Class are always use the Software Image
2386 if omci.EntityClass != me.SoftwareImageClassID {
2387 return me.NewProcessingError("invalid Entity Class for Download Section request")
2388 }
2389 omci.SectionNumber = data[4]
2390 copy(omci.SectionData[0:], data[5:])
2391 return nil
2392}
2393
2394func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2395 omci := &DownloadSectionRequest{}
2396 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2397 return decodingLayerDecoder(omci, data, p)
2398}
2399
2400// SerializeTo provides serialization of an Download Section Request message
2401func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2402 // Basic (common) OMCI Header is 8 octets, 10
2403 err := omci.MeBasePacket.SerializeTo(b)
2404 if err != nil {
2405 return err
2406 }
2407 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2408 me.ParamData{EntityID: omci.EntityInstance})
2409 if omciErr.StatusCode() != me.Success {
2410 return omciErr.GetError()
2411 }
2412 // ME needs to support Download section
2413 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2414 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2415 }
2416 // Software Image Entity Class are always use the Software Image
2417 if omci.EntityClass != me.SoftwareImageClassID {
2418 return me.NewProcessingError("invalid Entity Class for Download Section response")
2419 }
Chip Boling8c8018e2021-02-22 15:56:00 -06002420 bytes, err := b.AppendBytes(1 + len(omci.SectionData))
Chip Boling6e27b352020-02-14 09:10:01 -06002421 if err != nil {
2422 return err
2423 }
2424 bytes[0] = omci.SectionNumber
2425 copy(bytes[1:], omci.SectionData[0:])
2426 return nil
2427}
2428
2429/////////////////////////////////////////////////////////////////////////////
2430//
2431type DownloadSectionResponse struct {
2432 MeBasePacket // Note: EntityInstance for software download is two specific values
2433 Result me.Results
2434 SectionNumber byte
2435}
2436
2437func (omci *DownloadSectionResponse) String() string {
2438 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2439 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2440}
2441
2442// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
2443func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2444 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002445 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06002446 if err != nil {
2447 return err
2448 }
2449 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2450 me.ParamData{EntityID: omci.EntityInstance})
2451 if omciErr.StatusCode() != me.Success {
2452 return omciErr.GetError()
2453 }
2454 // ME needs to support Download section
2455 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2456 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2457 }
2458 // Software Image Entity Class are always use the Software Image
2459 if omci.EntityClass != me.SoftwareImageClassID {
2460 return me.NewProcessingError("invalid Entity Class for Download Section response")
2461 }
2462 omci.Result = me.Results(data[4])
2463 if omci.Result > me.DeviceBusy {
2464 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2465 omci.Result)
2466 return errors.New(msg)
2467 }
2468 omci.SectionNumber = data[5]
2469 return nil
2470}
2471
2472func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2473 omci := &DownloadSectionResponse{}
2474 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2475 return decodingLayerDecoder(omci, data, p)
2476}
2477
2478// SerializeTo provides serialization of an Download Section Response message
2479func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2480 // Basic (common) OMCI Header is 8 octets, 10
2481 err := omci.MeBasePacket.SerializeTo(b)
2482 if err != nil {
2483 return err
2484 }
2485 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2486 me.ParamData{EntityID: omci.EntityInstance})
2487 if omciErr.StatusCode() != me.Success {
2488 return omciErr.GetError()
2489 }
2490 // ME needs to support Download section
2491 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2492 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2493 }
2494 // Software Image Entity Class are always use the Software Image
2495 if omci.EntityClass != me.SoftwareImageClassID {
2496 return me.NewProcessingError("invalid Entity Class for Download Section response")
2497 }
2498 bytes, err := b.AppendBytes(2)
2499 if err != nil {
2500 return err
2501 }
Chip Boling6e27b352020-02-14 09:10:01 -06002502 if omci.Result > me.DeviceBusy {
2503 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2504 omci.Result)
2505 return errors.New(msg)
2506 }
Chip Boling588d9702021-02-26 09:48:07 -06002507 bytes[0] = byte(omci.Result)
2508 bytes[1] = omci.SectionNumber
Chip Boling6e27b352020-02-14 09:10:01 -06002509 return nil
2510}
2511
2512/////////////////////////////////////////////////////////////////////////////
2513//
2514type EndSoftwareDownloadRequest struct {
2515 MeBasePacket // Note: EntityInstance for software download is two specific values
2516 CRC32 uint32
2517 ImageSize uint32
2518 NumberOfInstances byte
2519 ImageInstances []uint16
2520}
2521
2522func (omci *EndSoftwareDownloadRequest) String() string {
2523 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2524 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2525}
2526
2527// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
2528func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2529 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002530 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Chip Boling6e27b352020-02-14 09:10:01 -06002531 if err != nil {
2532 return err
2533 }
2534 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2535 me.ParamData{EntityID: omci.EntityInstance})
2536 if omciErr.StatusCode() != me.Success {
2537 return omciErr.GetError()
2538 }
2539 // ME needs to support End Software Download
2540 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2541 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2542 }
2543 // Software Image Entity Class are always use the Software Image
2544 if omci.EntityClass != me.SoftwareImageClassID {
2545 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2546 }
2547 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2548 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
Chip Boling2ccec852021-02-24 11:18:02 -06002549 omci.NumberOfInstances = data[12]
Chip Boling6e27b352020-02-14 09:10:01 -06002550
2551 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2552 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2553 omci.NumberOfInstances))
2554 }
2555 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2556
2557 for index := 0; index < int(omci.NumberOfInstances); index++ {
Chip Boling2ccec852021-02-24 11:18:02 -06002558 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[13+(index*2):])
Chip Boling6e27b352020-02-14 09:10:01 -06002559 }
2560 return nil
2561}
2562
2563func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2564 omci := &EndSoftwareDownloadRequest{}
2565 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2566 return decodingLayerDecoder(omci, data, p)
2567}
2568
2569// SerializeTo provides serialization of an End Software Download Request message
2570func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2571 // Basic (common) OMCI Header is 8 octets, 10
2572 err := omci.MeBasePacket.SerializeTo(b)
2573 if err != nil {
2574 return err
2575 }
2576 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2577 me.ParamData{EntityID: omci.EntityInstance})
2578 if omciErr.StatusCode() != me.Success {
2579 return omciErr.GetError()
2580 }
2581 // ME needs to support End Software Download
2582 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2583 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2584 }
2585 // Software Image Entity Class are always use the Software Image
2586 if omci.EntityClass != me.SoftwareImageClassID {
2587 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2588 }
2589 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
2590 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2591 omci.NumberOfInstances))
2592 }
2593 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2594 if err != nil {
2595 return err
2596 }
Chip Boling2ccec852021-02-24 11:18:02 -06002597 binary.BigEndian.PutUint32(bytes[0:4], omci.CRC32)
2598 binary.BigEndian.PutUint32(bytes[4:8], omci.ImageSize)
2599 bytes[8] = omci.NumberOfInstances
Chip Boling6e27b352020-02-14 09:10:01 -06002600 for index := 0; index < int(omci.NumberOfInstances); index++ {
Chip Boling2ccec852021-02-24 11:18:02 -06002601 binary.BigEndian.PutUint16(bytes[9+(index*2):], omci.ImageInstances[index])
Chip Boling6e27b352020-02-14 09:10:01 -06002602 }
2603 return nil
2604}
2605
2606/////////////////////////////////////////////////////////////////////////////
2607//
2608type EndSoftwareDownloadResponse struct {
2609 MeBasePacket // Note: EntityInstance for software download is two specific values
2610 Result me.Results
2611 NumberOfInstances byte
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002612 MeResults []DownloadResults
Chip Boling6e27b352020-02-14 09:10:01 -06002613}
2614
2615func (omci *EndSoftwareDownloadResponse) String() string {
2616 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2617 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2618}
2619
2620// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
2621func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2622 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002623 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06002624 if err != nil {
2625 return err
2626 }
2627 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2628 me.ParamData{EntityID: omci.EntityInstance})
2629 if omciErr.StatusCode() != me.Success {
2630 return omciErr.GetError()
2631 }
2632 // ME needs to support End Software Download
2633 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2634 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2635 }
2636 // Software Image Entity Class are always use the Software Image
2637 if omci.EntityClass != me.SoftwareImageClassID {
2638 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2639 }
2640 omci.Result = me.Results(data[4])
2641 if omci.Result > me.DeviceBusy {
2642 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2643 omci.Result)
2644 return errors.New(msg)
2645 }
2646 omci.NumberOfInstances = data[5]
2647
2648 if omci.NumberOfInstances > 9 {
2649 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2650 omci.NumberOfInstances)
2651 return errors.New(msg)
2652 }
2653 if omci.NumberOfInstances > 0 {
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -08002654 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Chip Boling6e27b352020-02-14 09:10:01 -06002655
2656 for index := 0; index < int(omci.NumberOfInstances); index++ {
2657 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2658 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2659 if omci.MeResults[index].Result > me.DeviceBusy {
2660 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2661 index, omci.MeResults[index])
2662 return errors.New(msg)
2663 }
2664 }
2665 }
2666 return nil
2667}
2668
2669func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2670 omci := &EndSoftwareDownloadResponse{}
2671 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2672 return decodingLayerDecoder(omci, data, p)
2673}
2674
2675// SerializeTo provides serialization of an End Software Download Response message
2676func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2677 // Basic (common) OMCI Header is 8 octets, 10
2678 err := omci.MeBasePacket.SerializeTo(b)
2679 if err != nil {
2680 return err
2681 }
2682 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2683 me.ParamData{EntityID: omci.EntityInstance})
2684 if omciErr.StatusCode() != me.Success {
2685 return omciErr.GetError()
2686 }
2687 // ME needs to support End Software Download
2688 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2689 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2690 }
2691 // Software Image Entity Class are always use the Software Image
2692 if omci.EntityClass != me.SoftwareImageClassID {
2693 return me.NewProcessingError("invalid Entity Class for End Download response")
2694 }
Chip Boling2ccec852021-02-24 11:18:02 -06002695 bytes, err := b.AppendBytes(2 + (3 * int(omci.NumberOfInstances)))
Chip Boling6e27b352020-02-14 09:10:01 -06002696 if err != nil {
2697 return err
2698 }
2699 if omci.Result > me.DeviceBusy {
2700 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2701 omci.Result)
2702 return errors.New(msg)
2703 }
2704 bytes[0] = byte(omci.Result)
2705 bytes[1] = omci.NumberOfInstances
2706
2707 if omci.NumberOfInstances > 9 {
2708 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2709 omci.NumberOfInstances)
2710 return errors.New(msg)
2711 }
2712 if omci.NumberOfInstances > 0 {
2713 for index := 0; index < int(omci.NumberOfInstances); index++ {
2714 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2715
2716 if omci.MeResults[index].Result > me.DeviceBusy {
2717 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2718 index, omci.MeResults[index])
2719 return errors.New(msg)
2720 }
2721 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2722 }
2723 }
2724 return nil
2725}
2726
2727/////////////////////////////////////////////////////////////////////////////
2728//
2729type ActivateSoftwareRequest struct {
2730 MeBasePacket // Note: EntityInstance for software download is two specific values
2731 ActivateFlags byte
2732}
2733
2734func (omci *ActivateSoftwareRequest) String() string {
2735 return fmt.Sprintf("%v, Flags: %#x",
2736 omci.MeBasePacket.String(), omci.ActivateFlags)
2737}
2738
2739// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
2740func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2741 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002742 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002743 if err != nil {
2744 return err
2745 }
2746 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2747 me.ParamData{EntityID: omci.EntityInstance})
2748 if omciErr.StatusCode() != me.Success {
2749 return omciErr.GetError()
2750 }
2751 // ME needs to support End Software Download
2752 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2753 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2754 }
2755 // Software Image Entity Class are always use the Software Image
2756 if omci.EntityClass != me.SoftwareImageClassID {
2757 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2758 }
2759 omci.ActivateFlags = data[4]
2760 if omci.ActivateFlags > 2 {
2761 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2762 omci.ActivateFlags))
2763 }
2764 return nil
2765}
2766
2767func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2768 omci := &ActivateSoftwareRequest{}
2769 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2770 return decodingLayerDecoder(omci, data, p)
2771}
2772
2773// SerializeTo provides serialization of an Activate Software message
2774func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2775 // Basic (common) OMCI Header is 8 octets, 10
2776 err := omci.MeBasePacket.SerializeTo(b)
2777 if err != nil {
2778 return err
2779 }
2780 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2781 me.ParamData{EntityID: omci.EntityInstance})
2782 if omciErr.StatusCode() != me.Success {
2783 return omciErr.GetError()
2784 }
2785 // ME needs to support End Software Download
2786 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2787 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2788 }
2789 // Software Image Entity Class are always use the Software Image
2790 if omci.EntityClass != me.SoftwareImageClassID {
2791 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2792 }
2793 bytes, err := b.AppendBytes(1)
2794 if err != nil {
2795 return err
2796 }
2797 bytes[0] = omci.ActivateFlags
2798 if omci.ActivateFlags > 2 {
2799 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2800 omci.ActivateFlags)
2801 return errors.New(msg)
2802 }
2803 return nil
2804}
2805
2806/////////////////////////////////////////////////////////////////////////////
2807//
2808type ActivateSoftwareResponse struct {
2809 MeBasePacket
2810 Result me.Results
2811}
2812
2813func (omci *ActivateSoftwareResponse) String() string {
2814 return fmt.Sprintf("%v, Result: %d (%v)",
2815 omci.MeBasePacket.String(), omci.Result, omci.Result)
2816}
2817
2818// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
2819func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2820 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002821 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002822 if err != nil {
2823 return err
2824 }
2825 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2826 me.ParamData{EntityID: omci.EntityInstance})
2827 if omciErr.StatusCode() != me.Success {
2828 return omciErr.GetError()
2829 }
2830 // ME needs to support End Software Download
2831 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2832 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2833 }
2834 // Software Image Entity Class are always use the Software Image
2835 if omci.EntityClass != me.SoftwareImageClassID {
2836 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2837 }
2838 omci.Result = me.Results(data[4])
2839 if omci.Result > me.Results(6) {
2840 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2841 omci.Result)
2842 return errors.New(msg)
2843 }
2844 return nil
2845}
2846
2847func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2848 omci := &ActivateSoftwareResponse{}
2849 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2850 return decodingLayerDecoder(omci, data, p)
2851}
2852
2853// SerializeTo provides serialization of an Activate Software Response message
2854func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2855 // Basic (common) OMCI Header is 8 octets, 10
2856 err := omci.MeBasePacket.SerializeTo(b)
2857 if err != nil {
2858 return err
2859 }
2860 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2861 me.ParamData{EntityID: omci.EntityInstance})
2862 if omciErr.StatusCode() != me.Success {
2863 return omciErr.GetError()
2864 }
2865 // ME needs to support End Software Download
2866 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2867 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2868 }
2869 // Software Image Entity Class are always use the Software Image
2870 if omci.EntityClass != me.SoftwareImageClassID {
2871 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2872 }
2873 bytes, err := b.AppendBytes(1)
2874 if err != nil {
2875 return err
2876 }
2877 bytes[0] = byte(omci.Result)
2878 if omci.Result > me.Results(6) {
2879 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2880 omci.Result)
2881 return errors.New(msg)
2882 }
2883 return nil
2884}
2885
2886/////////////////////////////////////////////////////////////////////////////
2887//
2888type CommitSoftwareRequest struct {
2889 MeBasePacket
2890}
2891
2892func (omci *CommitSoftwareRequest) String() string {
2893 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2894}
2895
2896// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
2897func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2898 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06002899 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06002900 if err != nil {
2901 return err
2902 }
2903 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2904 me.ParamData{EntityID: omci.EntityInstance})
2905 if omciErr.StatusCode() != me.Success {
2906 return omciErr.GetError()
2907 }
2908 // ME needs to support End Software Download
2909 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2910 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2911 }
2912 // Software Image Entity Class are always use the Software Image
2913 if omci.EntityClass != me.SoftwareImageClassID {
2914 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2915 }
2916 return nil
2917}
2918
2919func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2920 omci := &CommitSoftwareRequest{}
2921 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
2922 return decodingLayerDecoder(omci, data, p)
2923}
2924
2925// SerializeTo provides serialization of an Commit Software Request message
2926func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2927 // Basic (common) OMCI Header is 8 octets, 10
2928 err := omci.MeBasePacket.SerializeTo(b)
2929 if err != nil {
2930 return err
2931 }
2932 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2933 me.ParamData{EntityID: omci.EntityInstance})
2934 if omciErr.StatusCode() != me.Success {
2935 return omciErr.GetError()
2936 }
2937 // ME needs to support End Software Download
2938 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2939 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2940 }
2941 // Software Image Entity Class are always use the Software Image
2942 if omci.EntityClass != me.SoftwareImageClassID {
2943 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2944 }
2945 return nil
2946}
2947
2948/////////////////////////////////////////////////////////////////////////////
2949//
2950type CommitSoftwareResponse struct {
2951 MeBasePacket
Chip Boling58fc4d22021-03-10 13:23:53 -06002952 Result me.Results
Chip Boling6e27b352020-02-14 09:10:01 -06002953}
2954
2955func (omci *CommitSoftwareResponse) String() string {
2956 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2957}
2958
2959// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
2960func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2961 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06002962 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06002963 if err != nil {
2964 return err
2965 }
2966 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
2967 me.ParamData{EntityID: omci.EntityInstance})
2968 if omciErr.StatusCode() != me.Success {
2969 return omciErr.GetError()
2970 }
Chip Boling58fc4d22021-03-10 13:23:53 -06002971 // ME needs to support Commit Software
Chip Boling6e27b352020-02-14 09:10:01 -06002972 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2973 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2974 }
2975 // Software Image Entity Class are always use the Software Image
2976 if omci.EntityClass != me.SoftwareImageClassID {
2977 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2978 }
Chip Boling58fc4d22021-03-10 13:23:53 -06002979 omci.Result = me.Results(data[4])
2980 if omci.Result > me.Results(6) {
2981 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
2982 omci.Result)
2983 return errors.New(msg)
2984 }
Chip Boling6e27b352020-02-14 09:10:01 -06002985 return nil
2986}
2987
2988func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2989 omci := &CommitSoftwareResponse{}
2990 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
2991 return decodingLayerDecoder(omci, data, p)
2992}
2993
2994// SerializeTo provides serialization of an Commit Software Response message
2995func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2996 // Basic (common) OMCI Header is 8 octets, 10
2997 err := omci.MeBasePacket.SerializeTo(b)
2998 if err != nil {
2999 return err
3000 }
3001 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3002 me.ParamData{EntityID: omci.EntityInstance})
3003 if omciErr.StatusCode() != me.Success {
3004 return omciErr.GetError()
3005 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003006 // ME needs to support Commit Software
Chip Boling6e27b352020-02-14 09:10:01 -06003007 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
3008 return me.NewProcessingError("managed entity does not support Commit Message-Type")
3009 }
3010 // Software Image Entity Class are always use the Software Image
3011 if omci.EntityClass != me.SoftwareImageClassID {
3012 return me.NewProcessingError("invalid Entity Class for Commit Software response")
3013 }
Chip Boling58fc4d22021-03-10 13:23:53 -06003014 bytes, err := b.AppendBytes(1)
3015 if err != nil {
3016 return err
3017 }
3018 bytes[0] = byte(omci.Result)
3019 if omci.Result > me.Results(6) {
3020 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
3021 omci.Result)
3022 return errors.New(msg)
3023 }
Chip Boling6e27b352020-02-14 09:10:01 -06003024 return nil
3025}
3026
3027/////////////////////////////////////////////////////////////////////////////
3028//
3029type SynchronizeTimeRequest struct {
3030 MeBasePacket
3031 Year uint16
3032 Month uint8
3033 Day uint8
3034 Hour uint8
3035 Minute uint8
3036 Second uint8
3037}
3038
3039func (omci *SynchronizeTimeRequest) String() string {
3040 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
3041 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
3042}
3043
3044// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
3045func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3046 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003047 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Chip Boling6e27b352020-02-14 09:10:01 -06003048 if err != nil {
3049 return err
3050 }
3051 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3052 me.ParamData{EntityID: omci.EntityInstance})
3053 if omciErr.StatusCode() != me.Success {
3054 return omciErr.GetError()
3055 }
3056 // ME needs to support Synchronize Time
3057 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3058 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3059 }
3060 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3061 if omci.EntityClass != me.OnuGClassID {
3062 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
3063 }
3064 if omci.EntityInstance != 0 {
3065 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
3066 }
3067 omci.Year = binary.BigEndian.Uint16(data[4:6])
3068 omci.Month = data[6]
3069 omci.Day = data[7]
3070 omci.Hour = data[8]
3071 omci.Minute = data[9]
3072 omci.Second = data[10]
3073 return nil
3074}
3075
3076func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
3077 omci := &SynchronizeTimeRequest{}
3078 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
3079 return decodingLayerDecoder(omci, data, p)
3080}
3081
3082// SerializeTo provides serialization of an Synchronize Time Request message
3083func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3084 // Basic (common) OMCI Header is 8 octets, 10
3085 err := omci.MeBasePacket.SerializeTo(b)
3086 if err != nil {
3087 return err
3088 }
3089 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3090 me.ParamData{EntityID: omci.EntityInstance})
3091 if omciErr.StatusCode() != me.Success {
3092 return omciErr.GetError()
3093 }
3094 // ME needs to support Synchronize Time
3095 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3096 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3097 }
3098 bytes, err := b.AppendBytes(7)
3099 if err != nil {
3100 return err
3101 }
3102 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
3103 bytes[2] = omci.Month
3104 bytes[3] = omci.Day
3105 bytes[4] = omci.Hour
3106 bytes[5] = omci.Minute
3107 bytes[6] = omci.Second
3108 return nil
3109}
3110
3111/////////////////////////////////////////////////////////////////////////////
3112//
3113type SynchronizeTimeResponse struct {
3114 MeBasePacket
3115 Result me.Results
3116 SuccessResults uint8 // Only if 'Result' is 0 -> success
3117}
3118
3119func (omci *SynchronizeTimeResponse) String() string {
3120 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
3121 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
3122}
3123
3124// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
3125func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3126 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003127 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003128 if err != nil {
3129 return err
3130 }
3131 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3132 me.ParamData{EntityID: omci.EntityInstance})
3133 if omciErr.StatusCode() != me.Success {
3134 return omciErr.GetError()
3135 }
3136 // ME needs to support Synchronize Time
3137 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
3138 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
3139 }
3140 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
3141 if omci.EntityClass != me.OnuGClassID {
3142 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3143 }
3144 if omci.EntityInstance != 0 {
3145 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3146 }
3147 omci.Result = me.Results(data[4])
3148 if omci.Result > me.DeviceBusy {
Chip Bolingd8637b02021-04-29 08:36:38 -05003149 msg := fmt.Sprintf("invalid results code: %v, must be 0..6", omci.Result)
Chip Boling6e27b352020-02-14 09:10:01 -06003150 return errors.New(msg)
3151 }
3152 omci.SuccessResults = data[5]
3153 return nil
3154}
3155
3156func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
3157 omci := &SynchronizeTimeResponse{}
3158 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
3159 return decodingLayerDecoder(omci, data, p)
3160}
3161
3162// SerializeTo provides serialization of an Synchronize Time Response message
3163func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3164 // Basic (common) OMCI Header is 8 octets, 10
3165 err := omci.MeBasePacket.SerializeTo(b)
3166 if err != nil {
3167 return err
3168 }
3169 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3170 me.ParamData{EntityID: omci.EntityInstance})
3171 if omciErr.StatusCode() != me.Success {
3172 return omciErr.GetError()
3173 }
3174 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
3175 if omci.EntityClass != me.OnuGClassID {
3176 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
3177 }
3178 if omci.EntityInstance != 0 {
3179 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
3180 }
3181 // ME needs to support Synchronize Time
3182 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
3183 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3184 }
3185 numBytes := 2
3186 if omci.Result != me.Success {
3187 numBytes = 1
3188 }
3189 bytes, err := b.AppendBytes(numBytes)
3190 if err != nil {
3191 return err
3192 }
3193 bytes[0] = uint8(omci.Result)
3194 if omci.Result == me.Success {
3195 bytes[1] = omci.SuccessResults
3196 }
3197 return nil
3198}
3199
3200/////////////////////////////////////////////////////////////////////////////
3201//
3202type RebootRequest struct {
3203 MeBasePacket
3204 RebootCondition byte
3205}
3206
3207func (omci *RebootRequest) String() string {
3208 return fmt.Sprintf("%v, Reboot Condition: %v",
3209 omci.MeBasePacket.String(), omci.RebootCondition)
3210}
3211
3212// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
3213func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3214 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003215 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003216 if err != nil {
3217 return err
3218 }
3219 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3220 me.ParamData{EntityID: omci.EntityInstance})
3221 if omciErr.StatusCode() != me.Success {
3222 return omciErr.GetError()
3223 }
3224 // ME needs to support Reboot
3225 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3226 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3227 }
3228 omci.RebootCondition = data[4]
3229 if omci.RebootCondition > 3 {
3230 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
3231 return errors.New(msg)
3232 }
3233 return nil
3234}
3235
3236func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
3237 omci := &RebootRequest{}
3238 omci.MsgLayerType = LayerTypeRebootRequest
3239 return decodingLayerDecoder(omci, data, p)
3240}
3241
3242// SerializeTo provides serialization of an Reboot Request message
3243func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3244 // Basic (common) OMCI Header is 8 octets, 10
3245 err := omci.MeBasePacket.SerializeTo(b)
3246 if err != nil {
3247 return err
3248 }
3249 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3250 me.ParamData{EntityID: omci.EntityInstance})
3251 if omciErr.StatusCode() != me.Success {
3252 return omciErr.GetError()
3253 }
3254 // ME needs to support Reboot
3255 if !me.SupportsMsgType(entity, me.Reboot) {
3256 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3257 }
3258 bytes, err := b.AppendBytes(1)
3259 if err != nil {
3260 return err
3261 }
3262 if omci.RebootCondition > 3 {
3263 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
3264 omci.RebootCondition))
3265 }
3266 bytes[0] = omci.RebootCondition
3267 return nil
3268}
3269
3270/////////////////////////////////////////////////////////////////////////////
3271//
3272type RebootResponse struct {
3273 MeBasePacket
3274 Result me.Results
3275}
3276
3277// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3278func (omci *RebootResponse) String() string {
3279 return fmt.Sprintf("%v, Result: %d (%v)",
3280 omci.MeBasePacket.String(), omci.Result, omci.Result)
3281}
3282
3283// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
3284func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3285 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003286 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003287 if err != nil {
3288 return err
3289 }
3290 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3291 me.ParamData{EntityID: omci.EntityInstance})
3292 if omciErr.StatusCode() != me.Success {
3293 return omciErr.GetError()
3294 }
3295 // ME needs to support Reboot
3296 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3297 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3298 }
3299 if omci.Result > 6 {
3300 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3301 return errors.New(msg)
3302 }
3303 omci.Result = me.Results(data[4])
3304 return nil
3305}
3306
3307func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3308 omci := &RebootResponse{}
3309 omci.MsgLayerType = LayerTypeRebootResponse
3310 return decodingLayerDecoder(omci, data, p)
3311}
3312
3313// SerializeTo provides serialization of an Reboot Response message
3314func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3315 // Basic (common) OMCI Header is 8 octets, 10
3316 err := omci.MeBasePacket.SerializeTo(b)
3317 if err != nil {
3318 return err
3319 }
3320 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3321 me.ParamData{EntityID: omci.EntityInstance})
3322 if omciErr.StatusCode() != me.Success {
3323 return omciErr.GetError()
3324 }
3325 // ME needs to support Reboot
3326 if !me.SupportsMsgType(entity, me.Reboot) {
3327 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3328 }
3329 bytes, err := b.AppendBytes(1)
3330 if err != nil {
3331 return err
3332 }
3333 if omci.Result > 6 {
3334 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3335 return errors.New(msg)
3336 }
3337 bytes[0] = byte(omci.Result)
3338 return nil
3339}
3340
3341/////////////////////////////////////////////////////////////////////////////
3342//
3343type GetNextRequest struct {
3344 MeBasePacket
3345 AttributeMask uint16
3346 SequenceNumber uint16
3347}
3348
3349func (omci *GetNextRequest) String() string {
3350 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3351 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3352}
3353
3354// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
3355func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3356 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003357 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Chip Boling6e27b352020-02-14 09:10:01 -06003358 if err != nil {
3359 return err
3360 }
3361 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3362 me.ParamData{EntityID: omci.EntityInstance})
3363 if omciErr.StatusCode() != me.Success {
3364 return omciErr.GetError()
3365 }
3366 // ME needs to support GetNext
3367 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3368 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3369 }
3370 // Note: G.988 specifies that an error code of (3) should result if more
3371 // than one attribute is requested
3372 // TODO: Return error. Have flag to optionally allow it to be encoded
3373 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3374 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3375 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3376 return nil
3377}
3378
3379func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3380 omci := &GetNextRequest{}
3381 omci.MsgLayerType = LayerTypeGetNextRequest
3382 return decodingLayerDecoder(omci, data, p)
3383}
3384
3385// SerializeTo provides serialization of an Get Next Message Type Request
3386func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3387 // Basic (common) OMCI Header is 8 octets, 10
3388 err := omci.MeBasePacket.SerializeTo(b)
3389 if err != nil {
3390 return err
3391 }
3392 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3393 me.ParamData{EntityID: omci.EntityInstance})
3394 if omciErr.StatusCode() != me.Success {
3395 return omciErr.GetError()
3396 }
3397 // ME needs to support GetNext
3398 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3399 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3400 }
3401 bytes, err := b.AppendBytes(4)
3402 if err != nil {
3403 return err
3404 }
3405 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3406 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3407 return nil
3408}
3409
3410/////////////////////////////////////////////////////////////////////////////
3411//
3412type GetNextResponse struct {
3413 MeBasePacket
3414 Result me.Results
3415 AttributeMask uint16
3416 Attributes me.AttributeValueMap
3417}
3418
3419// SerializeTo provides serialization of an Get Next Message Type Response
3420func (omci *GetNextResponse) String() string {
3421 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3422 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3423}
3424
3425// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
3426func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3427 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003428 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -06003429 if err != nil {
3430 return err
3431 }
3432 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3433 me.ParamData{EntityID: omci.EntityInstance})
3434 if omciErr.StatusCode() != me.Success {
3435 return omciErr.GetError()
3436 }
3437 // ME needs to support Set
3438 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3439 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3440 }
3441 omci.Result = me.Results(data[4])
3442 if omci.Result > 6 {
3443 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3444 return errors.New(msg)
3445 }
3446 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3447
3448 // Attribute decode
3449 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3450 if err != nil {
3451 return err
3452 }
3453 // Validate all attributes support read
3454 for attrName := range omci.Attributes {
3455 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3456 if err != nil {
3457 return err
3458 }
3459 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3460 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3461 return me.NewProcessingError(msg)
3462 }
3463 }
3464 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
3465 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3466 return nil
3467 }
3468 panic("All Managed Entities have an EntityID attribute")
3469}
3470
3471func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3472 omci := &GetNextResponse{}
3473 omci.MsgLayerType = LayerTypeGetNextResponse
3474 return decodingLayerDecoder(omci, data, p)
3475}
3476
3477// SerializeTo provides serialization of an Get Next Message Type Response
3478func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3479 // Basic (common) OMCI Header is 8 octets, 10
3480 err := omci.MeBasePacket.SerializeTo(b)
3481 if err != nil {
3482 return err
3483 }
3484 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3485 me.ParamData{EntityID: omci.EntityInstance})
3486 if omciErr.StatusCode() != me.Success {
3487 return omciErr.GetError()
3488 }
3489 // ME needs to support Get
3490 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3491 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3492 }
3493 bytes, err := b.AppendBytes(3)
3494 if err != nil {
3495 return err
3496 }
3497 bytes[0] = byte(omci.Result)
3498 if omci.Result > 6 {
3499 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3500 return errors.New(msg)
3501 }
3502 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3503
3504 // Validate all attributes support read
3505 for attrName := range omci.Attributes {
3506 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3507 if err != nil {
3508 return err
3509 }
3510 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
3511 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3512 return me.NewProcessingError(msg)
3513 }
3514 }
3515 // Attribute serialization
3516 switch omci.Result {
3517 default:
3518 break
3519
3520 case me.Success:
3521 // TODO: Only Baseline supported at this time
3522 bytesAvailable := MaxBaselineLength - 11 - 8
3523
3524 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3525 byte(GetNextResponseType), bytesAvailable, false)
3526 if err != nil {
3527 return err
3528 }
3529 }
3530 return nil
3531}
3532
Chip Bolingd8637b02021-04-29 08:36:38 -05003533func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3534 // Peek at Managed Entity Type
3535 if len(data) < 8 {
3536 p.SetTruncated()
3537 return errors.New("frame too small")
3538 }
3539 classID := binary.BigEndian.Uint16(data)
3540
3541 // Is it a Managed Entity class we support customized decode of?
3542 switch me.ClassID(classID) {
3543 default:
3544 omci := &TestResultNotification{}
3545 omci.MsgLayerType = LayerTypeTestResult
3546 return decodingLayerDecoder(omci, data, p)
3547
3548 case me.AniGClassID, me.ReAniGClassID, me.PhysicalPathTerminationPointReUniClassID,
3549 me.ReUpstreamAmplifierClassID, me.ReDownstreamAmplifierClassID:
3550 omci := &OpticalLineSupervisionTestResult{}
3551 omci.MsgLayerType = LayerTypeTestResult
3552 return decodingLayerDecoder(omci, data, p)
3553 }
Chip Boling6e27b352020-02-14 09:10:01 -06003554}
3555
Chip Bolingd8637b02021-04-29 08:36:38 -05003556type TestResultNotification struct {
3557 MeBasePacket
3558 Payload []byte
3559}
3560
3561func (omci *TestResultNotification) TestResults() []byte {
3562 return omci.Payload
3563}
3564
3565func (omci *TestResultNotification) String() string {
3566 return fmt.Sprintf("%v, Payload: %v octets", omci.MeBasePacket.String(), len(omci.Payload))
Chip Boling6e27b352020-02-14 09:10:01 -06003567}
3568
3569// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
Chip Bolingd8637b02021-04-29 08:36:38 -05003570func (omci *TestResultNotification) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
Chip Boling6e27b352020-02-14 09:10:01 -06003571 // Common ClassID/EntityID decode in msgBase
Chip Bolingd8543b22021-03-08 08:34:26 -06003572 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Chip Boling6e27b352020-02-14 09:10:01 -06003573 if err != nil {
3574 return err
3575 }
Chip Boling6e27b352020-02-14 09:10:01 -06003576
Chip Bolingd8637b02021-04-29 08:36:38 -05003577 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3578 me.ParamData{EntityID: omci.EntityInstance})
3579 if omciErr.StatusCode() != me.Success {
3580 return omciErr.GetError()
3581 }
3582
3583 // ME needs to support Test requests
3584 if !me.SupportsMsgType(meDefinition, me.Test) {
3585 return me.NewProcessingError("managed entity does not support Test Message-Type")
3586 }
3587 omci.Payload = make([]byte, MaxTestResultsLength)
3588 copy(omci.Payload, omci.MeBasePacket.Payload)
3589 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06003590}
3591
3592// SerializeTo provides serialization of an Test Result notification message
Chip Bolingd8637b02021-04-29 08:36:38 -05003593func (omci *TestResultNotification) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3594 // Basic (common) OMCI Header is 8 octets
3595 err := omci.MeBasePacket.SerializeTo(b)
3596 if err != nil {
3597 return err
3598 }
3599
3600 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3601 me.ParamData{EntityID: omci.EntityInstance})
3602 if omciErr.StatusCode() != me.Success {
3603 return omciErr.GetError()
3604 }
3605
3606 // ME needs to support Test requests
3607 if !me.SupportsMsgType(meDefinition, me.Test) {
3608 return me.NewProcessingError("managed entity does not support Test Message-Type")
3609 }
3610 if omci.Payload == nil {
3611 return errors.New("Test Results payload is missing")
3612 }
3613 if len(omci.Payload) > MaxTestResultsLength {
3614 msg := fmt.Sprintf("Invalid Test Results payload size. Received %v bytes, expected %v",
3615 len(omci.Payload), MaxTestResultsLength)
3616 return errors.New(msg)
3617 }
3618 bytes, err := b.AppendBytes(len(omci.Payload))
3619 if err != nil {
3620 return err
3621 }
3622
3623 copy(bytes, omci.Payload)
3624 return nil
3625}
3626
3627// OpticalLineSupervisionTestResult provides a Optical Specific test results
3628// message decode for the associated Managed Entities
3629type OpticalLineSupervisionTestResult struct {
3630 MeBasePacket
3631 PowerFeedVoltageType uint8 // Type = 1
3632 PowerFeedVoltage uint16 // value
3633 ReceivedOpticalPowerType uint8 // Type = 3
3634 ReceivedOpticalPower uint16 // value
3635 MeanOpticalLaunchType uint8 // Type = 5
3636 MeanOpticalLaunch uint16 // value
3637 LaserBiasCurrentType uint8 // Type = 9
3638 LaserBiasCurrent uint16 // value
3639 TemperatureType uint8 // Type = 12
3640 Temperature uint16 // value
3641
3642 GeneralPurposeBuffer uint16 // Pointer to General Purpose Buffer ME
3643}
3644
3645func (omci *OpticalLineSupervisionTestResult) String() string {
3646 return fmt.Sprintf("Optical Line Supervision Test Result")
3647}
3648
3649func (omci *OpticalLineSupervisionTestResult) TestResults() []byte {
3650 return omci.MeBasePacket.Payload
3651}
3652
3653// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
3654func (omci *OpticalLineSupervisionTestResult) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3655 // Common ClassID/EntityID decode in msgBase
3656 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+17)
3657 if err != nil {
3658 return err
3659 }
3660
3661 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3662 me.ParamData{EntityID: omci.EntityInstance})
3663 if omciErr.StatusCode() != me.Success {
3664 return omciErr.GetError()
3665 }
3666
3667 // ME needs to support Test requests
3668 if !me.SupportsMsgType(meDefinition, me.Test) {
3669 return me.NewProcessingError("managed entity does not support Test Message-Type")
3670 }
3671 // Note: Unsupported tests will have a type = 0 and the value should be zero
3672 // as well, but that constraint is not enforced at this time.
3673 // Type = 1
3674 omci.PowerFeedVoltageType = data[4]
3675 omci.PowerFeedVoltage = binary.BigEndian.Uint16(data[5:])
3676
3677 // Type = 3
3678 omci.ReceivedOpticalPowerType = data[7]
3679 omci.ReceivedOpticalPower = binary.BigEndian.Uint16(data[8:])
3680
3681 // Type = 5
3682 omci.MeanOpticalLaunchType = data[10]
3683 omci.MeanOpticalLaunch = binary.BigEndian.Uint16(data[11:])
3684
3685 // Type = 9
3686 omci.LaserBiasCurrentType = data[13]
3687 omci.LaserBiasCurrent = binary.BigEndian.Uint16(data[14:])
3688
3689 // Type = 12
3690 omci.TemperatureType = data[16]
3691 omci.Temperature = binary.BigEndian.Uint16(data[17:])
3692
3693 omci.GeneralPurposeBuffer = binary.BigEndian.Uint16(data[19:])
3694 return nil
3695}
3696
3697// SerializeTo provides serialization of an Test Result notification message
3698func (omci *OpticalLineSupervisionTestResult) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
Chip Boling6e27b352020-02-14 09:10:01 -06003699 // Basic (common) OMCI Header is 8 octets, 10
3700 err := omci.MeBasePacket.SerializeTo(b)
3701 if err != nil {
3702 return err
3703 }
Chip Bolingd8637b02021-04-29 08:36:38 -05003704 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3705 me.ParamData{EntityID: omci.EntityInstance})
3706 if omciErr.StatusCode() != me.Success {
3707 return omciErr.GetError()
3708 }
3709
3710 // ME needs to support Test requests
3711 if !me.SupportsMsgType(meDefinition, me.Test) {
3712 return me.NewProcessingError("managed entity does not support Test Message-Type")
3713 }
3714 bytes, err := b.AppendBytes(17)
3715 if err != nil {
3716 return err
3717 }
3718
3719 bytes[0] = omci.PowerFeedVoltageType
3720 binary.BigEndian.PutUint16(bytes[1:], omci.PowerFeedVoltage)
3721 bytes[3] = omci.ReceivedOpticalPowerType
3722 binary.BigEndian.PutUint16(bytes[4:], omci.ReceivedOpticalPower)
3723 bytes[6] = omci.MeanOpticalLaunchType
3724 binary.BigEndian.PutUint16(bytes[7:], omci.MeanOpticalLaunch)
3725 bytes[9] = omci.LaserBiasCurrentType
3726 binary.BigEndian.PutUint16(bytes[10:], omci.LaserBiasCurrent)
3727 bytes[12] = omci.TemperatureType
3728 binary.BigEndian.PutUint16(bytes[13:], omci.Temperature)
3729 binary.BigEndian.PutUint16(bytes[15:], omci.GeneralPurposeBuffer)
3730 return nil
Chip Boling6e27b352020-02-14 09:10:01 -06003731}
3732
3733/////////////////////////////////////////////////////////////////////////////
3734//
3735type GetCurrentDataRequest struct {
3736 MeBasePacket
3737 AttributeMask uint16
3738}
3739
3740func (omci *GetCurrentDataRequest) String() string {
3741 return fmt.Sprintf("%v, Attribute Mask: %#x",
3742 omci.MeBasePacket.String(), omci.AttributeMask)
3743}
3744
3745// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
3746func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3747 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003748 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003749 if err != nil {
3750 return err
3751 }
3752 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3753 me.ParamData{EntityID: omci.EntityInstance})
3754 if omciErr.StatusCode() != me.Success {
3755 return omciErr.GetError()
3756 }
3757 // ME needs to support GetNext
3758 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3759 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3760 }
3761 // Note: G.988 specifies that an error code of (3) should result if more
3762 // than one attribute is requested
3763 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3764 return nil
3765}
3766
3767func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3768 omci := &GetCurrentDataRequest{}
3769 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3770 return decodingLayerDecoder(omci, data, p)
3771}
3772
3773// SerializeTo provides serialization of an Get Current Data Request message
3774func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3775 // Basic (common) OMCI Header is 8 octets, 10
3776 err := omci.MeBasePacket.SerializeTo(b)
3777 if err != nil {
3778 return err
3779 }
3780 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3781 me.ParamData{EntityID: omci.EntityInstance})
3782 if omciErr.StatusCode() != me.Success {
3783 return omciErr.GetError()
3784 }
3785 // ME needs to support GetNext
3786 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3787 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3788 }
3789 bytes, err := b.AppendBytes(2)
3790 if err != nil {
3791 return err
3792 }
3793 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3794 return nil
3795}
3796
3797/////////////////////////////////////////////////////////////////////////////
3798//
3799type GetCurrentDataResponse struct {
3800 MeBasePacket
3801 Result me.Results
3802 AttributeMask uint16
3803 Attributes me.AttributeValueMap
3804}
3805
3806func (omci *GetCurrentDataResponse) String() string {
3807 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
3808 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
3809}
3810
3811// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
3812func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3813 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003814 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Chip Boling6e27b352020-02-14 09:10:01 -06003815 if err != nil {
3816 return err
3817 }
3818 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3819 me.ParamData{EntityID: omci.EntityInstance})
3820 if omciErr.StatusCode() != me.Success {
3821 return omciErr.GetError()
3822 }
3823 // ME needs to support Set
3824 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3825 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3826 }
3827 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3828
Chip Boling4e0ac9a2021-01-20 14:23:09 -06003829 switch omci.Result {
3830 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
3831 return nil // Done (do not try and decode attributes)
3832 }
Chip Boling6e27b352020-02-14 09:10:01 -06003833 // Attribute decode
3834 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(GetCurrentDataResponseType))
3835 if err != nil {
3836 return err
3837 }
3838 return nil
3839}
3840
3841func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
3842 omci := &GetCurrentDataResponse{}
3843 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
3844 return decodingLayerDecoder(omci, data, p)
3845}
3846
3847// SerializeTo provides serialization of an Get Current Data Message Type Response
3848func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3849 // Basic (common) OMCI Header is 8 octets, 10
3850 err := omci.MeBasePacket.SerializeTo(b)
3851 if err != nil {
3852 return err
3853 }
3854 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
3855 me.ParamData{EntityID: omci.EntityInstance})
3856 if omciErr.StatusCode() != me.Success {
3857 return omciErr.GetError()
3858 }
3859 // ME needs to support Get
3860 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3861 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
3862 }
3863 bytes, err := b.AppendBytes(2)
3864 if err != nil {
3865 return err
3866 }
3867 binary.BigEndian.PutUint16(bytes[0:2], omci.AttributeMask)
3868
3869 // Attribute serialization
3870 // TODO: Only Baseline supported at this time
3871 bytesAvailable := MaxBaselineLength - 9 - 8
3872 var failedMask uint16
3873
3874 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3875 byte(GetCurrentDataResponseType), bytesAvailable, opts.FixLengths)
3876
3877 if failedMask != 0 {
3878 // TODO: See GetResponse serialization above for the steps here
3879 return me.NewMessageTruncatedError("getCurrentData attribute truncation not yet supported")
3880 }
3881 if err != nil {
3882 return err
3883 }
3884 return nil
3885}
3886
3887/////////////////////////////////////////////////////////////////////////////
3888//
3889type SetTableRequest struct {
3890 MeBasePacket
3891 // TODO: Fix me when extended messages supported)
3892}
3893
3894func (omci *SetTableRequest) String() string {
3895 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3896}
3897
3898// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
3899func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3900 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003901 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+2)
Chip Boling6e27b352020-02-14 09:10:01 -06003902 if err != nil {
3903 return err
3904 }
3905 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3906}
3907
3908func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
3909 omci := &SetTableRequest{}
3910 omci.MsgLayerType = LayerTypeSetTableRequest
3911 return decodingLayerDecoder(omci, data, p)
3912}
3913
3914// SerializeTo provides serialization of an Set Table Message Type Request
3915func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3916 // Basic (common) OMCI Header is 8 octets, 10
3917 err := omci.MeBasePacket.SerializeTo(b)
3918 if err != nil {
3919 return err
3920 }
3921 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
3922}
3923
3924/////////////////////////////////////////////////////////////////////////////
3925//
3926type SetTableResponse struct {
3927 MeBasePacket
3928 // TODO: Fix me when extended messages supported)
3929}
3930
3931func (omci *SetTableResponse) String() string {
3932 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3933}
3934
3935// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
3936func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3937 // Common ClassID/EntityID decode in msgBase
Chip Boling58fc4d22021-03-10 13:23:53 -06003938 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+1)
Chip Boling6e27b352020-02-14 09:10:01 -06003939 if err != nil {
3940 return err
3941 }
3942 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3943}
3944
3945func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
3946 omci := &SetTableResponse{}
3947 omci.MsgLayerType = LayerTypeSetTableResponse
3948 return decodingLayerDecoder(omci, data, p)
3949}
3950
3951// SerializeTo provides serialization of an Set Table Message Type Response
3952func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3953 // Basic (common) OMCI Header is 8 octets, 10
3954 err := omci.MeBasePacket.SerializeTo(b)
3955 if err != nil {
3956 return err
3957 }
3958 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3959}
3960
3961/////////////////////////////////////////////////////////////////////////////
3962//
3963type UnsupportedMessageTypeResponse struct {
3964 MeBasePacket
3965 Result me.Results
3966}
3967
3968// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
3969func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3970 return errors.New("you should never really decode this")
3971}
3972
3973// SerializeTo provides serialization of an Unsupported Message Type Response
3974func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3975 // Basic (common) OMCI Header is 8 octets, 10
3976 err := omci.MeBasePacket.SerializeTo(b)
3977 if err != nil {
3978 return err
3979 }
3980 bytes, err := b.AppendBytes(1)
3981 if err != nil {
3982 return err
3983 }
3984 bytes[0] = byte(omci.Result)
3985 return nil
3986}