blob: de5cb7423e545531f9e9545ecf42793f51980bfe [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 StartSoftwareDownloadRequest struct {
29 MeBasePacket // Note: EntityInstance for software download is two specific values
30 WindowSize byte // Window Size -1
31 ImageSize uint32 // Octets
32 NumberOfCircuitPacks byte
33 CircuitPacks []uint16 // MSB & LSB of software image instance
34}
35
36func (omci *StartSoftwareDownloadRequest) String() string {
37 return fmt.Sprintf("%v, Window Size: %v, Image Size: %v, # Circuit Packs: %v",
38 omci.MeBasePacket.String(), omci.WindowSize, omci.ImageSize, omci.NumberOfCircuitPacks)
39}
40
41// LayerType returns LayerTypeStartSoftwareDownloadRequest
42func (omci *StartSoftwareDownloadRequest) LayerType() gopacket.LayerType {
43 return LayerTypeStartSoftwareDownloadRequest
44}
45
46// CanDecode returns the set of layer types that this DecodingLayer can decode
47func (omci *StartSoftwareDownloadRequest) CanDecode() gopacket.LayerClass {
48 return LayerTypeStartSoftwareDownloadRequest
49}
50
51// NextLayerType returns the layer type contained by this DecodingLayer.
52func (omci *StartSoftwareDownloadRequest) NextLayerType() gopacket.LayerType {
53 return gopacket.LayerTypePayload
54}
55
56// DecodeFromBytes decodes the given bytes of a Start Software Download Request into this layer
57func (omci *StartSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
58 // Common ClassID/EntityID decode in msgBase
59 var hdrSize int
60 if omci.Extended {
61 hdrSize = 6 + 4
62 } else {
63 hdrSize = 4 + 4
64 }
65 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
66 if err != nil {
67 return err
68 }
69 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
70 me.ParamData{EntityID: omci.EntityInstance})
71 if omciErr.StatusCode() != me.Success {
72 return omciErr.GetError()
73 }
74 // ME needs to support Start Software Download
75 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
76 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
77 }
78 // Software Image Entity Class are always use the Software Image
79 if omci.EntityClass != me.SoftwareImageClassID {
80 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
81 }
82 var offset int
83 if omci.Extended {
84 offset = 2
85 }
86 omci.WindowSize = data[offset+4]
87 omci.ImageSize = binary.BigEndian.Uint32(data[offset+5:])
88 omci.NumberOfCircuitPacks = data[offset+9]
89 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
90 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
91 omci.NumberOfCircuitPacks))
92 }
93 omci.CircuitPacks = make([]uint16, omci.NumberOfCircuitPacks)
94 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
95 omci.CircuitPacks[index] = binary.BigEndian.Uint16(data[offset+10+(index*2):])
96 }
97 return nil
98}
99
100func decodeStartSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
101 omci := &StartSoftwareDownloadRequest{}
102 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
103 return decodingLayerDecoder(omci, data, p)
104}
105
106func decodeStartSoftwareDownloadRequestExtended(data []byte, p gopacket.PacketBuilder) error {
107 omci := &StartSoftwareDownloadRequest{}
108 omci.MsgLayerType = LayerTypeStartSoftwareDownloadRequest
109 omci.Extended = true
110 return decodingLayerDecoder(omci, data, p)
111}
112
113// SerializeTo provides serialization of an Start Software Download Request message
114func (omci *StartSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
115 // Basic (common) OMCI Header is 8 octets, 10
116 err := omci.MeBasePacket.SerializeTo(b)
117 if err != nil {
118 return err
119 }
120 entity, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
121 me.ParamData{EntityID: omci.EntityInstance})
122 if omciErr.StatusCode() != me.Success {
123 return omciErr.GetError()
124 }
125 // ME needs to support Start Software Download
126 if !me.SupportsMsgType(entity, me.StartSoftwareDownload) {
127 return me.NewProcessingError("managed entity does not support the Start Software Download Message-Type")
128 }
129 // Software Image Entity Class are always use the Software Image
130 if omci.EntityClass != me.SoftwareImageClassID {
131 return me.NewProcessingError("invalid Entity Class for Start Software Download request")
132 }
133 if omci.NumberOfCircuitPacks < 1 || omci.NumberOfCircuitPacks > 9 {
134 return me.NewProcessingError(fmt.Sprintf("invalid number of Circuit Packs: %v, must be 1..9",
135 omci.NumberOfCircuitPacks))
136 }
137 var offset int
138 if omci.Extended {
139 offset = 2
140 }
141 bytes, err := b.AppendBytes(offset + 6 + (2 * int(omci.NumberOfCircuitPacks)))
142 if err != nil {
143 return err
144 }
145 if omci.Extended {
146 binary.BigEndian.PutUint16(bytes, uint16(6+(2*int(omci.NumberOfCircuitPacks))))
147 }
148 bytes[offset] = omci.WindowSize
149 binary.BigEndian.PutUint32(bytes[offset+1:], omci.ImageSize)
150 bytes[offset+5] = omci.NumberOfCircuitPacks
151 for index := 0; index < int(omci.NumberOfCircuitPacks); index++ {
152 binary.BigEndian.PutUint16(bytes[offset+6+(index*2):], omci.CircuitPacks[index])
153 }
154 return nil
155}
156
157type DownloadResults struct {
158 ManagedEntityID uint16 // ME ID of software image entity instance (slot number plus instance 0..1 or 2..254 vendor-specific)
159 Result me.Results
160}
161
162func (dr *DownloadResults) String() string {
163 return fmt.Sprintf("ME: %v (%#x), Results: %d (%v)", dr.ManagedEntityID, dr.ManagedEntityID,
164 dr.Result, dr.Result)
165}
166
167type StartSoftwareDownloadResponse struct {
168 MeBasePacket // Note: EntityInstance for software download is two specific values
169 Result me.Results
170 WindowSize byte // Window Size -1
171 NumberOfInstances byte
172 MeResults []DownloadResults
173}
174
175func (omci *StartSoftwareDownloadResponse) String() string {
176 return fmt.Sprintf("%v, Results: %v, Window Size: %v, # of Instances: %v, ME Results: %v",
177 omci.MeBasePacket.String(), omci.Result, omci.WindowSize, omci.NumberOfInstances, omci.MeResults)
178}
179
180// LayerType returns LayerTypeStartSoftwareDownloadResponse
181func (omci *StartSoftwareDownloadResponse) LayerType() gopacket.LayerType {
182 return LayerTypeStartSoftwareDownloadResponse
183}
184
185// CanDecode returns the set of layer types that this DecodingLayer can decode
186func (omci *StartSoftwareDownloadResponse) CanDecode() gopacket.LayerClass {
187 return LayerTypeStartSoftwareDownloadResponse
188}
189
190// NextLayerType returns the layer type contained by this DecodingLayer.
191func (omci *StartSoftwareDownloadResponse) NextLayerType() gopacket.LayerType {
192 return gopacket.LayerTypePayload
193}
194
195// DecodeFromBytes decodes the given bytes of a Start Software Download Response into this layer
196func (omci *StartSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
197 // Common ClassID/EntityID decode in msgBase
198 var hdrSize int
199 if omci.Extended {
200 hdrSize = 6 + 3
201 } else {
202 hdrSize = 4 + 3
203 }
204 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
205 if err != nil {
206 return err
207 }
208 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
209 me.ParamData{EntityID: omci.EntityInstance})
210 if omciErr.StatusCode() != me.Success {
211 return omciErr.GetError()
212 }
213 // ME needs to support Start Software Download
214 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
215 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
216 }
217 // Software Image Entity Class are always use the Software Image
218 if omci.EntityClass != me.SoftwareImageClassID {
219 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
220 }
221 var offset int
222 if omci.Extended {
223 offset = 2
224 }
225 omci.Result = me.Results(data[offset+4])
226 if omci.Result > me.DeviceBusy {
227 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
228 omci.Result)
229 return errors.New(msg)
230 }
231 omci.WindowSize = data[offset+5]
232 omci.NumberOfInstances = data[offset+6]
233
234 if omci.NumberOfInstances > 9 {
235 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
236 omci.NumberOfInstances)
237 return errors.New(msg)
238 }
239 if omci.NumberOfInstances > 0 {
240 // TODO: Calculate additional space needed and see if it is truncated
241 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
242
243 for index := 0; index < int(omci.NumberOfInstances); index++ {
244 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[offset+7+(index*3):])
245 omci.MeResults[index].Result = me.Results(data[offset+9+(index*3)])
246 if omci.MeResults[index].Result > me.DeviceBusy {
247 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
248 index, omci.MeResults[index])
249 return errors.New(msg)
250 }
251 }
252 }
253 return nil
254}
255
256func decodeStartSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
257 omci := &StartSoftwareDownloadResponse{}
258 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
259 return decodingLayerDecoder(omci, data, p)
260}
261
262func decodeStartSoftwareDownloadResponseExtended(data []byte, p gopacket.PacketBuilder) error {
263 omci := &StartSoftwareDownloadResponse{}
264 omci.MsgLayerType = LayerTypeStartSoftwareDownloadResponse
265 omci.Extended = true
266 return decodingLayerDecoder(omci, data, p)
267}
268
269// SerializeTo provides serialization of an Start Software Download Response message
270func (omci *StartSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
271 // Basic (common) OMCI Header is 8 octets, 10
272 err := omci.MeBasePacket.SerializeTo(b)
273 if err != nil {
274 return err
275 }
276 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
277 me.ParamData{EntityID: omci.EntityInstance})
278 if omciErr.StatusCode() != me.Success {
279 return omciErr.GetError()
280 }
281 // ME needs to support Start Software Download
282 if !me.SupportsMsgType(meDefinition, me.StartSoftwareDownload) {
283 return me.NewProcessingError("managed entity does not support Start Software Download Message-Type")
284 }
285 // Software Image Entity Class are always use the Software Image
286 if omci.EntityClass != me.SoftwareImageClassID {
287 return me.NewProcessingError("invalid Entity Class for Start Software Download response")
288 }
289 if omci.Result > me.DeviceBusy {
290 msg := fmt.Sprintf("invalid results for Start Software Download response: %v, must be 0..6",
291 omci.Result)
292 return errors.New(msg)
293 }
294 if omci.NumberOfInstances > 9 {
295 msg := fmt.Sprintf("invalid number of Circuit Packs: %v, must be 0..9",
296 omci.NumberOfInstances)
297 return errors.New(msg)
298 }
299 var offset int
300 if omci.Extended {
301 offset = 2
302 }
303 bytes, err := b.AppendBytes(offset + 3 + (3 * int(omci.NumberOfInstances)))
304 if err != nil {
305 return err
306 }
307 if omci.Extended {
308 binary.BigEndian.PutUint16(bytes, uint16(3+(3*int(omci.NumberOfInstances))))
309 }
310 bytes[offset] = byte(omci.Result)
311 bytes[offset+1] = omci.WindowSize
312 bytes[offset+2] = omci.NumberOfInstances
313
314 if omci.NumberOfInstances > 0 {
315 for index := 0; index < int(omci.NumberOfInstances); index++ {
316 binary.BigEndian.PutUint16(bytes[offset+3+(3*index):], omci.MeResults[index].ManagedEntityID)
317
318 if omci.MeResults[index].Result > me.DeviceBusy {
319 msg := fmt.Sprintf("invalid results for Start Software Download instance %v response: %v, must be 0..6",
320 index, omci.MeResults[index])
321 return errors.New(msg)
322 }
323 bytes[offset+5+(3*index)] = byte(omci.MeResults[index].Result)
324 }
325 }
326 return nil
327}
328
329// DownloadSectionRequest data is bound by the message set in use. For the
330// Baseline message set use MaxDownloadSectionLength and for the Extended message
331// set, MaxDownloadSectionExtendedLength is provided
332type DownloadSectionRequest struct {
333 MeBasePacket // Note: EntityInstance for software download is two specific values
334 SectionNumber byte
335 SectionData []byte // 0 padding if final transfer requires only a partial block for baseline set
336}
337
338func (omci *DownloadSectionRequest) String() string {
339 return fmt.Sprintf("%v, Section #: %v, Data Length: %v",
340 omci.MeBasePacket.String(), omci.SectionNumber, len(omci.SectionData))
341}
342
343// LayerType returns LayerTypeDownloadSectionRequest
344func (omci *DownloadSectionRequest) LayerType() gopacket.LayerType {
345 return LayerTypeDownloadSectionRequest
346}
347
348// CanDecode returns the set of layer types that this DecodingLayer can decode
349func (omci *DownloadSectionRequest) CanDecode() gopacket.LayerClass {
350 return LayerTypeDownloadSectionRequest
351}
352
353// NextLayerType returns the layer type contained by this DecodingLayer.
354func (omci *DownloadSectionRequest) NextLayerType() gopacket.LayerType {
355 return gopacket.LayerTypePayload
356}
357
358// DecodeFromBytes decodes the given bytes of a Download Section Request into this layer
359func (omci *DownloadSectionRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
360 // Common ClassID/EntityID decode in msgBase
361 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+1)
362 if err != nil {
363 return err
364 }
365 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
366 me.ParamData{EntityID: omci.EntityInstance})
367 if omciErr.StatusCode() != me.Success {
368 return omciErr.GetError()
369 }
370 // ME needs to support Download section
371 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
372 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
373 }
374 // Software Image Entity Class are always use the Software Image
375 if omci.EntityClass != me.SoftwareImageClassID {
376 return me.NewProcessingError("invalid Entity Class for Download Section request")
377 }
378 if omci.Extended {
379 if len(data) < 7 {
380 p.SetTruncated()
381 return errors.New("frame too small")
382 }
383 if len(data[7:]) > MaxDownloadSectionExtendedLength {
384 return errors.New(fmt.Sprintf("software image data too large. Received %v, Max: %v",
385 len(data[7:]), MaxDownloadSectionExtendedLength))
386 }
387 omci.SectionData = make([]byte, len(data[7:]))
388 omci.SectionNumber = data[6]
389 copy(omci.SectionData, data[7:])
390 } else {
391 if len(data[5:]) != MaxDownloadSectionLength {
392 p.SetTruncated()
393 return errors.New(fmt.Sprintf("software image size invalid. Received %v, Expected: %v",
394 len(data[5:]), MaxDownloadSectionLength))
395 }
396 omci.SectionData = make([]byte, MaxDownloadSectionLength)
397 omci.SectionNumber = data[4]
398 copy(omci.SectionData, data[5:])
399 }
400 return nil
401}
402
403func decodeDownloadSectionRequest(data []byte, p gopacket.PacketBuilder) error {
404 omci := &DownloadSectionRequest{}
405 omci.MsgLayerType = LayerTypeDownloadSectionRequest
406 return decodingLayerDecoder(omci, data, p)
407}
408
409func decodeDownloadSectionRequestExtended(data []byte, p gopacket.PacketBuilder) error {
410 omci := &DownloadSectionRequest{}
411 omci.MsgLayerType = LayerTypeDownloadSectionRequest
412 omci.Extended = true
413 return decodingLayerDecoder(omci, data, p)
414}
415
416// SerializeTo provides serialization of an Download Section Request message
417func (omci *DownloadSectionRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
418 // Basic (common) OMCI Header is 8 octets, 10
419 err := omci.MeBasePacket.SerializeTo(b)
420 if err != nil {
421 return err
422 }
423 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
424 me.ParamData{EntityID: omci.EntityInstance})
425 if omciErr.StatusCode() != me.Success {
426 return omciErr.GetError()
427 }
428 // ME needs to support Download section
429 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
430 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
431 }
432 // Software Image Entity Class are always use the Software Image
433 if omci.EntityClass != me.SoftwareImageClassID {
434 return me.NewProcessingError("invalid Entity Class for Download Section response")
435 }
436 sectionLength := len(omci.SectionData)
437 if omci.Extended {
438 if sectionLength > MaxDownloadSectionExtendedLength {
439 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
440 MaxDownloadSectionExtendedLength, sectionLength)
441 return me.NewProcessingError(msg)
442 }
443 // Append section data
444 bytes, err := b.AppendBytes(3 + sectionLength)
445 if err != nil {
446 return err
447 }
448 binary.BigEndian.PutUint16(bytes, uint16(1+sectionLength))
449 bytes[2] = omci.SectionNumber
450 copy(bytes[3:], omci.SectionData)
451 } else {
452 if sectionLength > MaxDownloadSectionLength {
453 msg := fmt.Sprintf("invalid Download Section data length, must be <= %v, received: %v",
454 MaxDownloadSectionLength, sectionLength)
455 return me.NewProcessingError(msg)
456 }
457 // Append section data
458 bytes, err := b.AppendBytes(1 + MaxDownloadSectionLength)
459 if err != nil {
460 return err
461 }
462 bytes[0] = omci.SectionNumber
463 copy(bytes[1:], omci.SectionData)
464
465 // Zero extended if needed
466 if sectionLength < MaxDownloadSectionLength {
467 copy(omci.SectionData[sectionLength:], lotsOfZeros[:MaxDownloadSectionLength-sectionLength])
468 }
469 }
470 return nil
471}
472
473type DownloadSectionResponse struct {
474 MeBasePacket // Note: EntityInstance for software download is two specific values
475 Result me.Results
476 SectionNumber byte
477}
478
479func (omci *DownloadSectionResponse) String() string {
480 return fmt.Sprintf("%v, Result: %d (%v), Section #: %v",
481 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.SectionNumber)
482}
483
484// LayerType returns LayerTypeDownloadSectionResponse
485func (omci *DownloadSectionResponse) LayerType() gopacket.LayerType {
486 return LayerTypeDownloadSectionResponse
487}
488
489// CanDecode returns the set of layer types that this DecodingLayer can decode
490func (omci *DownloadSectionResponse) CanDecode() gopacket.LayerClass {
491 return LayerTypeDownloadSectionResponse
492}
493
494// NextLayerType returns the layer type contained by this DecodingLayer.
495func (omci *DownloadSectionResponse) NextLayerType() gopacket.LayerType {
496 return gopacket.LayerTypePayload
497}
498
499// DecodeFromBytes decodes the given bytes of a Download Section Response into this layer
500func (omci *DownloadSectionResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
501 // Common ClassID/EntityID decode in msgBase
502 err := omci.MeBasePacket.DecodeFromBytes(data, p, 4+2)
503 if err != nil {
504 return err
505 }
506 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
507 me.ParamData{EntityID: omci.EntityInstance})
508 if omciErr.StatusCode() != me.Success {
509 return omciErr.GetError()
510 }
511 // ME needs to support Download section
512 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
513 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
514 }
515 // Software Image Entity Class are always use the Software Image
516 if omci.EntityClass != me.SoftwareImageClassID {
517 return me.NewProcessingError("invalid Entity Class for Download Section response")
518 }
519 if omci.Extended {
520 if len(data) < 8 {
521 p.SetTruncated()
522 return errors.New("frame too small")
523 }
524 omci.Result = me.Results(data[6])
525 omci.SectionNumber = data[7]
526 } else {
527 omci.Result = me.Results(data[4])
528 omci.SectionNumber = data[5]
529 }
530 if omci.Result > me.DeviceBusy {
531 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
532 omci.Result)
533 return errors.New(msg)
534 }
535 return nil
536}
537
538func decodeDownloadSectionResponse(data []byte, p gopacket.PacketBuilder) error {
539 omci := &DownloadSectionResponse{}
540 omci.MsgLayerType = LayerTypeDownloadSectionResponse
541 return decodingLayerDecoder(omci, data, p)
542}
543
544func decodeDownloadSectionResponseExtended(data []byte, p gopacket.PacketBuilder) error {
545 omci := &DownloadSectionResponse{}
546 omci.MsgLayerType = LayerTypeDownloadSectionResponse
547 omci.Extended = true
548 return decodingLayerDecoder(omci, data, p)
549}
550
551// SerializeTo provides serialization of an Download Section Response message
552func (omci *DownloadSectionResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
553 // Basic (common) OMCI Header is 8 octets, 10
554 err := omci.MeBasePacket.SerializeTo(b)
555 if err != nil {
556 return err
557 }
558 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
559 me.ParamData{EntityID: omci.EntityInstance})
560 if omciErr.StatusCode() != me.Success {
561 return omciErr.GetError()
562 }
563 // ME needs to support Download section
564 if !me.SupportsMsgType(meDefinition, me.DownloadSection) {
565 return me.NewProcessingError("managed entity does not support Download Section Message-Type")
566 }
567 // Software Image Entity Class are always use the Software Image
568 if omci.EntityClass != me.SoftwareImageClassID {
569 return me.NewProcessingError("invalid Entity Class for Download Section response")
570 }
571 if omci.Result > me.DeviceBusy {
572 msg := fmt.Sprintf("invalid results for Download Section response: %v, must be 0..6",
573 omci.Result)
574 return errors.New(msg)
575 }
576 if omci.Extended {
577 bytes, err := b.AppendBytes(4)
578 if err != nil {
579 return err
580 }
581 binary.BigEndian.PutUint16(bytes, uint16(2))
582 bytes[2] = byte(omci.Result)
583 bytes[3] = omci.SectionNumber
584 } else {
585 bytes, err := b.AppendBytes(2)
586 if err != nil {
587 return err
588 }
589 bytes[0] = byte(omci.Result)
590 bytes[1] = omci.SectionNumber
591 }
592 return nil
593}
594
595type EndSoftwareDownloadRequest struct {
596 MeBasePacket // Note: EntityInstance for software download is two specific values
597 CRC32 uint32
598 ImageSize uint32
599 NumberOfInstances byte
600 ImageInstances []uint16
601}
602
603func (omci *EndSoftwareDownloadRequest) String() string {
604 return fmt.Sprintf("%v, CRC: %#x, Image Size: %v, Number of Instances: %v, Instances: %v",
605 omci.MeBasePacket.String(), omci.CRC32, omci.ImageSize, omci.NumberOfInstances, omci.ImageInstances)
606}
607
608// LayerType returns LayerTypeEndSoftwareDownloadRequest
609func (omci *EndSoftwareDownloadRequest) LayerType() gopacket.LayerType {
610 return LayerTypeEndSoftwareDownloadRequest
611}
612
613// CanDecode returns the set of layer types that this DecodingLayer can decode
614func (omci *EndSoftwareDownloadRequest) CanDecode() gopacket.LayerClass {
615 return LayerTypeEndSoftwareDownloadRequest
616}
617
618// NextLayerType returns the layer type contained by this DecodingLayer.
619func (omci *EndSoftwareDownloadRequest) NextLayerType() gopacket.LayerType {
620 return gopacket.LayerTypePayload
621}
622
623// DecodeFromBytes decodes the given bytes of an End Software Download Request into this layer
624func (omci *EndSoftwareDownloadRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
625 // Common ClassID/EntityID decode in msgBase
626 var hdrSize int
627 if omci.Extended {
628 hdrSize = 6 + 7
629 } else {
630 hdrSize = 4 + 7
631 }
632 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
633 if err != nil {
634 return err
635 }
636 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
637 me.ParamData{EntityID: omci.EntityInstance})
638 if omciErr.StatusCode() != me.Success {
639 return omciErr.GetError()
640 }
641 // ME needs to support End Software Download
642 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
643 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
644 }
645 // Software Image Entity Class are always use the Software Image
646 if omci.EntityClass != me.SoftwareImageClassID {
647 return me.NewProcessingError("invalid Entity Class for End Software Download request")
648 }
649 var offset int
650 if omci.Extended {
651 offset = 2
652 }
653 omci.CRC32 = binary.BigEndian.Uint32(data[offset+4:])
654 omci.ImageSize = binary.BigEndian.Uint32(data[offset+8:])
655 omci.NumberOfInstances = data[offset+12]
656
657 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
658 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
659 omci.NumberOfInstances))
660 }
661 omci.ImageInstances = make([]uint16, omci.NumberOfInstances)
662
663 for index := 0; index < int(omci.NumberOfInstances); index++ {
664 omci.ImageInstances[index] = binary.BigEndian.Uint16(data[offset+13+(index*2):])
665 }
666 return nil
667}
668
669func decodeEndSoftwareDownloadRequest(data []byte, p gopacket.PacketBuilder) error {
670 omci := &EndSoftwareDownloadRequest{}
671 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
672 return decodingLayerDecoder(omci, data, p)
673}
674
675func decodeEndSoftwareDownloadRequestExtended(data []byte, p gopacket.PacketBuilder) error {
676 omci := &EndSoftwareDownloadRequest{}
677 omci.MsgLayerType = LayerTypeEndSoftwareDownloadRequest
678 omci.Extended = true
679 return decodingLayerDecoder(omci, data, p)
680}
681
682// SerializeTo provides serialization of an End Software Download Request message
683func (omci *EndSoftwareDownloadRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
684 // Basic (common) OMCI Header is 8 octets, 10
685 err := omci.MeBasePacket.SerializeTo(b)
686 if err != nil {
687 return err
688 }
689 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
690 me.ParamData{EntityID: omci.EntityInstance})
691 if omciErr.StatusCode() != me.Success {
692 return omciErr.GetError()
693 }
694 // ME needs to support End Software Download
695 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
696 return me.NewProcessingError("managed entity does not support Start End Download Message-Type")
697 }
698 // Software Image Entity Class are always use the Software Image
699 if omci.EntityClass != me.SoftwareImageClassID {
700 return me.NewProcessingError("invalid Entity Class for End Software Download response")
701 }
702 if omci.NumberOfInstances < 1 || omci.NumberOfInstances > 9 {
703 return me.NewProcessingError(fmt.Sprintf("invalid number of Instances: %v, must be 1..9",
704 omci.NumberOfInstances))
705 }
706 var offset int
707 if omci.Extended {
708 offset = 2
709 }
710 bytes, err := b.AppendBytes(offset + 9 + (2 * int(omci.NumberOfInstances)))
711 if err != nil {
712 return err
713 }
714 if omci.Extended {
715 binary.BigEndian.PutUint16(bytes, uint16(9+(2*int(omci.NumberOfInstances))))
716 }
717 binary.BigEndian.PutUint32(bytes[offset+0:], omci.CRC32)
718 binary.BigEndian.PutUint32(bytes[offset+4:], omci.ImageSize)
719 bytes[offset+8] = omci.NumberOfInstances
720 for index := 0; index < int(omci.NumberOfInstances); index++ {
721 binary.BigEndian.PutUint16(bytes[offset+9+(index*2):], omci.ImageInstances[index])
722 }
723 return nil
724}
725
726type EndSoftwareDownloadResponse struct {
727 MeBasePacket // Note: EntityInstance for software download is two specific values
728 Result me.Results
729 NumberOfInstances byte
730 MeResults []DownloadResults
731}
732
733func (omci *EndSoftwareDownloadResponse) String() string {
734 return fmt.Sprintf("%v, Result: %d (%v), Number of Instances: %v, ME Results: %v",
735 omci.MeBasePacket.String(), omci.Result, omci.Result, omci.NumberOfInstances, omci.MeResults)
736}
737
738// LayerType returns LayerTypeCreateResponse
739func (omci *EndSoftwareDownloadResponse) LayerType() gopacket.LayerType {
740 return LayerTypeEndSoftwareDownloadResponse
741}
742
743// CanDecode returns the set of layer types that this DecodingLayer can decode
744func (omci *EndSoftwareDownloadResponse) CanDecode() gopacket.LayerClass {
745 return LayerTypeEndSoftwareDownloadResponse
746}
747
748// NextLayerType returns the layer type contained by this DecodingLayer.
749func (omci *EndSoftwareDownloadResponse) NextLayerType() gopacket.LayerType {
750 return gopacket.LayerTypePayload
751}
752
753// DecodeFromBytes decodes the given bytes of an End Software Download Response into this layer
754func (omci *EndSoftwareDownloadResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
755 // Common ClassID/EntityID decode in msgBase
756 var hdrSize int
757 if omci.Extended {
758 hdrSize = 6 + 2
759 } else {
760 hdrSize = 4 + 2
761 }
762 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
763 if err != nil {
764 return err
765 }
766 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
767 me.ParamData{EntityID: omci.EntityInstance})
768 if omciErr.StatusCode() != me.Success {
769 return omciErr.GetError()
770 }
771 // ME needs to support End Software Download
772 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
773 return me.NewProcessingError("managed entity does not support End Software Download Message-Type")
774 }
775 // Software Image Entity Class are always use the Software Image
776 if omci.EntityClass != me.SoftwareImageClassID {
777 return me.NewProcessingError("invalid Entity Class for End Software Download response")
778 }
779 var offset int
780 if omci.Extended {
781 offset = 2
782 }
783 omci.Result = me.Results(data[offset+4])
784 if omci.Result > me.DeviceBusy {
785 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
786 omci.Result)
787 return errors.New(msg)
788 }
789 omci.NumberOfInstances = data[offset+5]
790
791 if omci.NumberOfInstances > 9 {
792 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
793 omci.NumberOfInstances)
794 return errors.New(msg)
795 }
796 if omci.NumberOfInstances > 0 {
797 omci.MeResults = make([]DownloadResults, omci.NumberOfInstances)
798
799 for index := 0; index < int(omci.NumberOfInstances); index++ {
800 omci.MeResults[index].ManagedEntityID = binary.BigEndian.Uint16(data[offset+6+(index*3):])
801 omci.MeResults[index].Result = me.Results(data[offset+8+(index*3)])
802 if omci.MeResults[index].Result > me.DeviceBusy {
803 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
804 index, omci.MeResults[index])
805 return errors.New(msg)
806 }
807 }
808 }
809 return nil
810}
811
812func decodeEndSoftwareDownloadResponse(data []byte, p gopacket.PacketBuilder) error {
813 omci := &EndSoftwareDownloadResponse{}
814 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
815 return decodingLayerDecoder(omci, data, p)
816}
817
818func decodeEndSoftwareDownloadResponseExtended(data []byte, p gopacket.PacketBuilder) error {
819 omci := &EndSoftwareDownloadResponse{}
820 omci.MsgLayerType = LayerTypeEndSoftwareDownloadResponse
821 omci.Extended = true
822 return decodingLayerDecoder(omci, data, p)
823}
824
825// SerializeTo provides serialization of an End Software Download Response message
826func (omci *EndSoftwareDownloadResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
827 // Basic (common) OMCI Header is 8 octets, 10
828 err := omci.MeBasePacket.SerializeTo(b)
829 if err != nil {
830 return err
831 }
832 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
833 me.ParamData{EntityID: omci.EntityInstance})
834 if omciErr.StatusCode() != me.Success {
835 return omciErr.GetError()
836 }
837 // ME needs to support End Software Download
838 if !me.SupportsMsgType(meDefinition, me.EndSoftwareDownload) {
839 return me.NewProcessingError("managed entity does not support End End Download Message-Type")
840 }
841 // Software Image Entity Class are always use the Software Image
842 if omci.EntityClass != me.SoftwareImageClassID {
843 return me.NewProcessingError("invalid Entity Class for End Download response")
844 }
845 var offset int
846 if omci.Extended {
847 offset = 2
848 }
849 bytes, err := b.AppendBytes(offset + 2 + (3 * int(omci.NumberOfInstances)))
850 if err != nil {
851 return err
852 }
853 if omci.Result > me.DeviceBusy {
854 msg := fmt.Sprintf("invalid results for End Software Download response: %v, must be 0..6",
855 omci.Result)
856 return errors.New(msg)
857 }
858 if omci.Extended {
859 binary.BigEndian.PutUint16(bytes, uint16(2+(3*int(omci.NumberOfInstances))))
860 }
861 bytes[offset] = byte(omci.Result)
862 bytes[offset+1] = omci.NumberOfInstances
863
864 if omci.NumberOfInstances > 9 {
865 msg := fmt.Sprintf("invalid number of Instances: %v, must be 0..9",
866 omci.NumberOfInstances)
867 return errors.New(msg)
868 }
869 if omci.NumberOfInstances > 0 {
870 for index := 0; index < int(omci.NumberOfInstances); index++ {
871 binary.BigEndian.PutUint16(bytes[offset+2+(3*index):], omci.MeResults[index].ManagedEntityID)
872
873 if omci.MeResults[index].Result > me.DeviceBusy {
874 msg := fmt.Sprintf("invalid results for End Software Download instance %v response: %v, must be 0..6",
875 index, omci.MeResults[index])
876 return errors.New(msg)
877 }
878 bytes[offset+4+(3*index)] = byte(omci.MeResults[index].Result)
879 }
880 }
881 return nil
882}
883
884type ActivateSoftwareRequest struct {
885 MeBasePacket // Note: EntityInstance for software download is two specific values
886 ActivateFlags byte
887}
888
889func (omci *ActivateSoftwareRequest) String() string {
890 return fmt.Sprintf("%v, Flags: %#x",
891 omci.MeBasePacket.String(), omci.ActivateFlags)
892}
893
894// LayerType returns LayerTypeActivateSoftwareRequest
895func (omci *ActivateSoftwareRequest) LayerType() gopacket.LayerType {
896 return LayerTypeActivateSoftwareRequest
897}
898
899// CanDecode returns the set of layer types that this DecodingLayer can decode
900func (omci *ActivateSoftwareRequest) CanDecode() gopacket.LayerClass {
901 return LayerTypeActivateSoftwareRequest
902}
903
904// NextLayerType returns the layer type contained by this DecodingLayer.
905func (omci *ActivateSoftwareRequest) NextLayerType() gopacket.LayerType {
906 return gopacket.LayerTypePayload
907}
908
909// DecodeFromBytes decodes the given bytes of an Activate Software Request into this layer
910func (omci *ActivateSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
911 // Common ClassID/EntityID decode in msgBase
912 var hdrSize int
913 if omci.Extended {
914 hdrSize = 6 + 1
915 } else {
916 hdrSize = 4 + 1
917 }
918 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
919 if err != nil {
920 return err
921 }
922 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
923 me.ParamData{EntityID: omci.EntityInstance})
924 if omciErr.StatusCode() != me.Success {
925 return omciErr.GetError()
926 }
927 // ME needs to support End Software Download
928 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
929 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
930 }
931 // Software Image Entity Class are always use the Software Image
932 if omci.EntityClass != me.SoftwareImageClassID {
933 return me.NewProcessingError("invalid Entity Class for Activate Software request")
934 }
935 if omci.Extended {
936 omci.ActivateFlags = data[6]
937 } else {
938 omci.ActivateFlags = data[4]
939 }
940 if omci.ActivateFlags > 2 {
941 return me.NewProcessingError(fmt.Sprintf("invalid number of Activation flangs: %v, must be 0..2",
942 omci.ActivateFlags))
943 }
944 return nil
945}
946
947func decodeActivateSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
948 omci := &ActivateSoftwareRequest{}
949 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
950 return decodingLayerDecoder(omci, data, p)
951}
952
953func decodeActivateSoftwareRequestExtended(data []byte, p gopacket.PacketBuilder) error {
954 omci := &ActivateSoftwareRequest{}
955 omci.MsgLayerType = LayerTypeActivateSoftwareRequest
956 omci.Extended = true
957 return decodingLayerDecoder(omci, data, p)
958}
959
960// SerializeTo provides serialization of an Activate Software message
961func (omci *ActivateSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
962 // Basic (common) OMCI Header is 8 octets, 10
963 err := omci.MeBasePacket.SerializeTo(b)
964 if err != nil {
965 return err
966 }
967 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
968 me.ParamData{EntityID: omci.EntityInstance})
969 if omciErr.StatusCode() != me.Success {
970 return omciErr.GetError()
971 }
972 // ME needs to support End Software Download
973 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
974 return me.NewProcessingError("managed entity does not support Activate Message-Type")
975 }
976 // Software Image Entity Class are always use the Software Image
977 if omci.EntityClass != me.SoftwareImageClassID {
978 return me.NewProcessingError("invalid Entity Class for Activate Software request")
979 }
980 var offset int
981 if omci.Extended {
982 offset = 2
983 }
984 bytes, err := b.AppendBytes(offset + 1)
985 if err != nil {
986 return err
987 }
988 if omci.Extended {
989 binary.BigEndian.PutUint16(bytes, uint16(1))
990 }
991 bytes[offset] = omci.ActivateFlags
992 if omci.ActivateFlags > 2 {
993 msg := fmt.Sprintf("invalid results for Activate Software request: %v, must be 0..2",
994 omci.ActivateFlags)
995 return errors.New(msg)
996 }
997 return nil
998}
999
1000type ActivateSoftwareResponse struct {
1001 MeBasePacket
1002 Result me.Results
1003}
1004
1005func (omci *ActivateSoftwareResponse) String() string {
1006 return fmt.Sprintf("%v, Result: %d (%v)",
1007 omci.MeBasePacket.String(), omci.Result, omci.Result)
1008}
1009
1010// LayerType returns LayerTypeActivateSoftwareResponse
1011func (omci *ActivateSoftwareResponse) LayerType() gopacket.LayerType {
1012 return LayerTypeActivateSoftwareResponse
1013}
1014
1015// CanDecode returns the set of layer types that this DecodingLayer can decode
1016func (omci *ActivateSoftwareResponse) CanDecode() gopacket.LayerClass {
1017 return LayerTypeActivateSoftwareResponse
1018}
1019
1020// NextLayerType returns the layer type contained by this DecodingLayer.
1021func (omci *ActivateSoftwareResponse) NextLayerType() gopacket.LayerType {
1022 return gopacket.LayerTypePayload
1023}
1024
1025// DecodeFromBytes decodes the given bytes of an Activate Software Response into this layer
1026func (omci *ActivateSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1027 // Common ClassID/EntityID decode in msgBase
1028 var hdrSize int
1029 if omci.Extended {
1030 hdrSize = 6 + 1
1031 } else {
1032 hdrSize = 4 + 1
1033 }
1034 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
1035 if err != nil {
1036 return err
1037 }
1038 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1039 me.ParamData{EntityID: omci.EntityInstance})
1040 if omciErr.StatusCode() != me.Success {
1041 return omciErr.GetError()
1042 }
1043 // ME needs to support End Software Download
1044 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
1045 return me.NewProcessingError("managed entity does not support Activate Software Message-Type")
1046 }
1047 // Software Image Entity Class are always use the Software Image
1048 if omci.EntityClass != me.SoftwareImageClassID {
1049 return me.NewProcessingError("invalid Entity Class for Activate Software response")
1050 }
1051 if omci.Extended {
1052 omci.Result = me.Results(data[6])
1053 } else {
1054 omci.Result = me.Results(data[4])
1055 }
1056 if omci.Result > me.Results(6) {
1057 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
1058 omci.Result)
1059 return errors.New(msg)
1060 }
1061 return nil
1062}
1063
1064func decodeActivateSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
1065 omci := &ActivateSoftwareResponse{}
1066 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
1067 return decodingLayerDecoder(omci, data, p)
1068}
1069
1070func decodeActivateSoftwareResponseExtended(data []byte, p gopacket.PacketBuilder) error {
1071 omci := &ActivateSoftwareResponse{}
1072 omci.MsgLayerType = LayerTypeActivateSoftwareResponse
1073 omci.Extended = true
1074 return decodingLayerDecoder(omci, data, p)
1075}
1076
1077// SerializeTo provides serialization of an Activate Software Response message
1078func (omci *ActivateSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
1079 // Basic (common) OMCI Header is 8 octets, 10
1080 err := omci.MeBasePacket.SerializeTo(b)
1081 if err != nil {
1082 return err
1083 }
1084 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1085 me.ParamData{EntityID: omci.EntityInstance})
1086 if omciErr.StatusCode() != me.Success {
1087 return omciErr.GetError()
1088 }
1089 // ME needs to support End Software Download
1090 if !me.SupportsMsgType(meDefinition, me.ActivateSoftware) {
1091 return me.NewProcessingError("managed entity does not support Activate Message-Type")
1092 }
1093 // Software Image Entity Class are always use the Software Image
1094 if omci.EntityClass != me.SoftwareImageClassID {
1095 return me.NewProcessingError("invalid Entity Class for Activate Software response")
1096 }
1097 if omci.Result > me.Results(6) {
1098 msg := fmt.Sprintf("invalid results for Activate Software response: %v, must be 0..6",
1099 omci.Result)
1100 return errors.New(msg)
1101 }
1102 var offset int
1103 if omci.Extended {
1104 offset = 2
1105 }
1106 bytes, err := b.AppendBytes(offset + 1)
1107 if err != nil {
1108 return err
1109 }
1110 if omci.Extended {
1111 binary.BigEndian.PutUint16(bytes, 1)
1112 }
1113 bytes[offset] = byte(omci.Result)
1114 return nil
1115}
1116
1117type CommitSoftwareRequest struct {
1118 MeBasePacket
1119}
1120
1121func (omci *CommitSoftwareRequest) String() string {
1122 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1123}
1124
1125// LayerType returns LayerTypeCommitSoftwareRequest
1126func (omci *CommitSoftwareRequest) LayerType() gopacket.LayerType {
1127 return LayerTypeCommitSoftwareRequest
1128}
1129
1130// CanDecode returns the set of layer types that this DecodingLayer can decode
1131func (omci *CommitSoftwareRequest) CanDecode() gopacket.LayerClass {
1132 return LayerTypeCommitSoftwareRequest
1133}
1134
1135// NextLayerType returns the layer type contained by this DecodingLayer.
1136func (omci *CommitSoftwareRequest) NextLayerType() gopacket.LayerType {
1137 return gopacket.LayerTypePayload
1138}
1139
1140// DecodeFromBytes decodes the given bytes of a Commit Software Request into this layer
1141func (omci *CommitSoftwareRequest) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1142 // Common ClassID/EntityID decode in msgBase
1143 var hdrSize int
1144 if omci.Extended {
1145 hdrSize = 6
1146 } else {
1147 hdrSize = 4
1148 }
1149 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
1150 if err != nil {
1151 return err
1152 }
1153 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1154 me.ParamData{EntityID: omci.EntityInstance})
1155 if omciErr.StatusCode() != me.Success {
1156 return omciErr.GetError()
1157 }
1158 // ME needs to support End Software Download
1159 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
1160 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
1161 }
1162 // Software Image Entity Class are always use the Software Image
1163 if omci.EntityClass != me.SoftwareImageClassID {
1164 return me.NewProcessingError("invalid Entity Class for Commit Software request")
1165 }
1166 return nil
1167}
1168
1169func decodeCommitSoftwareRequest(data []byte, p gopacket.PacketBuilder) error {
1170 omci := &CommitSoftwareRequest{}
1171 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
1172 return decodingLayerDecoder(omci, data, p)
1173}
1174
1175func decodeCommitSoftwareRequestExtended(data []byte, p gopacket.PacketBuilder) error {
1176 omci := &CommitSoftwareRequest{}
1177 omci.MsgLayerType = LayerTypeCommitSoftwareRequest
1178 omci.Extended = true
1179 return decodingLayerDecoder(omci, data, p)
1180}
1181
1182// SerializeTo provides serialization of an Commit Software Request message
1183func (omci *CommitSoftwareRequest) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
1184 // Basic (common) OMCI Header is 8 octets, 10
1185 err := omci.MeBasePacket.SerializeTo(b)
1186 if err != nil {
1187 return err
1188 }
1189 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1190 me.ParamData{EntityID: omci.EntityInstance})
1191 if omciErr.StatusCode() != me.Success {
1192 return omciErr.GetError()
1193 }
1194 // ME needs to support End Software Download
1195 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
1196 return me.NewProcessingError("managed entity does not support Commit Message-Type")
1197 }
1198 // Software Image Entity Class are always use the Software Image
1199 if omci.EntityClass != me.SoftwareImageClassID {
1200 return me.NewProcessingError("invalid Entity Class for Commit Software request")
1201 }
1202 if omci.Extended {
1203 bytes, err := b.AppendBytes(2)
1204 if err != nil {
1205 return err
1206 }
1207 binary.BigEndian.PutUint16(bytes, 0)
1208 }
1209 return nil
1210}
1211
1212type CommitSoftwareResponse struct {
1213 MeBasePacket
1214 Result me.Results
1215}
1216
1217func (omci *CommitSoftwareResponse) String() string {
1218 return fmt.Sprintf("%v", omci.MeBasePacket.String())
1219}
1220
1221// LayerType returns LayerTypeCommitSoftwareResponse
1222func (omci *CommitSoftwareResponse) LayerType() gopacket.LayerType {
1223 return LayerTypeCommitSoftwareResponse
1224}
1225
1226// CanDecode returns the set of layer types that this DecodingLayer can decode
1227func (omci *CommitSoftwareResponse) CanDecode() gopacket.LayerClass {
1228 return LayerTypeCommitSoftwareResponse
1229}
1230
1231// NextLayerType returns the layer type contained by this DecodingLayer.
1232func (omci *CommitSoftwareResponse) NextLayerType() gopacket.LayerType {
1233 return gopacket.LayerTypePayload
1234}
1235
1236// DecodeFromBytes decodes the given bytes of a Commit Software Response into this layer
1237func (omci *CommitSoftwareResponse) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
1238 // Common ClassID/EntityID decode in msgBase
1239 var hdrSize int
1240 if omci.Extended {
1241 hdrSize = 6 + 1
1242 } else {
1243 hdrSize = 4 + 1
1244 }
1245 err := omci.MeBasePacket.DecodeFromBytes(data, p, hdrSize)
1246 if err != nil {
1247 return err
1248 }
1249 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1250 me.ParamData{EntityID: omci.EntityInstance})
1251 if omciErr.StatusCode() != me.Success {
1252 return omciErr.GetError()
1253 }
1254 // ME needs to support Commit Software
1255 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
1256 return me.NewProcessingError("managed entity does not support Commit Software Message-Type")
1257 }
1258 // Software Image Entity Class are always use the Software Image
1259 if omci.EntityClass != me.SoftwareImageClassID {
1260 return me.NewProcessingError("invalid Entity Class for Commit Software response")
1261 }
1262 if omci.Extended {
1263 omci.Result = me.Results(data[6])
1264 } else {
1265 omci.Result = me.Results(data[4])
1266 }
1267 if omci.Result > me.Results(6) {
1268 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
1269 omci.Result)
1270 return errors.New(msg)
1271 }
1272 return nil
1273}
1274
1275func decodeCommitSoftwareResponse(data []byte, p gopacket.PacketBuilder) error {
1276 omci := &CommitSoftwareResponse{}
1277 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
1278 return decodingLayerDecoder(omci, data, p)
1279}
1280
1281func decodeCommitSoftwareResponseExtended(data []byte, p gopacket.PacketBuilder) error {
1282 omci := &CommitSoftwareResponse{}
1283 omci.MsgLayerType = LayerTypeCommitSoftwareResponse
1284 omci.Extended = true
1285 return decodingLayerDecoder(omci, data, p)
1286}
1287
1288// SerializeTo provides serialization of an Commit Software Response message
1289func (omci *CommitSoftwareResponse) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {
1290 // Basic (common) OMCI Header is 8 octets, 10
1291 err := omci.MeBasePacket.SerializeTo(b)
1292 if err != nil {
1293 return err
1294 }
1295 meDefinition, omciErr := me.LoadManagedEntityDefinition(omci.EntityClass,
1296 me.ParamData{EntityID: omci.EntityInstance})
1297 if omciErr.StatusCode() != me.Success {
1298 return omciErr.GetError()
1299 }
1300 // ME needs to support Commit Software
1301 if !me.SupportsMsgType(meDefinition, me.CommitSoftware) {
1302 return me.NewProcessingError("managed entity does not support Commit Message-Type")
1303 }
1304 // Software Image Entity Class are always use the Software Image
1305 if omci.EntityClass != me.SoftwareImageClassID {
1306 return me.NewProcessingError("invalid Entity Class for Commit Software response")
1307 }
1308 if omci.Result > me.Results(6) {
1309 msg := fmt.Sprintf("invalid results for Commit Software response: %v, must be 0..6",
1310 omci.Result)
1311 return errors.New(msg)
1312 }
1313 var offset int
1314 if omci.Extended {
1315 offset = 2
1316 }
1317 bytes, err := b.AppendBytes(offset + 1)
1318 if err != nil {
1319 return err
1320 }
1321 if omci.Extended {
1322 binary.BigEndian.PutUint16(bytes, 1)
1323 bytes[2] = byte(omci.Result)
1324 } else {
1325 bytes[0] = byte(omci.Result)
1326 }
1327 return nil
1328}