blob: a50c6a58901bfeec43962dc08e6acdcb2e5167f2 [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
28const (
29 ActionTypeProtocolFilter = 1
30
31 ActionTypeTrafficProfile = 2
32)
33
34// GenerateGenericActionCreate generates "Generic/Action Create" message
35func GenerateGenericActionCreate(actionType int) gopacket.SerializableLayer {
36 tibitData := &setGenericActionCreateReq{
37 // IEEE 1904.2
38 Opcode: 0x03,
39 // OMI Protocol
40 Flags: 0x0050,
41 OAMPDUCode: 0xfe,
42 OUId: []byte{0x2a, 0xea, 0x15},
43 // TiBiT OLT Management Interface
44 TOMIOpcode: 0x03,
45 // Correlation Tag
46 CTBranch: 0x0c,
47 CTType: 0x0c7a,
48 CTLength: 4,
49 CTInstance: getOltInstance(),
50 // Object Context
51 OCBranch: 0x0c,
52 OCType: 0x0dce,
53 OCLength: 4,
54 OCInstance: 00000000,
55 //Vc
56 VcBranch: 0x6e,
57 VcLeaf: 0x7001,
58 VcLength: 4,
59 //OT
60 OT: []OTGenericActionCreate{{OTLength: 3, OTValue: getObjectType(actionType)}},
61 // End
62 EndBranch: 0,
63 }
64
65 return tibitData
66}
67
68func getObjectType(actionType int) []byte {
69 switch actionType {
70 case ActionTypeProtocolFilter:
71 return []byte{0x0c, 0x0c, 0xff}
72 case ActionTypeTrafficProfile:
73 return []byte{0x0c, 0x07, 0x0f}
74 default:
75 return []byte{0x00, 0x00, 0x00}
76 }
77}
78
79type setGenericActionCreateReq struct {
80 layers.BaseLayer
81 Opcode uint8
82 Flags uint16
83 OAMPDUCode uint8
84 OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
85 TOMIOpcode uint8
86 CTBranch uint8
87 CTType uint16
88 CTLength uint8
89 CTInstance uint32
90 OCBranch uint8
91 OCType uint16
92 OCLength uint8
93 OCInstance uint32
94 VcBranch uint8
95 VcLeaf uint16
96 VcLength uint8
97 OT []OTGenericActionCreate
98 EndBranch uint8
99}
100
101// OTGenericActionCreate is a structure for "Object Type"
102type OTGenericActionCreate struct {
103 OTLength uint8
104 OTValue []byte
105}
106
107// String returns the string expression of setGenericActionCreateReq
108func (d *setGenericActionCreateReq) String() string {
109 message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
110 message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
111 message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
112 message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
113 message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
114 for _, ot := range d.OT {
115 message = fmt.Sprintf("%s, OTLength:%x, OTValue:%v", message, ot.OTLength, hex.EncodeToString(ot.OTValue))
116 }
117 message = fmt.Sprintf("%s, EndBranch:%x", message, d.EndBranch)
118 return message
119}
120
121// Len returns the length of setGenericActionCreateReq
122func (d *setGenericActionCreateReq) Len() int {
123 return 21 + int(d.CTLength) + int(d.OCLength) + int(d.VcLength)
124
125}
126
127// LayerType returns the ethernet type of setGenericActionCreateReq
128func (d *setGenericActionCreateReq) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet }
129
130// SerializeTo serializes a data structure to byte arrays
131func (d *setGenericActionCreateReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
132 plen := int(d.Len())
133 data, err := b.PrependBytes(plen)
134 if err != nil {
135 return err
136 }
137
138 i := 0
139 data[i] = byte(d.Opcode)
140 i++
141 binary.BigEndian.PutUint16(data[i:i+2], d.Flags)
142 i += 2
143 data[i] = byte(d.OAMPDUCode)
144 i++
145 copy(data[i:i+len(d.OUId)], d.OUId)
146 i += len(d.OUId)
147 data[i] = byte(d.TOMIOpcode)
148 i++
149 data[i] = byte(d.CTBranch)
150 i++
151 binary.BigEndian.PutUint16(data[i:i+2], d.CTType)
152 i += 2
153 data[i] = byte(d.CTLength)
154 i++
155 binary.BigEndian.PutUint32(data[i:i+4], d.CTInstance)
156 i += 4
157 data[i] = byte(d.OCBranch)
158 i++
159 binary.BigEndian.PutUint16(data[i:i+2], d.OCType)
160 i += 2
161 data[i] = byte(d.OCLength)
162 i++
163 binary.BigEndian.PutUint32(data[i:i+4], d.OCInstance)
164 i += 4
165 data[i] = byte(d.VcBranch)
166 i++
167 binary.BigEndian.PutUint16(data[i:i+2], d.VcLeaf)
168 i += 2
169 data[i] = byte(d.VcLength)
170 i++
171 for _, ot := range d.OT {
172 nextIndex := serializeObjectType(&ot, data, i)
173 i = nextIndex
174 }
175
176 data[i] = byte(d.EndBranch)
177
178 return nil
179
180}
181
182func serializeObjectType(ot *OTGenericActionCreate, data []byte, startIndex int) int {
183 i := startIndex
184 data[i] = ot.OTLength
185 i++
186 copy(data[i:i+int(ot.OTLength)], ot.OTValue)
187 i += int(ot.OTLength)
188
189 return i
190
191}
192
193// SetGenericActionCreateRes is a structure for a response of "Generic/Action Create"
194type SetGenericActionCreateRes struct {
195 layers.BaseLayer
196 Opcode uint8
197 Flags uint16
198 OAMPDUCode uint8
199 OUId []byte // Organizationally Unique Identifier: 2a:ea:15 (Tibit Communications)
200 TOMIOpcode uint8
201 CTBranch uint8
202 CTType uint16
203 CTLength uint8
204 CTInstance uint32
205 OCBranch uint8
206 OCType uint16
207 OCLength uint8
208 OCInstance uint32
209 VcBranch uint8
210 VcLeaf uint16
211 VcLength uint8
212
213 ObOCLength uint8
214 ObOCBranch uint8
215 ObOCType uint16
216 ObOCLength2 uint8
217 ObOCInstance []byte
218
219 EndBranch uint8
220}
221
222// ObOC is a structure for "Object OC"
223type ObOC struct {
224 ObOCLength uint8
225 ObOCBranch uint8
226 ObOCType uint16
227 ObOCLength2 uint8
228 ObOCInstance []byte
229}
230
231// String returns the string expression of SetGenericActionCreateRes
232func (d *SetGenericActionCreateRes) String() string {
233 message := fmt.Sprintf("Opcode:%x, Flags:%x, OAMPDUCode:%x, OUId:%v", d.Opcode, d.Flags, d.OAMPDUCode, hex.EncodeToString(d.OUId))
234 message = fmt.Sprintf("%s, TOMIOpcode:%x", message, d.TOMIOpcode)
235 message = fmt.Sprintf("%s, CTBranch:%x, CTType:%x, CTLength:%x, CTInstance:%x", message, d.CTBranch, d.CTType, d.CTLength, d.CTInstance)
236 message = fmt.Sprintf("%s, OCBranch:%x, OCType:%x, OCLength:%x, OCInstance:%x", message, d.OCBranch, d.OCType, d.OCLength, d.OCInstance)
237 message = fmt.Sprintf("%s, VcBranch:%x, VcLeaf:%x, VcLength:%x", message, d.VcBranch, d.VcLeaf, d.VcLength)
238 message = fmt.Sprintf("%s, ObOCLength:%x, ObOCBranch:%x, ObOCType:%x, ObOCLength2:%x, ObOCInstance:%x, EndBranch:%x",
239 message, d.ObOCLength, d.ObOCBranch, d.ObOCType, d.ObOCLength2, d.ObOCInstance, d.EndBranch)
240 return message
241}
242
243// Decode decodes byte arrays to a data structure
244func (d *SetGenericActionCreateRes) Decode(data []byte) error {
245 i := 0
246 d.Opcode = data[i]
247 i++
248 d.Flags = binary.BigEndian.Uint16(data[i : i+2])
249 i += 2
250 d.OAMPDUCode = data[i]
251 i++
252 d.OUId = data[i : i+3]
253 i += len(d.OUId)
254 d.TOMIOpcode = data[i]
255 i++
256 d.CTBranch = data[i]
257 i++
258 d.CTType = binary.BigEndian.Uint16(data[i : i+2])
259 i += 2
260 d.CTLength = data[i]
261 i++
262 d.CTInstance = binary.BigEndian.Uint32(data[i : i+4])
263 i += 4
264 d.OCBranch = data[i]
265 i++
266 d.OCType = binary.BigEndian.Uint16(data[i : i+2])
267 i += 2
268 d.OCLength = data[i]
269 i++
270 d.OCInstance = binary.BigEndian.Uint32(data[i : i+4])
271 i += 4
272 d.VcBranch = data[i]
273 i++
274 d.VcLeaf = binary.BigEndian.Uint16(data[i : i+2])
275 i += 2
276 d.VcLength = data[i]
277 i++
278
279 d.ObOCLength = data[i]
280 i++
281 d.ObOCBranch = data[i]
282 i++
283 d.ObOCType = binary.BigEndian.Uint16(data[i : i+2])
284 i = i + 2
285 d.ObOCLength2 = data[i]
286 i++
287 d.ObOCInstance = data[i : i+int(d.ObOCLength2)]
288 i = i + int(d.ObOCLength2)
289
290 d.EndBranch = data[i]
291
292 return nil
293}
294
295// GetTrafficProfile returns the traffic profile of this message
296func (d *SetGenericActionCreateRes) GetTrafficProfile() []byte {
297 return d.ObOCInstance
298}