blob: f2983ca75bd7ed6710863b8b6df225212bf56bef [file] [log] [blame]
Chip Boling610117d2021-09-09 11:24:34 -05001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
3 * Copyright 2020-present Open Networking Foundation
4
5 * 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
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * 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.
16 */
17
18package omci
19
20import (
21 "encoding/binary"
22 "errors"
23 "fmt"
24 "github.com/google/gopacket"
25 me "github.com/opencord/omci-lib-go/generated"
26)
27
28type RebootRequest struct {
29 MeBasePacket
30 RebootCondition byte
31}
32
33func (omci *RebootRequest) String() string {
34 return fmt.Sprintf("%v, Reboot Condition: %v",
35 omci.MeBasePacket.String(), omci.RebootCondition)
36}
37
38// LayerType returns LayerTypeRebootRequest
39func (omci *RebootRequest) LayerType() gopacket.LayerType {
40 return LayerTypeRebootRequest
41}
42
43// CanDecode returns the set of layer types that this DecodingLayer can decode
44func (omci *RebootRequest) CanDecode() gopacket.LayerClass {
45 return LayerTypeRebootRequest
46}
47
48// NextLayerType returns the layer type contained by this DecodingLayer.
49func (omci *RebootRequest) NextLayerType() gopacket.LayerType {
50 return gopacket.LayerTypePayload
51}
52
53// DecodeFromBytes decodes the given bytes of a Reboot Request into this layer
54func (omci *RebootRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
55 // Common ClassID/EntityID decode in msgBase
56 var hdrSize int
57 if omci.Extended {
58 hdrSize = 6 + 1
59 } else {
60 hdrSize = 4 + 1
61 }
62 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
63 if err != nil {
64 return err
65 }
66 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
67 me.ParamData{EntityID: omci.EntityInstance})
68 if omciErr.StatusCode() != me.Success {
69 return omciErr.GetError()
70 }
71 // ME needs to support Reboot
72 if !me.SupportsMsgType(meDefinition, me.Reboot) {
73 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
74 }
75 offset := hdrSize - 1
76 omci.RebootCondition = data[offset]
77 if omci.RebootCondition > 3 {
78 msg := fmt.Sprintf("invalid reboot condition code: %v, must be 0..3", omci.RebootCondition)
79 return errors.New(msg)
80 }
81 return nil
82}
83
84func decodeRebootRequest(data []byte, p gopacket.PacketBuilder) error {
85 omci := &RebootRequest{}
86 omci.MsgLayerType = LayerTypeRebootRequest
87 return decodingLayerDecoder(omci, data, p)
88}
89
90func decodeRebootRequestExtended(data []byte, p gopacket.PacketBuilder) error {
91 omci := &RebootRequest{}
92 omci.MsgLayerType = LayerTypeRebootRequest
93 omci.Extended = true
94 return decodingLayerDecoder(omci, data, p)
95}
96
97// SerializeTo provides serialization of an Reboot Request message
98func (omci *RebootRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
99 // Basic (common) OMCI Header is 8 octets, 10
100 err := omci.MeBasePacket.SerializeTo(b)
101 if err != nil {
102 return err
103 }
104 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
105 me.ParamData{EntityID: omci.EntityInstance})
106 if omciErr.StatusCode() != me.Success {
107 return omciErr.GetError()
108 }
109 // ME needs to support Reboot
110 if !me.SupportsMsgType(entity, me.Reboot) {
111 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
112 }
113 var offset int
114 if omci.Extended {
115 offset = 2
116 } else {
117 offset = 0
118 }
119 bytes, err := b.AppendBytes(offset + 1)
120 if err != nil {
121 return err
122 }
123 if omci.RebootCondition > 3 {
124 return me.NewProcessingError(fmt.Sprintf("invalid reboot condition code: %v, must be 0..3",
125 omci.RebootCondition))
126 }
127 if omci.Extended {
128 binary.BigEndian.PutUint16(bytes, 1)
129 }
130 bytes[offset] = omci.RebootCondition
131 return nil
132}
133
134type RebootResponse struct {
135 MeBasePacket
136 Result me.Results
137}
138
139// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
140func (omci *RebootResponse) String() string {
141 return fmt.Sprintf("%v, Result: %d (%v)",
142 omci.MeBasePacket.String(), omci.Result, omci.Result)
143}
144
145// LayerType returns LayerTypeRebootResponse
146func (omci *RebootResponse) LayerType() gopacket.LayerType {
147 return LayerTypeRebootResponse
148}
149
150// CanDecode returns the set of layer types that this DecodingLayer can decode
151func (omci *RebootResponse) CanDecode() gopacket.LayerClass {
152 return LayerTypeRebootResponse
153}
154
155// NextLayerType returns the layer type contained by this DecodingLayer.
156func (omci *RebootResponse) NextLayerType() gopacket.LayerType {
157 return gopacket.LayerTypePayload
158}
159
160// DecodeFromBytes decodes the given bytes of a Reboot Response into this layer
161func (omci *RebootResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
162 // Common ClassID/EntityID decode in msgBase
163 var hdrSize int
164 if omci.Extended {
165 hdrSize = 6 + 1
166 } else {
167 hdrSize = 4 + 1
168 }
169 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
170 if err != nil {
171 return err
172 }
173 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
174 me.ParamData{EntityID: omci.EntityInstance})
175 if omciErr.StatusCode() != me.Success {
176 return omciErr.GetError()
177 }
178 // ME needs to support Reboot
179 if !me.SupportsMsgType(meDefinition, me.Reboot) {
180 return me.NewProcessingError("managed entity does not support Reboot Message-Type")
181 }
182 if omci.Result > 6 {
183 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
184 return errors.New(msg)
185 }
186 offset := hdrSize - 1
187 omci.Result = me.Results(data[offset])
188 return nil
189}
190
191func decodeRebootResponse(data []byte, p gopacket.PacketBuilder) error {
192 omci := &RebootResponse{}
193 omci.MsgLayerType = LayerTypeRebootResponse
194 return decodingLayerDecoder(omci, data, p)
195}
196
197func decodeRebootResponseExtended(data []byte, p gopacket.PacketBuilder) error {
198 omci := &RebootResponse{}
199 omci.MsgLayerType = LayerTypeRebootResponse
200 omci.Extended = true
201 return decodingLayerDecoder(omci, data, p)
202}
203
204// SerializeTo provides serialization of an Reboot Response message
205func (omci *RebootResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
206 // Basic (common) OMCI Header is 8 octets, 10
207 err := omci.MeBasePacket.SerializeTo(b)
208 if err != nil {
209 return err
210 }
211 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
212 me.ParamData{EntityID: omci.EntityInstance})
213 if omciErr.StatusCode() != me.Success {
214 return omciErr.GetError()
215 }
216 // ME needs to support Reboot
217 if !me.SupportsMsgType(entity, me.Reboot) {
218 return me.NewProcessingError("managed entity does not support the Synchronize Time Message-Type")
219 }
220 var offset int
221 if omci.Extended {
222 offset = 2
223 } else {
224 offset = 0
225 }
226 bytes, err := b.AppendBytes(offset + 1)
227 if err != nil {
228 return err
229 }
230 if omci.Result > 6 {
231 msg := fmt.Sprintf("invalid reboot results code: %v, must be 0..6", omci.Result)
232 return errors.New(msg)
233 }
234 if omci.Extended {
235 binary.BigEndian.PutUint16(bytes, 1)
236 }
237 bytes[offset] = byte(omci.Result)
238 return nil
239}