blob: ec1b08c4a50bf2aba988415caa427c2725672ca8 [file] [log] [blame]
Chip Boling6e27b352020-02-14 09:10:01 -06001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
Andrea Campanella7167ebb2020-02-24 09:56:38 +01003 * Copyright 2020-present Open Networking Foundation
4
Chip Boling6e27b352020-02-14 09:10:01 -06005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Andrea Campanella7167ebb2020-02-24 09:56:38 +01008
Chip Boling6e27b352020-02-14 09:10:01 -06009 * http://www.apache.org/licenses/LICENSE-2.0
Andrea Campanella7167ebb2020-02-24 09:56:38 +010010
Chip Boling6e27b352020-02-14 09:10:01 -060011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Chip Boling6e27b352020-02-14 09:10:01 -060016 */
17
18package omci
19
20import (
21 "encoding/binary"
22 "fmt"
Andrea Campanella7167ebb2020-02-24 09:56:38 +010023 me "github.com/opencord/omci-lib-go/generated"
Chip Boling6e27b352020-02-14 09:10:01 -060024 "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
42// CanDecode returns the set of layer types that this DecodingLayer can decode
43func (msg *MeBasePacket) CanDecode() gopacket.LayerClass {
44 return msg.MsgLayerType
45}
46
47// LayerType returns MsgLayerType. It partially satisfies Layer and SerializableLayer
48func (msg *MeBasePacket) LayerType() gopacket.LayerType {
49 return msg.MsgLayerType
50}
51
52// LayerContents returns the bytes of the packet layer.
53func (msg *MeBasePacket) LayerContents() []byte {
54 return msg.Contents
55}
56
57// LayerPayload returns the bytes contained within the packet layer
58func (msg *MeBasePacket) LayerPayload() []byte {
59 return msg.Payload
60}
61
62// NextLayerType returns the layer type contained by this DecodingLayer
63func (msg *MeBasePacket) NextLayerType() gopacket.LayerType {
64 return gopacket.LayerTypeZero
65}
66
67// DecodeFromBytes decodes the given bytes into this layer
Chip Bolingd8543b22021-03-08 08:34:26 -060068func (msg *MeBasePacket) DecodeFromBytes(data []byte, p gopacket.PacketBuilder, contentSize int) error {
Chip Boling6e27b352020-02-14 09:10:01 -060069 // 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:])
Chip Bolingd8543b22021-03-08 08:34:26 -060072 msg.BaseLayer = layers.BaseLayer{Contents: data[:contentSize], Payload: data[contentSize:]}
Chip Boling6e27b352020-02-14 09:10:01 -060073 return nil
74}
75
76// SerializeTo provides serialization of this message layer
77func (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}