[VOL-1349] EPON OLT adapter (package B)
Change-Id: I634ef62c53813dcf4456f54948f13e06358e263c
diff --git a/internal/pkg/core/l2oam/common.go b/internal/pkg/core/l2oam/common.go
new file mode 100644
index 0000000..b77cf3d
--- /dev/null
+++ b/internal/pkg/core/l2oam/common.go
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//Package l2oam Common Logger initialization
+package l2oam
+
+import (
+ "context"
+ "fmt"
+ "time"
+)
+
+//var logger log.CLogger
+var logger l2OAMLogger
+
+// func init() {
+// // Setup this package so that it's log level can be modified at run time
+// var err error
+// logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+// if err != nil {
+// panic(err)
+// }
+// }
+
+func init() {
+ logger = l2OAMLogger{}
+ logger.Debug(context.Background(), "initialize l2oam logger")
+}
+
+//l2OAMLogger ...
+type l2OAMLogger struct {
+}
+
+//Debug ...
+func (l *l2OAMLogger) Debug(ctx context.Context, message string) {
+ fmt.Printf("%v:%s\n", time.Now(), message)
+}
diff --git a/internal/pkg/core/l2oam/message.go b/internal/pkg/core/l2oam/message.go
new file mode 100644
index 0000000..dd092da
--- /dev/null
+++ b/internal/pkg/core/l2oam/message.go
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "net"
+ "sync"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// OnuPkgType describes target package type
+var OnuPkgType = "PkgB"
+
+// OnuPkgTypeA is a constant of package
+const OnuPkgTypeA = "PkgA"
+
+// OnuPkgTypeB is a constant of package
+const OnuPkgTypeB = "PkgB"
+
+// TibitFrame is a typical structure of a frame
+type TibitFrame struct {
+ layers.BaseLayer
+ Data []byte
+}
+
+// LayerType returns ethernet layer type
+func (t *TibitFrame) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (t *TibitFrame) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ length := len(t.Data)
+ bytes, err := b.PrependBytes(length)
+ if err != nil {
+ return err
+ }
+ copy(bytes, t.Data)
+ return nil
+}
+
+// TomiObjectContext is a structure for tomi object
+type TomiObjectContext struct {
+ Branch uint8
+ Type uint16
+ Length uint8
+ Instance uint32
+}
+
+// CreateMessage creates l2 message
+func CreateMessage(srcMac string, dstMac string, ethernetType layers.EthernetType, tibitData gopacket.SerializableLayer) []byte {
+ srcMAC, _ := net.ParseMAC(srcMac)
+ dstMAC, _ := net.ParseMAC(dstMac)
+
+ ethernetLayer := &layers.Ethernet{
+ SrcMAC: srcMAC,
+ DstMAC: dstMAC,
+ EthernetType: ethernetType,
+ }
+
+ buf := gopacket.NewSerializeBuffer()
+ if err := gopacket.SerializeLayers(
+ buf,
+ gopacket.SerializeOptions{
+ ComputeChecksums: true,
+ FixLengths: true,
+ },
+ ethernetLayer,
+ tibitData,
+ ); err != nil {
+ return buf.Bytes()
+ }
+ return buf.Bytes()
+}
+
+// CreateMessage creates vlan message
+func CreateMessageVlan(srcMac string, dstMac string, ethernetType layers.EthernetType, tibitData gopacket.SerializableLayer, vlanLayer *layers.Dot1Q) []byte {
+ srcMAC, _ := net.ParseMAC(srcMac)
+ dstMAC, _ := net.ParseMAC(dstMac)
+
+ ethernetLayer := &layers.Ethernet{
+ SrcMAC: srcMAC,
+ DstMAC: dstMAC,
+ EthernetType: ethernetType,
+ }
+
+ buf := gopacket.NewSerializeBuffer()
+ if err := gopacket.SerializeLayers(
+ buf,
+ gopacket.SerializeOptions{
+ ComputeChecksums: true,
+ FixLengths: true,
+ },
+ ethernetLayer,
+ vlanLayer,
+ tibitData,
+ ); err != nil {
+ return buf.Bytes()
+ }
+ return buf.Bytes()
+}
+
+// CorrelationTag instance ID
+// It is incremented automatically for each TOMI message with OLT
+var instance uint32 = 0x5c1f6a60
+var instanceMutex sync.Mutex
+
+func getOltInstance() uint32 {
+ instanceMutex.Lock()
+ defer instanceMutex.Unlock()
+ instance = instance + 1
+
+ return instance
+
+}
diff --git a/internal/pkg/core/l2oam/msg_after_keep_alive.go b/internal/pkg/core/l2oam/msg_after_keep_alive.go
new file mode 100644
index 0000000..4772e11
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_after_keep_alive.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+func GeneratePcscompuTibitcom() gopacket.SerializableLayer {
+
+ data := &TibitFrame{
+ Data: []byte{0x03, 0x00, 0x50, 0xfe, 0x2a, 0xea, 0x15, 0x01, 0x0c, 0x0c, 0x7a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x11, 0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x07, 0x00, 0x00},
+ }
+
+ binary.BigEndian.PutUint32(data.Data[12:16], getOltInstance())
+
+ return data
+
+}
diff --git a/internal/pkg/core/l2oam/msg_autonomous.go b/internal/pkg/core/l2oam/msg_autonomous.go
new file mode 100644
index 0000000..dff723d
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_autonomous.go
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// AutonomousEvent is a structure for Autonomous Event
+type AutonomousEvent struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of AutonomousEvent
+func (d *AutonomousEvent) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%v, EcValue:%v, EndBranch:%v", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of AutonomousEvent
+func (d *AutonomousEvent) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// LayerType returns the ethernet type of AutonomousEvent
+func (d *AutonomousEvent) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *AutonomousEvent) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ return nil
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *AutonomousEvent) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i = i + int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// IsRegistrationStatusMessage returns true if the message is for ONU registration
+func (d *AutonomousEvent) IsRegistrationStatusMessage() bool {
+ return d.ComResp.VcBranch == 0x01 && d.ComResp.VcLeaf == 0x0009
+}
diff --git a/internal/pkg/core/l2oam/msg_best_effort_mbs.go b/internal/pkg/core/l2oam/msg_best_effort_mbs.go
new file mode 100644
index 0000000..fe63edf
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_best_effort_mbs.go
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateBestEffortMbs generates "Traffic Profile/Best Effort MBS" message
+func GenerateBestEffortMbs() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: 0x00000002,
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x0009,
+ VcLength: 5,
+ // EC
+ ECLength: 4,
+ ECValue: []byte{0x00, 0x06, 0x40, 0x00},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_best_effort_rate.go b/internal/pkg/core/l2oam/msg_best_effort_rate.go
new file mode 100644
index 0000000..42ccd43
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_best_effort_rate.go
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateBestEffortRate generates "Traffic Profile/Best Effort Rate" message
+func GenerateBestEffortRate(ecvalue []byte, trafficProfile []byte) gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: binary.BigEndian.Uint32(trafficProfile),
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x0008,
+ VcLength: uint8(1 + len(ecvalue)), //5
+ // EC
+ ECLength: uint8(len(ecvalue)), //4
+ ECValue: ecvalue, //[]byte{0x00, 0x4c, 0x4b, 0x40}
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_best_effort_rate_test.go b/internal/pkg/core/l2oam/msg_best_effort_rate_test.go
new file mode 100644
index 0000000..25bfb49
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_best_effort_rate_test.go
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package l2oam
+
+import (
+ "encoding/binary"
+ "reflect"
+ "testing"
+
+ "github.com/google/gopacket"
+)
+
+func TestGenerateBestEffortRate(t *testing.T) {
+ type args struct {
+ ecvalue []byte
+ trafficProfile []byte
+ }
+ tests := []struct {
+ name string
+ args args
+ want gopacket.SerializableLayer
+ }{
+ // TODO: Add test cases.
+ {
+ name: "GenerateBestEffortRate-1",
+ args: args{
+ ecvalue: []byte{0x00, 0x4c, 0x4b, 0x40},
+ trafficProfile: []byte{0x00, 0x00, 0x00, 0x01},
+ },
+ want: &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance() + 1,
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: binary.BigEndian.Uint32([]byte{0x00, 0x00, 0x00, 0x01}),
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x0008,
+ VcLength: 5, //5
+ // EC
+ ECLength: 4, //4
+ ECValue: []byte{0x00, 0x4c, 0x4b, 0x40}, //[]byte{0x00, 0x4c, 0x4b, 0x40}
+ // End
+ EndBranch: 0x00,
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := GenerateBestEffortRate(tt.args.ecvalue, tt.args.trafficProfile); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("GenerateBestEffortRate() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/internal/pkg/core/l2oam/msg_discovery.go b/internal/pkg/core/l2oam/msg_discovery.go
new file mode 100644
index 0000000..ab104bc
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_discovery.go
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateDiscoverySOLICIT generates "Discovery: SOLICIT" message
+func GenerateDiscoverySOLICIT() gopacket.SerializableLayer {
+
+ tibitData := &DiscoverySolicit{
+ // IEEE 1904.2
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ // Vendor-specific
+ VendorType: 0xfe,
+ Length: 37,
+ // Vendor ID
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ // Controller Priority
+ CPType: 0x05,
+ CPLength: 1,
+ CPValue: []byte{128},
+ //NetworkID
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte("tibitcom.com"),
+ //Device Type
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{1},
+ //Supported CLient Protocols
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ //Padding
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ }
+
+ return tibitData
+}
+
+// DiscoverySolicit is a structure for Discovery message
+type DiscoverySolicit struct {
+ layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16 // length of after this data without Padding
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+}
+
+// String returns the string expression of DiscoverySolicit
+func (d *DiscoverySolicit) String() string {
+ message := fmt.Sprintf("Opcode:%v, DiscoveryType:%v, VendorType:%v, Length:%v", d.Opcode, d.DiscoveryType, d.VendorType, d.Length)
+ message = fmt.Sprintf("%s, VendorIDType:%v, VendorIDLength:%v, VendorID:%v", message, d.VendorIDType, d.VendorIDLength, hex.EncodeToString(d.VendorID))
+ message = fmt.Sprintf("%s, CPType:%v, CPLength:%v, CPValue:%v", message, d.CPType, d.CPLength, hex.EncodeToString(d.CPValue))
+ message = fmt.Sprintf("%s, NWType:%v, NWLength:%v, NWValue:%v", message, d.NWType, d.NWLength, hex.EncodeToString(d.NWValue))
+ message = fmt.Sprintf("%s, DVType:%v, DVLength:%v, DVValue:%v", message, d.DVType, d.DVLength, hex.EncodeToString(d.DVValue))
+ message = fmt.Sprintf("%s, SCPType:%v, SCPLength:%v, SCPValue:%v", message, d.SCPType, d.SCPLength, hex.EncodeToString(d.SCPValue))
+ return message
+}
+
+// Len returns the length of DiscoverySolicit
+func (d *DiscoverySolicit) Len() int {
+ len := (2) + (3) + int(d.Length) + (int(d.PadLength) + 3)
+ return len
+}
+
+// LayerType returns the ethernet type of DiscoverySolicit
+func (d *DiscoverySolicit) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *DiscoverySolicit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ data[i] = byte(d.DiscoveryType)
+ i++
+ data[i] = byte(d.VendorType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Length)
+ i = i + 2
+
+ data[i] = byte(d.VendorIDType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VendorIDLength)
+ i = i + 2
+ copy(data[i:i+int(d.VendorIDLength)], d.VendorID)
+ i = i + int(d.VendorIDLength)
+
+ data[i] = byte(d.CPType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CPLength)
+ i = i + 2
+ copy(data[i:i+int(d.CPLength)], d.CPValue)
+ i = i + int(d.CPLength)
+
+ data[i] = byte(d.NWType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.NWLength)
+ i = i + 2
+ copy(data[i:i+int(d.NWLength)], d.NWValue)
+ i = i + int(d.NWLength)
+
+ data[i] = byte(d.DVType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.DVLength)
+ i = i + 2
+ copy(data[i:i+int(d.DVLength)], d.DVValue)
+ i = i + int(d.DVLength)
+
+ data[i] = byte(d.SCPType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.SCPLength)
+ i = i + 2
+ copy(data[i:i+int(d.SCPLength)], d.SCPValue)
+ i = i + int(d.SCPLength)
+
+ data[i] = byte(d.PadType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.PadLength)
+ i = i + 2
+ copy(data[i:i+int(d.PadLength)], d.PadValue)
+
+ return nil
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *DiscoverySolicit) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.DiscoveryType = data[i]
+ i++
+ d.VendorType = data[i]
+ i++
+ d.Length = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+
+ d.VendorIDType = data[i]
+ i++
+ d.VendorIDLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.VendorID = data[i : i+int(d.VendorIDLength)]
+ i = i + int(d.VendorIDLength)
+
+ d.CPType = data[i]
+ i++
+ d.CPLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.CPValue = data[i : i+int(d.CPLength)]
+ i = i + int(d.CPLength)
+
+ d.NWType = data[i]
+ i++
+ d.NWLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.NWValue = data[i : i+int(d.NWLength)]
+ i = i + int(d.NWLength)
+
+ d.DVType = data[i]
+ i++
+ d.DVLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.DVValue = data[i : i+int(d.DVLength)]
+ i = i + int(d.DVLength)
+
+ d.SCPType = data[i]
+ i++
+ d.SCPLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.SCPValue = data[i : i+int(d.SCPLength)]
+ i = i + int(d.SCPLength)
+
+ d.PadType = data[i]
+ i++
+ d.PadLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.PadValue = data[i : i+int(d.PadLength)]
+
+ return nil
+}
+
+// DiscoveryHello is a structure for Discovery message
+type DiscoveryHello struct {
+ layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16 // length of after this data without Padding
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+}
+
+// String returns the string expression of DiscoveryHello
+func (d *DiscoveryHello) String() string {
+ message := fmt.Sprintf("Opcode:%v, DiscoveryType:%v, VendorType:%v, Length:%v", d.Opcode, d.DiscoveryType, d.VendorType, d.Length)
+ message = fmt.Sprintf("%s, VendorIDType:%v, VendorIDLength:%v, VendorID:%v", message, d.VendorIDType, d.VendorIDLength, hex.EncodeToString(d.VendorID))
+ message = fmt.Sprintf("%s, NWType:%v, NWLength:%v, NWValue:%v", message, d.NWType, d.NWLength, hex.EncodeToString(d.NWValue))
+ message = fmt.Sprintf("%s, DVType:%v, DVLength:%v, DVValue:%v", message, d.DVType, d.DVLength, hex.EncodeToString(d.DVValue))
+ message = fmt.Sprintf("%s, SCPType:%v, SCPLength:%v, SCPValue:%v", message, d.SCPType, d.SCPLength, hex.EncodeToString(d.SCPValue))
+ message = fmt.Sprintf("%s, TunnelType:%v, TunnelLength:%v, TunnelValue:%v", message, d.TunnelType, d.TunnelLength, hex.EncodeToString(d.TunnelValue))
+ message = fmt.Sprintf("%s, PadType:%v, PadLength:%v, PadValue:%v", message, d.PadType, d.PadLength, hex.EncodeToString(d.PadValue))
+ return message
+}
+
+// Len returns the length of DiscoveryHello
+func (d *DiscoveryHello) Len() int {
+ len := (2) + (3) + int(d.Length) + (int(d.PadLength) + 3)
+ return len
+}
+
+// LayerType returns the ethernet type of DiscoveryHello
+func (d *DiscoveryHello) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *DiscoveryHello) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ data[i] = byte(d.DiscoveryType)
+ i++
+ data[i] = byte(d.VendorType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Length)
+ i = i + 2
+
+ data[i] = byte(d.VendorIDType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VendorIDLength)
+ i = i + 2
+ copy(data[i:i+int(d.VendorIDLength)], d.VendorID)
+ i = i + int(d.VendorIDLength)
+
+ data[i] = byte(d.NWType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.NWLength)
+ i = i + 2
+ copy(data[i:i+int(d.NWLength)], d.NWValue)
+ i = i + int(d.NWLength)
+
+ data[i] = byte(d.DVType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.DVLength)
+ i = i + 2
+ copy(data[i:i+int(d.DVLength)], d.DVValue)
+ i = i + int(d.DVLength)
+
+ data[i] = byte(d.SCPType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.SCPLength)
+ i = i + 2
+ copy(data[i:i+int(d.SCPLength)], d.SCPValue)
+ i = i + int(d.SCPLength)
+
+ data[i] = byte(d.TunnelType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.TunnelLength)
+ i = i + 2
+ copy(data[i:i+int(d.TunnelLength)], d.TunnelValue)
+ i = i + int(d.TunnelLength)
+
+ data[i] = byte(d.PadType)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.PadLength)
+ i = i + 2
+ copy(data[i:i+int(d.PadLength)], d.PadValue)
+
+ return nil
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *DiscoveryHello) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.DiscoveryType = data[i]
+ i++
+ d.VendorType = data[i]
+ i++
+ d.Length = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+
+ d.VendorIDType = data[i]
+ i++
+ d.VendorIDLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.VendorID = data[i : i+int(d.VendorIDLength)]
+ i = i + int(d.VendorIDLength)
+
+ d.NWType = data[i]
+ i++
+ d.NWLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.NWValue = data[i : i+int(d.NWLength)]
+ i = i + int(d.NWLength)
+
+ d.DVType = data[i]
+ i++
+ d.DVLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.DVValue = data[i : i+int(d.DVLength)]
+ i = i + int(d.DVLength)
+
+ d.SCPType = data[i]
+ i++
+ d.SCPLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.SCPValue = data[i : i+int(d.SCPLength)]
+ i = i + int(d.SCPLength)
+
+ d.TunnelType = data[i]
+ i++
+ d.TunnelLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.TunnelValue = data[i : i+int(d.TunnelLength)]
+ i = i + int(d.TunnelLength)
+
+ d.PadType = data[i]
+ i++
+ d.PadLength = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.PadValue = data[i : i+int(d.PadLength)]
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/msg_discovery_test.go b/internal/pkg/core/l2oam/msg_discovery_test.go
new file mode 100644
index 0000000..618c81a
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_discovery_test.go
@@ -0,0 +1,1409 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+ "reflect"
+ "testing"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+func TestGenerateDiscoverySOLICIT(t *testing.T) {
+ tests := []struct {
+ name string
+ want gopacket.SerializableLayer
+ }{
+ // TODO: Add test cases.
+ {
+ name: "GenerateDiscoverySOLICIT-1",
+ want: &DiscoverySolicit{
+ // IEEE 1904.2
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ // Vendor-specific
+ VendorType: 0xfe,
+ Length: 37,
+ // Vendor ID
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ // Controller Priority
+ CPType: 0x05,
+ CPLength: 1,
+ CPValue: []byte{128},
+ //NetworkID
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte("tibitcom.com"),
+ //Device Type
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{1},
+ //Supported CLient Protocols
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ //Padding
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := GenerateDiscoverySOLICIT(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("GenerateDiscoverySOLICIT() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoverySolicit_String(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want string
+ }{
+ // TODO: Add test cases.
+ {
+ name: "String-1",
+ fields: fields{
+ // IEEE 1904.2
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ // Vendor-specific
+ VendorType: 0xfe,
+ Length: 37,
+ // Vendor ID
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ // Controller Priority
+ CPType: 0x05,
+ CPLength: 1,
+ CPValue: []byte{128},
+ //NetworkID
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte("tibitcom.com"),
+ //Device Type
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{1},
+ //Supported CLient Protocols
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ //Padding
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ want: fmt.Sprintf("Opcode:253, DiscoveryType:1, VendorType:254, Length:37, VendorIDType:253, VendorIDLength:3, VendorID:2aea15, CPType:5, CPLength:1, CPValue:80, NWType:6, NWLength:16, NWValue:%v, DVType:7, DVLength:1, DVValue:01, SCPType:8, SCPLength:1, SCPValue:03", hex.EncodeToString([]byte("tibitcom.com"))),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoverySolicit{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ CPType: tt.fields.CPType,
+ CPLength: tt.fields.CPLength,
+ CPValue: tt.fields.CPValue,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.String(); got != tt.want {
+ t.Errorf("DiscoverySolicit.String() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoverySolicit_Len(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want int
+ }{
+ // TODO: Add test cases.
+ {
+ name: "Len-1",
+ fields: fields{
+ // IEEE 1904.2
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ // Vendor-specific
+ VendorType: 0xfe,
+ Length: 37,
+ // Vendor ID
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ // Controller Priority
+ CPType: 0x05,
+ CPLength: 1,
+ CPValue: []byte{128},
+ //NetworkID
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte("tibitcom.com"),
+ //Device Type
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{1},
+ //Supported CLient Protocols
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ //Padding
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ want: 46,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoverySolicit{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ CPType: tt.fields.CPType,
+ CPLength: tt.fields.CPLength,
+ CPValue: tt.fields.CPValue,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.Len(); got != tt.want {
+ t.Errorf("DiscoverySolicit.Len() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoverySolicit_LayerType(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want gopacket.LayerType
+ }{
+ // TODO: Add test cases.
+ {
+ name: "LayerType-1",
+ want: layers.LayerTypeEthernet,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoverySolicit{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ CPType: tt.fields.CPType,
+ CPLength: tt.fields.CPLength,
+ CPValue: tt.fields.CPValue,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.LayerType(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("DiscoverySolicit.LayerType() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoverySolicit_SerializeTo(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ type args struct {
+ b gopacket.SerializeBuffer
+ opts gopacket.SerializeOptions
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ wantErr bool
+ }{
+ // TODO: Add test cases.
+ {
+ name: "SerializeTo-1",
+ fields: fields{
+ // IEEE 1904.2
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ // Vendor-specific
+ VendorType: 0xfe,
+ Length: 37,
+ // Vendor ID
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ // Controller Priority
+ CPType: 0x05,
+ CPLength: 1,
+ CPValue: []byte{128},
+ //NetworkID
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte("tibitcom.com"),
+ //Device Type
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{1},
+ //Supported CLient Protocols
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ //Padding
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ args: args{
+ b: gopacket.NewSerializeBufferExpectedSize(0, 36),
+ opts: gopacket.SerializeOptions{},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoverySolicit{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ CPType: tt.fields.CPType,
+ CPLength: tt.fields.CPLength,
+ CPValue: tt.fields.CPValue,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if err := d.SerializeTo(tt.args.b, tt.args.opts); (err != nil) != tt.wantErr {
+ t.Errorf("DiscoverySolicit.SerializeTo error = %v, wantErr %v", err, tt.wantErr)
+ }
+
+ data := tt.args.b.Bytes()
+ cnt := 0
+ digits := 0
+ if !reflect.DeepEqual(d.Opcode, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo Opcode error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DiscoveryType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo DiscoveryType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo VendorType error")
+ }
+ cnt++
+
+ if !reflect.DeepEqual(d.Length, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo Length error")
+ }
+ cnt += 2
+
+ if !reflect.DeepEqual(d.VendorIDType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo VendorIDType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorIDLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo VendorIDLength error")
+ }
+ cnt += 2
+ digits = int(d.VendorIDLength)
+ if !reflect.DeepEqual(d.VendorID, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo VendorID error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.CPType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo CPType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.CPLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo CPLength error")
+ }
+ cnt += 2
+ digits = int(d.CPLength)
+ if !reflect.DeepEqual(d.CPValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo CPValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.NWType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo NWType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.NWLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo NWLength error")
+ }
+ cnt += 2
+ //digits = int(d.NWLength)
+ for _, dvalue := range d.NWValue {
+ if !reflect.DeepEqual(dvalue, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo NWValue error")
+ }
+ cnt++
+ }
+ // if !reflect.DeepEqual(string(d.NWValue), string(data[cnt:cnt+digits])) {
+ // t.Errorf("DiscoverySolicit.SerializeTo NWValue error %x %x", d.NWValue, data[cnt:cnt+digits])
+ // }
+ cnt += 4
+ if !reflect.DeepEqual(d.DVType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo DVType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DVLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo DVLength error")
+ }
+ cnt += 2
+ digits = int(d.DVLength)
+ if !reflect.DeepEqual(d.DVValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo DVValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.SCPType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo SCPType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.SCPLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo SCPLength error")
+ }
+ cnt += 2
+ digits = int(d.SCPLength)
+ if !reflect.DeepEqual(d.SCPValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo SCPValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.PadType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo PadType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.PadLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo PadLength error")
+ }
+ cnt += 2
+ digits = int(d.PadLength)
+ if !reflect.DeepEqual(d.PadValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo PadValue error")
+ }
+
+ })
+ }
+}
+
+func TestDiscoverySolicit_Decode(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ CPType uint8
+ CPLength uint16
+ CPValue []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ type args struct {
+ data []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ wantErr bool
+ }{
+ // TODO: Add test cases.
+ {
+ name: "Decode-1",
+ args: args{
+ data: []byte{0xfd, 0x01, 0xfe, 0x00, 0x25, 0xfd, 0x00, 0x03, 0x2a, 0xea, 0x15, 0x05, 0x00, 0x01, 0x80, 0x06, 0x00, 0x10, 0x74, 0x69, 0x62, 0x69, 0x74, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x01, 0x08, 0x00, 0x01, 0x03, 0xff, 0x00, 0x01, 0x00},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoverySolicit{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ CPType: tt.fields.CPType,
+ CPLength: tt.fields.CPLength,
+ CPValue: tt.fields.CPValue,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if err := d.Decode(tt.args.data); (err != nil) != tt.wantErr {
+ t.Errorf("DiscoverySolicit.Decode error = %v, wantErr %v", err, tt.wantErr)
+ }
+
+ cnt := 0
+ digits := 0
+
+ if !reflect.DeepEqual(d.Opcode, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode Opcode error Opcode=%x,data=%x,cnt=%x", d.Opcode, tt.args.data[cnt:], cnt)
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DiscoveryType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode DiscoveryType error DiscoveryType=%X data=%x", d.DiscoveryType, tt.args.data[cnt:cnt+1])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode VendorType error %x %x", tt.args.data[cnt], d.VendorType)
+ }
+ cnt++
+
+ if !reflect.DeepEqual(d.Length, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.Decode Length error Length=%x data[cnt:cnt+2]=%x", string(d.Length), string(binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])))
+ }
+ cnt += 2
+
+ if !reflect.DeepEqual(d.VendorIDType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode VendorIDType error VendorIDType=%x data=%x", d.VendorIDType, tt.args.data[cnt])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorIDLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.Decode VendorIDLength error VendorIDLength=%x data[cnt:cnt+2]=%x", d.VendorIDLength, tt.args.data[cnt:cnt+2])
+ }
+ cnt += 2
+ digits = int(d.VendorIDLength)
+ if !reflect.DeepEqual(d.VendorID, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode VendorID error %v %v", d.VendorID, tt.args.data[cnt:cnt+3])
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.CPType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode CPType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.CPLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode CPLength error")
+ }
+ cnt += 2
+ digits = int(d.CPLength)
+ if !reflect.DeepEqual(d.CPValue, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode CPValue error %x %x", tt.args.data[14:15], d.CPValue)
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.NWType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode NWType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.NWLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode NWLength error")
+ }
+ cnt += 2
+ //digits = int(d.NWLength)
+ for _, dvalue := range d.NWValue {
+ if !reflect.DeepEqual(dvalue, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode NWValue error %x %x", dvalue, tt.args.data[cnt])
+ }
+ cnt++
+ }
+ // if !reflect.DeepEqual(string(d.NWValue), string(tt.args.data[cnt:cnt+digits])) {
+ // t.Errorf("DiscoverySolicit.Decode NWValue error %x %x", d.NWValue, tt.args.data[cnt:cnt+digits])
+ // }
+ // cnt += 4
+ if !reflect.DeepEqual(d.DVType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode DVType error %x %x", d.DVType, tt.args.data[cnt])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DVLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.Decode DVLength error %x %x", d.DVLength, tt.args.data[cnt:cnt+2])
+ }
+ cnt += 2
+ digits = int(d.DVLength)
+ if !reflect.DeepEqual(d.DVValue, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode DVValue error %x %x", d.DVValue, tt.args.data[cnt:cnt+digits])
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.SCPType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode SCPType error %x %x", d.SCPType, tt.args.data[cnt])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.SCPLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode SCPLength error")
+ }
+ cnt += 2
+ digits = int(d.SCPLength)
+ if !reflect.DeepEqual(d.SCPValue, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode SCPValue error cnt= %x digits=%x", cnt, digits)
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.PadType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode PadType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.PadLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode PadLength error")
+ }
+ cnt += 2
+ digits = int(d.PadLength)
+ if !reflect.DeepEqual(d.PadValue, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode PadValue error %x %x", d.PadValue, tt.args.data[cnt:cnt+digits])
+ }
+
+ })
+ }
+}
+
+func TestDiscoveryHello_String(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want string
+ }{
+ // TODO: Add test cases.
+ {
+ name: "String-1",
+ fields: fields{
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ VendorType: 0xfe,
+ Length: 0x25,
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16},
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{2},
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ TunnelType: 0x0a,
+ TunnelLength: 2,
+ TunnelValue: []byte{0x00, 0x01},
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ want: "Opcode:253, DiscoveryType:1, VendorType:254, Length:37, VendorIDType:253, VendorIDLength:3, VendorID:2aea15, NWType:6, NWLength:16, NWValue:01020304050607080910111213141516, DVType:7, DVLength:1, DVValue:02, SCPType:8, SCPLength:1, SCPValue:03, TunnelType:10, TunnelLength:2, TunnelValue:0001, PadType:255, PadLength:1, PadValue:00",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoveryHello{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ TunnelType: tt.fields.TunnelType,
+ TunnelLength: tt.fields.TunnelLength,
+ TunnelValue: tt.fields.TunnelValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.String(); got != tt.want {
+ t.Errorf("DiscoveryHello.String() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoveryHello_Len(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want int
+ }{
+ // TODO: Add test cases.
+ {
+ name: "Len-1",
+ fields: fields{
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ VendorType: 0xfe,
+ Length: 0x25,
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16},
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{2},
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ TunnelType: 0x0a,
+ TunnelLength: 2,
+ TunnelValue: []byte{0x00, 0x01},
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ want: 46,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoveryHello{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ TunnelType: tt.fields.TunnelType,
+ TunnelLength: tt.fields.TunnelLength,
+ TunnelValue: tt.fields.TunnelValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.Len(); got != tt.want {
+ t.Errorf("DiscoveryHello.Len() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoveryHello_LayerType(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ want gopacket.LayerType
+ }{
+ // TODO: Add test cases.
+ {
+ name: "LayerType-1",
+ want: layers.LayerTypeEthernet,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoveryHello{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ TunnelType: tt.fields.TunnelType,
+ TunnelLength: tt.fields.TunnelLength,
+ TunnelValue: tt.fields.TunnelValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if got := d.LayerType(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("DiscoveryHello.LayerType() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDiscoveryHello_SerializeTo(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ type args struct {
+ b gopacket.SerializeBuffer
+ opts gopacket.SerializeOptions
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ wantErr bool
+ }{
+ // TODO: Add test cases.
+ {
+ name: "SerializeTo-1",
+ fields: fields{
+ Opcode: 0xfd,
+ DiscoveryType: 0x01,
+ VendorType: 0xfe,
+ Length: 0x25,
+ VendorIDType: 0xfd,
+ VendorIDLength: 3,
+ VendorID: []byte{0x2a, 0xea, 0x15},
+ NWType: 0x06,
+ NWLength: 16,
+ NWValue: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16},
+ DVType: 0x07,
+ DVLength: 1,
+ DVValue: []byte{2},
+ SCPType: 0x08,
+ SCPLength: 1,
+ SCPValue: []byte{0x03},
+ TunnelType: 0x0a,
+ TunnelLength: 2,
+ TunnelValue: []byte{0x00, 0x01},
+ PadType: 0xff,
+ PadLength: 1,
+ PadValue: []byte{0},
+ },
+ args: args{
+ b: gopacket.NewSerializeBufferExpectedSize(0, 46),
+ opts: gopacket.SerializeOptions{},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoveryHello{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ TunnelType: tt.fields.TunnelType,
+ TunnelLength: tt.fields.TunnelLength,
+ TunnelValue: tt.fields.TunnelValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if err := d.SerializeTo(tt.args.b, tt.args.opts); (err != nil) != tt.wantErr {
+ t.Errorf("DiscoveryHello.SerializeTo() error = %v, wantErr %v", err, tt.wantErr)
+ }
+
+ data := tt.args.b.Bytes()
+ cnt := 0
+ digits := 0
+ if !reflect.DeepEqual(d.Opcode, data[cnt]) {
+ t.Errorf("DiscoverySolicit.SerializeTo Opcode error Opcode=%x,data=%x,cnt=%x", d.Opcode, data[cnt:], cnt)
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DiscoveryType, data[cnt]) {
+ t.Errorf("DiscoverySolicit.SerializeTo DiscoveryType error DiscoveryType=%X data=%x", d.DiscoveryType, data[cnt:cnt+1])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorType, data[cnt]) {
+ t.Errorf("DiscoverySolicit.SerializeTo VendorType error %x %x", data[cnt], d.VendorType)
+ }
+ cnt++
+
+ if !reflect.DeepEqual(d.Length, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.SerializeTo Length error Length=%x data[cnt:cnt+2]=%x", string(d.Length), string(binary.BigEndian.Uint16(data[cnt:cnt+2])))
+ }
+ cnt += 2
+
+ if !reflect.DeepEqual(d.VendorIDType, data[cnt]) {
+ t.Errorf("DiscoverySolicit.SerializeTo VendorIDType error VendorIDType=%x data=%x", d.VendorIDType, data[cnt])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorIDLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.SerializeTo VendorIDLength error VendorIDLength=%x data[cnt:cnt+2]=%x", d.VendorIDLength, data[cnt:cnt+2])
+ }
+ cnt += 2
+ digits = int(d.VendorIDLength)
+ if !reflect.DeepEqual(d.VendorID, data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.SerializeTo VendorID error %v %v", d.VendorID, data[cnt:cnt+3])
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.NWType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo NWType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.NWLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo NWLength error")
+ }
+ cnt += 2
+ //digits = int(d.NWLength)
+ for _, dvalue := range d.NWValue {
+ if !reflect.DeepEqual(dvalue, data[cnt]) {
+ t.Errorf("DiscoverySolicit.SerializeTo NWValue error %x %x", dvalue, data[cnt])
+ }
+ cnt++
+ }
+ // if !reflect.DeepEqual(string(d.NWValue), string(data[cnt:cnt+digits])) {
+ // t.Errorf("DiscoverySolicit.SerializeTo NWValue error %x %x", d.NWValue, data[cnt:cnt+digits])
+ // }
+ // cnt += 16
+ if !reflect.DeepEqual(d.DVType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo DVType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DVLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo DVLength error")
+ }
+ cnt += 2
+ digits = int(d.DVLength)
+ if !reflect.DeepEqual(d.DVValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo DVValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.SCPType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo SCPType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.SCPLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo SCPLength error")
+ }
+ cnt += 2
+ digits = int(d.SCPLength)
+ if !reflect.DeepEqual(d.SCPValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo SCPValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.TunnelType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo TunnelType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.TunnelLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo TunnelLength error")
+ }
+ cnt += 2
+ digits = int(d.TunnelLength)
+ if !reflect.DeepEqual(d.TunnelValue, data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.SerializeTo TunnelValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.PadType, data[cnt]) {
+ t.Error("DiscoverySolicit.SerializeTo PadType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.PadLength, binary.BigEndian.Uint16(data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.SerializeTo PadLength error")
+ }
+ cnt += 2
+ digits = int(d.PadLength)
+ if !reflect.DeepEqual(d.PadValue, data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.SerializeTo PadValue error %x %x", d.PadValue, data[cnt:cnt+digits])
+ }
+ })
+ }
+}
+
+func TestDiscoveryHello_Decode(t *testing.T) {
+ type fields struct {
+ BaseLayer layers.BaseLayer
+ Opcode uint8
+ DiscoveryType uint8
+ VendorType uint8
+ Length uint16
+ VendorIDType uint8
+ VendorIDLength uint16
+ VendorID []byte
+ NWType uint8
+ NWLength uint16
+ NWValue []byte
+ DVType uint8
+ DVLength uint16
+ DVValue []byte
+ SCPType uint8
+ SCPLength uint16
+ SCPValue []byte
+ TunnelType uint8
+ TunnelLength uint16
+ TunnelValue []byte
+ PadType uint8
+ PadLength uint16
+ PadValue []byte
+ }
+ type args struct {
+ data []byte
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ wantErr bool
+ }{
+ // TODO: Add test cases.
+ {
+ name: "Decode-1",
+ args: args{
+ data: []byte{0xfd, 0x02, 0xfe, 0x00, 0x26, 0xfd, 0x00, 0x03, 0x2a, 0xea, 0x15, 0x06, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x07, 0x00, 0x01, 0x02, 0x08, 0x00, 0x01, 0x03, 0x0a, 0x00, 0x02, 0x00, 0x01, 0xff, 0x00, 0x01, 0x00},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ d := &DiscoveryHello{
+ BaseLayer: tt.fields.BaseLayer,
+ Opcode: tt.fields.Opcode,
+ DiscoveryType: tt.fields.DiscoveryType,
+ VendorType: tt.fields.VendorType,
+ Length: tt.fields.Length,
+ VendorIDType: tt.fields.VendorIDType,
+ VendorIDLength: tt.fields.VendorIDLength,
+ VendorID: tt.fields.VendorID,
+ NWType: tt.fields.NWType,
+ NWLength: tt.fields.NWLength,
+ NWValue: tt.fields.NWValue,
+ DVType: tt.fields.DVType,
+ DVLength: tt.fields.DVLength,
+ DVValue: tt.fields.DVValue,
+ SCPType: tt.fields.SCPType,
+ SCPLength: tt.fields.SCPLength,
+ SCPValue: tt.fields.SCPValue,
+ TunnelType: tt.fields.TunnelType,
+ TunnelLength: tt.fields.TunnelLength,
+ TunnelValue: tt.fields.TunnelValue,
+ PadType: tt.fields.PadType,
+ PadLength: tt.fields.PadLength,
+ PadValue: tt.fields.PadValue,
+ }
+ if err := d.Decode(tt.args.data); (err != nil) != tt.wantErr {
+ t.Errorf("DiscoveryHello.Decode() error = %v, wantErr %v", err, tt.wantErr)
+ }
+
+ cnt := 0
+ digits := 0
+ if !reflect.DeepEqual(d.Opcode, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode Opcode error Opcode=%x,data=%x,cnt=%x", d.Opcode, tt.args.data[cnt:], cnt)
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DiscoveryType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode DiscoveryType error DiscoveryType=%X data=%x", d.DiscoveryType, tt.args.data[cnt:cnt+1])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode VendorType error %x %x", tt.args.data[cnt], d.VendorType)
+ }
+ cnt++
+
+ if !reflect.DeepEqual(d.Length, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.Decode Length error Length=%x data[cnt:cnt+2]=%x", string(d.Length), string(binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])))
+ }
+ cnt += 2
+
+ if !reflect.DeepEqual(d.VendorIDType, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode VendorIDType error VendorIDType=%x data=%x", d.VendorIDType, tt.args.data[cnt])
+ }
+ cnt++
+ if !reflect.DeepEqual(d.VendorIDLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Errorf("DiscoverySolicit.Decode VendorIDLength error VendorIDLength=%x data[cnt:cnt+2]=%x", d.VendorIDLength, tt.args.data[cnt:cnt+2])
+ }
+ cnt += 2
+ digits = int(d.VendorIDLength)
+ if !reflect.DeepEqual(d.VendorID, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode VendorID error %v %v", d.VendorID, tt.args.data[cnt:cnt+3])
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.NWType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode NWType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.NWLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode NWLength error")
+ }
+ cnt += 2
+ //digits = int(d.NWLength)
+ for _, dvalue := range d.NWValue {
+ if !reflect.DeepEqual(dvalue, tt.args.data[cnt]) {
+ t.Errorf("DiscoverySolicit.Decode NWValue error %x %x", dvalue, tt.args.data[cnt])
+ }
+ cnt++
+ }
+ // if !reflect.DeepEqual(string(d.NWValue), string(tt.args.data[cnt:cnt+digits])) {
+ // t.Errorf("DiscoverySolicit.Decode NWValue error %x %x", d.NWValue, tt.args.data[cnt:cnt+digits])
+ // }
+ // cnt += 16
+ if !reflect.DeepEqual(d.DVType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode DVType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.DVLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode DVLength error")
+ }
+ cnt += 2
+ digits = int(d.DVLength)
+ if !reflect.DeepEqual(d.DVValue, tt.args.data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.Decode DVValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.SCPType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode SCPType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.SCPLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode SCPLength error")
+ }
+ cnt += 2
+ digits = int(d.SCPLength)
+ if !reflect.DeepEqual(d.SCPValue, tt.args.data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.Decode SCPValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.TunnelType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode TunnelType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.TunnelLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode TunnelLength error")
+ }
+ cnt += 2
+ digits = int(d.TunnelLength)
+ if !reflect.DeepEqual(d.TunnelValue, tt.args.data[cnt:cnt+digits]) {
+ t.Error("DiscoverySolicit.Decode TunnelValue error")
+ }
+ cnt += digits
+ if !reflect.DeepEqual(d.PadType, tt.args.data[cnt]) {
+ t.Error("DiscoverySolicit.Decode PadType error")
+ }
+ cnt++
+ if !reflect.DeepEqual(d.PadLength, binary.BigEndian.Uint16(tt.args.data[cnt:cnt+2])) {
+ t.Error("DiscoverySolicit.Decode PadLength error")
+ }
+ cnt += 2
+ digits = int(d.PadLength)
+ if !reflect.DeepEqual(d.PadValue, tt.args.data[cnt:cnt+digits]) {
+ t.Errorf("DiscoverySolicit.Decode PadValue error %x %x", d.PadValue, tt.args.data[cnt:cnt+digits])
+ }
+ })
+ }
+}
diff --git a/internal/pkg/core/l2oam/msg_generic_action_create.go b/internal/pkg/core/l2oam/msg_generic_action_create.go
new file mode 100644
index 0000000..a50c6a5
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_generic_action_create.go
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+const (
+ ActionTypeProtocolFilter = 1
+
+ ActionTypeTrafficProfile = 2
+)
+
+// GenerateGenericActionCreate generates "Generic/Action Create" message
+func GenerateGenericActionCreate(actionType int) gopacket.SerializableLayer {
+ tibitData := &setGenericActionCreateReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 00000000,
+ //Vc
+ VcBranch: 0x6e,
+ VcLeaf: 0x7001,
+ VcLength: 4,
+ //OT
+ OT: []OTGenericActionCreate{{OTLength: 3, OTValue: getObjectType(actionType)}},
+ // End
+ EndBranch: 0,
+ }
+
+ return tibitData
+}
+
+func getObjectType(actionType int) []byte {
+ switch actionType {
+ case ActionTypeProtocolFilter:
+ return []byte{0x0c, 0x0c, 0xff}
+ case ActionTypeTrafficProfile:
+ return []byte{0x0c, 0x07, 0x0f}
+ default:
+ return []byte{0x00, 0x00, 0x00}
+ }
+}
+
+type setGenericActionCreateReq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ OT []OTGenericActionCreate
+ EndBranch uint8
+}
+
+// OTGenericActionCreate is a structure for "Object Type"
+type OTGenericActionCreate struct {
+ OTLength uint8
+ OTValue []byte
+}
+
+// String returns the string expression of setGenericActionCreateReq
+func (d *setGenericActionCreateReq) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ for _, ot := range d.OT {
+ message = fmt.Sprintf("%s, OTLength:%x, OTValue:%v", message, ot.OTLength, hex.EncodeToString(ot.OTValue))
+ }
+ message = fmt.Sprintf("%s, EndBranch:%x", message, d.EndBranch)
+ return message
+}
+
+// Len returns the length of setGenericActionCreateReq
+func (d *setGenericActionCreateReq) Len() int {
+ return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
+
+}
+
+// LayerType returns the ethernet type of setGenericActionCreateReq
+func (d *setGenericActionCreateReq) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *setGenericActionCreateReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ for _, ot := range d.OT {
+ nextIndex := serializeObjectType(&ot, data, i)
+ i = nextIndex
+ }
+
+ data[i] = byte(d.EndBranch)
+
+ return nil
+
+}
+
+func serializeObjectType(ot *OTGenericActionCreate, data []byte, startIndex int) int {
+ i := startIndex
+ data[i] = ot.OTLength
+ i++
+ copy(data[i:i+int(ot.OTLength)], ot.OTValue)
+ i += int(ot.OTLength)
+
+ return i
+
+}
+
+// SetGenericActionCreateRes is a structure for a response of "Generic/Action Create"
+type SetGenericActionCreateRes struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+
+ ObOCLength uint8
+ ObOCBranch uint8
+ ObOCType uint16
+ ObOCLength2 uint8
+ ObOCInstance []byte
+
+ EndBranch uint8
+}
+
+// ObOC is a structure for "Object OC"
+type ObOC struct {
+ ObOCLength uint8
+ ObOCBranch uint8
+ ObOCType uint16
+ ObOCLength2 uint8
+ ObOCInstance []byte
+}
+
+// String returns the string expression of SetGenericActionCreateRes
+func (d *SetGenericActionCreateRes) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, ObOCLength:%x, ObOCBranch:%x, ObOCType:%x, ObOCLength2:%x, ObOCInstance:%x, EndBranch:%x",
+ message, d.ObOCLength, d.ObOCBranch, d.ObOCType, d.ObOCLength2, d.ObOCInstance, d.EndBranch)
+ return message
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *SetGenericActionCreateRes) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+
+ d.ObOCLength = data[i]
+ i++
+ d.ObOCBranch = data[i]
+ i++
+ d.ObOCType = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.ObOCLength2 = data[i]
+ i++
+ d.ObOCInstance = data[i : i+int(d.ObOCLength2)]
+ i = i + int(d.ObOCLength2)
+
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetTrafficProfile returns the traffic profile of this message
+func (d *SetGenericActionCreateRes) GetTrafficProfile() []byte {
+ return d.ObOCInstance
+}
diff --git a/internal/pkg/core/l2oam/msg_generic_action_create_ds.go b/internal/pkg/core/l2oam/msg_generic_action_create_ds.go
new file mode 100644
index 0000000..40356d3
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_generic_action_create_ds.go
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateGenericActionCreateDs generates "Generic/Action Create" message
+func GenerateGenericActionCreateDs() gopacket.SerializableLayer {
+
+ tibitData := &setGenericActionCreateReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ //Vc
+ VcBranch: 0x6e,
+ VcLeaf: 0x7001,
+ VcLength: 4,
+ //OT
+ OT: []OTGenericActionCreate{{OTLength: 3, OTValue: []byte{0x0c, 0x02, 0x5d}}},
+ // End
+ EndBranch: 0,
+ }
+
+ return tibitData
+
+}
diff --git a/internal/pkg/core/l2oam/msg_generic_action_create_req.go b/internal/pkg/core/l2oam/msg_generic_action_create_req.go
new file mode 100644
index 0000000..766d1a1
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_generic_action_create_req.go
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+func GenerateGenericActionCreateReq() gopacket.SerializableLayer {
+
+ data := &TibitFrame{
+ Data: []byte{0x03, 0x00, 0x50, 0xfe, 0x2a, 0xea, 0x15, 0x03, 0x0c, 0x0c, 0x7a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0d, 0xce, 0x04, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x70, 0x01, 0x04, 0x03, 0x0c, 0x02, 0x5d, 0x00, 0x00},
+ }
+
+ binary.BigEndian.PutUint32(data.Data[12:16], getOltInstance())
+
+ return data
+
+}
diff --git a/internal/pkg/core/l2oam/msg_get_firmware_version.go b/internal/pkg/core/l2oam/msg_get_firmware_version.go
new file mode 100644
index 0000000..82995a7
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_firmware_version.go
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGetFirmwareVersion generates "Running Firmware Version" message
+func GenerateGetFirmwareVersion() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x001b,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// GetFirmwareVersionRes is a structure for a response of "Running Firmware Version"
+type GetFirmwareVersionRes struct {
+ ComResp TOAMGetResponse
+ AKLength uint8
+ AKValue []byte
+ RVLength uint8
+ RVValue []byte
+ BSLength uint8
+ BSValue []byte
+ RNLength uint8
+ RNValue []byte
+ BDLength uint8
+ BDValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetFirmwareVersionRes
+func (d *GetFirmwareVersionRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, AKLength:%02x, AKValue:%s, RVLength:%02x, RVValue:%s", message, d.AKLength, hex.EncodeToString(d.AKValue), d.RVLength, hex.EncodeToString(d.RVValue))
+ message = fmt.Sprintf("%s, BSLength:%02x, BSValue:%s, RNLength:%02x, RNValue:%s", message, d.BSLength, hex.EncodeToString(d.BSValue), d.RNLength, hex.EncodeToString(d.RNValue))
+ message = fmt.Sprintf("%s, BDLength:%02x, BDValue:%s, EndBranch:%02x", message, d.BDLength, hex.EncodeToString(d.BDValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetFirmwareVersionRes
+func (d *GetFirmwareVersionRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetFirmwareVersionRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.AKLength = data[i]
+ i++
+ d.AKValue = data[i : i+int(d.AKLength)]
+ i += int(d.AKLength)
+ d.RVLength = data[i]
+ i++
+ d.RVValue = data[i : i+int(d.RVLength)]
+ i += int(d.RVLength)
+ d.BSLength = data[i]
+ i++
+ d.BSValue = data[i : i+int(d.BSLength)]
+ i += int(d.BSLength)
+ d.RNLength = data[i]
+ i++
+ d.RNValue = data[i : i+int(d.RNLength)]
+ i += int(d.RNLength)
+ d.BDLength = data[i]
+ i++
+ d.BDValue = data[i : i+int(d.BDLength)]
+ i += int(d.BDLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetFirmwareVersionNumber returns a firmware version number
+func (d *GetFirmwareVersionRes) GetFirmwareVersionNumber() string {
+ return string(d.RVValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_mac_address.go b/internal/pkg/core/l2oam/msg_get_mac_address.go
new file mode 100644
index 0000000..e1df063
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_mac_address.go
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+ "strings"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGetMacAddress generates "PON Port/MAC Address" message
+func GenerateGetMacAddress() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0x07,
+ VdLeaf: 0x0004,
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
+
+// GetMacAddressRes is a structure for a toam response
+type GetMacAddressRes struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetMacAddressRes
+func (d *GetMacAddressRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%x, EcValue:%v, EndBranch:%x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetMacAddressRes
+func (d *GetMacAddressRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetMacAddressRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i = i + int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetMacAddress returns a MAC address
+func (d *GetMacAddressRes) GetMacAddress() string {
+ var buf []string
+ for _, b := range d.EcValue {
+ buf = append(buf, fmt.Sprintf("%02x", b))
+ }
+ return strings.Join(buf, ":")
+}
diff --git a/internal/pkg/core/l2oam/msg_get_manufacturer.go b/internal/pkg/core/l2oam/msg_get_manufacturer.go
new file mode 100644
index 0000000..74aa268
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_manufacturer.go
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateManuFacturerInfo generates "Device/Manufacturer Info" message
+func GenerateManuFacturerInfo() gopacket.SerializableLayer {
+
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ //OAMPrtocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ //TiBitT OLT Management
+ TOMIOpcode: 0x01,
+ //Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ //Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ //Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x0006,
+ //End
+ EndBranch: 0x00,
+ }
+ return tibitData
+
+}
+
+// GetManufacturerRes is a structure for a toam response
+type GetManufacturerRes struct {
+ ComResp TOAMGetResponse
+ ECLength uint8
+ ECValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetManufacturerRes
+func (d *GetManufacturerRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, ECLength:%02x, ECValue:%v,EndBranch:%02x", message, d.ECLength, hex.EncodeToString(d.ECValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetManufacturerRes
+func (d *GetManufacturerRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetManufacturerRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.ECLength = data[i]
+ i++
+ d.ECValue = data[i : i+int(d.ECLength)]
+ i = i + int(d.ECLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetManufacturer returns a manufacturer info.
+func (d *GetManufacturerRes) GetManufacturer() string {
+ return string(d.ECValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_module_number.go b/internal/pkg/core/l2oam/msg_get_module_number.go
new file mode 100644
index 0000000..b256acd
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_module_number.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGetModuleNumber generates "Device/Model Number" message
+func GenerateGetModuleNumber() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x81,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x000a,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// GetModuleNumberRes is a structure for toam message
+type GetModuleNumberRes struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetModuleNumberRes
+func (d *GetModuleNumberRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%02x, EcValue:%s EndBranch:%02x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetModuleNumberRes
+func (d *GetModuleNumberRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetModuleNumberRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i += int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetModuleNumber returns a module number
+func (d *GetModuleNumberRes) GetModuleNumber() string {
+ return string(d.EcValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_mpcp_llid.go b/internal/pkg/core/l2oam/msg_get_mpcp_llid.go
new file mode 100644
index 0000000..f1f7a10
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_mpcp_llid.go
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GetMpcpLLIdReq is a structure for "MPCP/LLID" message
+type GetMpcpLLIdReq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VdBranch uint8
+ VdLeaf uint16
+ EndBranch uint8
+}
+
+// GenerateGetMpcpLLId generates "MPCP/LLID" message
+func GenerateGetMpcpLLId(oc *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &GetMpcpLLIdReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vd
+ VdBranch: 0xcc,
+ VdLeaf: 0x0007,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// String returns the string expression of GetMpcpLLIdReq
+func (d *GetMpcpLLIdReq) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VdBranch:%02x, VdLeaf:%04x, EndBranch:%02x", message, d.VdBranch, d.VdLeaf, d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetMpcpLLIdReq
+func (d *GetMpcpLLIdReq) Len() int {
+ return 21
+}
+
+// LayerType returns the ethernet type of GetMpcpLLIdReq
+func (d *GetMpcpLLIdReq) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *GetMpcpLLIdReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VdBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VdLeaf)
+ i += 2
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+// GetMpcpLLIdRes is a structure for a response of "MPCP/LLID" message
+type GetMpcpLLIdRes struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetMpcpLLIdRes
+func (d *GetMpcpLLIdRes) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%02x, VcLeaf:%04x, VcLength:%02x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, EcLength:%02x, EcValue:%v, EndBranch:%02x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetMpcpLLIdRes
+func (d *GetMpcpLLIdRes) Len() int {
+ return 20 + int(d.VcLength) + 1
+}
+
+// LayerType returns the ethernet type of GetMpcpLLIdRes
+func (d *GetMpcpLLIdRes) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// Decode decodes byte arrays to a data structure
+func (d *GetMpcpLLIdRes) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i += int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetLLID returns a LLID
+func (d *GetMpcpLLIdRes) GetLLID() uint16 {
+ return binary.BigEndian.Uint16(d.EcValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_mpcp_mac_address.go b/internal/pkg/core/l2oam/msg_get_mpcp_mac_address.go
new file mode 100644
index 0000000..7d9313c
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_mpcp_mac_address.go
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+ "strings"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GetMpcpMacAddressReq is a structure for "MPCP/MAC Address" message
+type GetMpcpMacAddressReq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VdBranch uint8
+ VdLeaf uint16
+ EndBranch uint8
+}
+
+// GenerateGetMpcpMacAddress generates "MPCP/MAC Address" message
+func GenerateGetMpcpMacAddress(oc *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &GetMpcpMacAddressReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vd
+ VdBranch: 0xcc,
+ VdLeaf: 0x0008,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// String returns the string expression of GetMpcpMacAddressReq
+func (d *GetMpcpMacAddressReq) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VdBranch:%02x, VdLeaf:%04x, EndBranch:%02x", message, d.VdBranch, d.VdLeaf, d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetModuleNumberRes
+func (d *GetMpcpMacAddressReq) Len() int {
+ return 21
+}
+
+// LayerType returns the ethernet type of GetMpcpMacAddressReq
+func (d *GetMpcpMacAddressReq) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *GetMpcpMacAddressReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VdBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VdLeaf)
+ i += 2
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+// GetMpcpMacAddressRes is a structure for a response of "MPCP/MAC Address" message
+type GetMpcpMacAddressRes struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetMpcpMacAddressRes
+func (d *GetMpcpMacAddressRes) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%02x, VcLeaf:%04x, VcLength:%02x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, EcLength:%02x, EcValue:%v, EndBranch:%02x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetMpcpMacAddressRes
+func (d *GetMpcpMacAddressRes) Len() int {
+ return 20 + int(d.VcLength) + 1
+}
+
+// LayerType returns the ethernet type of GetMpcpMacAddressRes
+func (d *GetMpcpMacAddressRes) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// Decode decodes byte arrays to a data structure
+func (d *GetMpcpMacAddressRes) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i += int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetMacAddress returns a MAC address
+func (d *GetMpcpMacAddressRes) GetMacAddress() string {
+ var buf []string
+ for _, b := range d.EcValue {
+ buf = append(buf, fmt.Sprintf("%02x", b))
+ }
+ return strings.Join(buf, ":")
+}
diff --git a/internal/pkg/core/l2oam/msg_get_pon_mode.go b/internal/pkg/core/l2oam/msg_get_pon_mode.go
new file mode 100644
index 0000000..74f8e00
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_pon_mode.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGetPonMode generates "Device/PON Mode" message
+func GenerateGetPonMode() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x0002,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// GetPonMode is a structure for toam message
+type GetPonMode struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetPonMode
+func (d *GetPonMode) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%02x, EcValue:%s EndBranch:%02x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetPonMode
+func (d *GetPonMode) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetPonMode) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i += int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetPonMode returns a PON mode
+func (d *GetPonMode) GetPonMode() string {
+ return string(d.EcValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_serial_number.go b/internal/pkg/core/l2oam/msg_get_serial_number.go
new file mode 100644
index 0000000..73c662d
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_serial_number.go
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGetSerialNumber generates "Device/Vendor Serial Number" message
+func GenerateGetSerialNumber() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x0012,
+ // End
+ EndBranch: 0,
+ }
+ return tibitData
+}
+
+// GetSerialNumberRes is a structure for toam message
+type GetSerialNumberRes struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetSerialNumberRes
+func (d *GetSerialNumberRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%02x, EcValue:%s EndBranch:%02x", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetSerialNumberRes
+func (d *GetSerialNumberRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetSerialNumberRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i += int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetSerialNumber returns a serial number
+func (d *GetSerialNumberRes) GetSerialNumber() string {
+ return string(d.EcValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_get_traffic_control_reference_table.go b/internal/pkg/core/l2oam/msg_get_traffic_control_reference_table.go
new file mode 100644
index 0000000..96b8c72
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_traffic_control_reference_table.go
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateGetTrafficControlReferenceTableReq generates "PON Link/Traffic Control Reference Table" message
+func GenerateGetTrafficControlReferenceTableReq(oc *TomiObjectContext) gopacket.SerializableLayer {
+ data := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vd
+ VdBranch: 0x01,
+ VdLeaf: 0x0007,
+ // End
+ EndBranch: 0x00,
+ }
+
+ return data
+}
+
+// GetTrafficControlReferenceTableRes is a structure for a response of "Traffic Control Reference Table" message
+type GetTrafficControlReferenceTableRes struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+
+ EcOcLengthDown uint8
+ EcOcBranchDown uint8
+ EcOcTypeDown uint16
+ EcOcLength2Down uint8
+ EcOcInstanceDown []byte
+
+ EcOcLengthUp uint8
+ EcOcBranchUp uint8
+ EcOcTypeUp uint16
+ EcOcLength2Up uint8
+ EcOcInstanceUp []byte
+
+ EndBranch uint8
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetTrafficControlReferenceTableRes) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+
+ d.EcOcLengthDown = data[i]
+ i++
+ d.EcOcBranchDown = data[i]
+ i++
+ d.EcOcTypeDown = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.EcOcLength2Down = data[i]
+ i++
+ d.EcOcInstanceDown = data[i : i+int(d.EcOcLength2Down)]
+ i += int(d.EcOcLength2Down)
+
+ d.EcOcLengthUp = data[i]
+ i++
+ d.EcOcBranchUp = data[i]
+ i++
+ d.EcOcTypeUp = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.EcOcLength2Up = data[i]
+ i++
+ d.EcOcInstanceUp = data[i : i+int(d.EcOcLength2Up)]
+ i += int(d.EcOcLength2Up)
+
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetReferenceControlDown returns a link id for downstream
+func (d *GetTrafficControlReferenceTableRes) GetReferenceControlDown() []byte {
+ return d.EcOcInstanceDown
+}
+
+// GetReferenceControlUp returns a link id for upstream
+func (d *GetTrafficControlReferenceTableRes) GetReferenceControlUp() []byte {
+ return d.EcOcInstanceUp
+}
diff --git a/internal/pkg/core/l2oam/msg_get_vendor_name.go b/internal/pkg/core/l2oam/msg_get_vendor_name.go
new file mode 100644
index 0000000..aa80fcd
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_get_vendor_name.go
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+// GnerateGetVendorName generates "Device/Vendor Name"
+func GnerateGetVendorName() gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x01,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vd
+ VdBranch: 0xde,
+ VdLeaf: 0x0009,
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
+
+// GetVendorNameRes is a structure for a response of "Device/Vendor Name" message
+type GetVendorNameRes struct {
+ ComResp TOAMGetResponse
+ EcLength uint8
+ EcValue []byte
+ EndBranch uint8
+}
+
+// String returns the string expression of GetVendorNameRes
+func (d *GetVendorNameRes) String() string {
+ message := d.ComResp.String()
+ message = fmt.Sprintf("%s, EcLength:%v, EcValue:%v, EndBranch:%v", message, d.EcLength, hex.EncodeToString(d.EcValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of GetVendorNameRes
+func (d *GetVendorNameRes) Len() int {
+ return d.ComResp.Len() + int(d.ComResp.VcLength) + 1
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *GetVendorNameRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ d.EcLength = data[i]
+ i++
+ d.EcValue = data[i : i+int(d.EcLength)]
+ i = i + int(d.EcLength)
+ d.EndBranch = data[i]
+
+ return nil
+}
+
+// GetVendorName returns a vendor name
+func (d *GetVendorNameRes) GetVendorName() string {
+ return string(d.EcValue)
+}
diff --git a/internal/pkg/core/l2oam/msg_guaranteed_mbs.go b/internal/pkg/core/l2oam/msg_guaranteed_mbs.go
new file mode 100644
index 0000000..675e44e
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_guaranteed_mbs.go
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateGuaranteedMbs generates "Traffic Profile/Guaranteed MBS" message
+func GenerateGuaranteedMbs() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: 0x00000002,
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x0007,
+ VcLength: 5,
+ // EC
+ ECLength: 4,
+ ECValue: []byte{0x00, 0x06, 0x40, 0x00},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_guaranteed_rate.go b/internal/pkg/core/l2oam/msg_guaranteed_rate.go
new file mode 100644
index 0000000..c26825d
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_guaranteed_rate.go
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateGuaranteedRate generates "Traffic Profile/Guaranteed Rate" message
+func GenerateGuaranteedRate(ecvalue []byte, trafficProfile []byte) gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: binary.BigEndian.Uint32(trafficProfile),
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x0006,
+ VcLength: uint8(1 + len(ecvalue)), //
+ // EC
+ ECLength: uint8(len(ecvalue)), //
+ ECValue: ecvalue, //0x80
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_l2switching_domain_action_Inlet_entry_del.go b/internal/pkg/core/l2oam/msg_l2switching_domain_action_Inlet_entry_del.go
new file mode 100644
index 0000000..667fb7f
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_l2switching_domain_action_Inlet_entry_del.go
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateL2switchingDomainActionInletEntryUsDel generates "L2 Switching Domain/Action Delete Inlet entry(for upstream)"
+func GenerateL2switchingDomainActionInletEntryUsDel(oc *TomiObjectContext,
+ tpid []byte, vid []byte, onuID *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &L2switchingDomainRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x5d,
+ VcLeaf: 0x7002,
+ VcLength: 21 + uint8(1+1+len(tpid)+1+len(vid)),
+ // Source OC
+ SOLength: 5,
+ SOBranch: 0x0c,
+ SOType: 0x0011,
+ SOValLength: 1,
+ SOInstance: uint8(onuID.Instance),
+ // TagMatchList
+ TMLLength: 7,
+ TMLList: []TpidVid{
+ {
+ Length: 3,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 1,
+ VIdValue: []byte{0x00},
+ },
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 0x80,
+ VIdValue: []byte{},
+ },
+ },
+ // TagOpPop(UI)
+ TOPopLength: 1,
+ TOPopValue: 0x00,
+ // TagOpSetList
+ TOSLength: 3,
+ TOSList: []TpidVid{
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 0x80,
+ VIdValue: []byte{},
+ },
+ },
+ // TagOpPushList
+ TOPushLength: uint8(1 + 1 + len(tpid) + 1 + len(vid)),
+ TOPushList: []TpidVid{
+ {
+ Length: uint8(1 + len(tpid) + 1 + len(vid)),
+ TpIDLength: uint8(len(tpid)),
+ TpIDValue: tpid,
+ VIdLength: uint8(len(vid)),
+ VIdValue: vid,
+ },
+ },
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
+
+// GenerateL2switchingDomainActionInletEntryDsDel generates "L2 Switching Domain/Action Delete Inlet entry(for downstream)"
+func GenerateL2switchingDomainActionInletEntryDsDel(oc *TomiObjectContext, tpid []byte, vid []byte) gopacket.SerializableLayer {
+ tibitData := &L2switchingDomainRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x5d,
+ VcLeaf: 0x7002,
+ VcLength: 16 + uint8(1+1+len(tpid)+1+len(vid)+4),
+ // Source OC
+ SOLength: 5,
+ SOBranch: 0x0c,
+ SOType: 0x0eca,
+ SOValLength: 1,
+ SOInstance: 0x00,
+ // TagMatchList
+ TMLLength: uint8(1 + 1 + len(tpid) + 1 + len(vid) + 3),
+ TMLList: []TpidVid{
+ {
+ Length: uint8(1 + len(tpid) + 1 + len(vid)),
+ TpIDLength: uint8(len(tpid)),
+ TpIDValue: tpid,
+ VIdLength: uint8(len(vid)),
+ VIdValue: vid,
+ },
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 0x80,
+ VIdValue: []byte{},
+ },
+ },
+ // TagOpPop(UI)
+ TOPopLength: 1,
+ TOPopValue: 0x01,
+ // TagOpSetList
+ TOSLength: 3,
+ TOSList: []TpidVid{
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 0x80,
+ VIdValue: []byte{},
+ },
+ },
+ // TagOpPushList
+ TOPushLength: 3,
+ TOPushList: []TpidVid{
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{},
+ VIdLength: 0x80,
+ VIdValue: []byte{},
+ },
+ },
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry.go b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry.go
new file mode 100644
index 0000000..b826292
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry.go
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// L2switchingDomainRequest is a structure for a request of "L2 Switching Domain/Action Inlet entry" message
+type L2switchingDomainRequest struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ SOLength uint8
+ SOBranch uint8
+ SOType uint16
+ SOValLength uint8
+ SOInstance uint8
+ TMLLength uint8
+ TMLList []TpidVid
+ TOPopLength uint8
+ TOPopValue uint8
+ TOSLength uint8
+ TOSList []TpidVid
+ TOPushLength uint8
+ TOPushList []TpidVid
+ EndBranch uint8
+ SizeMargin uint8
+}
+
+// TpidVid is a structure for TPID/VID set
+type TpidVid struct {
+ Length uint8
+ TpIDLength uint8
+ TpIDValue []byte
+ VIdLength uint8
+ VIdValue []byte
+}
+
+// String returns the string expression of L2switchingDomainRequest
+func (d *L2switchingDomainRequest) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, SOLength:%x, SOBranch:%x, SOType:%x, SOValLength:%x, SOInstance:%x", message, d.SOLength, d.SOBranch, d.SOType, d.SOValLength, d.SOInstance)
+ message = fmt.Sprintf("%s, TMLLength:%x", message, d.TMLLength)
+ for i, tagMatch := range d.TMLList {
+ message = fmt.Sprintf("%s, %s", message, stringToTpidVid(&tagMatch, i))
+ }
+ message = fmt.Sprintf("%s, TOPopLength:%x, TOPopValue:%x", message, d.TOPopLength, d.TOPopValue)
+ message = fmt.Sprintf("%s, TOSLength:%x", message, d.TOSLength)
+ for i, tagOpSet := range d.TOSList {
+ message = fmt.Sprintf("%s, %s", message, stringToTpidVid(&tagOpSet, i))
+ }
+ message = fmt.Sprintf("%s, TOPushLength:%x", message, d.TOPushLength)
+ for i, tagOpPush := range d.TOPushList {
+ message = fmt.Sprintf("%s, %s", message, stringToTpidVid(&tagOpPush, i))
+ }
+ return message
+}
+
+func stringToTpidVid(tpidVid *TpidVid, index int) string {
+ message := fmt.Sprintf("EC[%v]:{Length:%x, TpIdLength:%x", index, tpidVid.Length, tpidVid.TpIDLength)
+ if tpidVid.TpIDLength != 128 {
+ message = fmt.Sprintf("%s, TpIdValue:%v", message, hex.EncodeToString(tpidVid.TpIDValue))
+ }
+ message = fmt.Sprintf("%s, VIdLength:%x", message, tpidVid.VIdLength)
+ if tpidVid.VIdLength != 128 {
+ message = fmt.Sprintf("%s, VIdValue:%v", message, hex.EncodeToString(tpidVid.VIdValue))
+ }
+ message = fmt.Sprintf("%s}", message)
+ return message
+}
+
+// Len returns the length of L2switchingDomainRequest
+func (d *L2switchingDomainRequest) Len() int {
+ return 22 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength) + int(d.SizeMargin)
+}
+
+// LayerType returns the ethernet type of L2switchingDomainRequest
+func (d *L2switchingDomainRequest) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *L2switchingDomainRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ data[i] = byte(d.SOLength)
+ i++
+ data[i] = byte(d.SOBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.SOType)
+ i += 2
+ data[i] = byte(d.SOValLength)
+ i++
+ data[i] = byte(d.SOInstance)
+ i++
+ data[i] = byte(d.TMLLength)
+ i++
+ for _, tagMatch := range d.TMLList {
+ nextIndex := serializeTpidVid(&tagMatch, data, i)
+ i = nextIndex
+ }
+ data[i] = byte(d.TOPopLength)
+ i++
+ data[i] = byte(d.TOPopValue)
+ i++
+ data[i] = byte(d.TOSLength)
+ i++
+ for _, tagOpSet := range d.TOSList {
+ nextIndex := serializeTpidVid(&tagOpSet, data, i)
+ i = nextIndex
+ }
+ data[i] = d.TOPushLength
+ i++
+ for _, tagOpPush := range d.TOPushList {
+ nextIndex := serializeTpidVid(&tagOpPush, data, i)
+ i = nextIndex
+ }
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+func serializeTpidVid(tpidVid *TpidVid, data []byte, startIndex int) int {
+ i := startIndex
+ data[i] = tpidVid.Length
+ i++
+ ln := tpidVid.TpIDLength
+ data[i] = ln
+ i++
+ if ln != 128 { // !Empty?
+ copy(data[i:i+int(ln)], tpidVid.TpIDValue)
+ i += int(ln)
+ }
+ ln = tpidVid.VIdLength
+ data[i] = ln
+ i++
+ if ln != 128 { // !Empty?
+ copy(data[i:i+int(ln)], tpidVid.VIdValue)
+ i += int(ln)
+ }
+ return i
+}
diff --git a/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_ds.go b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_ds.go
new file mode 100644
index 0000000..6013ce3
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_ds.go
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateL2switchingDomainActionLnletEntryDs generates "L2 Switching Domain/Action Add Inlet entry(for downstream)"
+func GenerateL2switchingDomainActionLnletEntryDs(oc *TomiObjectContext, tmTpidValue []byte, tmVidValue []byte) gopacket.SerializableLayer {
+
+ tibitData := &L2switchingDomainRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x5d,
+ VcLeaf: 0x7001,
+ //VcLength: uint8(24 + len(tmTpidValue) + len(tmVidValue)), //27
+ VcLength: uint8(23 + len(tmTpidValue) + len(tmVidValue)), //26
+ // Source OC
+ SOLength: 5,
+ SOBranch: 0x0c,
+ SOType: 0x0eca,
+ SOValLength: 1,
+ SOInstance: 0x00,
+ // TagMatchList
+ //TMLLength: uint8(7 + len(tmTpidValue) + len(tmVidValue)), //10
+ TMLLength: uint8(6 + len(tmTpidValue) + len(tmVidValue)), //9
+ TMLList: []TpidVid{
+ {Length: uint8(2 + len(tmTpidValue) + len(tmVidValue)),
+ TpIDLength: uint8(len(tmTpidValue)),
+ TpIDValue: tmTpidValue,
+ VIdLength: uint8(len(tmVidValue)),
+ VIdValue: tmVidValue},
+ ////{Length: 5, TpIdLength: 2, TpIdValue: []byte{0x88, 0xa8}, VIdLength: 1, VIdValue: []byte{0x64}}
+
+ //{Length: 3, TpIdLength: 128, TpIdValue: []byte{0}, VIdLength: 1, VIdValue: []byte{0x00}}},
+ {Length: 2, TpIDLength: 128, TpIDValue: []byte{0}, VIdLength: 128, VIdValue: []byte{0x00}}},
+ // TagOpPop(UI)
+ TOPopLength: 1,
+ TOPopValue: 0x01,
+ // TagOpSetList
+ TOSLength: 3,
+ TOSList: []TpidVid{
+ {Length: 2, TpIDLength: 128, TpIDValue: []byte{0}, VIdLength: 128, VIdValue: []byte{0}}},
+ // TagOpPushList
+ TOPushLength: 3,
+ TOPushList: []TpidVid{
+ {Length: 2, TpIDLength: 128, TpIDValue: []byte{0}, VIdLength: 128, VIdValue: []byte{0}}},
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_us.go b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_us.go
new file mode 100644
index 0000000..5f07c98
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_l2switching_domain_action_lnlet_entry_us.go
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateL2switchingDomainActionLnletEntryUs generates "L2 Switching Domain/Action Add Inlet entry(upstream)" message
+func GenerateL2switchingDomainActionLnletEntryUs(oc *TomiObjectContext,
+ pushTpidValue []byte, pushVidValue []byte, onuID *TomiObjectContext) gopacket.SerializableLayer {
+
+ tibitData := &L2switchingDomainRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x5d,
+ VcLeaf: 0x7001,
+ VcLength: uint8(24 + len(pushTpidValue) + len(pushVidValue)), //27
+ // Source OC
+ SOLength: 5,
+ SOBranch: 0x0c,
+ SOType: 0x0011,
+ SOValLength: 1,
+ SOInstance: uint8(onuID.Instance),
+ // TagMatchList
+ TMLLength: 7,
+ TMLList: []TpidVid{
+ {
+ Length: 3,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{0},
+ VIdLength: 1,
+ VIdValue: []byte{0x00},
+ },
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{0},
+ VIdLength: 0x80,
+ VIdValue: []byte{0},
+ }},
+ // TagOpPop(UI)
+ TOPopLength: 1,
+ TOPopValue: 0x00,
+ // TagOpSetList
+ TOSLength: 3,
+ TOSList: []TpidVid{
+ {
+ Length: 2,
+ TpIDLength: 0x80,
+ TpIDValue: []byte{0},
+ VIdLength: 0x80,
+ VIdValue: []byte{0},
+ }},
+ // TagOpPushList
+ TOPushLength: uint8(3 + len(pushTpidValue) + len(pushVidValue)), //6
+ TOPushList: []TpidVid{
+ {Length: uint8(2 + len(pushTpidValue) + len(pushVidValue)),
+ TpIDLength: uint8(len(pushTpidValue)),
+ TpIDValue: pushTpidValue,
+ VIdLength: uint8(len(pushVidValue)),
+ VIdValue: pushVidValue}}, ///{Length: 5, TpIdLength: 2, TpIdValue: []byte{0x88, 0xa8}, VIdLength: 1, VIdValue: []byte{0x64}}
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_oampdu_information.go b/internal/pkg/core/l2oam/msg_oampdu_information.go
new file mode 100644
index 0000000..6d7a9f8
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_oampdu_information.go
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// OampduTlvTypeLocalInfo means that TLV type is "Local Information"
+var OampduTlvTypeLocalInfo uint8 = 0x01
+
+// OampduTlvTypeRemoteInfo means that TLV type is "Remote Information"
+var OampduTlvTypeRemoteInfo uint8 = 0x02
+
+// OampduTlvTypeOrganizationSpecificInfo means that TLV type is "Organization Specific Information"
+var OampduTlvTypeOrganizationSpecificInfo uint8 = 0xfe
+
+// GeneateKeepAlive1 generates "OAMPDU Information(first)"
+func GeneateKeepAlive1(isOnuPkgA bool) gopacket.SerializableLayer {
+ var osiLength uint8
+ var osiValue []byte
+ if isOnuPkgA {
+ osiLength = 7
+ osiValue = []byte{0x00, 0x10, 0x00, 0x00, 0x23}
+ } else {
+ osiLength = 8
+ osiValue = []byte{0x90, 0x82, 0x60, 0x02, 0x01, 0x01}
+ }
+ tibitData := &OAMPDUInformation{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0008,
+ Code: 0x00,
+ // Local Information TLV
+ LIType: OampduTlvTypeLocalInfo,
+ LILength: 16,
+ LIValue: []byte{0x01, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x2a, 0xea, 0x15, 0x00, 0x00, 0x00, 0x23},
+ // Organization Specific Information TLV
+ OSIType: OampduTlvTypeOrganizationSpecificInfo,
+ OSILength: osiLength,
+ OSIValue: osiValue,
+ }
+
+ return tibitData
+}
+
+// GeneateKeepAlive2 generates "OAMPDU Information(second)"
+func GeneateKeepAlive2(riValue []byte, isOnuPkgA bool) gopacket.SerializableLayer {
+ var osiLength uint8
+ var osiValue []byte
+ if isOnuPkgA {
+ osiLength = 7
+ osiValue = []byte{0x00, 0x10, 0x00, 0x00, 0x23}
+ } else {
+ osiLength = 8
+ osiValue = []byte{0x90, 0x82, 0x60, 0x02, 0x01, 0x01}
+ }
+ tibitData := &OAMPDUInformation{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0030,
+ Code: 0x00,
+ // Local Information TLV
+ LIType: OampduTlvTypeLocalInfo,
+ LILength: 16,
+ LIValue: []byte{0x01, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x2a, 0xea, 0x15, 0x00, 0x00, 0x00, 0x23},
+ // Remote Information TLV
+ RIType: OampduTlvTypeRemoteInfo,
+ RILength: 16,
+ RIValue: riValue,
+ // Organization Specific Information TLV
+ OSIType: OampduTlvTypeOrganizationSpecificInfo,
+ OSILength: osiLength,
+ OSIValue: osiValue,
+ }
+
+ return tibitData
+
+}
+
+// GeneateKeepAlive3 generates "OAMPDU Information(third)"
+func GeneateKeepAlive3(riValue []byte) gopacket.SerializableLayer {
+ tibitData := &OAMPDUInformation{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ Code: 0x00,
+ // Local Information TLV
+ LIType: OampduTlvTypeLocalInfo,
+ LILength: 16,
+ LIValue: []byte{0x01, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x2a, 0xea, 0x15, 0x00, 0x00, 0x00, 0x23},
+ // Remote Information TLV
+ RIType: OampduTlvTypeRemoteInfo,
+ RILength: 16,
+ RIValue: riValue,
+ }
+
+ return tibitData
+
+}
+
+// OAMPDUInformation is a structure for "OAMPDU Information" message
+type OAMPDUInformation struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ Code uint8
+ LIType uint8
+ LILength uint8
+ LIValue []byte
+ RIType uint8
+ RILength uint8
+ RIValue []byte
+ OSIType uint8
+ OSILength uint8
+ OSIValue []byte
+}
+
+// String returns the string expression of OAMPDUInformation
+func (d *OAMPDUInformation) String() string {
+ message := fmt.Sprintf("Opcode:%v, Flags:%v, Code:%v", d.Opcode, d.Flags, d.Code)
+ message = fmt.Sprintf("%s, LIType:%v, LILength:%v, LIValue:%v", message, d.LIType, d.LILength, hex.EncodeToString(d.LIValue))
+ message = fmt.Sprintf("%s, RIType:%v, RILength:%v, RIValue:%v", message, d.RIType, d.RILength, hex.EncodeToString(d.RIValue))
+ message = fmt.Sprintf("%s, OSIType:%v, OSILength:%v, OSIValue:%v", message, d.OSIType, d.OSILength, hex.EncodeToString(d.OSIValue))
+ return message
+}
+
+// Len returns the length of OAMPDUInformation
+func (d *OAMPDUInformation) Len() int {
+ len := (1) + (3) + int(d.LILength) + int(d.RILength) + int(d.OSILength)
+ return len
+}
+
+// LayerType returns the ethernet type of OAMPDUInformation
+func (d *OAMPDUInformation) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *OAMPDUInformation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i = i + 2
+ data[i] = byte(d.Code)
+ i++
+
+ if d.LILength != 0 {
+ data[i] = byte(d.LIType)
+ data[i+1] = byte(d.LILength)
+ copy(data[i+2:i+int(d.LILength)], d.LIValue)
+ i = i + int(d.LILength)
+ }
+
+ if d.RILength != 0 {
+ data[i] = byte(d.RIType)
+ data[i+1] = byte(d.RILength)
+ copy(data[i+2:i+int(d.RILength)], d.RIValue)
+ i = i + int(d.RILength)
+ }
+
+ if d.OSILength != 0 {
+ data[i] = byte(d.OSIType)
+ data[i+1] = byte(d.OSILength)
+ copy(data[i+2:i+int(d.OSILength)], d.OSIValue)
+ //i = i + int(d.OSILength)
+ }
+
+ return nil
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *OAMPDUInformation) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i = i + 2
+ d.Code = data[i]
+ i++
+
+ for {
+ if len(data) <= i {
+ break
+ }
+ tlvType := data[i]
+ tlvLength := data[i+1]
+ if tlvLength == 0 {
+ break
+ }
+ tlvValue := data[i+2 : i+int(tlvLength)]
+ i = i + int(tlvLength)
+
+ switch tlvType {
+ case OampduTlvTypeLocalInfo:
+ d.LIType = tlvType
+ d.LILength = tlvLength
+ d.LIValue = tlvValue
+ case OampduTlvTypeRemoteInfo:
+ d.RIType = tlvType
+ d.RILength = tlvLength
+ d.RIValue = tlvValue
+ case OampduTlvTypeOrganizationSpecificInfo:
+ d.OSIType = tlvType
+ d.OSILength = tlvLength
+ d.OSIValue = tlvValue
+ default:
+ return fmt.Errorf("tlvType Error: %v", tlvType)
+ }
+ }
+
+ return nil
+}
+
+// IsOnuPkgA returns true if message type of OAMPDUInformation is PkgA
+func (d *OAMPDUInformation) IsOnuPkgA() bool {
+ if d.OSILength == 0 {
+ // return true if OSILength is 0, this means the message is KeepAlive3
+ return true
+ } else if d.OSILength == 7 {
+ return (d.OSIValue[0] == 0x00 && d.OSIValue[1] == 0x10 && d.OSIValue[2] == 0x00)
+ }
+ return false
+}
+
+// IsOnuPkgB returns true if message type of OAMPDUInformation is PkgA
+func (d *OAMPDUInformation) IsOnuPkgB() bool {
+ if d.OSILength == 0 {
+ // return true if OSILength is 0, this means the message is KeepAlive3
+ return true
+ } else if d.OSILength == 7 {
+ return (d.OSIValue[0] == 0x90 && d.OSIValue[1] == 0x82 && d.OSIValue[2] == 0x60)
+ }
+ return false
+}
diff --git a/internal/pkg/core/l2oam/msg_pcscompu_tibitcom.go b/internal/pkg/core/l2oam/msg_pcscompu_tibitcom.go
new file mode 100644
index 0000000..80e7d18
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_pcscompu_tibitcom.go
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+)
+
+func GeneratePcscompuTivitcom(oc *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &TOAMGetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x81,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: 0x00000003,
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vd
+ VdBranch: 0x01,
+ VdLeaf: 0x0007,
+ // End
+ EndBranch: 0,
+ }
+
+ return tibitData
+}
+
+type GetTrafficControlRefTableRes struct {
+ ComResp TOAMGetResponse
+
+ ECOC []EcOcPONLinkTrafficControlReferenceTable
+ EndBranch uint8
+}
+
+type EcOcPONLinkTrafficControlReferenceTable struct {
+ EcOcLength uint8
+ EcOcBranch uint8
+ EcOcType uint16
+ EcOcLength2 uint8
+ EcOcInstance []byte
+}
+
+func (d *GetTrafficControlRefTableRes) String() string {
+ message := d.ComResp.String()
+ for k, ec := range d.ECOC {
+ message = message + "EC[" + string(k) + "],EcOcLength:" + string(ec.EcOcLength) + ",EcOcBranch:" + string(ec.EcOcBranch) + ",EcOcType:" + string(ec.EcOcType) + ",EcOcLength2" + string(ec.EcOcLength2) + ",EcOcInstance:" + hex.EncodeToString(ec.EcOcInstance)
+ }
+ message = fmt.Sprintf("%s", message)
+ return message
+
+}
+
+func (d *GetTrafficControlRefTableRes) Decode(data []byte) error {
+ d.ComResp.Decode(data)
+ i := d.ComResp.Len()
+ for _, ec := range d.ECOC {
+ ec.EcOcLength = data[i]
+ i++
+ ec.EcOcBranch = data[i]
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], ec.EcOcType)
+ i = i + 2
+ ec.EcOcLength2 = data[i]
+ i++
+ copy(data[i:i+int(ec.EcOcLength2)], ec.EcOcInstance)
+ i = i + int(ec.EcOcLength2)
+ }
+
+ d.EndBranch = data[i]
+ i++
+
+ return nil
+
+}
diff --git a/internal/pkg/core/l2oam/msg_priority.go b/internal/pkg/core/l2oam/msg_priority.go
new file mode 100644
index 0000000..cbfff24
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_priority.go
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+// GeneratePriority generates "Traffic Profile/Priority" message
+func GeneratePriority(trafficProfile []byte) gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x070f,
+ OCLength: 4,
+ OCInstance: binary.BigEndian.Uint32(trafficProfile),
+ // Vc
+ VcBranch: 0x7f,
+ VcLeaf: 0x000a,
+ VcLength: 2,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x04},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_action_delete.go b/internal/pkg/core/l2oam/msg_set_action_delete.go
new file mode 100644
index 0000000..b05f661
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_action_delete.go
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateSetActionDelete generates "Generic/Action Delete" message
+func GenerateSetActionDelete(trafficProfile []byte, actionType int) gopacket.SerializableLayer {
+ ocInstance := binary.BigEndian.Uint32(trafficProfile)
+ objectType := getObjectType(actionType)
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: objectType[0],
+ OCType: binary.BigEndian.Uint16(objectType[1:3]),
+ OCLength: 4,
+ OCInstance: ocInstance,
+ // Vc
+ VcBranch: 0x6e,
+ VcLeaf: 0x7002,
+ VcLength: 0x80,
+ // EC
+ ECLength: 0,
+ ECValue: []byte{},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
+
+// GenerateSetActionDeleteStream generates "Generic/Action Delete(for stream)" message
+func GenerateSetActionDeleteStream(oc *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x6e,
+ VcLeaf: 0x7002,
+ VcLength: 0x80,
+ // EC
+ ECLength: 0,
+ ECValue: []byte{},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_action_delete_onu.go b/internal/pkg/core/l2oam/msg_set_action_delete_onu.go
new file mode 100644
index 0000000..fe8a728
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_action_delete_onu.go
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetActionDeleteOnu generates "Generic/Action Delete" message
+func GenerateSetActionDeleteOnu(oc *TomiObjectContext) gopacket.SerializableLayer {
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x6e,
+ VcLeaf: 0x7002,
+ VcLength: 0x80,
+ // EC
+ ECLength: 0,
+ ECValue: []byte{},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_action_reset.go b/internal/pkg/core/l2oam/msg_set_action_reset.go
new file mode 100644
index 0000000..0dc4a28
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_action_reset.go
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+)
+
+// GenerateSetActionReset generates "Device/Action Reset" message
+func GenerateSetActionReset() gopacket.SerializableLayer {
+
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x2a, 0xea, 0x15, 0x03,
+ 0x0c, 0x0c, 0x7a, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x0c, 0x0d, 0xce, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0xde, 0x70, 0x01, 0x80, 0x00, 0x00},
+ }
+
+ binary.BigEndian.PutUint32(data.Data[12:16], getOltInstance())
+
+ return data
+
+}
diff --git a/internal/pkg/core/l2oam/msg_set_admin_state.go b/internal/pkg/core/l2oam/msg_set_admin_state.go
new file mode 100644
index 0000000..aae58ab
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_admin_state.go
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetAdminState generates "PON Port/Admin State" message
+func GenerateSetAdminState() gopacket.SerializableLayer {
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0x07,
+ VcLeaf: 0x0001,
+ VcLength: 2,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x01},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+
+}
+
+// GenerateSetAdminStateDelete generates "PON Port/Admin State(for delete)" message
+func GenerateSetAdminStateDelete() gopacket.SerializableLayer {
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0x07,
+ VcLeaf: 0x0001,
+ VcLength: 2,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x02},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+
+}
diff --git a/internal/pkg/core/l2oam/msg_set_capture_protocols.go b/internal/pkg/core/l2oam/msg_set_capture_protocols.go
new file mode 100644
index 0000000..49c335a
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_capture_protocols.go
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateCaptureProtocols generates "Protocol Filter/Capture Protocols" message
+func GenerateCaptureProtocols(ocInstance uint32) gopacket.SerializableLayer {
+
+ return &SetGenerteCaptureProtocolsreq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0cff,
+ OCLength: 4,
+ OCInstance: ocInstance,
+ // Vc
+ VcBranch: 0xcf,
+ VcLeaf: 0x0003,
+ VcLength: 5,
+ // EC
+ ECLength: 4,
+ //Protocol
+ ProtocolLength: 1,
+ ProtocolValue: 0x01,
+ //Action
+ ActionLength: 1,
+ ActionValue: 0x01,
+ // End
+ EndBranch: 0x00,
+ }
+
+}
+
+// SetGenerteCaptureProtocolsreq is a structure for a request of "Protocol Filter/Capture Protocols" message
+type SetGenerteCaptureProtocolsreq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ ECLength uint8
+ ProtocolLength uint8
+ ProtocolValue uint8
+ ActionLength uint8
+ ActionValue uint8
+ EndBranch uint8
+}
+
+// Len returns the length of SetGenerteCaptureProtocolsreq
+func (d *SetGenerteCaptureProtocolsreq) Len() int {
+ return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
+}
+
+// LayerType returns the ethernet type of SetGenerteCaptureProtocolsreq
+func (d *SetGenerteCaptureProtocolsreq) LayerType() gopacket.LayerType {
+ return layers.LayerTypeEthernet
+}
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *SetGenerteCaptureProtocolsreq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ data[i] = byte(d.ECLength)
+ i++
+ data[i] = byte(d.ProtocolLength)
+ i++
+ data[i] = byte(d.ProtocolValue)
+ i++
+ data[i] = byte(d.ActionLength)
+ i++
+ data[i] = byte(d.ActionValue)
+ i++
+ data[i] = byte(d.EndBranch)
+
+ return nil
+
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *SetGenerteCaptureProtocolsreq) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+ d.ECLength = data[i]
+ i++
+ d.ProtocolLength = data[i]
+ i++
+ d.ProtocolValue = data[i]
+ i++
+ d.ActionLength = data[i]
+ i++
+ d.ActionValue = data[i]
+ i++
+ d.EndBranch = data[i]
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/msg_set_default_outlet.go b/internal/pkg/core/l2oam/msg_set_default_outlet.go
new file mode 100644
index 0000000..a794903
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_default_outlet.go
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateSetDefaultOutlet generates "Default Outlet" message
+func GenerateSetDefaultOutlet(oc *TomiObjectContext, onuID *TomiObjectContext) gopacket.SerializableLayer {
+
+ tibitData := &DefaultOutletRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: oc.Branch,
+ OCType: oc.Type,
+ OCLength: oc.Length,
+ OCInstance: oc.Instance,
+ // Vc
+ VcBranch: 0x5d,
+ VcLeaf: 0x0003,
+ VcLength: 0x09,
+ // Default Outlet
+ DOLength: 8,
+ DOBranch: 0x0c,
+ DOType: 0x0011,
+ DOValLength: 4,
+ DOInstance: onuID.Instance,
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
+
+// DefaultOutletRequest is a structure for a request of "Default Outlet" message
+type DefaultOutletRequest struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ DOLength uint8
+ DOBranch uint8
+ DOType uint16
+ DOValLength uint8
+ DOInstance uint32
+ EndBranch uint8
+}
+
+// String returns the string expression of DefaultOutletRequest
+func (d *DefaultOutletRequest) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, DOLength:%x, DOBranch:%x, DOType:%x, DOValLength:%x, DOInstance:%x", message, d.DOLength, d.DOBranch, d.DOType, d.DOValLength, d.DOInstance)
+
+ return message
+}
+
+// Len returns the length of DefaultOutletRequest
+func (d *DefaultOutletRequest) Len() int {
+ return 38
+}
+
+// LayerType returns the ethernet type of DefaultOutletRequest
+func (d *DefaultOutletRequest) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *DefaultOutletRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ data[i] = byte(d.DOLength)
+ i++
+ data[i] = byte(d.DOBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.DOType)
+ i += 2
+ data[i] = byte(d.DOValLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.DOInstance)
+ i += 4
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/msg_set_hbtx_period.go b/internal/pkg/core/l2oam/msg_set_hbtx_period.go
new file mode 100644
index 0000000..f2b784a
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_hbtx_period.go
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetHbtxPeriod generates "OAM/HBTx Period"
+func GenerateSetHbtxPeriod() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0x0a,
+ VcLeaf: 0x0002,
+ VcLength: 3,
+ // EC
+ ECLength: 2,
+ ECValue: []byte{0x03, 0xe8},
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_hbtx_template.go b/internal/pkg/core/l2oam/msg_set_hbtx_template.go
new file mode 100644
index 0000000..f319e52
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_hbtx_template.go
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+//GenerateSetHbtxTemplate generates "OAM/HBTx Template" message
+func GenerateSetHbtxTemplate() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0x0a,
+ VcLeaf: 0x0003,
+ VcLength: 35,
+ // EC
+ ECLength: 34,
+ ECValue: []byte{
+ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x02, 0xe8, 0xb4,
+ 0x70, 0x70, 0x04, 0x07, 0x88, 0x09, 0x03, 0x00,
+ 0x50, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00,
+ 0x1b, 0x04, 0xb0, 0x2a, 0xea, 0x15, 0x00, 0x00,
+ 0x00, 0x23},
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_ingress_port.go b/internal/pkg/core/l2oam/msg_set_ingress_port.go
new file mode 100644
index 0000000..d55efdc
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_ingress_port.go
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateIngressPort generates "Protocol Filter/Ingress Port" message
+func GenerateIngressPort(OCInstance uint32, isponport bool) gopacket.SerializableLayer {
+
+ var ponPort uint16 = 0x0007
+
+ if !isponport {
+ ponPort = 0x0e07
+ }
+
+ return &SetGenerteIngressPortreq{
+ //IEEE 1904.2
+ Opcode: 0x03,
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ //TiBiT OLT Management Interface
+ TOMIOpcode: 0x03,
+ //Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ //Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0cff,
+ OCLength: 4,
+ OCInstance: OCInstance,
+ //Vc
+ VcBranch: 0xcf,
+ VcLeaf: 0x0002,
+ VcLength: 9,
+ //EC OC
+ ECOCLength1: 8,
+ ECOCBranch: 0x0c,
+ ECOCType: ponPort,
+ ECOCLength2: 4,
+ ECOCInstance: 0x00000000,
+ //End
+ EndBranch: 0x00,
+ }
+
+}
+
+// SetGenerteIngressPortreq is a structure for a reqest of "Protocol Filter/Ingress Port" message
+type SetGenerteIngressPortreq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ ECOCLength1 uint8
+ ECOCBranch uint8
+ ECOCType uint16
+ ECOCLength2 uint8
+ ECOCInstance uint32
+ EndBranch uint8
+}
+
+// Len returns the length of SetGenerteIngressPortreq
+func (d *SetGenerteIngressPortreq) Len() int {
+ return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
+}
+
+// LayerType returns the ethernet type of SetGenerteIngressPortreq
+func (d *SetGenerteIngressPortreq) LayerType() gopacket.LayerType {
+ return layers.LayerTypeEthernet
+}
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *SetGenerteIngressPortreq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ data[i] = byte(d.ECOCLength1)
+ i++
+ data[i] = byte(d.ECOCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.ECOCType)
+ i += 2
+ data[i] = byte(d.ECOCLength2)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.ECOCInstance)
+ i += 4
+ data[i] = byte(d.EndBranch)
+
+ return nil
+
+}
+
+// Decode decodes byte arrays to a data structure
+func (d *SetGenerteIngressPortreq) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+ i++
+ d.ECOCLength1 = data[i]
+ i++
+ d.ECOCBranch = data[i]
+ i++
+ d.ECOCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.ECOCLength2 = data[i]
+ i++
+ d.ECOCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.EndBranch = data[i]
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/msg_set_management_lock.go b/internal/pkg/core/l2oam/msg_set_management_lock.go
new file mode 100644
index 0000000..c1490cf
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_management_lock.go
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetManagementLock generates "Device/ManagementLock" message
+func GenerateSetManagementLock() gopacket.SerializableLayer {
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0dce,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0xde,
+ VcLeaf: 0x002e,
+ VcLength: 0x04,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x00},
+ ECList: []ECValueSet{
+ {
+ Length: 0x01,
+ Value: []byte{0x02},
+ },
+ },
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_mpcp_sync.go b/internal/pkg/core/l2oam/msg_set_mpcp_sync.go
new file mode 100644
index 0000000..bfa1d4d
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_mpcp_sync.go
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetMPCPSync generates "MPCP/Sync Type" message
+func GenerateSetMPCPSync() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x43,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0xcc,
+ VcLeaf: 0x0004,
+ VcLength: 2,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x20},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_request_saved.go b/internal/pkg/core/l2oam/msg_set_request_saved.go
new file mode 100644
index 0000000..6869a79
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_request_saved.go
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+//
+func GenerateSetRequestSaved() gopacket.SerializableLayer {
+
+ tibitData := &TOAMSetRequest{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x43,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x0007,
+ OCLength: 4,
+ OCInstance: 0x00000000,
+ // Vc
+ VcBranch: 0xcc,
+ VcLeaf: 0x0004,
+ VcLength: 2,
+ // EC
+ ECLength: 1,
+ ECValue: []byte{0x20},
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_set_traffic_profile.go b/internal/pkg/core/l2oam/msg_set_traffic_profile.go
new file mode 100644
index 0000000..af11a66
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_set_traffic_profile.go
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetTrafficProfile generates "Traffic Control/Traffic Profile" message
+func GenerateSetTrafficProfile(trafficControl []byte, trafficProfile []byte) gopacket.SerializableLayer {
+ tibitData := &setTrafficControlTrafficProfileReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OAM Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15},
+ // TiBit OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x07c0,
+ OCLength: 4,
+ OCInstance: trafficControl,
+ // Vc
+ VcBranch: 0x7c,
+ VcLeaf: 0x0002,
+ VcLength: 9,
+ // EC OC
+ ECOC: []ECOCTrafficControlTrafficProfile{
+ {
+ EcOcLength: 8,
+ EcOcBranch: 0x0c,
+ EcOcType: 0x070f,
+ EcOcLength2: 4,
+ EcOcInstance: trafficProfile,
+ },
+ },
+ // End
+ EndBranch: 0x00,
+ }
+ return tibitData
+}
diff --git a/internal/pkg/core/l2oam/msg_toam_get.go b/internal/pkg/core/l2oam/msg_toam_get.go
new file mode 100644
index 0000000..f831aa0
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_toam_get.go
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// TOAMGetRequest is a structure for GET request of TOAM message
+type TOAMGetRequest struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VdBranch uint8
+ VdLeaf uint16
+ EndBranch uint8
+}
+
+// String returns the string expression of TOAMGetRequest
+func (d *TOAMGetRequest) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%02x, CTType:%04x, CTLength:%02x, CTInstance:%08x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VdBranch:%02x, VdLeaf:%04x, EndBranch:%02x", message, d.VdBranch, d.VdLeaf, d.EndBranch)
+ return message
+}
+
+// Len returns the length of TOAMGetRequest
+func (d *TOAMGetRequest) Len() int {
+ return 29
+}
+
+// LayerType returns the ethernet type of TOAMGetRequest
+func (d *TOAMGetRequest) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *TOAMGetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VdBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VdLeaf)
+ i += 2
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+// TOAMGetResponse is a structure for GET response of TOAM message
+type TOAMGetResponse struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+}
+
+// String returns the string expression of TOAMGetResponse
+func (d *TOAMGetResponse) String() string {
+ message := fmt.Sprintf("Opcode:%02x, Flags:%04x, OAMPDUCode:%02x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%02x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%02x, CTType:%04x, CTLength:%02x, CTInstance:%08x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%02x, OCType:%04x, OCLength:%02x, OCInstance:%08x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%02x, VcLeaf:%04x, VcLength:%02x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ return message
+}
+
+// Len returns the length of TOAMGetResponse
+func (d *TOAMGetResponse) Len() int {
+ return 28
+}
+
+// LayerType returns the ethernet type of TOAMGetResponse
+func (d *TOAMGetResponse) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// Decode decodes byte arrays to a data structure
+func (d *TOAMGetResponse) Decode(data []byte) {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcLength = data[i]
+}
diff --git a/internal/pkg/core/l2oam/msg_toam_set.go b/internal/pkg/core/l2oam/msg_toam_set.go
new file mode 100644
index 0000000..7aa6bec
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_toam_set.go
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// TOAMSetRequest is a structure for SET request of TOAM message
+type TOAMSetRequest struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+ ECLength uint8
+ ECValue []byte
+ ECList []ECValueSet
+ EndBranch uint8
+}
+
+// ECValueSet is a structure for Vc-EC object
+type ECValueSet struct {
+ Length uint8
+ Value []byte
+}
+
+// String returns the string expression of TOAMSetRequest
+func (d *TOAMSetRequest) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ message = fmt.Sprintf("%s, ECLength:%x, ECValue:%v, EndBranch:%x", message, d.ECLength, hex.EncodeToString(d.ECValue), d.EndBranch)
+ return message
+}
+
+// Len returns the length of TOAMSetRequest
+func (d *TOAMSetRequest) Len() int {
+ if d.VcLength != 0x80 {
+ return 22 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
+ }
+ return 22 + int(d.CTLength) + int(d.OCLength)
+
+}
+
+// LayerType returns the ethernet type of TOAMSetRequest
+func (d *TOAMSetRequest) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *TOAMSetRequest) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ if d.VcLength != 0x80 {
+ // EC
+ data[i] = byte(d.ECLength)
+ i++
+ copy(data[i:i+int(d.ECLength)], d.ECValue)
+ i += int(d.ECLength)
+ }
+ if d.ECList != nil {
+ for _, ecSet := range d.ECList {
+ data[i] = byte(ecSet.Length)
+ i++
+ copy(data[i:i+int(ecSet.Length)], ecSet.Value)
+ i += int(ecSet.Length)
+ }
+ }
+
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+// TOAMSetResponse is a structure for SET response of TOAM message
+type TOAMSetResponse struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance uint32
+ VcBranch uint8
+ VcLeaf uint16
+ VcTOMIResCode uint8
+ EndBranch uint8
+}
+
+// String returns the string expression of TOAMSetResponse
+func (d *TOAMSetResponse) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcTOMIResCode:%x, EndBranch:%x", message, d.VcBranch, d.VcLeaf, d.VcTOMIResCode, d.EndBranch)
+ return message
+}
+
+// Len returns the length of TOAMSetResponse
+func (d *TOAMSetResponse) Len() int {
+ return 34 + int(d.CTLength) + int(d.OCLength)
+}
+
+// LayerType returns the ethernet type of TOAMSetResponse
+func (d *TOAMSetResponse) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
+
+// Decode decodes byte arrays to a data structure
+func (d *TOAMSetResponse) Decode(data []byte) error {
+ i := 0
+ d.Opcode = data[i]
+ i++
+ d.Flags = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OAMPDUCode = data[i]
+ i++
+ d.OUId = data[i : i+3]
+ i += len(d.OUId)
+ d.TOMIOpcode = data[i]
+ i++
+ d.CTBranch = data[i]
+ i++
+ d.CTType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.CTLength = data[i]
+ i++
+ d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.OCBranch = data[i]
+ i++
+ d.OCType = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.OCLength = data[i]
+ i++
+ d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
+ i += 4
+ d.VcBranch = data[i]
+ i++
+ d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
+ i += 2
+ d.VcTOMIResCode = data[i]
+ i++
+ d.EndBranch = data[i]
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/msg_traffic_control_traffic_profile.go b/internal/pkg/core/l2oam/msg_traffic_control_traffic_profile.go
new file mode 100644
index 0000000..84a325a
--- /dev/null
+++ b/internal/pkg/core/l2oam/msg_traffic_control_traffic_profile.go
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "fmt"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/layers"
+)
+
+// GenerateTrafficControlTrafficProfile generates "Traffic Control/Traffic Profile" message
+func GenerateTrafficControlTrafficProfile(trafficControl []byte, trafficProfile []byte) gopacket.SerializableLayer {
+
+ tibitData := &setTrafficControlTrafficProfileReq{
+ // IEEE 1904.2
+ Opcode: 0x03,
+ // OMI Protocol
+ Flags: 0x0050,
+ OAMPDUCode: 0xfe,
+ OUId: []byte{0x2a, 0xea, 0x15}, // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ // TiBiT OLT Management Interface
+ TOMIOpcode: 0x03,
+ // Correlation Tag
+ CTBranch: 0x0c,
+ CTType: 0x0c7a,
+ CTLength: 4,
+ CTInstance: getOltInstance(),
+ // Object Context
+ OCBranch: 0x0c,
+ OCType: 0x07c0,
+ OCLength: 4,
+ OCInstance: trafficControl,
+ // Vc
+ VcBranch: 0x7c,
+ VcLeaf: 0x0002,
+ VcLength: 0x09,
+
+ //EC OC
+ ECOC: []ECOCTrafficControlTrafficProfile{{EcOcLength: 8, EcOcBranch: 0x0c, EcOcType: 0x070f, EcOcLength2: 4, EcOcInstance: trafficProfile}},
+
+ // End
+ EndBranch: 0x00,
+ }
+
+ return tibitData
+}
+
+type setTrafficControlTrafficProfileReq struct {
+ layers.BaseLayer
+ Opcode uint8
+ Flags uint16
+ OAMPDUCode uint8
+ OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
+ TOMIOpcode uint8
+ CTBranch uint8
+ CTType uint16
+ CTLength uint8
+ CTInstance uint32
+ OCBranch uint8
+ OCType uint16
+ OCLength uint8
+ OCInstance []byte
+ VcBranch uint8
+ VcLeaf uint16
+ VcLength uint8
+
+ ECOC []ECOCTrafficControlTrafficProfile
+
+ EndBranch uint8
+}
+
+// ECOCTrafficControlTrafficProfile is a structure for Vc-EC OC object
+type ECOCTrafficControlTrafficProfile struct {
+ EcOcLength uint8
+ EcOcBranch uint8
+ EcOcType uint16
+ EcOcLength2 uint8
+ EcOcInstance []byte
+}
+
+// String returns the string expression of setTrafficControlTrafficProfileReq
+func (d *setTrafficControlTrafficProfileReq) String() string {
+ message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
+ message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
+ message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
+ message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
+ message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
+ for _, ecoc := range d.ECOC {
+ message = fmt.Sprintf("%s, EcOcLength:%x, EcOcBranch:%v, EcOcType:%x, EcOcLength2:%x, EcOcInstance:%x, ", message, ecoc.EcOcLength, ecoc.EcOcBranch, ecoc.EcOcType, ecoc.EcOcLength2, hex.EncodeToString(ecoc.EcOcInstance))
+ }
+ message = fmt.Sprintf("%s, EndBranch:%x", message, d.EndBranch)
+ return message
+}
+
+// Len returns the length of setTrafficControlTrafficProfileReq
+func (d *setTrafficControlTrafficProfileReq) Len() int {
+ return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
+}
+
+// LayerType returns the ethernet type of setTrafficControlTrafficProfileReq
+func (d *setTrafficControlTrafficProfileReq) LayerType() gopacket.LayerType {
+ return layers.LayerTypeEthernet
+}
+
+// SerializeTo serializes a data structure to byte arrays
+func (d *setTrafficControlTrafficProfileReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ plen := int(d.Len())
+ data, err := b.PrependBytes(plen)
+ if err != nil {
+ return err
+ }
+
+ i := 0
+ data[i] = byte(d.Opcode)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
+ i += 2
+ data[i] = byte(d.OAMPDUCode)
+ i++
+ copy(data[i:i+len(d.OUId)], d.OUId)
+ i += len(d.OUId)
+ data[i] = byte(d.TOMIOpcode)
+ i++
+ data[i] = byte(d.CTBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
+ i += 2
+ data[i] = byte(d.CTLength)
+ i++
+ binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
+ i += 4
+ data[i] = byte(d.OCBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
+ i += 2
+ data[i] = byte(d.OCLength)
+ i++
+ copy(data[i:i+4], d.OCInstance)
+ i += 4
+ data[i] = byte(d.VcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
+ i += 2
+ data[i] = byte(d.VcLength)
+ i++
+ for _, ecoc := range d.ECOC {
+ nextIndex := SerializeECOC(&ecoc, data, i)
+ i = nextIndex
+ }
+
+ data[i] = byte(d.EndBranch)
+
+ return nil
+}
+
+// SerializeECOC serializes a "EC OC" structure to byte arrays
+func SerializeECOC(ecoc *ECOCTrafficControlTrafficProfile, data []byte, startIndex int) int {
+ i := startIndex
+ data[i] = byte(ecoc.EcOcLength)
+ i++
+ data[i] = byte(ecoc.EcOcBranch)
+ i++
+ binary.BigEndian.PutUint16(data[i:i+2], ecoc.EcOcType)
+ i += 2
+ data[i] = byte(ecoc.EcOcLength2)
+ i++
+ copy(data[i:i+int(ecoc.EcOcLength2)], ecoc.EcOcInstance)
+ i += int(ecoc.EcOcLength2)
+
+ return i
+}
diff --git a/internal/pkg/core/l2oam/onu_list_access.go b/internal/pkg/core/l2oam/onu_list_access.go
new file mode 100644
index 0000000..0ca4714
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_list_access.go
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "os"
+)
+
+// JSON file name
+const jsonname = "/onu_list.json"
+
+// OnuStatus has ONU status
+type OnuStatus struct {
+ ID string `json:"id"`
+ AdminState string `json:"admin_state"`
+ OpeState string `json:"ope_state"`
+ ConnectState string `json:"con_state"`
+ MacAddress string `json:"mac_addr"`
+ RebootState string `json:"reboot_state"`
+}
+
+// ReadOnuStatusList reads JSON file
+func ReadOnuStatusList() ([]OnuStatus, error) {
+ bytes, err := ioutil.ReadFile(os.Getenv("HOME") + jsonname)
+ if err != nil && os.IsNotExist(err) {
+ return nil, nil
+ }
+ var onuList []OnuStatus
+ if err := json.Unmarshal(bytes, &onuList); err != nil {
+ return nil, err
+ }
+ return onuList, nil
+}
+
+// WriteOnuStatusList writes JSON file
+func WriteOnuStatusList(list []OnuStatus) error {
+ bytes, err := json.Marshal(list)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(os.Getenv("HOME")+jsonname, bytes, 0644)
+}
+
+// AddOnu adds ONU to ONU status list
+func AddOnu(sts *OnuStatus) error {
+ list, err := ReadOnuStatusList()
+ if err != nil {
+ return err
+ }
+ if list == nil {
+ newList := []OnuStatus{*sts}
+ return WriteOnuStatusList(newList)
+ }
+ return WriteOnuStatusList(append(list, *sts))
+}
+
+// UpdateOnu updates ONU status
+func UpdateOnu(upSts *OnuStatus) error {
+ list, err := ReadOnuStatusList()
+ if (err != nil) || (list == nil) {
+ return err
+ }
+ newList := []OnuStatus{}
+ for _, sts := range list {
+ if sts.ID == upSts.ID {
+ newList = append(newList, *upSts)
+ } else {
+ newList = append(newList, sts)
+ }
+ }
+ return WriteOnuStatusList(newList)
+}
+
+// RemoveOnu removes ONU from ONU status list
+func RemoveOnu(id string) error {
+ list, err := ReadOnuStatusList()
+ if (err != nil) || (list == nil) {
+ return err
+ }
+ newList := []OnuStatus{}
+ for _, sts := range list {
+ if sts.ID != id {
+ newList = append(newList, sts)
+ }
+ }
+ return WriteOnuStatusList(newList)
+}
+
+// GetOnuFromDeviceID returns ONU status from ONU status list using its device ID
+func GetOnuFromDeviceID(id string) (*OnuStatus, error) {
+ list, err := ReadOnuStatusList()
+ if err != nil {
+ return nil, err
+ }
+ if list == nil {
+ return nil, nil
+ }
+ for _, sts := range list {
+ if sts.ID != id {
+ return &sts, nil
+ }
+ }
+ return nil, nil
+}
+
+// GetOnuFromMacAddr returns ONU status from ONU status list using its MAC address
+func GetOnuFromMacAddr(addr string) (*OnuStatus, error) {
+ list, err := ReadOnuStatusList()
+ if err != nil {
+ return nil, err
+ }
+ if list == nil {
+ return nil, nil
+ }
+ for _, sts := range list {
+ if sts.MacAddress == addr {
+ return &sts, nil
+ }
+ }
+ return nil, nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_get_onu_system_info.go b/internal/pkg/core/l2oam/onu_msg_get_onu_system_info.go
new file mode 100644
index 0000000..6dd13d8
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_get_onu_system_info.go
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateOnuSystemInfo generates "ONU System Information" message
+func GenerateOnuSystemInfo(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x01,
+ 0xd7, 0x00, 0x06, 0x00, 0x00,
+ },
+ }
+
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x40, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
+
+// GetOnuSerialNo returns a serial number
+func GetOnuSerialNo(pkgType string, data []byte) string {
+ if pkgType == OnuPkgTypeA {
+ // 030050fe00100002 00 - 07
+ // d70006404d493920 08 - 15
+ // 32304b2042303041 16 - 23
+ // 3730204130302031 24 - 31
+ // 3730382020202020
+ // 2000000030313233
+ // 3435363730313233
+ // 3435363738394041
+ // 42434445
+ return string(data[20:26])
+ }
+ return ""
+}
+
+// GetOnuManufacture returns a manufacture information
+func GetOnuManufacture(pkgType string, data []byte) string {
+ if pkgType == OnuPkgTypeA {
+ if data[16] == 0x32 && data[17] == 0x30 && data[18] == 0x4b {
+ return "FURUKAWA"
+ }
+ }
+ return ""
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_get_unip_info.go b/internal/pkg/core/l2oam/onu_msg_get_unip_info.go
new file mode 100644
index 0000000..f3efa24
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_get_unip_info.go
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateGetUnipInfo generates UnipInfo message
+func GenerateGetUnipInfo(pkgType string) gopacket.SerializableLayer {
+ if pkgType == OnuPkgTypeB {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0xb7, 0x00, 0x41,
+ },
+ }
+ }
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x01,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0x07, 0x00, 0x20,
+ 0x07, 0x00, 0x5d, 0x07, 0x00, 0x5a, 0x07, 0x00,
+ 0x4f, 0x07, 0x00, 0xa3, 0x07, 0x00, 0x1a, 0x07,
+ 0x00, 0x47, 0x07, 0x00, 0xb0, 0x00, 0x00,
+ },
+ }
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_dyn_learning_mode.go b/internal/pkg/core/l2oam/onu_msg_set_dyn_learning_mode.go
new file mode 100644
index 0000000..33c7a00
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_dyn_learning_mode.go
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateDynLearningMode generates "Dyn Learning Mode" message
+func GenerateDynLearningMode(PkgType string, index int) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ if index == 1 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x01,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0xd7, 0x01, 0x01,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if index == 2 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0xd7, 0x01, 0x02,
+ 0x07, 0xd0, 0x00, 0x00,
+ },
+ }
+ return data
+ } else if index == 3 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x01,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0xd7, 0x01, 0x03,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ }
+
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x01,
+ 0x00, 0x00, 0x01, 0xb7, 0x00, 0x1c, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_encryption_mode.go b/internal/pkg/core/l2oam/onu_msg_set_encryption_mode.go
new file mode 100644
index 0000000..599e8d4
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_encryption_mode.go
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateEncryptionMode generates "Encryption Mode" message
+func GenerateEncryptionMode(PkgType string, index int) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ if index == 1 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x02, 0x01, 0x00, 0xd7, 0x04, 0x01,
+ 0x02, 0x01, 0x2c, 0x00, 0x00,
+ },
+ }
+ return data
+ } else if index == 2 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x02, 0x01, 0x00, 0xd7, 0x04, 0x02,
+ 0x01, 0x02, 0x00, 0x00,
+ },
+ }
+ return data
+ }
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ if index == 1 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x01, 0x01, 0x02,
+ },
+ }
+ return data
+ }
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_fec_mode.go b/internal/pkg/core/l2oam/onu_msg_set_fec_mode.go
new file mode 100644
index 0000000..22712ad
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_fec_mode.go
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateFecMode generates "FEC Mode" message
+func GenerateFecMode(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x02, 0x01, 0x00, 0xD7, 0x06, 0x05,
+ 0x02, 0x01, 0x01,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x16, 0x01, 0x01,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_onu_config.go b/internal/pkg/core/l2oam/onu_msg_set_onu_config.go
new file mode 100644
index 0000000..e648138
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_onu_config.go
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateOnuConfig generates "ONU Config" message
+func GenerateOnuConfig(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+
+ return nil
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x45, 0x00, 0x00,
+ },
+ }
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_threshold.go b/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_threshold.go
new file mode 100644
index 0000000..2649171
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_threshold.go
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateOnuErroredFrameThreshold generates "Errored Frame Threshold" message
+func GenerateOnuErroredFrameThreshold(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+
+ return nil
+
+ } else if PkgType == OnuPkgTypeB {
+
+ return &TibitFrame{Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x0d, 0x04, 0x00,
+ 0x00, 0xff, 0xff,
+ }}
+
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_window.go b/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_window.go
new file mode 100644
index 0000000..fa02acd
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_onu_errored_frame_window.go
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateOnuErroredFrameWindow generates "Errored Frame Window" message
+func GenerateOnuErroredFrameWindow(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+
+ return nil
+
+ } else if PkgType == OnuPkgTypeB {
+
+ return &TibitFrame{Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x0c, 0x02, 0x00,
+ 0x0a,
+ }}
+
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_onu_priority_queue_count.go b/internal/pkg/core/l2oam/onu_msg_set_onu_priority_queue_count.go
new file mode 100644
index 0000000..e868f9c
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_onu_priority_queue_count.go
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateOnuPriorityQueueCount generates "Priority Queue Count" message
+func GenerateOnuPriorityQueueCount(PkgType string, index int) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ if index == 1 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x01,
+ 0xd7, 0x00, 0x0a, 0x00, 0x00,
+ },
+ }
+ return data
+ } else if index == 2 {
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0xd7, 0x01, 0x0d, 0x08, 0x01, 0x01, 0xd0, 0x02,
+ 0x01, 0xd0, 0x01, 0x32, 0x00, 0x00,
+ },
+ }
+ return data
+ }
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x01, 0x01, 0x02,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_rx_input_power.go b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_rx_input_power.go
new file mode 100644
index 0000000..8c498f2
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_rx_input_power.go
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GeneratePonpOptRxInputPower generates "Ponp Optical Rx Input Power" message
+func GeneratePonpOptRxInputPower(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x01,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x02, 0x21,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x01,
+ 0x00, 0x00, 0x01, 0xb7, 0x00, 0x34, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_trx_supply_voltage.go b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_trx_supply_voltage.go
new file mode 100644
index 0000000..0fd9d15
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_trx_supply_voltage.go
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GeneratePonpOptTRxSupplyVoltage generates "Ponp Optical TRx Supply Voltage" message
+func GeneratePonpOptTRxSupplyVoltage(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x01,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x02, 0x1E,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x31, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_bias_current.go b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_bias_current.go
new file mode 100644
index 0000000..e0edf9b
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_bias_current.go
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GeneratePonpOptTxBiasCurrent generates "Ponp Optical Tx Bias Current" message
+func GeneratePonpOptTxBiasCurrent(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x01,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x02, 0x1F,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x01,
+ 0x00, 0x00, 0x01, 0xb7, 0x00, 0x32, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_output_power.go b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_output_power.go
new file mode 100644
index 0000000..7112c7d
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_ponp_opt_tx_output_power.go
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GeneratePonpOptTxOutputPower generates "Ponp Optical Tx Output Power" message
+func GeneratePonpOptTxOutputPower(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x01,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x02, 0x20,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x01,
+ 0x00, 0x00, 0x01, 0xb7, 0x00, 0x33, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_ponp_temperature.go b/internal/pkg/core/l2oam/onu_msg_set_ponp_temperature.go
new file mode 100644
index 0000000..2f9064c
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_ponp_temperature.go
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GeneratePonpTemperature generates "Ponp Temerature" message
+func GeneratePonpTemperature(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA 最後尾に0追加
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x01,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x02, 0x1D,
+ 0x00, 0x00,
+ },
+ }
+ return data
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x00,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x01,
+ 0x00, 0x00, 0x01, 0xb7, 0x00, 0x30, 0x00, 0x00,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_qos_policer_burst.go b/internal/pkg/core/l2oam/onu_msg_set_qos_policer_burst.go
new file mode 100644
index 0000000..ce83c6e
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_qos_policer_burst.go
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetQosPolicerBurst generates QosPolicerBurst message
+func GenerateSetQosPolicerBurst(pkgType string) gopacket.SerializableLayer {
+ if pkgType == OnuPkgTypeB {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x10, 0x08, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ },
+ }
+ }
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x01, 0x01, 0x00, 0xD7, 0x06, 0x01,
+ 0x00, 0x00, 0x4E, 0x20, 0x00, 0x00,
+ },
+ }
+
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_qos_policer_rate.go b/internal/pkg/core/l2oam/onu_msg_set_qos_policer_rate.go
new file mode 100644
index 0000000..d343366
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_qos_policer_rate.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetQosPolicerRate generates QosPolicerRate message
+func GenerateSetQosPolicerRate(pkgType string, idx int) gopacket.SerializableLayer {
+ if pkgType == OnuPkgTypeB {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x0F, 0x20, 0x00,
+ 0x01, 0x86, 0xa0, 0x00, 0x01, 0x86, 0xa0, 0x00,
+ 0x01, 0x86, 0xa0, 0x00, 0x01, 0x86, 0xa0, 0x00,
+ 0x01, 0x86, 0xa0, 0x00, 0x01, 0x86, 0xa0, 0x00,
+ 0x01, 0x86, 0xa0, 0x00, 0x01, 0x86, 0xa0,
+ },
+ }
+ }
+ switch idx {
+ case 1:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0xd7, 0x06, 0x02,
+ 0x0a, 0xff, 0x00, 0x01, 0x00, 0x00, 0x04,
+ },
+ }
+ case 2:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xD7,
+ 0x00, 0x24,
+ },
+ }
+ case 3:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xD7,
+ 0x00, 0x25,
+ },
+ }
+ case 4:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x03, 0x00, 0xD7, 0x06, 0x02, 0x0A,
+ 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ },
+ }
+ case 5:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x03, 0x00, 0xD7, 0x06, 0x03, 0x07,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ }
+ default:
+ return &TibitFrame{
+ Data: []byte{},
+ }
+ }
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_reset_onu.go b/internal/pkg/core/l2oam/onu_msg_set_reset_onu.go
new file mode 100644
index 0000000..f204ba7
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_reset_onu.go
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetResetOnu generates reset ONU message
+func GenerateSetResetOnu(pkgType string) gopacket.SerializableLayer {
+ if pkgType == OnuPkgTypeB {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb9, 0x00, 0x0e, 0x01, 0x01,
+ 0x00, 0x00,
+ },
+ }
+ }
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x00, 0xd9, 0x00, 0x01, 0x80, 0x00,
+ 0x00,
+ },
+ }
+
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_traffic_enable.go b/internal/pkg/core/l2oam/onu_msg_set_traffic_enable.go
new file mode 100644
index 0000000..bdfdeed
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_traffic_enable.go
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetTrafficEnable generates "Traffic Enable" message
+func GenerateSetTrafficEnable(pkgType string) gopacket.SerializableLayer {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x02, 0x01, 0x00, 0xd9, 0x06, 0x01,
+ 0x80,
+ },
+ }
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_unip_link_mode.go b/internal/pkg/core/l2oam/onu_msg_set_unip_link_mode.go
new file mode 100644
index 0000000..7054436
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_unip_link_mode.go
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetUnipLinkMode generates UnipLinkMode message
+func GenerateSetUnipLinkMode(pkgType string) gopacket.SerializableLayer {
+ if pkgType == OnuPkgTypeB {
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb6, 0x00, 0x01, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0xb7, 0x00, 0x11, 0x01, 0x24,
+ },
+ }
+ }
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x03, 0x01, 0x00, 0xD7, 0x01, 0x05,
+ 0x04, 0x00, 0xDF,
+ },
+ }
+
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_unip_target_queue_priority.go b/internal/pkg/core/l2oam/onu_msg_set_unip_target_queue_priority.go
new file mode 100644
index 0000000..0947405
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_unip_target_queue_priority.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateUnipTargetQueuePriority generates "UnipTargetQueuePriority" message
+func GenerateUnipTargetQueuePriority(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+ //TypeA
+
+ return nil
+ } else if PkgType == OnuPkgTypeB {
+ //TypeB
+
+ data := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x43, 0x08, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ },
+ }
+
+ return data
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_unip_toscos_conversion.go b/internal/pkg/core/l2oam/onu_msg_set_unip_toscos_conversion.go
new file mode 100644
index 0000000..a1f3abe
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_unip_toscos_conversion.go
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateUnipTOSCOSConversion generates "Unip TOSCOS Conversion" message
+func GenerateUnipTOSCOSConversion(PkgType string) gopacket.SerializableLayer {
+
+ if PkgType == OnuPkgTypeA {
+
+ return nil
+
+ } else if PkgType == OnuPkgTypeB {
+
+ return &TibitFrame{Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x35, 0x08, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ }}
+ }
+
+ return nil
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_vlan_pon_vid_value.go b/internal/pkg/core/l2oam/onu_msg_set_vlan_pon_vid_value.go
new file mode 100644
index 0000000..416dd69
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_vlan_pon_vid_value.go
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetVlanPonVIDValue generates VlanPonVIDValue message
+func GenerateSetVlanPonVIDValue(pkgType string, idx int, iTpidValue []byte, iVidValue []byte) gopacket.SerializableLayer {
+
+ if pkgType == OnuPkgTypeB {
+ tibitData := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x15, 0x02,
+ },
+ }
+
+ tibitData.Data = append(tibitData.Data, iVidValue...)
+
+ return tibitData
+ }
+ switch idx {
+ case 1: // Downstream Rule
+ tibitData := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x03, 0x01, 0x00, 0xd7, 0x05, 0x01,
+ 0x02, 0x01, 0x0a, 0xd7, 0x05, 0x01, 0x07, 0x02,
+ 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0xd7, 0x05,
+ 0x01, 0x02, 0x03, 0x02, 0xd7, 0x05, 0x01, 0x0b,
+ 0x03, 0x04, 0x08, 0x00, 0x00, 0x00, 0x04,
+ },
+ }
+
+ // itpid must be 4 bytes length
+ tibitData.Data = append(tibitData.Data, iTpidValue...)
+ // ivid must be 2 bytes length
+ tibitData.Data = append(tibitData.Data, iVidValue...)
+
+ bytes := []byte{
+ 0xd7, 0x05, 0x01, 0x04, 0x03, 0x07, 0x08, 0x00,
+ 0xd7, 0x05, 0x01, 0x01, 0x00, 0xd9, 0x05, 0x02,
+ 0x80, 0x00,
+ }
+
+ tibitData.Data = append(tibitData.Data, bytes...)
+
+ return tibitData
+
+ case 2: // Upstream Rule
+ tibitData := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x00, 0x10, 0x00, 0x03,
+ 0xd6, 0x00, 0x01, 0x01, 0x00, 0xd7, 0x05, 0x01,
+ 0x02, 0x01, 0x0a, 0xd7, 0x05, 0x01, 0x07, 0x02,
+ 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0xd7, 0x05,
+ 0x01, 0x02, 0x03, 0x02, 0xd7, 0x05, 0x01, 0x0b,
+ 0x03, 0x04, 0x08, 0x00, 0x00, 0x00, 0x04,
+ },
+ }
+
+ // itpid must be 4 bytes length
+ tibitData.Data = append(tibitData.Data, iTpidValue...)
+ // ivid must be 2 bytes length
+ tibitData.Data = append(tibitData.Data, iVidValue...)
+
+ bytes := []byte{
+ 0xd7, 0x05, 0x01, 0x04, 0x03, 0x07, 0x08, 0x00,
+ 0xd7, 0x05, 0x01, 0x01, 0x00, 0xd9, 0x05, 0x02,
+ 0x80, 0x00,
+ }
+
+ tibitData.Data = append(tibitData.Data, bytes...)
+
+ return tibitData
+
+ default:
+ return &TibitFrame{
+ Data: []byte{},
+ }
+ }
+}
diff --git a/internal/pkg/core/l2oam/onu_msg_set_vlan_tag_filter.go b/internal/pkg/core/l2oam/onu_msg_set_vlan_tag_filter.go
new file mode 100644
index 0000000..980f444
--- /dev/null
+++ b/internal/pkg/core/l2oam/onu_msg_set_vlan_tag_filter.go
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package l2oam
+
+import (
+ "github.com/google/gopacket"
+)
+
+// GenerateSetVlanTagFilter generates VlanTagFilter message
+func GenerateSetVlanTagFilter(pkgType string, idx int, value []byte) gopacket.SerializableLayer {
+
+ if pkgType == OnuPkgTypeB {
+ switch idx {
+ case 1:
+ tibitData := &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x13, 0x03, 0x03,
+ }, //,0x81,0x00
+ }
+
+ tibitData.Data = append(tibitData.Data, value...)
+
+ return tibitData
+ case 2:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xfe, 0x90, 0x82, 0x60, 0x03,
+ 0xca, 0xfe, 0x00, 0xb7, 0x00, 0x14, 0x03, 0x01,
+ 0x00, 0x64,
+ },
+ }
+ default:
+ return &TibitFrame{
+ Data: []byte{},
+ }
+ }
+ } else {
+ switch idx {
+ case 1:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x00, 0xD7, 0x05, 0x03, 0x03, 0x81,
+ 0x00, 0x01,
+ },
+ }
+ case 2:
+ return &TibitFrame{
+ Data: []byte{
+ 0x03, 0x00, 0x50, 0xFE, 0x00, 0x10, 0x00, 0x03,
+ 0xD6, 0x00, 0x00, 0xD7, 0x05, 0x04, 0x03, 0x88,
+ 0xa8, 0x00,
+ },
+ }
+ default:
+ return &TibitFrame{
+ Data: []byte{},
+ }
+ }
+ }
+}