blob: 84a325a2eb5ac3873963425adde42daf462b791c [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001/*
2 * Copyright 2020-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package l2oam
18
19import (
20 "encoding/binary"
21 "encoding/hex"
22 "fmt"
23
24 "github.com/google/gopacket"
25 "github.com/google/gopacket/layers"
26)
27
28// GenerateTrafficControlTrafficProfile generates "Traffic Control/Traffic Profile" message
29func GenerateTrafficControlTrafficProfile(trafficControl []byte, trafficProfile []byte) gopacket.SerializableLayer {
30
31 tibitData := &setTrafficControlTrafficProfileReq{
32 // IEEE 1904.2
33 Opcode: 0x03,
34 // OMI Protocol
35 Flags: 0x0050,
36 OAMPDUCode: 0xfe,
37 OUId: []byte{0x2a, 0xea, 0x15}, // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
38 // TiBiT OLT Management Interface
39 TOMIOpcode: 0x03,
40 // Correlation Tag
41 CTBranch: 0x0c,
42 CTType: 0x0c7a,
43 CTLength: 4,
44 CTInstance: getOltInstance(),
45 // Object Context
46 OCBranch: 0x0c,
47 OCType: 0x07c0,
48 OCLength: 4,
49 OCInstance: trafficControl,
50 // Vc
51 VcBranch: 0x7c,
52 VcLeaf: 0x0002,
53 VcLength: 0x09,
54
55 //EC OC
56 ECOC: []ECOCTrafficControlTrafficProfile{{EcOcLength: 8, EcOcBranch: 0x0c, EcOcType: 0x070f, EcOcLength2: 4, EcOcInstance: trafficProfile}},
57
58 // End
59 EndBranch: 0x00,
60 }
61
62 return tibitData
63}
64
65type setTrafficControlTrafficProfileReq struct {
66 layers.BaseLayer
67 Opcode uint8
68 Flags uint16
69 OAMPDUCode uint8
70 OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
71 TOMIOpcode uint8
72 CTBranch uint8
73 CTType uint16
74 CTLength uint8
75 CTInstance uint32
76 OCBranch uint8
77 OCType uint16
78 OCLength uint8
79 OCInstance []byte
80 VcBranch uint8
81 VcLeaf uint16
82 VcLength uint8
83
84 ECOC []ECOCTrafficControlTrafficProfile
85
86 EndBranch uint8
87}
88
89// ECOCTrafficControlTrafficProfile is a structure for Vc-EC OC object
90type ECOCTrafficControlTrafficProfile struct {
91 EcOcLength uint8
92 EcOcBranch uint8
93 EcOcType uint16
94 EcOcLength2 uint8
95 EcOcInstance []byte
96}
97
98// String returns the string expression of setTrafficControlTrafficProfileReq
99func (d *setTrafficControlTrafficProfileReq) String() string {
100 message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
101 message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
102 message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
103 message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
104 message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
105 for _, ecoc := range d.ECOC {
106 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))
107 }
108 message = fmt.Sprintf("%s, EndBranch:%x", message, d.EndBranch)
109 return message
110}
111
112// Len returns the length of setTrafficControlTrafficProfileReq
113func (d *setTrafficControlTrafficProfileReq) Len() int {
114 return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
115}
116
117// LayerType returns the ethernet type of setTrafficControlTrafficProfileReq
118func (d *setTrafficControlTrafficProfileReq) LayerType() gopacket.LayerType {
119 return layers.LayerTypeEthernet
120}
121
122// SerializeTo serializes a data structure to byte arrays
123func (d *setTrafficControlTrafficProfileReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
124 plen := int(d.Len())
125 data, err := b.PrependBytes(plen)
126 if err != nil {
127 return err
128 }
129
130 i := 0
131 data[i] = byte(d.Opcode)
132 i++
133 binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
134 i += 2
135 data[i] = byte(d.OAMPDUCode)
136 i++
137 copy(data[i:i+len(d.OUId)], d.OUId)
138 i += len(d.OUId)
139 data[i] = byte(d.TOMIOpcode)
140 i++
141 data[i] = byte(d.CTBranch)
142 i++
143 binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
144 i += 2
145 data[i] = byte(d.CTLength)
146 i++
147 binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
148 i += 4
149 data[i] = byte(d.OCBranch)
150 i++
151 binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
152 i += 2
153 data[i] = byte(d.OCLength)
154 i++
155 copy(data[i:i+4], d.OCInstance)
156 i += 4
157 data[i] = byte(d.VcBranch)
158 i++
159 binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
160 i += 2
161 data[i] = byte(d.VcLength)
162 i++
163 for _, ecoc := range d.ECOC {
164 nextIndex := SerializeECOC(&ecoc, data, i)
165 i = nextIndex
166 }
167
168 data[i] = byte(d.EndBranch)
169
170 return nil
171}
172
173// SerializeECOC serializes a "EC OC" structure to byte arrays
174func SerializeECOC(ecoc *ECOCTrafficControlTrafficProfile, data []byte, startIndex int) int {
175 i := startIndex
176 data[i] = byte(ecoc.EcOcLength)
177 i++
178 data[i] = byte(ecoc.EcOcBranch)
179 i++
180 binary.BigEndian.PutUint16(data[i:i+2], ecoc.EcOcType)
181 i += 2
182 data[i] = byte(ecoc.EcOcLength2)
183 i++
184 copy(data[i:i+int(ecoc.EcOcLength2)], ecoc.EcOcInstance)
185 i += int(ecoc.EcOcLength2)
186
187 return i
188}