blob: 750233d175890bce55b2c1ada83f2ae86e15aa88 [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 "fmt"
Matteo Scandolof9d43412021-01-12 11:11:34 -080023 me "github.com/opencord/omci-lib-go/generated"
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070024 "github.com/google/gopacket"
25 "github.com/google/gopacket/layers"
26)
27
28type MeBasePacket struct {
29 EntityClass me.ClassID
30 EntityInstance uint16
31
32 gopacket.Layer
33 layers.BaseLayer
34 MsgLayerType gopacket.LayerType
35}
36
37func (msg *MeBasePacket) String() string {
38 return fmt.Sprintf("ClassID: %v, InstanceId: %d/%#x",
39 msg.EntityClass, msg.EntityInstance, msg.EntityInstance)
40}
41
Matteo Scandolof9d43412021-01-12 11:11:34 -080042// CanDecode returns the set of layer types that this DecodingLayer can decode
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070043func (msg *MeBasePacket) CanDecode() gopacket.LayerClass {
44 return msg.MsgLayerType
45}
46
Matteo Scandolof9d43412021-01-12 11:11:34 -080047// LayerType returns MsgLayerType. It partially satisfies Layer and SerializableLayer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070048func (msg *MeBasePacket) LayerType() gopacket.LayerType {
49 return msg.MsgLayerType
50}
Matteo Scandolof9d43412021-01-12 11:11:34 -080051
52// LayerContents returns the bytes of the packet layer.
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070053func (msg *MeBasePacket) LayerContents() []byte {
54 return msg.Contents
55}
Matteo Scandolof9d43412021-01-12 11:11:34 -080056
57// LayerPayload returns the bytes contained within the packet layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070058func (msg *MeBasePacket) LayerPayload() []byte {
59 return msg.Payload
60}
61
Matteo Scandolof9d43412021-01-12 11:11:34 -080062// NextLayerType returns the layer type contained by this DecodingLayer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070063func (msg *MeBasePacket) NextLayerType() gopacket.LayerType {
64 return gopacket.LayerTypeZero
65}
Matteo Scandolof9d43412021-01-12 11:11:34 -080066
67// DecodeFromBytes decodes the given bytes into this layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070068func (msg *MeBasePacket) DecodeFromBytes(data []byte, p gopacket.PacketBuilder) error {
69 // Note: Base OMCI frame already checked for frame with at least 10 octets
70 msg.EntityClass = me.ClassID(binary.BigEndian.Uint16(data[0:]))
71 msg.EntityInstance = binary.BigEndian.Uint16(data[2:])
72 msg.BaseLayer = layers.BaseLayer{Contents: data[:4], Payload: data[4:]}
73 return nil
74}
Matteo Scandolof9d43412021-01-12 11:11:34 -080075
76// SerializeTo provides serialization of this message layer
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070077func (msg *MeBasePacket) SerializeTo(b gopacket.SerializeBuffer) error {
78 // Add class ID and entity ID
79 bytes, err := b.PrependBytes(4)
80 if err != nil {
81 return err
82 }
83 binary.BigEndian.PutUint16(bytes, uint16(msg.EntityClass))
84 binary.BigEndian.PutUint16(bytes[2:], msg.EntityInstance)
85 return nil
86}
87
88type layerDecodingLayer interface {
89 gopacket.Layer
90 DecodeFromBytes([]byte, gopacket.PacketBuilder) error
91 NextLayerType() gopacket.LayerType
92}
93
94func decodingLayerDecoder(d layerDecodingLayer, data []byte, p gopacket.PacketBuilder) error {
95 err := d.DecodeFromBytes(data, p)
96 if err != nil {
97 return err
98 }
99 p.AddLayer(d)
100 next := d.NextLayerType()
101 if next == gopacket.LayerTypeZero {
102 return nil
103 }
104 return p.NextDecoder(next)
105}