blob: acf7bbe4f1033ea840f44cf7caf33dec87393eec [file] [log] [blame]
Shad Ansari2eac6a42018-11-14 22:35:39 -08001/*
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 core
18
Shad Ansari45806172018-11-19 17:13:08 -080019import (
Shad Ansaria5c79892018-11-29 16:32:59 -080020 "bytes"
21 "encoding/binary"
22
Shad Ansari45806172018-11-19 17:13:08 -080023 "gerrit.opencord.org/voltha-bbsim/common/logger"
Shad Ansaria5c79892018-11-29 16:32:59 -080024 "gerrit.opencord.org/voltha-bbsim/protos"
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +090025 "gerrit.opencord.org/voltha-bbsim/device"
26 "time"
Shad Ansari45806172018-11-19 17:13:08 -080027)
28
Shad Ansaria5c79892018-11-29 16:32:59 -080029//
30// OMCI definitions
31//
32
33// OmciMsgType represents a OMCI message-type
34type OmciMsgType byte
35
36const (
37 // Message Types
38 _ = iota
39 Create OmciMsgType = 4
40 Delete OmciMsgType = 6
41 Set OmciMsgType = 8
42 Get OmciMsgType = 9
43 GetAllAlarms OmciMsgType = 11
44 GetAllAlarmsNext OmciMsgType = 12
45 MibUpload OmciMsgType = 13
46 MibUploadNext OmciMsgType = 14
47 MibReset OmciMsgType = 15
48 AlarmNotification OmciMsgType = 16
49 AttributeValueChange OmciMsgType = 17
50 Test OmciMsgType = 18
51 StartSoftwareDownload OmciMsgType = 19
52 DownloadSection OmciMsgType = 20
53 EndSoftwareDownload OmciMsgType = 21
54 ActivateSoftware OmciMsgType = 22
55 CommitSoftware OmciMsgType = 23
56 SynchronizeTime OmciMsgType = 24
57 Reboot OmciMsgType = 25
58 GetNext OmciMsgType = 26
59 TestResult OmciMsgType = 27
60 GetCurrentData OmciMsgType = 28
61 SetTable OmciMsgType = 29 // Defined in Extended Message Set Only
62)
63
64const (
65 // Managed Entity Class values
66 GEMPortNetworkCTP OmciClass = 268
67)
68
69// OMCI Managed Entity Class
70type OmciClass uint16
71
72// OMCI Message Identifier
73type OmciMessageIdentifier struct {
74 Class OmciClass
75 Instance uint16
76}
77
78type OmciContent [32]byte
79
80type OmciMessage struct {
81 TransactionId uint16
82 MessageType OmciMsgType
83 DeviceId uint8
84 MessageId OmciMessageIdentifier
85 Content OmciContent
Shad Ansari2eac6a42018-11-14 22:35:39 -080086}
87
Shad Ansari45806172018-11-19 17:13:08 -080088const NumMibUploads byte = 9
89
90type OnuKey struct {
91 IntfId, OnuId uint32
92}
93
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +090094type OnuOmciState struct {
Shad Ansaria5c79892018-11-29 16:32:59 -080095 gemPortId uint16
Shad Ansari45806172018-11-19 17:13:08 -080096 mibUploadCtr uint16
97 uniGInstance uint8
98 pptpInstance uint8
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +090099 init istate
Shad Ansari45806172018-11-19 17:13:08 -0800100}
101
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900102type istate int
103
104const (
105 INCOMPLETE istate = iota
106 DONE
107)
108
Shad Ansari8213c532018-12-11 13:53:34 -0800109type OmciMsgHandler func(class OmciClass, content OmciContent, key OnuKey) []byte
110
111var Handlers = map[OmciMsgType]OmciMsgHandler{
112 MibReset: mibReset,
113 MibUpload: mibUpload,
114 MibUploadNext: mibUploadNext,
115 Set: set,
116 Create: create,
117 Get: get,
118 GetAllAlarms: getAllAlarms,
119}
120
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900121var OnuOmciStateMap = map[OnuKey]*OnuOmciState{}
Shad Ansari45806172018-11-19 17:13:08 -0800122
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900123func OmciRun(omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication, onumap map[uint32][] *device.Onu, errch chan error) {
124 go func() { //For monitoring the OMCI states
125 for {
126 time.Sleep(1 * time.Second)
127 if isAllOmciInitDone(onumap) {
128 logger.Info("OmciRun - All the omci init process were done")
129 close(errch)
130 break
131 }
Shad Ansari45806172018-11-19 17:13:08 -0800132 }
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900133 }()
Shad Ansari8213c532018-12-11 13:53:34 -0800134
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900135 go func(){
136 for {
137 var resp openolt.OmciIndication
138
139 m := <-omciOut
140
141 transactionId, deviceId, msgType, class, instance, content := ParsePkt(m.Pkt)
142
143 logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
144 transactionId, msgType, class, instance)
145
146 key := OnuKey{m.IntfId, m.OnuId}
147 if _, ok := OnuOmciStateMap[key]; !ok {
148 OnuOmciStateMap[key] = NewOnuOmciState()
149 }
150
151 if _, ok := Handlers[msgType]; !ok {
152 logger.Warn("Ignore omci msg (msgType %d not handled)", msgType)
153 continue
154 }
155
156 resp.Pkt = Handlers[msgType](class, content, key)
157
158 resp.Pkt[0] = byte(transactionId >> 8)
159 resp.Pkt[1] = byte(transactionId & 0xFF)
160 resp.Pkt[2] = 0x2<<4 | byte(msgType)
161 resp.Pkt[3] = deviceId
162 resp.IntfId = m.IntfId
163 resp.OnuId = m.OnuId
164 omciIn <- resp
Shad Ansari45806172018-11-19 17:13:08 -0800165 }
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900166 }()
Shad Ansari2eac6a42018-11-14 22:35:39 -0800167}
Shad Ansari45806172018-11-19 17:13:08 -0800168
Shad Ansaria5c79892018-11-29 16:32:59 -0800169func ParsePkt(pkt []byte) (uint16, uint8, OmciMsgType, OmciClass, uint16, OmciContent) {
170 var m OmciMessage
171
172 r := bytes.NewReader(HexDecode(pkt))
173
174 if err := binary.Read(r, binary.BigEndian, &m); err != nil {
175 logger.Error("binary.Read failed: %s", err)
176 }
177 logger.Debug("OmciRun - TransactionId: %d MessageType: %d, ME Class: %d, ME Instance: %d, Content: %x",
178 m.TransactionId, m.MessageType&0x0F, m.MessageId.Class, m.MessageId.Instance, m.Content)
Shad Ansaria5c79892018-11-29 16:32:59 -0800179 return m.TransactionId, m.DeviceId, m.MessageType & 0x0F, m.MessageId.Class, m.MessageId.Instance, m.Content
180
181}
182
183func HexDecode(pkt []byte) []byte {
184 // Convert the hex encoding to binary
185 // TODO - Change openolt adapter to send raw binary instead of hex encoded
Shad Ansari45806172018-11-19 17:13:08 -0800186 p := make([]byte, len(pkt)/2)
187 for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
Shad Ansaria5c79892018-11-29 16:32:59 -0800188 // Go figure this ;)
Shad Ansari45806172018-11-19 17:13:08 -0800189 u := (pkt[i] & 15) + (pkt[i]>>6)*9
190 l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
191 p[j] = u<<4 + l
192 }
193 logger.Debug("Omci decoded: %x.", p)
Shad Ansaria5c79892018-11-29 16:32:59 -0800194 return p
Shad Ansari45806172018-11-19 17:13:08 -0800195}
196
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900197func NewOnuOmciState() *OnuOmciState {
198 return &OnuOmciState{gemPortId: 0, mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
Shad Ansari45806172018-11-19 17:13:08 -0800199}
200
Shad Ansari8213c532018-12-11 13:53:34 -0800201func mibReset(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800202 var pkt []byte
203
204 logger.Debug("Omci MibReset")
205
206 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800207 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800213 return pkt
214}
215
Shad Ansari8213c532018-12-11 13:53:34 -0800216func mibUpload(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800217 var pkt []byte
218
219 logger.Debug("Omci MibUpload")
220
221 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800222 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800228
229 pkt[9] = NumMibUploads // Number of subsequent MibUploadNext cmds
230
231 return pkt
232}
233
Shad Ansari8213c532018-12-11 13:53:34 -0800234func mibUploadNext(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800235 var pkt []byte
236
237 logger.Debug("Omci MibUploadNext")
238
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900239 state := OnuOmciStateMap[key]
Shad Ansari8213c532018-12-11 13:53:34 -0800240
Shad Ansari45806172018-11-19 17:13:08 -0800241 switch state.mibUploadCtr {
242 case 0:
243 // ANI-G
244 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800245 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800246 0x01, 0x07, 0x80, 0x01, 0xff, 0xff, 0x01, 0x00,
247 0x08, 0x00, 0x30, 0x00, 0x00, 0x05, 0x09, 0x00,
248 0x00, 0xe0, 0x54, 0xff, 0xff, 0x00, 0x00, 0x0c,
249 0x63, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800251 case 1, 2, 3, 4:
252 // UNI-G
253 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800254 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800255 0x01, 0x08, 0x01, 0x01, 0xf8, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800260 pkt[11] = state.uniGInstance // ME Instance
261 state.uniGInstance++
262 case 5, 6, 7, 8:
263 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800264 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800265 0x00, 0x0b, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x2f,
266 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0xee, 0x00,
267 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800270 pkt[11] = state.pptpInstance // ME Instance
271 state.pptpInstance++
272 default:
273 logger.Error("Invalid MibUpload request %d", state.mibUploadCtr)
274 }
275
276 state.mibUploadCtr++
277
278 return pkt
279}
280
Shad Ansari8213c532018-12-11 13:53:34 -0800281func set(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800282 var pkt []byte
283
284 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800285 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
Shad Ansari45806172018-11-19 17:13:08 -0800286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800291
292 logger.Debug("Omci Set")
293
294 return pkt
295}
296
Shad Ansaria5c79892018-11-29 16:32:59 -0800297func create(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800298 var pkt []byte
299
Shad Ansaria5c79892018-11-29 16:32:59 -0800300 if class == GEMPortNetworkCTP {
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900301 if onuOmciState, ok := OnuOmciStateMap[key]; !ok {
Shad Ansaria5c79892018-11-29 16:32:59 -0800302 logger.Error("ONU Key Error - IntfId: %d, OnuId:", key.IntfId, key.OnuId)
303 } else {
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900304 onuOmciState.gemPortId = binary.BigEndian.Uint16(content[:2])
305 logger.Debug("Gem Port Id %d", onuOmciState.gemPortId)
306 OnuOmciStateMap[key].init = DONE
Shad Ansaria5c79892018-11-29 16:32:59 -0800307 }
308 }
309
Shad Ansari45806172018-11-19 17:13:08 -0800310 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800311 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x01,
Shad Ansari45806172018-11-19 17:13:08 -0800312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800317
318 logger.Debug("Omci Create")
319
320 return pkt
321}
322
Shad Ansari8213c532018-12-11 13:53:34 -0800323func get(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansari45806172018-11-19 17:13:08 -0800324 var pkt []byte
325
326 pkt = []byte{
Shad Ansaria5c79892018-11-29 16:32:59 -0800327 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0x01,
Shad Ansari45806172018-11-19 17:13:08 -0800328 0x00, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Shad Ansaria5c79892018-11-29 16:32:59 -0800332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Shad Ansari45806172018-11-19 17:13:08 -0800333
334 logger.Debug("Omci Get")
335
336 return pkt
337}
Shad Ansaria5c79892018-11-29 16:32:59 -0800338
Shad Ansari8213c532018-12-11 13:53:34 -0800339func getAllAlarms(class OmciClass, content OmciContent, key OnuKey) []byte {
Shad Ansaria5c79892018-11-29 16:32:59 -0800340 var pkt []byte
341
342 pkt = []byte{
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
344 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
349
350 logger.Debug("Omci GetAllAlarms")
351
352 return pkt
353}
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900354
355func isAllOmciInitDone(onumap map[uint32][] *device.Onu) bool {
356 for _, onus := range onumap {
357 for _, onu := range onus{
358 key := OnuKey{onu.IntfID, onu.OnuID}
359 state := OnuOmciStateMap[key]
360 if state.init == INCOMPLETE{
361 return false
362 }
363 }
364 }
365 return true
366}
367