blob: f0ff44766d53422c46ac3c03a8f88371397bac80 [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
Matteo Scandolof9d43412021-01-12 11:11:34 -08003 * Copyright 2020-present Open Networking Foundation
4
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07005 * 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
Matteo Scandolof9d43412021-01-12 11:11:34 -08008
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07009 * http://www.apache.org/licenses/LICENSE-2.0
Matteo Scandolof9d43412021-01-12 11:11:34 -080010
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070011 * 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.
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070016 */
Matteo Scandolof9d43412021-01-12 11:11:34 -080017
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070018package omci
19
20import (
21 "encoding/binary"
22 "errors"
23 "fmt"
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070024 "github.com/google/gopacket"
Matteo Scandolof9d43412021-01-12 11:11:34 -080025 me "github.com/opencord/omci-lib-go/generated"
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070026)
27
28// MessageType is the OMCI Message Type or'ed with the AR/AK flags as appropriate.
29type MessageType byte
30
31const (
Girish Gowdrae2683102021-03-05 08:24:26 -080032 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)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070073 // Autonomous ONU messages
74 AlarmNotificationType = MessageType(byte(me.AlarmNotification))
75 AttributeValueChangeType = MessageType(byte(me.AttributeValueChange))
76 TestResultType = MessageType(byte(me.TestResult))
77)
78
79func (mt MessageType) String() string {
80 switch mt {
81 default:
82 return "Unknown"
83
84 case CreateRequestType:
85 return "Create Request"
86 case CreateResponseType:
87 return "Create Response"
88 case DeleteRequestType:
89 return "Delete Request"
90 case DeleteResponseType:
91 return "Delete Response"
92 case SetRequestType:
93 return "Set Request"
94 case SetResponseType:
95 return "Set Response"
96 case GetRequestType:
97 return "Get Request"
98 case GetResponseType:
99 return "Get Response"
100 case GetAllAlarmsRequestType:
101 return "Get All Alarms Request"
102 case GetAllAlarmsResponseType:
103 return "Get All Alarms Response"
104 case GetAllAlarmsNextRequestType:
105 return "Get All Alarms Next Request"
106 case GetAllAlarmsNextResponseType:
107 return "Get All Alarms Next Response"
108 case MibUploadRequestType:
109 return "MIB Upload Request"
110 case MibUploadResponseType:
111 return "MIB Upload Response"
112 case MibUploadNextRequestType:
113 return "MIB Upload Next Request"
114 case MibUploadNextResponseType:
115 return "MIB Upload Next Response"
116 case MibResetRequestType:
117 return "MIB Reset Request"
118 case MibResetResponseType:
119 return "MIB Reset Response"
120 case TestRequestType:
121 return "Test Request"
122 case TestResponseType:
123 return "Test Response"
124 case StartSoftwareDownloadRequestType:
125 return "Start Software Download Request"
126 case StartSoftwareDownloadResponseType:
127 return "Start Software Download Response"
128 case DownloadSectionRequestType:
129 return "Download Section Request"
130 case DownloadSectionResponseType:
131 return "Download Section Response"
132 case EndSoftwareDownloadRequestType:
133 return "End Software Download Request"
134 case EndSoftwareDownloadResponseType:
135 return "End Software Download Response"
136 case ActivateSoftwareRequestType:
137 return "Activate Software Request"
138 case ActivateSoftwareResponseType:
139 return "Activate Software Response"
140 case CommitSoftwareRequestType:
141 return "Commit Software Request"
142 case CommitSoftwareResponseType:
143 return "Commit Software Response"
144 case SynchronizeTimeRequestType:
145 return "Synchronize Time Request"
146 case SynchronizeTimeResponseType:
147 return "Synchronize Time Response"
148 case RebootRequestType:
149 return "Reboot Request"
150 case RebootResponseType:
151 return "Reboot Response"
152 case GetNextRequestType:
153 return "Get Next Request"
154 case GetNextResponseType:
155 return "Get Next Response"
156 case GetCurrentDataRequestType:
157 return "Get Current Data Request"
158 case GetCurrentDataResponseType:
159 return "Get Current Data Response"
160 case SetTableRequestType:
161 return "Set Table Request"
162 case SetTableResponseType:
163 return "Set Table Response"
164 case AlarmNotificationType:
165 return "Alarm Notification"
166 case AttributeValueChangeType:
167 return "Attribute Value Change"
168 case TestResultType:
169 return "Test Result"
170 }
171}
172
173/////////////////////////////////////////////////////////////////////////////
174// CreateRequest
175type CreateRequest struct {
176 MeBasePacket
177 Attributes me.AttributeValueMap
178}
179
180func (omci *CreateRequest) String() string {
181 return fmt.Sprintf("%v, attributes: %v", omci.MeBasePacket.String(), omci.Attributes)
182}
183
Matteo Scandolof9d43412021-01-12 11:11:34 -0800184// DecodeFromBytes decodes the given bytes of a Create Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700185func (omci *CreateRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
186 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -0800187 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700188 if err != nil {
189 return err
190 }
191 // Create attribute mask for all set-by-create entries
Matteo Scandolof9d43412021-01-12 11:11:34 -0800192 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700193 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800194 if omciErr.StatusCode() != me.Success {
195 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700196 }
197 // ME needs to support Create
198 if !me.SupportsMsgType(meDefinition, me.Create) {
199 return me.NewProcessingError("managed entity does not support Create Message-Type")
200 }
201 var sbcMask uint16
Matteo Scandolof9d43412021-01-12 11:11:34 -0800202 for index, attr := range meDefinition.GetAttributeDefinitions() {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700203 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
204 if index == 0 {
205 continue // Skip Entity ID
206 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800207 sbcMask |= attr.Mask
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700208 }
209 }
210 // Attribute decode
211 omci.Attributes, err = meDefinition.DecodeAttributes(sbcMask, data[4:], p, byte(CreateRequestType))
212 if err != nil {
213 return err
214 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800215 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700216 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
217 return nil
218 }
219 panic("All Managed Entities have an EntityID attribute")
220}
221
222func decodeCreateRequest(data []byte, p gopacket.PacketBuilder) error {
223 omci := &CreateRequest{}
224 omci.MsgLayerType = LayerTypeCreateRequest
225 return decodingLayerDecoder(omci, data, p)
226}
227
Matteo Scandolof9d43412021-01-12 11:11:34 -0800228// SerializeTo provides serialization of an Create Request Message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700229func (omci *CreateRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
230 // Basic (common) OMCI Header is 8 octets, 10
231 err := omci.MeBasePacket.SerializeTo(b)
232 if err != nil {
233 return err
234 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800235 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700236 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800237 if omciErr.StatusCode() != me.Success {
238 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700239 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800240 // Create attribute mask of SetByCreate attributes that should be present in the provided
241 // attributes.
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700242 var sbcMask uint16
Matteo Scandolof9d43412021-01-12 11:11:34 -0800243 for index, attr := range meDefinition.GetAttributeDefinitions() {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700244 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
245 if index == 0 {
246 continue // Skip Entity ID
247 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800248 sbcMask |= attr.Mask
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700249 }
250 }
251 // Attribute serialization
252 // TODO: Only Baseline supported at this time
253 bytesAvailable := MaxBaselineLength - 8 - 8
Matteo Scandolof9d43412021-01-12 11:11:34 -0800254 err, _ = meDefinition.SerializeAttributes(omci.Attributes, sbcMask, b, byte(CreateRequestType), bytesAvailable, false)
255 return err
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700256}
257
258/////////////////////////////////////////////////////////////////////////////
259// CreateResponse
260type CreateResponse struct {
261 MeBasePacket
262 Result me.Results
263 AttributeExecutionMask uint16 // Used when Result == ParameterError
264}
265
266func (omci *CreateResponse) String() string {
267 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x",
268 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeExecutionMask)
269}
270
Matteo Scandolof9d43412021-01-12 11:11:34 -0800271// DecodeFromBytes decodes the given bytes of a Create Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700272func (omci *CreateResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
273 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800274 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700275 if err != nil {
276 return err
277 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800278 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700279 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800280 if omciErr.StatusCode() != me.Success {
281 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700282 }
283 // ME needs to support Create
284 if !me.SupportsMsgType(entity, me.Create) {
285 return me.NewProcessingError("managed entity does not support the Create Message-Type")
286 }
287 omci.Result = me.Results(data[4])
288 if omci.Result == me.ParameterError {
289 omci.AttributeExecutionMask = binary.BigEndian.Uint16(data[5:])
290 // TODO: validation that attributes set in mask are SetByCreate would be good here
291 }
292 return nil
293}
294
295func decodeCreateResponse(data []byte, p gopacket.PacketBuilder) error {
296 omci := &CreateResponse{}
297 omci.MsgLayerType = LayerTypeCreateResponse
298 return decodingLayerDecoder(omci, data, p)
299}
300
Matteo Scandolof9d43412021-01-12 11:11:34 -0800301// SerializeTo provides serialization of an Create Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700302func (omci *CreateResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
303 // Basic (common) OMCI Header is 8 octets, 10
304 err := omci.MeBasePacket.SerializeTo(b)
305 if err != nil {
306 return err
307 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800308 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700309 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800310 if omciErr.StatusCode() != me.Success {
311 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700312 }
313 // ME needs to support Create
314 if !me.SupportsMsgType(entity, me.Create) {
315 return me.NewProcessingError("managed entity does not support the Create Message-Type")
316 }
317 bytes, err := b.AppendBytes(3)
318 if err != nil {
319 return err
320 }
321 bytes[0] = byte(omci.Result)
322 if omci.Result == me.ParameterError {
323 // TODO: validation that attributes set in mask are SetByCreate would be good here
324 binary.BigEndian.PutUint16(bytes[1:], omci.AttributeExecutionMask)
325 } else {
326 binary.BigEndian.PutUint16(bytes[1:], 0)
327 }
328 return nil
329}
330
331/////////////////////////////////////////////////////////////////////////////
332// DeleteRequest
333type DeleteRequest struct {
334 MeBasePacket
335}
336
337func (omci *DeleteRequest) String() string {
338 return fmt.Sprintf("%v", omci.MeBasePacket.String())
339}
340
Matteo Scandolof9d43412021-01-12 11:11:34 -0800341// DecodeFromBytes decodes the given bytes of a Delete Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700342func (omci *DeleteRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
343 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -0800344 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700345 if err != nil {
346 return err
347 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800348 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700349 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800350 if omciErr.StatusCode() != me.Success {
351 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700352 }
353 // ME needs to support Delete
354 if !me.SupportsMsgType(entity, me.Delete) {
355 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
356 }
357 return nil
358}
359
360func decodeDeleteRequest(data []byte, p gopacket.PacketBuilder) error {
361 omci := &DeleteRequest{}
362 omci.MsgLayerType = LayerTypeDeleteRequest
363 return decodingLayerDecoder(omci, data, p)
364}
365
Matteo Scandolof9d43412021-01-12 11:11:34 -0800366// SerializeTo provides serialization of an Delete Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700367func (omci *DeleteRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
368 // Basic (common) OMCI Header is 8 octets, 10
369 err := omci.MeBasePacket.SerializeTo(b)
370 if err != nil {
371 return err
372 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800373 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700374 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800375 if omciErr.StatusCode() != me.Success {
376 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700377 }
378 // ME needs to support Delete
379 if !me.SupportsMsgType(entity, me.Delete) {
380 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
381 }
382 return nil
383}
384
385/////////////////////////////////////////////////////////////////////////////
386// DeleteResponse
387type DeleteResponse struct {
388 MeBasePacket
389 Result me.Results
390}
391
392func (omci *DeleteResponse) String() string {
393 return fmt.Sprintf("%v, Result: %d (%v)",
394 omci.MeBasePacket.String(), omci.Result, omci.Result)
395}
396
Matteo Scandolof9d43412021-01-12 11:11:34 -0800397// DecodeFromBytes decodes the given bytes of a Delete Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700398func (omci *DeleteResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
399 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800400 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700401 if err != nil {
402 return err
403 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800404 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700405 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800406 if omciErr.StatusCode() != me.Success {
407 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700408 }
409 // ME needs to support Delete
410 if !me.SupportsMsgType(entity, me.Delete) {
411 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
412 }
413 omci.Result = me.Results(data[4])
414 return nil
415}
416
417func decodeDeleteResponse(data []byte, p gopacket.PacketBuilder) error {
418 omci := &DeleteResponse{}
419 omci.MsgLayerType = LayerTypeDeleteResponse
420 return decodingLayerDecoder(omci, data, p)
421}
422
Matteo Scandolof9d43412021-01-12 11:11:34 -0800423// SerializeTo provides serialization of an Delete Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700424func (omci *DeleteResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
425 // Basic (common) OMCI Header is 8 octets, 10
426 err := omci.MeBasePacket.SerializeTo(b)
427 if err != nil {
428 return err
429 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800430 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700431 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800432 if omciErr.StatusCode() != me.Success {
433 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700434 }
435 // ME needs to support Delete
436 if !me.SupportsMsgType(entity, me.Delete) {
437 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
438 }
439 bytes, err := b.AppendBytes(1)
440 if err != nil {
441 return err
442 }
443 bytes[0] = byte(omci.Result)
444 return nil
445}
446
447/////////////////////////////////////////////////////////////////////////////
448// SetRequest
449type SetRequest struct {
450 MeBasePacket
451 AttributeMask uint16
452 Attributes me.AttributeValueMap
453}
454
455func (omci *SetRequest) String() string {
456 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
457 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
458}
459
Matteo Scandolof9d43412021-01-12 11:11:34 -0800460// DecodeFromBytes decodes the given bytes of a Set Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700461func (omci *SetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
462 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800463 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700464 if err != nil {
465 return err
466 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800467 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700468 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800469 if omciErr.StatusCode() != me.Success {
470 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700471 }
472 // ME needs to support Set
473 if !me.SupportsMsgType(meDefinition, me.Set) {
474 return me.NewProcessingError("managed entity does not support Set Message-Type")
475 }
476 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
477
478 // Attribute decode
479 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(SetRequestType))
480 if err != nil {
481 return err
482 }
483 // Validate all attributes support write
484 for attrName := range omci.Attributes {
485 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
486 if err != nil {
487 return err
488 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800489 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700490 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
491 return me.NewProcessingError(msg)
492 }
493 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800494 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700495 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
496 return nil
497 }
498 panic("All Managed Entities have an EntityID attribute")
499}
500
501func decodeSetRequest(data []byte, p gopacket.PacketBuilder) error {
502 omci := &SetRequest{}
503 omci.MsgLayerType = LayerTypeSetRequest
504 return decodingLayerDecoder(omci, data, p)
505}
506
Matteo Scandolof9d43412021-01-12 11:11:34 -0800507// SerializeTo provides serialization of an Set Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700508func (omci *SetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
509 // Basic (common) OMCI Header is 8 octets, 10
510 err := omci.MeBasePacket.SerializeTo(b)
511 if err != nil {
512 return err
513 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800514 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700515 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800516 if omciErr.StatusCode() != me.Success {
517 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700518 }
519 // ME needs to support Set
520 if !me.SupportsMsgType(meDefinition, me.Set) {
521 return me.NewProcessingError("managed entity does not support Set Message-Type")
522 }
523 // Validate all attributes support write
524 for attrName := range omci.Attributes {
525 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
526 if err != nil {
527 return err
528 }
529 // Do not test for write of Entity ID in the attribute list
Matteo Scandolof9d43412021-01-12 11:11:34 -0800530 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Write) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700531 // TODO: Check ITU spec to see if this should be listed as a failed
532 // attribute and not a processing error.
533 msg := fmt.Sprintf("attribute '%v' does not support write access", attrName)
534 return me.NewProcessingError(msg)
535 }
536 }
537 bytes, err := b.AppendBytes(2)
538 if err != nil {
539 return err
540 }
541 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
542
543 // Attribute serialization
544 // TODO: Only Baseline supported at this time
545 bytesAvailable := MaxBaselineLength - 10 - 8
546
Matteo Scandolof9d43412021-01-12 11:11:34 -0800547 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
548 byte(SetRequestType), bytesAvailable, false)
549 return err
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700550}
551
552/////////////////////////////////////////////////////////////////////////////
553// SetResponse
554type SetResponse struct {
555 MeBasePacket
556 Result me.Results
557 UnsupportedAttributeMask uint16
558 FailedAttributeMask uint16
559}
560
561func (omci *SetResponse) String() string {
562 return fmt.Sprintf("%v, Result: %d (%v), Unsupported Mask: %#x, Failed Mask: %#x",
563 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.UnsupportedAttributeMask,
564 omci.FailedAttributeMask)
565}
566
Matteo Scandolof9d43412021-01-12 11:11:34 -0800567// DecodeFromBytes decodes the given bytes of a Set Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700568func (omci *SetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
569 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800570 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700571 if err != nil {
572 return err
573 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800574 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700575 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800576 if omciErr.StatusCode() != me.Success {
577 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700578 }
579 // ME needs to support Set
580 if !me.SupportsMsgType(entity, me.Set) {
581 return me.NewProcessingError("managed entity does not support the Delete Message-Type")
582 }
583 omci.Result = me.Results(data[4])
584
585 if omci.Result == me.AttributeFailure {
586 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[5:7])
587 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[7:9])
588 }
589 return nil
590}
591
592func decodeSetResponse(data []byte, p gopacket.PacketBuilder) error {
593 omci := &SetResponse{}
594 omci.MsgLayerType = LayerTypeSetResponse
595 return decodingLayerDecoder(omci, data, p)
596}
597
Matteo Scandolof9d43412021-01-12 11:11:34 -0800598// SerializeTo provides serialization of an Set Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700599func (omci *SetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
600 // Basic (common) OMCI Header is 8 octets, 10
601 err := omci.MeBasePacket.SerializeTo(b)
602 if err != nil {
603 return err
604 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800605 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700606 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800607 if omciErr.StatusCode() != me.Success {
608 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700609 }
610 // ME needs to support Set
611 if !me.SupportsMsgType(entity, me.Set) {
612 return me.NewProcessingError("managed entity does not support the Set Message-Type")
613 }
614 bytes, err := b.AppendBytes(5)
615 if err != nil {
616 return err
617 }
618 bytes[0] = byte(omci.Result)
619 binary.BigEndian.PutUint16(bytes[1:3], omci.UnsupportedAttributeMask)
620 binary.BigEndian.PutUint16(bytes[3:5], omci.FailedAttributeMask)
621 return nil
622}
623
624/////////////////////////////////////////////////////////////////////////////
625// GetRequest
626type GetRequest struct {
627 MeBasePacket
628 AttributeMask uint16
629}
630
631func (omci *GetRequest) String() string {
632 return fmt.Sprintf("%v, Mask: %#x",
633 omci.MeBasePacket.String(), omci.AttributeMask)
634}
Matteo Scandolof9d43412021-01-12 11:11:34 -0800635
636// DecodeFromBytes decodes the given bytes of a Get Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700637func (omci *GetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
638 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800639 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700640 if err != nil {
641 return err
642 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800643 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700644 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800645 if omciErr.StatusCode() != me.Success {
646 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700647 }
648 // ME needs to support Get
649 if !me.SupportsMsgType(meDefinition, me.Get) {
650 return me.NewProcessingError("managed entity does not support Get Message-Type")
651 }
652 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
653 return nil
654}
655
656func decodeGetRequest(data []byte, p gopacket.PacketBuilder) error {
657 omci := &GetRequest{}
658 omci.MsgLayerType = LayerTypeGetRequest
659 return decodingLayerDecoder(omci, data, p)
660}
661
Matteo Scandolof9d43412021-01-12 11:11:34 -0800662// SerializeTo provides serialization of an Get Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700663func (omci *GetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
664 // Basic (common) OMCI Header is 8 octets, 10
665 err := omci.MeBasePacket.SerializeTo(b)
666 if err != nil {
667 return err
668 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800669 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700670 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800671 if omciErr.StatusCode() != me.Success {
672 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700673 }
674 // ME needs to support Set
675 if !me.SupportsMsgType(meDefinition, me.Get) {
676 return me.NewProcessingError("managed entity does not support Get Message-Type")
677 }
678 bytes, err := b.AppendBytes(2)
679 if err != nil {
680 return err
681 }
682 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
683 return nil
684}
685
686/////////////////////////////////////////////////////////////////////////////
687// GetResponse
688type GetResponse struct {
689 MeBasePacket
690 Result me.Results
691 AttributeMask uint16
692 Attributes me.AttributeValueMap
693 UnsupportedAttributeMask uint16
694 FailedAttributeMask uint16
695}
696
697func (omci *GetResponse) String() string {
698 return fmt.Sprintf("%v, Result: %d (%v), Mask: %#x, Unsupported: %#x, Failed: %#x, attributes: %v",
699 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask,
700 omci.UnsupportedAttributeMask, omci.FailedAttributeMask, omci.Attributes)
701}
702
Matteo Scandolof9d43412021-01-12 11:11:34 -0800703// DecodeFromBytes decodes the given bytes of a Get Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700704func (omci *GetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
705 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800706 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700707 if err != nil {
708 return err
709 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800710 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700711 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800712 if omciErr.StatusCode() != me.Success {
713 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700714 }
715 // ME needs to support Get
716 if !me.SupportsMsgType(meDefinition, me.Get) {
717 return me.NewProcessingError("managed entity does not support Get Message-Type")
718 }
719 omci.Result = me.Results(data[4])
720 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
721
722 // Attribute decode. Note that the ITU-T G.988 specification states that the
723 // Unsupported and Failed attribute masks are always present
724 // but only valid if the status code== 9. However some XGS
725 // ONUs (T&W and Alpha, perhaps more) will use these last 4
726 // octets for data if the status code == 0. So accommodate
727 // this behaviour in favor of greater interoperability.
728 lastOctet := 36
Matteo Scandolof9d43412021-01-12 11:11:34 -0800729
730 switch omci.Result {
731 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
732 return nil // Done (do not try and decode attributes)
733
734 case me.AttributeFailure:
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700735 lastOctet = 32
736 }
737 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:lastOctet], p, byte(GetResponseType))
738 if err != nil {
739 return err
740 }
741 // If Attribute failed or Unknown, decode optional attribute mask
742 if omci.Result == me.AttributeFailure {
743 omci.UnsupportedAttributeMask = binary.BigEndian.Uint16(data[32:34])
744 omci.FailedAttributeMask = binary.BigEndian.Uint16(data[34:36])
745 }
746 // Validate all attributes support read
747 for attrName := range omci.Attributes {
748 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
749 if err != nil {
750 return err
751 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800752 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700753 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
754 return me.NewProcessingError(msg)
755 }
756 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800757 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700758 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
759 return nil
760 }
761 panic("All Managed Entities have an EntityID attribute")
762}
763
764func decodeGetResponse(data []byte, p gopacket.PacketBuilder) error {
765 omci := &GetResponse{}
766 omci.MsgLayerType = LayerTypeGetResponse
767 return decodingLayerDecoder(omci, data, p)
768}
769
Matteo Scandolof9d43412021-01-12 11:11:34 -0800770// SerializeTo provides serialization of an Get Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700771func (omci *GetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
772 // Basic (common) OMCI Header is 8 octets, 10
Matteo Scandolof9d43412021-01-12 11:11:34 -0800773 if err := omci.MeBasePacket.SerializeTo(b); err != nil {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700774 return err
775 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800776 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700777 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800778
779 if omciErr.StatusCode() != me.Success {
780 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700781 }
782 // ME needs to support Get
783 if !me.SupportsMsgType(meDefinition, me.Get) {
784 return me.NewProcessingError("managed entity does not support the Get Message-Type")
785 }
786 bytes, err := b.AppendBytes(3)
787 if err != nil {
788 return err
789 }
790 bytes[0] = byte(omci.Result)
791 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
792
793 // Validate all attributes support read
794 for attrName := range omci.Attributes {
795 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
796 if err != nil {
797 return err
798 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800799 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700800 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
801 return me.NewProcessingError(msg)
802 }
803 }
804 // Attribute serialization
805 switch omci.Result {
806 default:
807 break
808
809 case me.Success, me.AttributeFailure:
810 // TODO: Baseline only supported at this time)
Matteo Scandolof9d43412021-01-12 11:11:34 -0800811 available := MaxBaselineLength - 11 - 4 - 8
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700812
Matteo Scandolof9d43412021-01-12 11:11:34 -0800813 // Serialize to temporary buffer if we may need to reset values due to
814 // recoverable truncation errors
815 origBuffer := b
816 b := gopacket.NewSerializeBuffer()
817
818 err, failedMask := meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b, byte(GetResponseType),
819 available, opts.FixLengths)
820
821 if err == nil && failedMask != 0 && opts.FixLengths {
822 // Not all attributes would fit
823 omci.FailedAttributeMask |= failedMask
824 omci.AttributeMask &= ^failedMask
825 omci.Result = me.AttributeFailure
826
827 // Adjust already recorded values
828 bytes[0] = byte(omci.Result)
829 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
830 } else if err != nil {
831 return err
832 }
833 // Copy over attributes to the original serialization buffer
834 newSpace, err := origBuffer.AppendBytes(len(b.Bytes()))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700835 if err != nil {
836 return err
837 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800838 copy(newSpace, b.Bytes())
839 b = origBuffer
840
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700841 // Calculate space left. Max - msgType header - OMCI trailer - spacedUsedSoFar
842 bytesLeft := MaxBaselineLength - 4 - 8 - len(b.Bytes())
843
844 remainingBytes, err := b.AppendBytes(bytesLeft + 4)
845 if err != nil {
846 return me.NewMessageTruncatedError(err.Error())
847 }
848 copy(remainingBytes, lotsOfZeros[:])
Matteo Scandolof9d43412021-01-12 11:11:34 -0800849
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700850 if omci.Result == me.AttributeFailure {
851 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-4:bytesLeft-2], omci.UnsupportedAttributeMask)
852 binary.BigEndian.PutUint16(remainingBytes[bytesLeft-2:bytesLeft], omci.FailedAttributeMask)
853 }
854 }
855 return nil
856}
857
858/////////////////////////////////////////////////////////////////////////////
859// GetAllAlarms
860type GetAllAlarmsRequest struct {
861 MeBasePacket
862 AlarmRetrievalMode byte
863}
864
865func (omci *GetAllAlarmsRequest) String() string {
866 return fmt.Sprintf("%v, Retrieval Mode: %v",
867 omci.MeBasePacket.String(), omci.AlarmRetrievalMode)
868}
869
Matteo Scandolof9d43412021-01-12 11:11:34 -0800870// DecodeFromBytes decodes the given bytes of a Get All Alarms Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700871func (omci *GetAllAlarmsRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
872 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800873 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700874 if err != nil {
875 return err
876 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800877 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700878 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800879 if omciErr.StatusCode() != me.Success {
880 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700881 }
882 // ME needs to support Get All Alarms
883 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
884 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
885 }
886 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -0800887 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700888 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms request: %v",
889 omci.EntityClass)
890 return me.NewProcessingError(msg)
891 }
892 if omci.EntityInstance != 0 {
893 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms request: %v",
894 omci.EntityInstance)
895 return me.NewUnknownInstanceError(msg)
896 }
897 omci.AlarmRetrievalMode = data[4]
898 if omci.AlarmRetrievalMode > 1 {
899 msg := fmt.Sprintf("invalid Alarm Retrieval Mode for Get All Alarms request: %v, must be 0..1",
900 omci.AlarmRetrievalMode)
901 return errors.New(msg)
902 }
903 return nil
904}
905
906func decodeGetAllAlarmsRequest(data []byte, p gopacket.PacketBuilder) error {
907 omci := &GetAllAlarmsRequest{}
908 omci.MsgLayerType = LayerTypeGetAllAlarmsRequest
909 return decodingLayerDecoder(omci, data, p)
910}
911
Matteo Scandolof9d43412021-01-12 11:11:34 -0800912// SerializeTo provides serialization of an Get All Alarms Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700913func (omci *GetAllAlarmsRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
914 // Basic (common) OMCI Header is 8 octets, 10
915 err := omci.MeBasePacket.SerializeTo(b)
916 if err != nil {
917 return err
918 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800919 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700920 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800921 if omciErr.StatusCode() != me.Success {
922 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700923 }
924 // ME needs to support Get All Alarms
925 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
926 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
927 }
928 bytes, err := b.AppendBytes(1)
929 if err != nil {
930 return err
931 }
932 bytes[0] = omci.AlarmRetrievalMode
933 return nil
934}
935
936/////////////////////////////////////////////////////////////////////////////
937// GetAllAlarms
938type GetAllAlarmsResponse struct {
939 MeBasePacket
940 NumberOfCommands uint16
941}
942
943func (omci *GetAllAlarmsResponse) String() string {
944 return fmt.Sprintf("%v, NumberOfCommands: %d",
945 omci.MeBasePacket.String(), omci.NumberOfCommands)
946}
947
Matteo Scandolof9d43412021-01-12 11:11:34 -0800948// DecodeFromBytes decodes the given bytes of a Get All Alarms Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700949func (omci *GetAllAlarmsResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
950 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800951 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700952 if err != nil {
953 return err
954 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800955 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700956 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800957 if omciErr.StatusCode() != me.Success {
958 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700959 }
960 // ME needs to support Get All Alarms
961 if !me.SupportsMsgType(meDefinition, me.GetAllAlarms) {
962 return me.NewProcessingError("managed entity does not support Get All Alarms Message-Type")
963 }
964 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -0800965 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700966 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms response: %v",
967 omci.EntityClass)
968 return me.NewProcessingError(msg)
969 }
970 if omci.EntityInstance != 0 {
971 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms response: %v",
972 omci.EntityInstance)
973 return me.NewUnknownInstanceError(msg)
974 }
975 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
976 return nil
977}
978
979func decodeGetAllAlarmsResponse(data []byte, p gopacket.PacketBuilder) error {
980 omci := &GetAllAlarmsResponse{}
981 omci.MsgLayerType = LayerTypeGetAllAlarmsResponse
982 return decodingLayerDecoder(omci, data, p)
983}
984
Matteo Scandolof9d43412021-01-12 11:11:34 -0800985// SerializeTo provides serialization of an Get All Alarms Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700986func (omci *GetAllAlarmsResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
987 // Basic (common) OMCI Header is 8 octets, 10
988 err := omci.MeBasePacket.SerializeTo(b)
989 if err != nil {
990 return err
991 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800992 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700993 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -0800994 if omciErr.StatusCode() != me.Success {
995 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700996 }
997 // ME needs to support Get All Alarms
998 if !me.SupportsMsgType(entity, me.GetAllAlarms) {
999 return me.NewProcessingError("managed entity does not support the Get All Alarms Message-Type")
1000 }
1001 bytes, err := b.AppendBytes(2)
1002 if err != nil {
1003 return err
1004 }
1005 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1006 return nil
1007}
1008
1009/////////////////////////////////////////////////////////////////////////////
1010// GetAllAlarms
1011type GetAllAlarmsNextRequest struct {
1012 MeBasePacket
1013 CommandSequenceNumber uint16
1014}
1015
1016func (omci *GetAllAlarmsNextRequest) String() string {
1017 return fmt.Sprintf("%v, Sequence Number: %d",
1018 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1019}
1020
Matteo Scandolof9d43412021-01-12 11:11:34 -08001021// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001022func (omci *GetAllAlarmsNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1023 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001024 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001025 if err != nil {
1026 return err
1027 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001028 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001029 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001030 if omciErr.StatusCode() != me.Success {
1031 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001032 }
1033 // ME needs to support Get All Alarms
1034 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1035 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1036 }
1037 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001038 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001039 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next request: %v",
1040 omci.EntityClass)
1041 return me.NewProcessingError(msg)
1042 }
1043 if omci.EntityInstance != 0 {
1044 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next request: %v",
1045 omci.EntityInstance)
1046 return me.NewUnknownInstanceError(msg)
1047 }
1048 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1049 return nil
1050}
1051
1052func decodeGetAllAlarmsNextRequest(data []byte, p gopacket.PacketBuilder) error {
1053 omci := &GetAllAlarmsNextRequest{}
1054 omci.MsgLayerType = LayerTypeGetAllAlarmsNextRequest
1055 return decodingLayerDecoder(omci, data, p)
1056}
1057
Matteo Scandolof9d43412021-01-12 11:11:34 -08001058// SerializeTo provides serialization of an Get All Alarms Next Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001059func (omci *GetAllAlarmsNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1060 // Basic (common) OMCI Header is 8 octets, 10
1061 err := omci.MeBasePacket.SerializeTo(b)
1062 if err != nil {
1063 return err
1064 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001065 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001066 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001067 if omciErr.StatusCode() != me.Success {
1068 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001069 }
1070 // ME needs to support Get All Alarms Next
1071 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1072 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1073 }
1074 bytes, err := b.AppendBytes(2)
1075 if err != nil {
1076 return err
1077 }
1078 binary.BigEndian.PutUint16(bytes, omci.CommandSequenceNumber)
1079 return nil
1080}
1081
1082/////////////////////////////////////////////////////////////////////////////
1083// GetAllAlarms
1084type GetAllAlarmsNextResponse struct {
1085 MeBasePacket
1086 AlarmEntityClass me.ClassID
1087 AlarmEntityInstance uint16
1088 AlarmBitMap [28]byte // 224 bits
1089}
1090
1091func (omci *GetAllAlarmsNextResponse) String() string {
1092 return fmt.Sprintf("%v, CID: %v, EID: (%d/%#x), Bitmap: %v",
1093 omci.MeBasePacket.String(), omci.AlarmEntityClass, omci.AlarmEntityInstance,
1094 omci.AlarmEntityInstance, omci.AlarmBitMap)
1095}
1096
Matteo Scandolof9d43412021-01-12 11:11:34 -08001097// DecodeFromBytes decodes the given bytes of a Get All Alarms Next Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001098func (omci *GetAllAlarmsNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1099 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001100 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4+28)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001101 if err != nil {
1102 return err
1103 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001104 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001105 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001106 if omciErr.StatusCode() != me.Success {
1107 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001108 }
1109 // ME needs to support Get All Alarms Next
1110 if !me.SupportsMsgType(meDefinition, me.GetAllAlarmsNext) {
1111 return me.NewProcessingError("managed entity does not support Get All Alarms Next Message-Type")
1112 }
1113 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001114 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001115 msg := fmt.Sprintf("invalid Entity Class for Get All Alarms Next response: %v",
1116 omci.EntityClass)
1117 return me.NewProcessingError(msg)
1118 }
1119 if omci.EntityInstance != 0 {
1120 msg := fmt.Sprintf("invalid Entity Instance for Get All Alarms Next response: %v",
1121 omci.EntityInstance)
1122 return me.NewUnknownInstanceError(msg)
1123 }
1124 omci.AlarmEntityClass = me.ClassID(binary.BigEndian.Uint16(data[4:6]))
1125 omci.AlarmEntityInstance = binary.BigEndian.Uint16(data[6:8])
1126
1127 copy(omci.AlarmBitMap[:], data[8:36])
1128 return nil
1129}
1130
1131func decodeGetAllAlarmsNextResponse(data []byte, p gopacket.PacketBuilder) error {
1132 omci := &GetAllAlarmsNextResponse{}
1133 omci.MsgLayerType = LayerTypeGetAllAlarmsNextResponse
1134 return decodingLayerDecoder(omci, data, p)
1135}
1136
Matteo Scandolof9d43412021-01-12 11:11:34 -08001137// SerializeTo provides serialization of an Get All Alarms Next Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001138func (omci *GetAllAlarmsNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1139 // Basic (common) OMCI Header is 8 octets, 10
1140 err := omci.MeBasePacket.SerializeTo(b)
1141 if err != nil {
1142 return err
1143 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001144 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001145 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001146 if omciErr.StatusCode() != me.Success {
1147 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001148 }
1149 // ME needs to support Get All Alarms Next
1150 if !me.SupportsMsgType(entity, me.GetAllAlarmsNext) {
1151 return me.NewProcessingError("managed entity does not support the Get All Alarms Next Message-Type")
1152 }
1153 bytes, err := b.AppendBytes(2 + 2 + 28)
1154 if err != nil {
1155 return err
1156 }
1157 binary.BigEndian.PutUint16(bytes[0:], uint16(omci.AlarmEntityClass))
1158 binary.BigEndian.PutUint16(bytes[2:], omci.AlarmEntityInstance)
1159 copy(bytes[4:], omci.AlarmBitMap[:])
1160 return nil
1161}
1162
1163/////////////////////////////////////////////////////////////////////////////
1164// MibUploadRequest
1165type MibUploadRequest struct {
1166 MeBasePacket
1167}
1168
1169func (omci *MibUploadRequest) String() string {
1170 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1171}
1172
Matteo Scandolof9d43412021-01-12 11:11:34 -08001173// DecodeFromBytes decodes the given bytes of a MIB Upload Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001174func (omci *MibUploadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1175 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -08001176 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001177 if err != nil {
1178 return err
1179 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001180 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001181 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001182 if omciErr.StatusCode() != me.Success {
1183 return omciErr.GetError()
1184 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001185 // ME needs to support MIB Upload
1186 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1187 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1188 }
1189 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001190 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001191 msg := fmt.Sprintf("invalid Entity Class for MIB Upload request: %v",
1192 omci.EntityClass)
1193 return me.NewProcessingError(msg)
1194 }
1195 if omci.EntityInstance != 0 {
1196 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload request: %v",
1197 omci.EntityInstance)
1198 return me.NewUnknownInstanceError(msg)
1199 }
1200 return nil
1201}
1202
1203func decodeMibUploadRequest(data []byte, p gopacket.PacketBuilder) error {
1204 omci := &MibUploadRequest{}
1205 omci.MsgLayerType = LayerTypeMibUploadRequest
1206 return decodingLayerDecoder(omci, data, p)
1207}
1208
Matteo Scandolof9d43412021-01-12 11:11:34 -08001209// SerializeTo provides serialization of an MIB Upload Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001210func (omci *MibUploadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1211 // Basic (common) OMCI Header is 8 octets, 10
1212 err := omci.MeBasePacket.SerializeTo(b)
1213 if err != nil {
1214 return err
1215 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001216 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001217 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001218 if omciErr.StatusCode() != me.Success {
1219 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001220 }
1221 // ME needs to support Get
1222 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1223 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1224 }
1225 return nil
1226}
1227
1228/////////////////////////////////////////////////////////////////////////////
1229// MibUploadResponse
1230type MibUploadResponse struct {
1231 MeBasePacket
1232 NumberOfCommands uint16
1233}
1234
1235func (omci *MibUploadResponse) String() string {
1236 return fmt.Sprintf("%v, NumberOfCommands: %#v",
1237 omci.MeBasePacket.String(), omci.NumberOfCommands)
1238}
1239
Matteo Scandolof9d43412021-01-12 11:11:34 -08001240// DecodeFromBytes decodes the given bytes of a MIB Upload Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001241func (omci *MibUploadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1242 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001243 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001244 if err != nil {
1245 return err
1246 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001247 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001248 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001249 if omciErr.StatusCode() != me.Success {
1250 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001251 }
1252 // ME needs to support MIB Upload
1253 if !me.SupportsMsgType(meDefinition, me.MibUpload) {
1254 return me.NewProcessingError("managed entity does not support MIB Upload Message-Type")
1255 }
1256 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001257 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001258 msg := fmt.Sprintf("invalid Entity Class for MIB Upload response: %v",
1259 omci.EntityClass)
1260 return me.NewProcessingError(msg)
1261 }
1262 if omci.EntityInstance != 0 {
1263 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload response: %v",
1264 omci.EntityInstance)
1265 return me.NewUnknownInstanceError(msg)
1266 }
1267 omci.NumberOfCommands = binary.BigEndian.Uint16(data[4:6])
1268 return nil
1269}
1270
1271func decodeMibUploadResponse(data []byte, p gopacket.PacketBuilder) error {
1272 omci := &MibUploadResponse{}
1273 omci.MsgLayerType = LayerTypeMibUploadResponse
1274 return decodingLayerDecoder(omci, data, p)
1275}
1276
Matteo Scandolof9d43412021-01-12 11:11:34 -08001277// SerializeTo provides serialization of an MIB Upload Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001278func (omci *MibUploadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1279 // Basic (common) OMCI Header is 8 octets, 10
1280 err := omci.MeBasePacket.SerializeTo(b)
1281 if err != nil {
1282 return err
1283 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001284 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001285 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001286 if omciErr.StatusCode() != me.Success {
1287 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001288 }
1289 // ME needs to support MIB Upload
1290 if !me.SupportsMsgType(entity, me.MibUpload) {
1291 return me.NewProcessingError("managed entity does not support the MIB Upload Message-Type")
1292 }
1293 bytes, err := b.AppendBytes(2)
1294 if err != nil {
1295 return err
1296 }
1297 binary.BigEndian.PutUint16(bytes[0:2], omci.NumberOfCommands)
1298 return nil
1299}
1300
1301/////////////////////////////////////////////////////////////////////////////
1302//
1303type MibUploadNextRequest struct {
1304 MeBasePacket
1305 CommandSequenceNumber uint16
1306}
1307
1308func (omci *MibUploadNextRequest) String() string {
1309 return fmt.Sprintf("%v, SequenceNumberCountOrSize: %v",
1310 omci.MeBasePacket.String(), omci.CommandSequenceNumber)
1311}
1312
Matteo Scandolof9d43412021-01-12 11:11:34 -08001313// DecodeFromBytes decodes the given bytes of a MIB Upload Next Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001314func (omci *MibUploadNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1315 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001316 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001317 if err != nil {
1318 return err
1319 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001320 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001321 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001322 if omciErr.StatusCode() != me.Success {
1323 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001324 }
1325 // ME needs to support Get All Alarms
1326 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1327 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1328 }
1329 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001330 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001331 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next request: %v",
1332 omci.EntityClass)
1333 return me.NewProcessingError(msg)
1334 }
1335 if omci.EntityInstance != 0 {
1336 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next request: %v",
1337 omci.EntityInstance)
1338 return me.NewUnknownInstanceError(msg)
1339 }
1340 omci.CommandSequenceNumber = binary.BigEndian.Uint16(data[4:6])
1341 return nil
1342}
1343
1344func decodeMibUploadNextRequest(data []byte, p gopacket.PacketBuilder) error {
1345 omci := &MibUploadNextRequest{}
1346 omci.MsgLayerType = LayerTypeMibUploadNextRequest
1347 return decodingLayerDecoder(omci, data, p)
1348}
1349
Matteo Scandolof9d43412021-01-12 11:11:34 -08001350// SerializeTo provides serialization of an MIB Upload Next Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001351func (omci *MibUploadNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1352 // Basic (common) OMCI Header is 8 octets, 10
1353 err := omci.MeBasePacket.SerializeTo(b)
1354 if err != nil {
1355 return err
1356 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001357 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001358 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001359 if omciErr.StatusCode() != me.Success {
1360 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001361 }
1362 // ME needs to support MIB upload
1363 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1364 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1365 }
1366 bytes, err := b.AppendBytes(2)
1367 if err != nil {
1368 return err
1369 }
1370 binary.BigEndian.PutUint16(bytes[0:2], omci.CommandSequenceNumber)
1371 return nil
1372}
1373
1374/////////////////////////////////////////////////////////////////////////////
1375//
1376type MibUploadNextResponse struct {
1377 MeBasePacket
1378 ReportedME me.ManagedEntity
1379}
1380
1381func (omci *MibUploadNextResponse) String() string {
1382 return fmt.Sprintf("%v, ReportedME: [%v]",
1383 omci.MeBasePacket.String(), omci.ReportedME.String())
1384}
1385
Matteo Scandolof9d43412021-01-12 11:11:34 -08001386// DecodeFromBytes decodes the given bytes of a MIB Upload Next Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001387func (omci *MibUploadNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1388 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001389 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+6)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001390 if err != nil {
1391 return err
1392 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001393 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001394 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001395 if omciErr.StatusCode() != me.Success {
1396 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001397 }
1398 // ME needs to support MibUploadNext
1399 if !me.SupportsMsgType(meDefinition, me.MibUploadNext) {
1400 return me.NewProcessingError("managed entity does not support MIB Upload Next Message-Type")
1401 }
1402 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001403 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001404 msg := fmt.Sprintf("invalid Entity Class for MIB Upload Next response: %v",
1405 omci.EntityClass)
1406 return me.NewProcessingError(msg)
1407 }
1408 if omci.EntityInstance != 0 {
1409 msg := fmt.Sprintf("invalid Entity Instance for MIB Upload Next response: %v",
1410 omci.EntityInstance)
1411 return me.NewUnknownInstanceError(msg)
1412 }
1413 // Decode reported ME. If an out-of-range sequence number was sent, this will
1414 // contain an ME with class ID and entity ID of zero and you should get an
1415 // error of "managed entity definition not found" returned.
1416 return omci.ReportedME.DecodeFromBytes(data[4:], p, byte(MibUploadNextResponseType))
1417}
1418
1419func decodeMibUploadNextResponse(data []byte, p gopacket.PacketBuilder) error {
1420 omci := &MibUploadNextResponse{}
1421 omci.MsgLayerType = LayerTypeMibUploadNextResponse
1422 return decodingLayerDecoder(omci, data, p)
1423}
1424
Matteo Scandolof9d43412021-01-12 11:11:34 -08001425// SerializeTo provides serialization of an MIB Upload Next Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001426func (omci *MibUploadNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1427 // Basic (common) OMCI Header is 8 octets, 10
1428 err := omci.MeBasePacket.SerializeTo(b)
1429 if err != nil {
1430 return err
1431 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001432 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001433 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001434 if omciErr.StatusCode() != me.Success {
1435 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001436 }
1437 // ME needs to support MIB Upload
1438 if !me.SupportsMsgType(entity, me.MibUploadNext) {
1439 return me.NewProcessingError("managed entity does not support the MIB Upload Next Message-Type")
1440 }
1441 // TODO: Only Baseline supported at this time
1442 bytesAvailable := MaxBaselineLength - 8 - 8
1443
Matteo Scandolof9d43412021-01-12 11:11:34 -08001444 return omci.ReportedME.SerializeTo(b, byte(MibUploadNextResponseType), bytesAvailable, opts)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001445}
1446
1447/////////////////////////////////////////////////////////////////////////////
1448// MibResetRequest
1449type MibResetRequest struct {
1450 MeBasePacket
1451}
1452
1453func (omci *MibResetRequest) String() string {
1454 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1455}
1456
Matteo Scandolof9d43412021-01-12 11:11:34 -08001457// DecodeFromBytes decodes the given bytes of a MIB Reset Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001458func (omci *MibResetRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1459 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -08001460 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001461 if err != nil {
1462 return err
1463 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001464 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001465 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001466 if omciErr.StatusCode() != me.Success {
1467 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001468 }
1469 // ME needs to support MIB reset
1470 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1471 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1472 }
1473 // Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001474 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001475 msg := fmt.Sprintf("invalid Entity Class for MIB Reset request: %v",
1476 omci.EntityClass)
1477 return me.NewProcessingError(msg)
1478 }
1479 if omci.EntityInstance != 0 {
1480 msg := fmt.Sprintf("invalid Entity Instance for MIB Reset request: %v",
1481 omci.EntityInstance)
1482 return me.NewUnknownInstanceError(msg)
1483 }
1484 return nil
1485}
1486
1487func decodeMibResetRequest(data []byte, p gopacket.PacketBuilder) error {
1488 omci := &MibResetRequest{}
1489 omci.MsgLayerType = LayerTypeMibResetRequest
1490 return decodingLayerDecoder(omci, data, p)
1491}
1492
Matteo Scandolof9d43412021-01-12 11:11:34 -08001493// SerializeTo provides serialization of an MIB Reset Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001494func (omci *MibResetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1495 // Add class ID and entity ID
1496 return omci.MeBasePacket.SerializeTo(b)
1497}
1498
1499/////////////////////////////////////////////////////////////////////////////
1500// MibResetResponse
1501type MibResetResponse struct {
1502 MeBasePacket
1503 Result me.Results
1504}
1505
1506func (omci *MibResetResponse) String() string {
1507 return fmt.Sprintf("%v, Result: %d (%v)",
1508 omci.MeBasePacket.String(), omci.Result, omci.Result)
1509}
1510
Matteo Scandolof9d43412021-01-12 11:11:34 -08001511// DecodeFromBytes decodes the given bytes of a MIB Reset Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001512func (omci *MibResetResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1513 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001514 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001515 if err != nil {
1516 return err
1517 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001518 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001519 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001520 if omciErr.StatusCode() != me.Success {
1521 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001522 }
1523 // ME needs to support MIB reset
1524 if !me.SupportsMsgType(meDefinition, me.MibReset) {
1525 return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1526 }
1527 // MIB Reset Response Entity Class always ONU DATA (2) and
1528 // Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08001529 if omci.EntityClass != me.OnuDataClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001530 return me.NewProcessingError("invalid Entity Class for MIB Reset Response")
1531 }
1532 if omci.EntityInstance != 0 {
1533 return me.NewUnknownInstanceError("invalid Entity Instance for MIB Reset Response")
1534 }
1535 omci.Result = me.Results(data[4])
1536 if omci.Result > me.DeviceBusy {
1537 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
1538 return errors.New(msg)
1539 }
1540 return nil
1541}
1542
1543func decodeMibResetResponse(data []byte, p gopacket.PacketBuilder) error {
1544 omci := &MibResetResponse{}
1545 omci.MsgLayerType = LayerTypeMibResetResponse
1546 return decodingLayerDecoder(omci, data, p)
1547}
1548
Matteo Scandolof9d43412021-01-12 11:11:34 -08001549// SerializeTo provides serialization of an MIB Reset Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001550func (omci *MibResetResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1551 // Basic (common) OMCI Header is 8 octets, 10
1552 err := omci.MeBasePacket.SerializeTo(b)
1553 if err != nil {
1554 return err
1555 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001556 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001557 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001558 if omciErr.StatusCode() != me.Success {
1559 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001560 }
1561 // ME needs to support Set
1562 if !me.SupportsMsgType(entity, me.MibReset) {
1563 return me.NewProcessingError("managed entity does not support the MIB Reset Message-Type")
1564 }
1565 bytes, err := b.AppendBytes(1)
1566 if err != nil {
1567 return err
1568 }
1569 bytes[0] = byte(omci.Result)
1570 return nil
1571}
1572
1573/////////////////////////////////////////////////////////////////////////////
1574// AlarmNotificationMsg
1575const AlarmBitmapSize = 224
1576
1577type AlarmNotificationMsg struct {
1578 MeBasePacket
1579 AlarmBitmap [AlarmBitmapSize / 8]byte
1580 zeroPadding [3]byte
1581 AlarmSequenceNumber byte
1582}
1583
1584func (omci *AlarmNotificationMsg) String() string {
1585 return fmt.Sprintf("%v, Sequence Number: %d, Alarm Bitmap: %v",
1586 omci.MeBasePacket.String(), omci.AlarmSequenceNumber, omci.AlarmBitmap)
1587}
1588
1589func (omci *AlarmNotificationMsg) IsAlarmActive(alarmNumber uint8) (bool, error) {
1590 if alarmNumber >= AlarmBitmapSize {
1591 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1592 return false, errors.New(msg)
1593 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001594 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1595 me.ParamData{EntityID: omci.EntityInstance})
1596 if omciErr.StatusCode() != me.Success {
1597 return false, omciErr.GetError()
1598 }
1599 alarmMap := entity.GetAlarmMap()
1600 if alarmMap == nil {
1601 msg := "Managed Entity does not support Alarm notifications"
1602 return false, errors.New(msg)
1603 }
1604 if _, ok := alarmMap[alarmNumber]; !ok {
1605 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1606 return false, errors.New(msg)
1607 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001608 octet := alarmNumber / 8
1609 bit := 7 - (alarmNumber % 8)
1610 return omci.AlarmBitmap[octet]>>bit == 1, nil
1611}
1612
1613func (omci *AlarmNotificationMsg) IsAlarmClear(alarmNumber uint8) (bool, error) {
1614 if alarmNumber >= AlarmBitmapSize {
1615 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1616 return false, errors.New(msg)
1617 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001618 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1619 me.ParamData{EntityID: omci.EntityInstance})
1620 if omciErr.StatusCode() != me.Success {
1621 return false, omciErr.GetError()
1622 }
1623 alarmMap := entity.GetAlarmMap()
1624 if alarmMap == nil {
1625 return false, errors.New("Managed Entity does not support Alarm notifications")
1626 }
1627 if _, ok := alarmMap[alarmNumber]; !ok {
1628 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1629 return false, errors.New(msg)
1630 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001631 octet := alarmNumber / 8
1632 bit := 7 - (alarmNumber % 8)
1633 return omci.AlarmBitmap[octet]>>bit == 0, nil
1634}
1635
1636func (omci *AlarmNotificationMsg) ActivateAlarm(alarmNumber uint8) error {
1637 if alarmNumber >= AlarmBitmapSize {
1638 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1639 return errors.New(msg)
1640 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001641 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1642 me.ParamData{EntityID: omci.EntityInstance})
1643 if omciErr.StatusCode() != me.Success {
1644 return omciErr.GetError()
1645 }
1646 alarmMap := entity.GetAlarmMap()
1647 if alarmMap == nil {
1648 return errors.New("Managed Entity does not support Alarm notifications")
1649 }
1650 if _, ok := alarmMap[alarmNumber]; !ok {
1651 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1652 return errors.New(msg)
1653 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001654 octet := alarmNumber / 8
1655 bit := 7 - (alarmNumber % 8)
1656 omci.AlarmBitmap[octet] |= 1 << bit
1657 return nil
1658}
1659
1660func (omci *AlarmNotificationMsg) ClearAlarm(alarmNumber uint8) error {
1661 if alarmNumber >= AlarmBitmapSize {
1662 msg := fmt.Sprintf("invalid alarm number: %v, must be 0..224", alarmNumber)
1663 return errors.New(msg)
1664 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001665 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1666 me.ParamData{EntityID: omci.EntityInstance})
1667 if omciErr.StatusCode() != me.Success {
1668 return omciErr.GetError()
1669 }
1670 alarmMap := entity.GetAlarmMap()
1671 if alarmMap == nil {
1672 return errors.New("Managed Entity does not support Alarm notifications")
1673 }
1674 if _, ok := alarmMap[alarmNumber]; !ok {
1675 msg := fmt.Sprintf("unsupported invalid alarm number: %v", alarmNumber)
1676 return errors.New(msg)
1677 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001678 octet := alarmNumber / 8
1679 bit := 7 - (alarmNumber % 8)
1680 omci.AlarmBitmap[octet] &= ^(1 << bit)
1681 return nil
1682}
1683
Matteo Scandolof9d43412021-01-12 11:11:34 -08001684// DecodeFromBytes decodes the given bytes of an Alarm Notification into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001685func (omci *AlarmNotificationMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1686 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001687 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+28)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001688 if err != nil {
1689 return err
1690 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001691 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1692 me.ParamData{EntityID: omci.EntityInstance})
1693 if omciErr.StatusCode() != me.Success {
1694 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001695 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001696 // Is this an unsupported or vendor specific ME. If so, it is not an error to decode
1697 // the alarms. We just cannot provide any alarm names. Handle decode here.
1698 classSupport := meDefinition.GetClassSupport()
1699 isUnsupported := classSupport == me.UnsupportedManagedEntity ||
1700 classSupport == me.UnsupportedVendorSpecificManagedEntity
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001701
Matteo Scandolof9d43412021-01-12 11:11:34 -08001702 // Look for a non-nil/not empty Alarm Map to determine if this ME supports alarms
1703 if alarmMap := meDefinition.GetAlarmMap(); isUnsupported || (alarmMap != nil && len(alarmMap) > 0) {
1704 for index, octet := range data[4 : (AlarmBitmapSize/8)-4] {
1705 omci.AlarmBitmap[index] = octet
1706 }
1707 padOffset := 4 + (AlarmBitmapSize / 8)
1708 omci.zeroPadding[0] = data[padOffset]
1709 omci.zeroPadding[1] = data[padOffset+1]
1710 omci.zeroPadding[2] = data[padOffset+2]
1711
1712 omci.AlarmSequenceNumber = data[padOffset+3]
1713 return nil
1714 }
1715 return me.NewProcessingError("managed entity does not support alarm notifications")
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001716}
1717
1718func decodeAlarmNotification(data []byte, p gopacket.PacketBuilder) error {
1719 omci := &AlarmNotificationMsg{}
1720 omci.MsgLayerType = LayerTypeAlarmNotification
1721 return decodingLayerDecoder(omci, data, p)
1722}
1723
Matteo Scandolof9d43412021-01-12 11:11:34 -08001724// SerializeTo provides serialization of an Alarm Notification message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001725func (omci *AlarmNotificationMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1726 // Basic (common) OMCI Header is 8 octets, 10
1727 err := omci.MeBasePacket.SerializeTo(b)
1728 if err != nil {
1729 return err
1730 }
1731 //var meDefinition me.IManagedEntityDefinition
1732 //meDefinition, err = me.LoadManagedEntityDefinition(omci.EntityClass,
1733 // me.ParamData{EntityID: omci.EntityInstance})
1734 //if err != nil {
1735 // return err
1736 //}
1737 // ME needs to support Alarms
1738 // TODO: Add attribute to ME to specify that alarm is allowed
1739 //if !me.SupportsMsgType(meDefinition, me.MibReset) {
1740 // return me.NewProcessingError("managed entity does not support MIB Reset Message-Type")
1741 //}
1742 bytes, err := b.AppendBytes((AlarmBitmapSize / 8) + 3 + 1)
1743 if err != nil {
1744 return err
1745 }
1746 for index, octet := range omci.AlarmBitmap {
1747 bytes[index] = octet
1748 }
1749 padOffset := AlarmBitmapSize / 8
1750 bytes[padOffset] = 0
1751 bytes[padOffset+1] = 0
1752 bytes[padOffset+2] = 0
1753 bytes[padOffset+3] = omci.AlarmSequenceNumber
1754 return nil
1755}
1756
1757/////////////////////////////////////////////////////////////////////////////
1758// AttributeValueChangeMsg
1759type AttributeValueChangeMsg struct {
1760 MeBasePacket
1761 AttributeMask uint16
1762 Attributes me.AttributeValueMap
1763}
1764
1765func (omci *AttributeValueChangeMsg) String() string {
1766 return fmt.Sprintf("%v, Mask: %#x, attributes: %v",
1767 omci.MeBasePacket.String(), omci.AttributeMask, omci.Attributes)
1768}
1769
Matteo Scandolof9d43412021-01-12 11:11:34 -08001770// DecodeFromBytes decodes the given bytes of an Attribute Value Change notification into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001771func (omci *AttributeValueChangeMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1772 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001773 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001774 if err != nil {
1775 return err
1776 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001777 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001778 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001779 if omciErr.StatusCode() != me.Success {
1780 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001781 }
1782 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
1783 // Attribute decode
1784 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:40], p, byte(AttributeValueChangeType))
1785 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1786 // Validate all attributes support AVC
1787 //for attrName := range omci.attributes {
1788 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1789 // if err != nil {
1790 // return err
1791 // }
1792 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1793 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1794 // return me.NewProcessingError(msg)
1795 // }
1796 //}
1797 return err
1798}
1799
1800func decodeAttributeValueChange(data []byte, p gopacket.PacketBuilder) error {
1801 omci := &AttributeValueChangeMsg{}
1802 omci.MsgLayerType = LayerTypeAttributeValueChange
1803 return decodingLayerDecoder(omci, data, p)
1804}
1805
Matteo Scandolof9d43412021-01-12 11:11:34 -08001806// SerializeTo provides serialization of an Attribute Value Change Notification message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001807func (omci *AttributeValueChangeMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1808 // Basic (common) OMCI Header is 8 octets, 10
1809 err := omci.MeBasePacket.SerializeTo(b)
1810 if err != nil {
1811 return err
1812 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001813 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001814 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001815 if omciErr.StatusCode() != me.Success {
1816 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001817 }
1818 // TODO: Add support for attributes that can have an AVC associated with them and then add a check here
1819 // Validate all attributes support AVC
1820 //for attrName := range omci.attributes {
1821 // attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
1822 // if err != nil {
1823 // return err
1824 // }
1825 // if attr.Index != 0 && !me.SupportsAttributeAVC(attr) {
1826 // msg := fmt.Sprintf("attribute '%v' does not support AVC notifications", attrName)
1827 // return me.NewProcessingError(msg)
1828 // }
1829 //}
1830 bytes, err := b.AppendBytes(2)
1831 if err != nil {
1832 return err
1833 }
1834 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
1835
1836 // Attribute serialization
1837 // TODO: Only Baseline supported at this time
1838 bytesAvailable := MaxBaselineLength - 10 - 8
1839
Matteo Scandolof9d43412021-01-12 11:11:34 -08001840 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
1841 byte(AttributeValueChangeType), bytesAvailable, false)
1842 return err
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001843}
1844
1845/////////////////////////////////////////////////////////////////////////////
1846// TestRequest: TODO: Not yet implemented
1847type TestRequest struct {
1848 MeBasePacket
1849}
1850
1851func (omci *TestRequest) String() string {
1852 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1853}
1854
Matteo Scandolof9d43412021-01-12 11:11:34 -08001855// DecodeFromBytes decodes the given bytes of a Test Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001856func (omci *TestRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1857 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001858 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+5)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001859 if err != nil {
1860 return err
1861 }
1862 return errors.New("need to implement") // TODO: Fix me) // return nil
1863}
1864
1865func decodeTestRequest(data []byte, p gopacket.PacketBuilder) error {
1866 omci := &TestRequest{}
1867 omci.MsgLayerType = LayerTypeTestRequest
1868 return decodingLayerDecoder(omci, data, p)
1869}
1870
Matteo Scandolof9d43412021-01-12 11:11:34 -08001871// SerializeTo provides serialization of an Test Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001872func (omci *TestRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1873 // Basic (common) OMCI Header is 8 octets, 10
1874 err := omci.MeBasePacket.SerializeTo(b)
1875 if err != nil {
1876 return err
1877 }
1878 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1879}
1880
1881/////////////////////////////////////////////////////////////////////////////
1882// TestResponse: TODO: Not yet implemented
1883type TestResponse struct {
1884 MeBasePacket
1885}
1886
1887func (omci *TestResponse) String() string {
1888 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1889}
1890
Matteo Scandolof9d43412021-01-12 11:11:34 -08001891// DecodeFromBytes decodes the given bytes of a Test Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001892func (omci *TestResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1893 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001894 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001895 if err != nil {
1896 return err
1897 }
1898 return errors.New("need to implement") // TODO: Fix me) // return nil
1899}
1900
1901func decodeTestResponse(data []byte, p gopacket.PacketBuilder) error {
1902 omci := &TestResponse{}
1903 omci.MsgLayerType = LayerTypeTestResponse
1904 return decodingLayerDecoder(omci, data, p)
1905}
1906
Matteo Scandolof9d43412021-01-12 11:11:34 -08001907// SerializeTo provides serialization of an Test Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001908func (omci *TestResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1909 // Basic (common) OMCI Header is 8 octets, 10
1910 err := omci.MeBasePacket.SerializeTo(b)
1911 if err != nil {
1912 return err
1913 }
1914 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
1915}
1916
1917/////////////////////////////////////////////////////////////////////////////
1918//
1919type StartSoftwareDownloadRequest struct {
1920 MeBasePacket // Note: EntityInstance for software download is two specific values
1921 WindowSize byte // Window Size -1
1922 ImageSize uint32 // Octets
1923 NumberOfCircuitPacks byte
1924 CircuitPacks []uint16 // MSB & LSB of software image instance
1925}
1926
1927func (omci *StartSoftwareDownloadRequest) String() string {
1928 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
1929 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
1930}
1931
Matteo Scandolof9d43412021-01-12 11:11:34 -08001932// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001933func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08001934 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001935 if err != nil {
1936 return err
1937 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001938 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001939 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001940 if omciErr.StatusCode() != me.Success {
1941 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001942 }
1943 // ME needs to support Start Software Download
1944 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
1945 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
1946 }
1947 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08001948 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001949 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1950 }
1951 omci.WindowSize = data[4]
1952 omci.ImageSize = binary.BigEndian.Uint32(data[5:9])
1953 omci.NumberOfCircuitPacks = data[9]
1954 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08001955 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1956 omci.NumberOfCircuitPacks))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001957 }
1958 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
1959 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
1960 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[10+(index*2):])
1961 }
1962 return nil
1963}
1964
1965func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
1966 omci := &StartSoftwareDownloadRequest{}
1967 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
1968 return decodingLayerDecoder(omci, data, p)
1969}
1970
Matteo Scandolof9d43412021-01-12 11:11:34 -08001971// SerializeTo provides serialization of an Start Software Download Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001972func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
1973 // Basic (common) OMCI Header is 8 octets, 10
1974 err := omci.MeBasePacket.SerializeTo(b)
1975 if err != nil {
1976 return err
1977 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08001978 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001979 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08001980 if omciErr.StatusCode() != me.Success {
1981 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001982 }
1983 // ME needs to support Start Software Download
1984 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
1985 return me.NewProcessingError("managed entity does not support the SStart Software Download Message-Type")
1986 }
1987 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08001988 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001989 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
1990 }
1991 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08001992 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
1993 omci.NumberOfCircuitPacks))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001994 }
1995 bytes, err := b.AppendBytes(6 + (2 * int(omci.NumberOfCircuitPacks)))
1996 if err != nil {
1997 return err
1998 }
1999 bytes[0] = omci.WindowSize
2000 binary.BigEndian.PutUint32(bytes[1:], omci.ImageSize)
2001 bytes[5] = omci.NumberOfCircuitPacks
2002 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
2003 binary.BigEndian.PutUint16(bytes[6+(index*2):], omci.CircuitPacks[index])
2004 }
2005 return nil
2006}
2007
2008/////////////////////////////////////////////////////////////////////////////
2009//
Matteo Scandolocedde462021-03-09 17:37:16 -08002010type DownloadResults struct {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002011 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
2012 Result me.Results
2013}
2014
Matteo Scandolocedde462021-03-09 17:37:16 -08002015func (dr *DownloadResults) String() string {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002016 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
2017 dr.Result, dr.Result)
2018}
2019
2020type StartSoftwareDownloadResponse struct {
2021 MeBasePacket // Note: EntityInstance for software download is two specific values
2022 Result me.Results
2023 WindowSize byte // Window Size -1
2024 NumberOfInstances byte
Matteo Scandolocedde462021-03-09 17:37:16 -08002025 MeResults []DownloadResults
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002026}
2027
2028func (omci *StartSoftwareDownloadResponse) String() string {
2029 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
2030 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
2031}
2032
Matteo Scandolof9d43412021-01-12 11:11:34 -08002033// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002034func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2035 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002036 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002037 if err != nil {
2038 return err
2039 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002040 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002041 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002042 if omciErr.StatusCode() != me.Success {
2043 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002044 }
2045 // ME needs to support Start Software Download
2046 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2047 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2048 }
2049 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002050 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002051 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2052 }
2053 omci.Result = me.Results(data[4])
2054 if omci.Result > me.DeviceBusy {
2055 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2056 omci.Result)
2057 return errors.New(msg)
2058 }
2059 omci.WindowSize = data[5]
2060 omci.NumberOfInstances = data[6]
2061
2062 if omci.NumberOfInstances > 9 {
2063 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2064 omci.NumberOfInstances)
2065 return errors.New(msg)
2066 }
2067 if omci.NumberOfInstances > 0 {
Matteo Scandolocedde462021-03-09 17:37:16 -08002068 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002069
2070 for index := 0; index < int(omci.NumberOfInstances); index++ {
2071 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[7+(index*3):])
2072 omci.MeResults[index].Result = me.Results(data[9+(index*3)])
2073 if omci.MeResults[index].Result > me.DeviceBusy {
2074 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2075 index, omci.MeResults[index])
2076 return errors.New(msg)
2077 }
2078 }
2079 }
2080 return nil
2081}
2082
2083func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2084 omci := &StartSoftwareDownloadResponse{}
2085 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
2086 return decodingLayerDecoder(omci, data, p)
2087}
2088
Matteo Scandolof9d43412021-01-12 11:11:34 -08002089// SerializeTo provides serialization of an Start Software Download Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002090func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2091 // Basic (common) OMCI Header is 8 octets, 10
2092 err := omci.MeBasePacket.SerializeTo(b)
2093 if err != nil {
2094 return err
2095 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002096 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002097 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002098 if omciErr.StatusCode() != me.Success {
2099 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002100 }
2101 // ME needs to support Start Software Download
2102 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
2103 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
2104 }
2105 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002106 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002107 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
2108 }
2109 bytes, err := b.AppendBytes(3 + (3 * int(omci.NumberOfInstances)))
2110 if err != nil {
2111 return err
2112 }
2113 if omci.Result > me.DeviceBusy {
2114 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
2115 omci.Result)
2116 return errors.New(msg)
2117 }
2118 bytes[0] = byte(omci.Result)
2119 bytes[1] = omci.WindowSize
2120 bytes[2] = omci.NumberOfInstances
2121
2122 if omci.NumberOfInstances > 9 {
2123 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
2124 omci.NumberOfInstances)
2125 return errors.New(msg)
2126 }
2127 if omci.NumberOfInstances > 0 {
2128 for index := 0; index < int(omci.NumberOfInstances); index++ {
2129 binary.BigEndian.PutUint16(bytes[3+(3*index):], omci.MeResults[index].ManagedEntityID)
2130
2131 if omci.MeResults[index].Result > me.DeviceBusy {
2132 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
2133 index, omci.MeResults[index])
2134 return errors.New(msg)
2135 }
2136 bytes[5+(3*index)] = byte(omci.MeResults[index].Result)
2137 }
2138 }
2139 return nil
2140}
2141
2142/////////////////////////////////////////////////////////////////////////////
2143//
2144type DownloadSectionRequest struct {
2145 MeBasePacket // Note: EntityInstance for software download is two specific values
2146 SectionNumber byte
Girish Gowdrae2683102021-03-05 08:24:26 -08002147 SectionData [31]byte // 0 padding if final transfer requires only a partial block
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002148}
2149
2150func (omci *DownloadSectionRequest) String() string {
2151 return fmt.Sprintf("%v, Section #: %v",
2152 omci.MeBasePacket.String(), omci.SectionNumber)
2153}
2154
Matteo Scandolof9d43412021-01-12 11:11:34 -08002155// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002156func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2157 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002158 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002159 if err != nil {
2160 return err
2161 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002162 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002163 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002164 if omciErr.StatusCode() != me.Success {
2165 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002166 }
2167 // ME needs to support Download section
2168 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2169 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2170 }
2171 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002172 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002173 return me.NewProcessingError("invalid Entity Class for Download Section request")
2174 }
2175 omci.SectionNumber = data[4]
2176 copy(omci.SectionData[0:], data[5:])
2177 return nil
2178}
2179
2180func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
2181 omci := &DownloadSectionRequest{}
2182 omci.MsgLayerType = LayerTypeDownloadSectionRequest
2183 return decodingLayerDecoder(omci, data, p)
2184}
2185
Matteo Scandolof9d43412021-01-12 11:11:34 -08002186// SerializeTo provides serialization of an Download Section Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002187func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2188 // Basic (common) OMCI Header is 8 octets, 10
2189 err := omci.MeBasePacket.SerializeTo(b)
2190 if err != nil {
2191 return err
2192 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002193 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002194 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002195 if omciErr.StatusCode() != me.Success {
2196 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002197 }
2198 // ME needs to support Download section
2199 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2200 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2201 }
2202 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002203 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002204 return me.NewProcessingError("invalid Entity Class for Download Section response")
2205 }
Girish Gowdrae2683102021-03-05 08:24:26 -08002206 bytes, err := b.AppendBytes(1 + len(omci.SectionData))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002207 if err != nil {
2208 return err
2209 }
2210 bytes[0] = omci.SectionNumber
2211 copy(bytes[1:], omci.SectionData[0:])
2212 return nil
2213}
2214
2215/////////////////////////////////////////////////////////////////////////////
2216//
2217type DownloadSectionResponse struct {
2218 MeBasePacket // Note: EntityInstance for software download is two specific values
2219 Result me.Results
2220 SectionNumber byte
2221}
2222
2223func (omci *DownloadSectionResponse) String() string {
2224 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
2225 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
2226}
2227
Matteo Scandolof9d43412021-01-12 11:11:34 -08002228// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002229func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2230 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002231 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002232 if err != nil {
2233 return err
2234 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002235 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002236 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002237 if omciErr.StatusCode() != me.Success {
2238 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002239 }
2240 // ME needs to support Download section
2241 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2242 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2243 }
2244 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002245 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002246 return me.NewProcessingError("invalid Entity Class for Download Section response")
2247 }
2248 omci.Result = me.Results(data[4])
2249 if omci.Result > me.DeviceBusy {
2250 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2251 omci.Result)
2252 return errors.New(msg)
2253 }
2254 omci.SectionNumber = data[5]
2255 return nil
2256}
2257
2258func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
2259 omci := &DownloadSectionResponse{}
2260 omci.MsgLayerType = LayerTypeDownloadSectionResponse
2261 return decodingLayerDecoder(omci, data, p)
2262}
2263
Matteo Scandolof9d43412021-01-12 11:11:34 -08002264// SerializeTo provides serialization of an Download Section Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002265func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2266 // Basic (common) OMCI Header is 8 octets, 10
2267 err := omci.MeBasePacket.SerializeTo(b)
2268 if err != nil {
2269 return err
2270 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002271 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002272 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002273 if omciErr.StatusCode() != me.Success {
2274 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002275 }
2276 // ME needs to support Download section
2277 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
2278 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
2279 }
2280 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002281 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002282 return me.NewProcessingError("invalid Entity Class for Download Section response")
2283 }
2284 bytes, err := b.AppendBytes(2)
2285 if err != nil {
2286 return err
2287 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002288 if omci.Result > me.DeviceBusy {
2289 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
2290 omci.Result)
2291 return errors.New(msg)
2292 }
Girish Gowdrae2683102021-03-05 08:24:26 -08002293 bytes[0] = byte(omci.Result)
2294 bytes[1] = omci.SectionNumber
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002295 return nil
2296}
2297
2298/////////////////////////////////////////////////////////////////////////////
2299//
2300type EndSoftwareDownloadRequest struct {
2301 MeBasePacket // Note: EntityInstance for software download is two specific values
2302 CRC32 uint32
2303 ImageSize uint32
2304 NumberOfInstances byte
2305 ImageInstances []uint16
2306}
2307
2308func (omci *EndSoftwareDownloadRequest) String() string {
2309 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
2310 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
2311}
2312
Matteo Scandolof9d43412021-01-12 11:11:34 -08002313// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002314func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2315 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002316 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002317 if err != nil {
2318 return err
2319 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002320 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002321 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002322 if omciErr.StatusCode() != me.Success {
2323 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002324 }
2325 // ME needs to support End Software Download
2326 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2327 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2328 }
2329 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002330 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002331 return me.NewProcessingError("invalid Entity Class for End Software Download request")
2332 }
2333 omci.CRC32 = binary.BigEndian.Uint32(data[4:8])
2334 omci.ImageSize = binary.BigEndian.Uint32(data[8:12])
Girish Gowdrae2683102021-03-05 08:24:26 -08002335 omci.NumberOfInstances = data[12]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002336
2337 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08002338 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2339 omci.NumberOfInstances))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002340 }
2341 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
2342
2343 for index := 0; index < int(omci.NumberOfInstances); index++ {
Girish Gowdrae2683102021-03-05 08:24:26 -08002344 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[13+(index*2):])
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002345 }
2346 return nil
2347}
2348
2349func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
2350 omci := &EndSoftwareDownloadRequest{}
2351 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
2352 return decodingLayerDecoder(omci, data, p)
2353}
2354
Matteo Scandolof9d43412021-01-12 11:11:34 -08002355// SerializeTo provides serialization of an End Software Download Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002356func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2357 // Basic (common) OMCI Header is 8 octets, 10
2358 err := omci.MeBasePacket.SerializeTo(b)
2359 if err != nil {
2360 return err
2361 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002362 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002363 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002364 if omciErr.StatusCode() != me.Success {
2365 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002366 }
2367 // ME needs to support End Software Download
2368 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2369 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
2370 }
2371 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002372 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002373 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2374 }
2375 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08002376 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
2377 omci.NumberOfInstances))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002378 }
2379 bytes, err := b.AppendBytes(9 + (2 * int(omci.NumberOfInstances)))
2380 if err != nil {
2381 return err
2382 }
Girish Gowdrae2683102021-03-05 08:24:26 -08002383 binary.BigEndian.PutUint32(bytes[0:4], omci.CRC32)
2384 binary.BigEndian.PutUint32(bytes[4:8], omci.ImageSize)
2385 bytes[8] = omci.NumberOfInstances
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002386 for index := 0; index < int(omci.NumberOfInstances); index++ {
Girish Gowdrae2683102021-03-05 08:24:26 -08002387 binary.BigEndian.PutUint16(bytes[9+(index*2):], omci.ImageInstances[index])
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002388 }
2389 return nil
2390}
2391
2392/////////////////////////////////////////////////////////////////////////////
2393//
2394type EndSoftwareDownloadResponse struct {
2395 MeBasePacket // Note: EntityInstance for software download is two specific values
2396 Result me.Results
2397 NumberOfInstances byte
Matteo Scandolocedde462021-03-09 17:37:16 -08002398 MeResults []DownloadResults
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002399}
2400
2401func (omci *EndSoftwareDownloadResponse) String() string {
2402 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
2403 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
2404}
2405
Matteo Scandolof9d43412021-01-12 11:11:34 -08002406// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002407func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2408 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002409 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002410 if err != nil {
2411 return err
2412 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002413 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002414 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002415 if omciErr.StatusCode() != me.Success {
2416 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002417 }
2418 // ME needs to support End Software Download
2419 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2420 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
2421 }
2422 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002423 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002424 return me.NewProcessingError("invalid Entity Class for End Software Download response")
2425 }
2426 omci.Result = me.Results(data[4])
2427 if omci.Result > me.DeviceBusy {
2428 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2429 omci.Result)
2430 return errors.New(msg)
2431 }
2432 omci.NumberOfInstances = data[5]
2433
2434 if omci.NumberOfInstances > 9 {
2435 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2436 omci.NumberOfInstances)
2437 return errors.New(msg)
2438 }
2439 if omci.NumberOfInstances > 0 {
Matteo Scandolocedde462021-03-09 17:37:16 -08002440 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002441
2442 for index := 0; index < int(omci.NumberOfInstances); index++ {
2443 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[6+(index*3):])
2444 omci.MeResults[index].Result = me.Results(data[8+(index*3)])
2445 if omci.MeResults[index].Result > me.DeviceBusy {
2446 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2447 index, omci.MeResults[index])
2448 return errors.New(msg)
2449 }
2450 }
2451 }
2452 return nil
2453}
2454
2455func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
2456 omci := &EndSoftwareDownloadResponse{}
2457 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
2458 return decodingLayerDecoder(omci, data, p)
2459}
2460
Matteo Scandolof9d43412021-01-12 11:11:34 -08002461// SerializeTo provides serialization of an End Software Download Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002462func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2463 // Basic (common) OMCI Header is 8 octets, 10
2464 err := omci.MeBasePacket.SerializeTo(b)
2465 if err != nil {
2466 return err
2467 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002468 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002469 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002470 if omciErr.StatusCode() != me.Success {
2471 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002472 }
2473 // ME needs to support End Software Download
2474 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
2475 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
2476 }
2477 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002478 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002479 return me.NewProcessingError("invalid Entity Class for End Download response")
2480 }
Girish Gowdrae2683102021-03-05 08:24:26 -08002481 bytes, err := b.AppendBytes(2 + (3 * int(omci.NumberOfInstances)))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002482 if err != nil {
2483 return err
2484 }
2485 if omci.Result > me.DeviceBusy {
2486 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
2487 omci.Result)
2488 return errors.New(msg)
2489 }
2490 bytes[0] = byte(omci.Result)
2491 bytes[1] = omci.NumberOfInstances
2492
2493 if omci.NumberOfInstances > 9 {
2494 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
2495 omci.NumberOfInstances)
2496 return errors.New(msg)
2497 }
2498 if omci.NumberOfInstances > 0 {
2499 for index := 0; index < int(omci.NumberOfInstances); index++ {
2500 binary.BigEndian.PutUint16(bytes[2+(3*index):], omci.MeResults[index].ManagedEntityID)
2501
2502 if omci.MeResults[index].Result > me.DeviceBusy {
2503 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
2504 index, omci.MeResults[index])
2505 return errors.New(msg)
2506 }
2507 bytes[4+(3*index)] = byte(omci.MeResults[index].Result)
2508 }
2509 }
2510 return nil
2511}
2512
2513/////////////////////////////////////////////////////////////////////////////
2514//
2515type ActivateSoftwareRequest struct {
2516 MeBasePacket // Note: EntityInstance for software download is two specific values
2517 ActivateFlags byte
2518}
2519
2520func (omci *ActivateSoftwareRequest) String() string {
2521 return fmt.Sprintf("%v, Flags: %#x",
2522 omci.MeBasePacket.String(), omci.ActivateFlags)
2523}
2524
Matteo Scandolof9d43412021-01-12 11:11:34 -08002525// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002526func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2527 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002528 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002529 if err != nil {
2530 return err
2531 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002532 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002533 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002534 if omciErr.StatusCode() != me.Success {
2535 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002536 }
2537 // ME needs to support End Software Download
2538 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2539 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2540 }
2541 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002542 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002543 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2544 }
2545 omci.ActivateFlags = data[4]
2546 if omci.ActivateFlags > 2 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08002547 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
2548 omci.ActivateFlags))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002549 }
2550 return nil
2551}
2552
2553func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2554 omci := &ActivateSoftwareRequest{}
2555 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
2556 return decodingLayerDecoder(omci, data, p)
2557}
2558
Matteo Scandolof9d43412021-01-12 11:11:34 -08002559// SerializeTo provides serialization of an Activate Software message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002560func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2561 // Basic (common) OMCI Header is 8 octets, 10
2562 err := omci.MeBasePacket.SerializeTo(b)
2563 if err != nil {
2564 return err
2565 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002566 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002567 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002568 if omciErr.StatusCode() != me.Success {
2569 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002570 }
2571 // ME needs to support End Software Download
2572 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2573 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2574 }
2575 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002576 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002577 return me.NewProcessingError("invalid Entity Class for Activate Software request")
2578 }
2579 bytes, err := b.AppendBytes(1)
2580 if err != nil {
2581 return err
2582 }
2583 bytes[0] = omci.ActivateFlags
2584 if omci.ActivateFlags > 2 {
2585 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
2586 omci.ActivateFlags)
2587 return errors.New(msg)
2588 }
2589 return nil
2590}
2591
2592/////////////////////////////////////////////////////////////////////////////
2593//
2594type ActivateSoftwareResponse struct {
2595 MeBasePacket
2596 Result me.Results
2597}
2598
2599func (omci *ActivateSoftwareResponse) String() string {
2600 return fmt.Sprintf("%v, Result: %d (%v)",
2601 omci.MeBasePacket.String(), omci.Result, omci.Result)
2602}
2603
Matteo Scandolof9d43412021-01-12 11:11:34 -08002604// DecodeFromBytes decodes the given bytes of an Activate Softwre Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002605func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2606 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002607 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002608 if err != nil {
2609 return err
2610 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002611 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002612 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002613 if omciErr.StatusCode() != me.Success {
2614 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002615 }
2616 // ME needs to support End Software Download
2617 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2618 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
2619 }
2620 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002621 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002622 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2623 }
2624 omci.Result = me.Results(data[4])
2625 if omci.Result > me.Results(6) {
2626 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2627 omci.Result)
2628 return errors.New(msg)
2629 }
2630 return nil
2631}
2632
2633func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2634 omci := &ActivateSoftwareResponse{}
2635 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
2636 return decodingLayerDecoder(omci, data, p)
2637}
2638
Matteo Scandolof9d43412021-01-12 11:11:34 -08002639// SerializeTo provides serialization of an Activate Software Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002640func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2641 // Basic (common) OMCI Header is 8 octets, 10
2642 err := omci.MeBasePacket.SerializeTo(b)
2643 if err != nil {
2644 return err
2645 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002646 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002647 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002648 if omciErr.StatusCode() != me.Success {
2649 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002650 }
2651 // ME needs to support End Software Download
2652 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
2653 return me.NewProcessingError("managed entity does not support Activate Message-Type")
2654 }
2655 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002656 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002657 return me.NewProcessingError("invalid Entity Class for Activate Software response")
2658 }
2659 bytes, err := b.AppendBytes(1)
2660 if err != nil {
2661 return err
2662 }
2663 bytes[0] = byte(omci.Result)
2664 if omci.Result > me.Results(6) {
2665 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
2666 omci.Result)
2667 return errors.New(msg)
2668 }
2669 return nil
2670}
2671
2672/////////////////////////////////////////////////////////////////////////////
2673//
2674type CommitSoftwareRequest struct {
2675 MeBasePacket
2676}
2677
2678func (omci *CommitSoftwareRequest) String() string {
2679 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2680}
2681
Matteo Scandolof9d43412021-01-12 11:11:34 -08002682// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002683func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2684 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -08002685 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002686 if err != nil {
2687 return err
2688 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002689 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002690 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002691 if omciErr.StatusCode() != me.Success {
2692 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002693 }
2694 // ME needs to support End Software Download
2695 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2696 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2697 }
2698 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002699 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002700 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2701 }
2702 return nil
2703}
2704
2705func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
2706 omci := &CommitSoftwareRequest{}
2707 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
2708 return decodingLayerDecoder(omci, data, p)
2709}
2710
Matteo Scandolof9d43412021-01-12 11:11:34 -08002711// SerializeTo provides serialization of an Commit Software Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002712func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2713 // Basic (common) OMCI Header is 8 octets, 10
2714 err := omci.MeBasePacket.SerializeTo(b)
2715 if err != nil {
2716 return err
2717 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002718 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002719 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002720 if omciErr.StatusCode() != me.Success {
2721 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002722 }
2723 // ME needs to support End Software Download
2724 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2725 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2726 }
2727 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002728 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002729 return me.NewProcessingError("invalid Entity Class for Commit Software request")
2730 }
2731 return nil
2732}
2733
2734/////////////////////////////////////////////////////////////////////////////
2735//
2736type CommitSoftwareResponse struct {
2737 MeBasePacket
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002738 Result me.Results
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002739}
2740
2741func (omci *CommitSoftwareResponse) String() string {
2742 return fmt.Sprintf("%v", omci.MeBasePacket.String())
2743}
2744
Matteo Scandolof9d43412021-01-12 11:11:34 -08002745// DecodeFromBytes decodes the given bytes of a Commit Softwar Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002746func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2747 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002748 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002749 if err != nil {
2750 return err
2751 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002752 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002753 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002754 if omciErr.StatusCode() != me.Success {
2755 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002756 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002757 // ME needs to support Commit Software
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002758 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2759 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
2760 }
2761 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002762 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002763 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2764 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002765 omci.Result = me.Results(data[4])
2766 if omci.Result > me.Results(6) {
2767 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
2768 omci.Result)
2769 return errors.New(msg)
2770 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002771 return nil
2772}
2773
2774func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
2775 omci := &CommitSoftwareResponse{}
2776 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
2777 return decodingLayerDecoder(omci, data, p)
2778}
2779
Matteo Scandolof9d43412021-01-12 11:11:34 -08002780// SerializeTo provides serialization of an Commit Software Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002781func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2782 // Basic (common) OMCI Header is 8 octets, 10
2783 err := omci.MeBasePacket.SerializeTo(b)
2784 if err != nil {
2785 return err
2786 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002787 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002788 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002789 if omciErr.StatusCode() != me.Success {
2790 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002791 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002792 // ME needs to support Commit Software
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002793 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
2794 return me.NewProcessingError("managed entity does not support Commit Message-Type")
2795 }
2796 // Software Image Entity Class are always use the Software Image
Matteo Scandolof9d43412021-01-12 11:11:34 -08002797 if omci.EntityClass != me.SoftwareImageClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002798 return me.NewProcessingError("invalid Entity Class for Commit Software response")
2799 }
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002800 bytes, err := b.AppendBytes(1)
2801 if err != nil {
2802 return err
2803 }
2804 bytes[0] = byte(omci.Result)
2805 if omci.Result > me.Results(6) {
2806 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
2807 omci.Result)
2808 return errors.New(msg)
2809 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002810 return nil
2811}
2812
2813/////////////////////////////////////////////////////////////////////////////
2814//
2815type SynchronizeTimeRequest struct {
2816 MeBasePacket
2817 Year uint16
2818 Month uint8
2819 Day uint8
2820 Hour uint8
2821 Minute uint8
2822 Second uint8
2823}
2824
2825func (omci *SynchronizeTimeRequest) String() string {
2826 return fmt.Sprintf("%v, Date-Time: %d/%d/%d-%02d:%02d:%02d",
2827 omci.MeBasePacket.String(), omci.Year, omci.Month, omci.Day, omci.Hour, omci.Minute, omci.Second)
2828}
2829
Matteo Scandolof9d43412021-01-12 11:11:34 -08002830// DecodeFromBytes decodes the given bytes of a Synchronize Time Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002831func (omci *SynchronizeTimeRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2832 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002833 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+7)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002834 if err != nil {
2835 return err
2836 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002837 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002838 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002839 if omciErr.StatusCode() != me.Success {
2840 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002841 }
2842 // ME needs to support Synchronize Time
2843 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2844 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2845 }
2846 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08002847 if omci.EntityClass != me.OnuGClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002848 return me.NewProcessingError("invalid Entity Class for Synchronize Time request")
2849 }
2850 if omci.EntityInstance != 0 {
2851 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time request")
2852 }
2853 omci.Year = binary.BigEndian.Uint16(data[4:6])
2854 omci.Month = data[6]
2855 omci.Day = data[7]
2856 omci.Hour = data[8]
2857 omci.Minute = data[9]
2858 omci.Second = data[10]
2859 return nil
2860}
2861
2862func decodeSynchronizeTimeRequest(data []byte, p gopacket.PacketBuilder) error {
2863 omci := &SynchronizeTimeRequest{}
2864 omci.MsgLayerType = LayerTypeSynchronizeTimeRequest
2865 return decodingLayerDecoder(omci, data, p)
2866}
2867
Matteo Scandolof9d43412021-01-12 11:11:34 -08002868// SerializeTo provides serialization of an Synchronize Time Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002869func (omci *SynchronizeTimeRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2870 // Basic (common) OMCI Header is 8 octets, 10
2871 err := omci.MeBasePacket.SerializeTo(b)
2872 if err != nil {
2873 return err
2874 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002875 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002876 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002877 if omciErr.StatusCode() != me.Success {
2878 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002879 }
2880 // ME needs to support Synchronize Time
2881 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2882 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2883 }
2884 bytes, err := b.AppendBytes(7)
2885 if err != nil {
2886 return err
2887 }
2888 binary.BigEndian.PutUint16(bytes[0:2], omci.Year)
2889 bytes[2] = omci.Month
2890 bytes[3] = omci.Day
2891 bytes[4] = omci.Hour
2892 bytes[5] = omci.Minute
2893 bytes[6] = omci.Second
2894 return nil
2895}
2896
2897/////////////////////////////////////////////////////////////////////////////
2898//
2899type SynchronizeTimeResponse struct {
2900 MeBasePacket
2901 Result me.Results
2902 SuccessResults uint8 // Only if 'Result' is 0 -> success
2903}
2904
2905func (omci *SynchronizeTimeResponse) String() string {
2906 return fmt.Sprintf("%v, Results: %d (%v), Success: %d",
2907 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SuccessResults)
2908}
2909
Matteo Scandolof9d43412021-01-12 11:11:34 -08002910// DecodeFromBytes decodes the given bytes of a Synchronize Time Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002911func (omci *SynchronizeTimeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
2912 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08002913 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002914 if err != nil {
2915 return err
2916 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002917 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002918 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002919 if omciErr.StatusCode() != me.Success {
2920 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002921 }
2922 // ME needs to support Synchronize Time
2923 if !me.SupportsMsgType(meDefinition, me.SynchronizeTime) {
2924 return me.NewProcessingError("managed entity does not support Synchronize Time Message-Type")
2925 }
2926 // Synchronize Time Entity Class are always ONU-G (256) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08002927 if omci.EntityClass != me.OnuGClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002928 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2929 }
2930 if omci.EntityInstance != 0 {
2931 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2932 }
2933 omci.Result = me.Results(data[4])
2934 if omci.Result > me.DeviceBusy {
2935 msg := fmt.Sprintf("invalid results code: %v, must be 0..8", omci.Result)
2936 return errors.New(msg)
2937 }
2938 omci.SuccessResults = data[5]
2939 return nil
2940}
2941
2942func decodeSynchronizeTimeResponse(data []byte, p gopacket.PacketBuilder) error {
2943 omci := &SynchronizeTimeResponse{}
2944 omci.MsgLayerType = LayerTypeSynchronizeTimeResponse
2945 return decodingLayerDecoder(omci, data, p)
2946}
2947
Matteo Scandolof9d43412021-01-12 11:11:34 -08002948// SerializeTo provides serialization of an Synchronize Time Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002949func (omci *SynchronizeTimeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
2950 // Basic (common) OMCI Header is 8 octets, 10
2951 err := omci.MeBasePacket.SerializeTo(b)
2952 if err != nil {
2953 return err
2954 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08002955 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002956 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08002957 if omciErr.StatusCode() != me.Success {
2958 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002959 }
2960 // Synchronize Time Entity Class are always ONU DATA (2) and Entity Instance of 0
Matteo Scandolof9d43412021-01-12 11:11:34 -08002961 if omci.EntityClass != me.OnuGClassID {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002962 return me.NewProcessingError("invalid Entity Class for Synchronize Time response")
2963 }
2964 if omci.EntityInstance != 0 {
2965 return me.NewUnknownInstanceError("invalid Entity Instance for Synchronize Time response")
2966 }
2967 // ME needs to support Synchronize Time
2968 if !me.SupportsMsgType(entity, me.SynchronizeTime) {
2969 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
2970 }
2971 numBytes := 2
2972 if omci.Result != me.Success {
2973 numBytes = 1
2974 }
2975 bytes, err := b.AppendBytes(numBytes)
2976 if err != nil {
2977 return err
2978 }
2979 bytes[0] = uint8(omci.Result)
2980 if omci.Result == me.Success {
2981 bytes[1] = omci.SuccessResults
2982 }
2983 return nil
2984}
2985
2986/////////////////////////////////////////////////////////////////////////////
2987//
2988type RebootRequest struct {
2989 MeBasePacket
2990 RebootCondition byte
2991}
2992
2993func (omci *RebootRequest) String() string {
2994 return fmt.Sprintf("%v, Reboot Condition: %v",
2995 omci.MeBasePacket.String(), omci.RebootCondition)
2996}
2997
Matteo Scandolof9d43412021-01-12 11:11:34 -08002998// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07002999func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3000 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003001 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003002 if err != nil {
3003 return err
3004 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003005 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003006 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003007 if omciErr.StatusCode() != me.Success {
3008 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003009 }
3010 // ME needs to support Reboot
3011 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3012 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3013 }
3014 omci.RebootCondition = data[4]
3015 if omci.RebootCondition > 3 {
3016 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
3017 return errors.New(msg)
3018 }
3019 return nil
3020}
3021
3022func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
3023 omci := &RebootRequest{}
3024 omci.MsgLayerType = LayerTypeRebootRequest
3025 return decodingLayerDecoder(omci, data, p)
3026}
3027
Matteo Scandolof9d43412021-01-12 11:11:34 -08003028// SerializeTo provides serialization of an Reboot Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003029func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3030 // Basic (common) OMCI Header is 8 octets, 10
3031 err := omci.MeBasePacket.SerializeTo(b)
3032 if err != nil {
3033 return err
3034 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003035 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003036 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003037 if omciErr.StatusCode() != me.Success {
3038 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003039 }
3040 // ME needs to support Reboot
3041 if !me.SupportsMsgType(entity, me.Reboot) {
3042 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3043 }
3044 bytes, err := b.AppendBytes(1)
3045 if err != nil {
3046 return err
3047 }
3048 if omci.RebootCondition > 3 {
Matteo Scandolof9d43412021-01-12 11:11:34 -08003049 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
3050 omci.RebootCondition))
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003051 }
3052 bytes[0] = omci.RebootCondition
3053 return nil
3054}
3055
3056/////////////////////////////////////////////////////////////////////////////
3057//
3058type RebootResponse struct {
3059 MeBasePacket
3060 Result me.Results
3061}
3062
Matteo Scandolof9d43412021-01-12 11:11:34 -08003063// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003064func (omci *RebootResponse) String() string {
3065 return fmt.Sprintf("%v, Result: %d (%v)",
3066 omci.MeBasePacket.String(), omci.Result, omci.Result)
3067}
3068
Matteo Scandolof9d43412021-01-12 11:11:34 -08003069// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003070func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3071 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003072 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003073 if err != nil {
3074 return err
3075 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003076 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003077 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003078 if omciErr.StatusCode() != me.Success {
3079 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003080 }
3081 // ME needs to support Reboot
3082 if !me.SupportsMsgType(meDefinition, me.Reboot) {
3083 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
3084 }
3085 if omci.Result > 6 {
3086 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3087 return errors.New(msg)
3088 }
3089 omci.Result = me.Results(data[4])
3090 return nil
3091}
3092
3093func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
3094 omci := &RebootResponse{}
3095 omci.MsgLayerType = LayerTypeRebootResponse
3096 return decodingLayerDecoder(omci, data, p)
3097}
3098
Matteo Scandolof9d43412021-01-12 11:11:34 -08003099// SerializeTo provides serialization of an Reboot Response message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003100func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3101 // Basic (common) OMCI Header is 8 octets, 10
3102 err := omci.MeBasePacket.SerializeTo(b)
3103 if err != nil {
3104 return err
3105 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003106 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003107 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003108 if omciErr.StatusCode() != me.Success {
3109 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003110 }
3111 // ME needs to support Reboot
3112 if !me.SupportsMsgType(entity, me.Reboot) {
3113 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
3114 }
3115 bytes, err := b.AppendBytes(1)
3116 if err != nil {
3117 return err
3118 }
3119 if omci.Result > 6 {
3120 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
3121 return errors.New(msg)
3122 }
3123 bytes[0] = byte(omci.Result)
3124 return nil
3125}
3126
3127/////////////////////////////////////////////////////////////////////////////
3128//
3129type GetNextRequest struct {
3130 MeBasePacket
3131 AttributeMask uint16
3132 SequenceNumber uint16
3133}
3134
3135func (omci *GetNextRequest) String() string {
3136 return fmt.Sprintf("%v, Attribute Mask: %#x, Sequence Number: %v",
3137 omci.MeBasePacket.String(), omci.AttributeMask, omci.SequenceNumber)
3138}
3139
Matteo Scandolof9d43412021-01-12 11:11:34 -08003140// DecodeFromBytes decodes the given bytes of a Get Next Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003141func (omci *GetNextRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3142 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003143 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003144 if err != nil {
3145 return err
3146 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003147 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003148 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003149 if omciErr.StatusCode() != me.Success {
3150 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003151 }
3152 // ME needs to support GetNext
3153 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3154 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3155 }
3156 // Note: G.988 specifies that an error code of (3) should result if more
3157 // than one attribute is requested
3158 // TODO: Return error. Have flag to optionally allow it to be encoded
3159 // TODO: Check that the attribute is a table attirbute. Issue warning or return error
3160 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3161 omci.SequenceNumber = binary.BigEndian.Uint16(data[6:8])
3162 return nil
3163}
3164
3165func decodeGetNextRequest(data []byte, p gopacket.PacketBuilder) error {
3166 omci := &GetNextRequest{}
3167 omci.MsgLayerType = LayerTypeGetNextRequest
3168 return decodingLayerDecoder(omci, data, p)
3169}
3170
Matteo Scandolof9d43412021-01-12 11:11:34 -08003171// SerializeTo provides serialization of an Get Next Message Type Request
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003172func (omci *GetNextRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3173 // Basic (common) OMCI Header is 8 octets, 10
3174 err := omci.MeBasePacket.SerializeTo(b)
3175 if err != nil {
3176 return err
3177 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003178 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003179 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003180 if omciErr.StatusCode() != me.Success {
3181 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003182 }
3183 // ME needs to support GetNext
3184 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3185 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3186 }
3187 bytes, err := b.AppendBytes(4)
3188 if err != nil {
3189 return err
3190 }
3191 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3192 binary.BigEndian.PutUint16(bytes[2:], omci.SequenceNumber)
3193 return nil
3194}
3195
3196/////////////////////////////////////////////////////////////////////////////
3197//
3198type GetNextResponse struct {
3199 MeBasePacket
3200 Result me.Results
3201 AttributeMask uint16
3202 Attributes me.AttributeValueMap
3203}
3204
Matteo Scandolof9d43412021-01-12 11:11:34 -08003205// SerializeTo provides serialization of an Get Next Message Type Response
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003206func (omci *GetNextResponse) String() string {
3207 return fmt.Sprintf("%v, Result: %v, Attribute Mask: %#x, Attributes: %v",
3208 omci.MeBasePacket.String(), omci.Result, omci.AttributeMask, omci.Attributes)
3209}
3210
Matteo Scandolof9d43412021-01-12 11:11:34 -08003211// DecodeFromBytes decodes the given bytes of a Get Next Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003212func (omci *GetNextResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3213 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003214 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003215 if err != nil {
3216 return err
3217 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003218 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003219 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003220 if omciErr.StatusCode() != me.Success {
3221 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003222 }
3223 // ME needs to support Set
3224 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3225 return me.NewProcessingError("managed entity does not support Get Next Message-Type")
3226 }
3227 omci.Result = me.Results(data[4])
3228 if omci.Result > 6 {
3229 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3230 return errors.New(msg)
3231 }
3232 omci.AttributeMask = binary.BigEndian.Uint16(data[5:7])
3233
3234 // Attribute decode
3235 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[7:], p, byte(GetNextResponseType))
3236 if err != nil {
3237 return err
3238 }
3239 // Validate all attributes support read
3240 for attrName := range omci.Attributes {
3241 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3242 if err != nil {
3243 return err
3244 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003245 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003246 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3247 return me.NewProcessingError(msg)
3248 }
3249 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003250 if eidDef, eidDefOK := meDefinition.GetAttributeDefinitions()[0]; eidDefOK {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003251 omci.Attributes[eidDef.GetName()] = omci.EntityInstance
3252 return nil
3253 }
3254 panic("All Managed Entities have an EntityID attribute")
3255}
3256
3257func decodeGetNextResponse(data []byte, p gopacket.PacketBuilder) error {
3258 omci := &GetNextResponse{}
3259 omci.MsgLayerType = LayerTypeGetNextResponse
3260 return decodingLayerDecoder(omci, data, p)
3261}
3262
Matteo Scandolof9d43412021-01-12 11:11:34 -08003263// SerializeTo provides serialization of an Get Next Message Type Response
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003264func (omci *GetNextResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3265 // Basic (common) OMCI Header is 8 octets, 10
3266 err := omci.MeBasePacket.SerializeTo(b)
3267 if err != nil {
3268 return err
3269 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003270 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003271 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003272 if omciErr.StatusCode() != me.Success {
3273 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003274 }
3275 // ME needs to support Get
3276 if !me.SupportsMsgType(meDefinition, me.GetNext) {
3277 return me.NewProcessingError("managed entity does not support the Get Next Message-Type")
3278 }
3279 bytes, err := b.AppendBytes(3)
3280 if err != nil {
3281 return err
3282 }
3283 bytes[0] = byte(omci.Result)
3284 if omci.Result > 6 {
3285 msg := fmt.Sprintf("invalid get next results code: %v, must be 0..6", omci.Result)
3286 return errors.New(msg)
3287 }
3288 binary.BigEndian.PutUint16(bytes[1:3], omci.AttributeMask)
3289
3290 // Validate all attributes support read
3291 for attrName := range omci.Attributes {
3292 attr, err := me.GetAttributeDefinitionByName(meDefinition.GetAttributeDefinitions(), attrName)
3293 if err != nil {
3294 return err
3295 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003296 if attr.Index != 0 && !me.SupportsAttributeAccess(*attr, me.Read) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003297 msg := fmt.Sprintf("attribute '%v' does not support read access", attrName)
3298 return me.NewProcessingError(msg)
3299 }
3300 }
3301 // Attribute serialization
3302 switch omci.Result {
3303 default:
3304 break
3305
3306 case me.Success:
3307 // TODO: Only Baseline supported at this time
3308 bytesAvailable := MaxBaselineLength - 11 - 8
3309
Matteo Scandolof9d43412021-01-12 11:11:34 -08003310 err, _ = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3311 byte(GetNextResponseType), bytesAvailable, false)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003312 if err != nil {
3313 return err
3314 }
3315 }
3316 return nil
3317}
3318
3319/////////////////////////////////////////////////////////////////////////////
3320//
3321type TestResultMsg struct {
3322 MeBasePacket
3323}
3324
3325func (omci *TestResultMsg) String() string {
3326 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3327}
3328
Matteo Scandolof9d43412021-01-12 11:11:34 -08003329// DecodeFromBytes decodes the given bytes of a Test Result Notification into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003330func (omci *TestResultMsg) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3331 // Common ClassID/EntityID decode in msgBase
Matteo Scandolocedde462021-03-09 17:37:16 -08003332 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003333 if err != nil {
3334 return err
3335 }
3336 return errors.New("need to implement") // TODO: Fix me) // return nil
3337}
3338
3339func decodeTestResult(data []byte, p gopacket.PacketBuilder) error {
3340 omci := &TestResultMsg{}
3341 omci.MsgLayerType = LayerTypeTestResult
3342 return decodingLayerDecoder(omci, data, p)
3343}
3344
Matteo Scandolof9d43412021-01-12 11:11:34 -08003345// SerializeTo provides serialization of an Test Result notification message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003346func (omci *TestResultMsg) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3347 // Basic (common) OMCI Header is 8 octets, 10
3348 err := omci.MeBasePacket.SerializeTo(b)
3349 if err != nil {
3350 return err
3351 }
3352 return errors.New("need to implement") // TODO: Fix me) // omci.cachedME.SerializeTo(mask, b)
3353}
3354
3355/////////////////////////////////////////////////////////////////////////////
3356//
3357type GetCurrentDataRequest struct {
3358 MeBasePacket
3359 AttributeMask uint16
3360}
3361
3362func (omci *GetCurrentDataRequest) String() string {
3363 return fmt.Sprintf("%v, Attribute Mask: %#x",
3364 omci.MeBasePacket.String(), omci.AttributeMask)
3365}
3366
Matteo Scandolof9d43412021-01-12 11:11:34 -08003367// DecodeFromBytes decodes the given bytes of a Get Current Data Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003368func (omci *GetCurrentDataRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3369 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003370 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003371 if err != nil {
3372 return err
3373 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003374 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003375 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003376 if omciErr.StatusCode() != me.Success {
3377 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003378 }
3379 // ME needs to support GetNext
3380 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3381 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3382 }
3383 // Note: G.988 specifies that an error code of (3) should result if more
3384 // than one attribute is requested
3385 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3386 return nil
3387}
3388
3389func decodeGetCurrentDataRequest(data []byte, p gopacket.PacketBuilder) error {
3390 omci := &GetCurrentDataRequest{}
3391 omci.MsgLayerType = LayerTypeGetCurrentDataRequest
3392 return decodingLayerDecoder(omci, data, p)
3393}
3394
Matteo Scandolof9d43412021-01-12 11:11:34 -08003395// SerializeTo provides serialization of an Get Current Data Request message
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003396func (omci *GetCurrentDataRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3397 // Basic (common) OMCI Header is 8 octets, 10
3398 err := omci.MeBasePacket.SerializeTo(b)
3399 if err != nil {
3400 return err
3401 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003402 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003403 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003404 if omciErr.StatusCode() != me.Success {
3405 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003406 }
3407 // ME needs to support GetNext
3408 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3409 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3410 }
3411 bytes, err := b.AppendBytes(2)
3412 if err != nil {
3413 return err
3414 }
3415 binary.BigEndian.PutUint16(bytes, omci.AttributeMask)
3416 return nil
3417}
3418
3419/////////////////////////////////////////////////////////////////////////////
3420//
3421type GetCurrentDataResponse struct {
3422 MeBasePacket
3423 Result me.Results
3424 AttributeMask uint16
3425 Attributes me.AttributeValueMap
3426}
3427
3428func (omci *GetCurrentDataResponse) String() string {
3429 return fmt.Sprintf("%v, Result: %d (%v), Attribute Mask: %#x, Attributes: %v",
3430 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.AttributeMask, omci.Attributes)
3431}
3432
Matteo Scandolof9d43412021-01-12 11:11:34 -08003433// DecodeFromBytes decodes the given bytes of a Get Current Data Respnse into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003434func (omci *GetCurrentDataResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3435 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003436 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+3)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003437 if err != nil {
3438 return err
3439 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003440 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003441 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003442 if omciErr.StatusCode() != me.Success {
3443 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003444 }
3445 // ME needs to support Set
3446 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3447 return me.NewProcessingError("managed entity does not support Get Current Data Message-Type")
3448 }
3449 omci.AttributeMask = binary.BigEndian.Uint16(data[4:6])
3450
Matteo Scandolof9d43412021-01-12 11:11:34 -08003451 switch omci.Result {
3452 case me.ProcessingError, me.NotSupported, me.UnknownEntity, me.UnknownInstance, me.DeviceBusy:
3453 return nil // Done (do not try and decode attributes)
3454 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003455 // Attribute decode
3456 omci.Attributes, err = meDefinition.DecodeAttributes(omci.AttributeMask, data[6:], p, byte(GetCurrentDataResponseType))
3457 if err != nil {
3458 return err
3459 }
3460 return nil
3461}
3462
3463func decodeGetCurrentDataResponse(data []byte, p gopacket.PacketBuilder) error {
3464 omci := &GetCurrentDataResponse{}
3465 omci.MsgLayerType = LayerTypeGetCurrentDataResponse
3466 return decodingLayerDecoder(omci, data, p)
3467}
3468
Matteo Scandolof9d43412021-01-12 11:11:34 -08003469// SerializeTo provides serialization of an Get Current Data Message Type Response
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003470func (omci *GetCurrentDataResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3471 // Basic (common) OMCI Header is 8 octets, 10
3472 err := omci.MeBasePacket.SerializeTo(b)
3473 if err != nil {
3474 return err
3475 }
Matteo Scandolof9d43412021-01-12 11:11:34 -08003476 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003477 me.ParamData{EntityID: omci.EntityInstance})
Matteo Scandolof9d43412021-01-12 11:11:34 -08003478 if omciErr.StatusCode() != me.Success {
3479 return omciErr.GetError()
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003480 }
3481 // ME needs to support Get
3482 if !me.SupportsMsgType(meDefinition, me.GetCurrentData) {
3483 return me.NewProcessingError("managed entity does not support the Get Current Data Message-Type")
3484 }
3485 bytes, err := b.AppendBytes(2)
3486 if err != nil {
3487 return err
3488 }
3489 binary.BigEndian.PutUint16(bytes[0:2], omci.AttributeMask)
3490
3491 // Attribute serialization
3492 // TODO: Only Baseline supported at this time
3493 bytesAvailable := MaxBaselineLength - 9 - 8
Matteo Scandolof9d43412021-01-12 11:11:34 -08003494 var failedMask uint16
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003495
Matteo Scandolof9d43412021-01-12 11:11:34 -08003496 err, failedMask = meDefinition.SerializeAttributes(omci.Attributes, omci.AttributeMask, b,
3497 byte(GetCurrentDataResponseType), bytesAvailable, opts.FixLengths)
3498
3499 if failedMask != 0 {
3500 // TODO: See GetResponse serialization above for the steps here
3501 return me.NewMessageTruncatedError("getCurrentData attribute truncation not yet supported")
3502 }
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003503 if err != nil {
3504 return err
3505 }
3506 return nil
3507}
3508
3509/////////////////////////////////////////////////////////////////////////////
3510//
3511type SetTableRequest struct {
3512 MeBasePacket
3513 // TODO: Fix me when extended messages supported)
3514}
3515
3516func (omci *SetTableRequest) String() string {
3517 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3518}
3519
Matteo Scandolof9d43412021-01-12 11:11:34 -08003520// DecodeFromBytes decodes the given bytes of a Set Table Request into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003521func (omci *SetTableRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3522 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003523 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+2)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003524 if err != nil {
3525 return err
3526 }
3527 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3528}
3529
3530func decodeSetTableRequest(data []byte, p gopacket.PacketBuilder) error {
3531 omci := &SetTableRequest{}
3532 omci.MsgLayerType = LayerTypeSetTableRequest
3533 return decodingLayerDecoder(omci, data, p)
3534}
3535
Matteo Scandolof9d43412021-01-12 11:11:34 -08003536// SerializeTo provides serialization of an Set Table Message Type Request
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003537func (omci *SetTableRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3538 // Basic (common) OMCI Header is 8 octets, 10
3539 err := omci.MeBasePacket.SerializeTo(b)
3540 if err != nil {
3541 return err
3542 }
3543 return errors.New("need to implement") /// TODO: Fix me when extended messages supported)
3544}
3545
3546/////////////////////////////////////////////////////////////////////////////
3547//
3548type SetTableResponse struct {
3549 MeBasePacket
3550 // TODO: Fix me when extended messages supported)
3551}
3552
3553func (omci *SetTableResponse) String() string {
3554 return fmt.Sprintf("%v", omci.MeBasePacket.String())
3555}
3556
Matteo Scandolof9d43412021-01-12 11:11:34 -08003557// DecodeFromBytes decodes the given bytes of a Set Table Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003558func (omci *SetTableResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3559 // Common ClassID/EntityID decode in msgBase
Matteo Scandolo4b077aa2021-02-16 17:33:37 -08003560 err := omci.MeBasePacket.DecodeFromBytes(data, p, 6+1)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003561 if err != nil {
3562 return err
3563 }
3564 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3565}
3566
3567func decodeSetTableResponse(data []byte, p gopacket.PacketBuilder) error {
3568 omci := &SetTableResponse{}
3569 omci.MsgLayerType = LayerTypeSetTableResponse
3570 return decodingLayerDecoder(omci, data, p)
3571}
3572
Matteo Scandolof9d43412021-01-12 11:11:34 -08003573// SerializeTo provides serialization of an Set Table Message Type Response
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003574func (omci *SetTableResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3575 // Basic (common) OMCI Header is 8 octets, 10
3576 err := omci.MeBasePacket.SerializeTo(b)
3577 if err != nil {
3578 return err
3579 }
3580 return errors.New("need to implement") // TODO: Fix me when extended messages supported)
3581}
3582
3583/////////////////////////////////////////////////////////////////////////////
3584//
3585type UnsupportedMessageTypeResponse struct {
3586 MeBasePacket
3587 Result me.Results
3588}
3589
Matteo Scandolof9d43412021-01-12 11:11:34 -08003590// DecodeFromBytes decodes the given bytes of an Unsupported Message Type Response into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003591func (omci *UnsupportedMessageTypeResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
3592 return errors.New("you should never really decode this")
3593}
3594
Matteo Scandolof9d43412021-01-12 11:11:34 -08003595// SerializeTo provides serialization of an Unsupported Message Type Response
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07003596func (omci *UnsupportedMessageTypeResponse) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
3597 // Basic (common) OMCI Header is 8 octets, 10
3598 err := omci.MeBasePacket.SerializeTo(b)
3599 if err != nil {
3600 return err
3601 }
3602 bytes, err := b.AppendBytes(1)
3603 if err != nil {
3604 return err
3605 }
3606 bytes[0] = byte(omci.Result)
3607 return nil
3608}