blob: 99ebb562b68d9a23fdc233b3d5bcb4989f8e4f0e [file] [log] [blame]
Matteo Scandolo40e067f2019-10-16 16:59:41 -07001/*
2 * Copyright 2018-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 omci
18
19import (
20 "encoding/hex"
21 "github.com/cboling/omci"
22 me "github.com/cboling/omci/generated"
23 "github.com/google/gopacket"
24 omcisim "github.com/opencord/omci-sim"
25 log "github.com/sirupsen/logrus"
26)
27
28var omciLogger = log.WithFields(log.Fields{
29 "module": "OMCI",
30})
31
32const galEthernetEID = uint16(1)
33const maxGemPayloadSize = uint16(48)
34const gemEID = uint16(1)
35
36type txFrameCreator func() ([]byte, error)
37type rxFrameParser func(gopacket.Packet) error
38
39type ServiceStep struct {
40 MakeTxFrame txFrameCreator
41 RxHandler rxFrameParser
42}
43
44func serialize(msgType omci.MessageType, request gopacket.SerializableLayer, tid uint16) ([]byte, error) {
45 omciLayer := &omci.OMCI{
46 TransactionID: tid,
47 MessageType: msgType,
48 }
49 var options gopacket.SerializeOptions
50 options.FixLengths = true
51
52 buffer := gopacket.NewSerializeBuffer()
53 err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
54 if err != nil {
55 return nil, err
56 }
57 return buffer.Bytes(), nil
58}
59
60func hexEncode(omciPkt []byte) ([]byte, error) {
61 dst := make([]byte, hex.EncodedLen(len(omciPkt)))
62 hex.Encode(dst, omciPkt)
63 return dst, nil
64}
65
66func DecodeOmci(payload []byte) (omci.MessageType, gopacket.Packet) {
67 // Perform base OMCI decode (common to all requests)
68 packet := gopacket.NewPacket(payload, omci.LayerTypeOMCI, gopacket.NoCopy)
69
70 if omciLayer := packet.Layer(omci.LayerTypeOMCI); omciLayer != nil {
71
72 omciObj, omciOk := omciLayer.(*omci.OMCI)
73 if !omciOk {
74 panic("Not Expected") // TODO: Do something better or delete...
75 }
76 if byte(omciObj.MessageType) & ^me.AK == 0 {
77 // Not a response, silently discard
78 return 0, nil
79 }
80 return omciObj.MessageType, packet
81 }
82
83 // FIXME
84 // if we can't properly decode the packet, try using shad helper method
85 // most likely this won't be necessary once we move omci-sim to use cboling/omci
86 // to generate packets
87 _, _, msgType, _, _, _, err := omcisim.ParsePkt(payload)
88 if err != nil {
89 return 0, nil
90 }
91 if msgType == omcisim.MibReset {
92 return omci.MibResetResponseType, nil
93 }
94 if msgType == omcisim.MibUpload {
95 return omci.MibUploadResponseType, nil
96 }
97 if msgType == omcisim.MibUploadNext {
98 return omci.MibUploadNextResponseType, nil
99 }
100 if msgType == omcisim.Create {
101 return omci.CreateResponseType, nil
102 }
103 if msgType == omcisim.Set {
104 return omci.SetResponseType, nil
105 }
106
107 omciLogger.Warnf("omci-sim returns msgType: %d", msgType)
108
109 return 0, nil
110}
111
112func CreateMibResetRequest(tid uint16) ([]byte, error) {
113
114 request := &omci.MibResetRequest{
115 MeBasePacket: omci.MeBasePacket{
116 EntityClass: me.OnuDataClassId,
117 },
118 }
119 pkt, err := serialize(omci.MibResetRequestType, request, tid)
120 if err != nil {
121 omciLogger.WithFields(log.Fields{
122 "Err": err,
123 }).Fatalf("Cannot serialize MibResetRequest")
124 return nil, err
125 }
126 return hexEncode(pkt)
127}
128
129func CreateMibUploadRequest(tid uint16) ([]byte, error) {
130 request := &omci.MibUploadRequest{
131 MeBasePacket: omci.MeBasePacket{
132 EntityClass: me.OnuDataClassId,
133 // Default Instance ID is 0
134 },
135 }
136 pkt, err := serialize(omci.MibUploadRequestType, request, tid)
137 if err != nil {
138 omciLogger.WithFields(log.Fields{
139 "Err": err,
140 }).Fatalf("Cannot serialize MibUploadRequest")
141 return nil, err
142 }
143 return hexEncode(pkt)
144}
145
146func CreateMibUploadNextRequest(tid uint16, seqNumber uint16) ([]byte, error) {
147
148 request := &omci.MibUploadNextRequest{
149 MeBasePacket: omci.MeBasePacket{
150 EntityClass: me.OnuDataClassId,
151 // Default Instance ID is 0
152 },
153 CommandSequenceNumber: seqNumber,
154 }
155 pkt, err := serialize(omci.MibUploadNextRequestType, request, tid)
156
157 if err != nil {
158 omciLogger.WithFields(log.Fields{
159 "Err": err,
160 }).Fatalf("Cannot serialize MibUploadNextRequest")
161 return nil, err
162 }
163 return hexEncode(pkt)
164}
165
166// TODO understand and refactor
167
168func CreateGalEnetRequest(tid uint16) ([]byte, error) {
169 params := me.ParamData{
170 EntityID: galEthernetEID,
171 Attributes: me.AttributeValueMap{"MaximumGemPayloadSize": maxGemPayloadSize},
172 }
173 meDef, _ := me.NewGalEthernetProfile(params)
174 pkt, err := omci.GenFrame(meDef, omci.CreateRequestType, omci.TransactionID(tid))
175 if err != nil {
176 omciLogger.WithField("err", err).Fatalf("Can't generate GalEnetRequest")
177 }
178 return hexEncode(pkt)
179}
180
181func CreateEnableUniRequest(tid uint16, uniId uint16, enabled bool, isPtp bool) ([]byte, error) {
182
183 var _enabled uint8
184 if enabled {
185 _enabled = uint8(1)
186 } else {
187 _enabled = uint8(0)
188 }
189
190 data := me.ParamData{
191 EntityID: uniId,
192 Attributes: me.AttributeValueMap{
193 "AdministrativeState": _enabled,
194 },
195 }
196 var medef *me.ManagedEntity
197 var omciErr me.OmciErrors
198
199 if isPtp {
200 medef, omciErr = me.NewPhysicalPathTerminationPointEthernetUni(data)
201 } else {
202 medef, omciErr = me.NewVirtualEthernetInterfacePoint(data)
203 }
204 if omciErr != nil {
205 return nil, omciErr.GetError()
206 }
207 pkt, err := omci.GenFrame(medef, omci.SetRequestType, omci.TransactionID(tid))
208 if err != nil {
209 omciLogger.WithField("err", err).Fatalf("Can't generate EnableUniRequest")
210 }
211 return hexEncode(pkt)
212}
213
214func CreateGemPortRequest(tid uint16) ([]byte, error) {
215 params := me.ParamData{
216 EntityID: gemEID,
217 Attributes: me.AttributeValueMap{
218 "PortId": 1,
219 "TContPointer": 1,
220 "Direction": 0,
221 "TrafficManagementPointerForUpstream": 0,
222 "TrafficDescriptorProfilePointerForUpstream": 0,
223 "UniCounter": 0,
224 "PriorityQueuePointerForDownStream": 0,
225 "EncryptionState": 0,
226 "TrafficDescriptorProfilePointerForDownstream": 0,
227 "EncryptionKeyRing": 0,
228 },
229 }
230 meDef, _ := me.NewGemPortNetworkCtp(params)
231 pkt, err := omci.GenFrame(meDef, omci.CreateRequestType, omci.TransactionID(tid))
232 if err != nil {
233 omciLogger.WithField("err", err).Fatalf("Can't generate GemPortRequest")
234 }
235 return hexEncode(pkt)
236}
237
238// END TODO