blob: e1ea77fa672db9cac7369018f01a1b42534f9510 [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -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 core
18
19import (
20 "fmt"
21 log "github.com/sirupsen/logrus"
22)
23
Matteo Scandolodf3f85d2020-01-15 12:50:48 -080024var omciCh = make(chan OmciChMessage, 4096)
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070025
26func GetChannel() chan OmciChMessage {
27 return omciCh
28}
29
Matteo Scandolo7b512202020-11-09 16:38:10 -080030func OmciSim(oltId int, intfId uint32, onuId uint32, request []byte) ([]byte, error) {
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070031 var resp []byte
32
33 transactionId, deviceId, msgType, class, instance, content, err := ParsePkt(request)
34 if err != nil {
35 log.WithFields(log.Fields{
36 "IntfId": intfId,
37 "OnuId": onuId,
38 }).Errorf("Cannot parse OMCI msg")
39 return resp, &OmciError{"Cannot parse OMCI msg"}
40 }
41
42 log.WithFields(log.Fields{
43 "IntfId": intfId,
44 "OnuId": onuId,
45 "TransactionId": transactionId,
46 "MessageType": msgType.PrettyPrint(),
47 "MeClass": class,
48 "MeInstance": instance,
49 //"Conent": content,
50 "omciMsg": fmt.Sprintf("%x", content),
Matteo Scandolodf3f85d2020-01-15 12:50:48 -080051 }).Tracef("Processing OMCI packet")
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070052
Matteo Scandolo7b512202020-11-09 16:38:10 -080053 key := OnuKey{OltId: oltId, IntfId: intfId, OnuId: onuId}
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -070054 OnuOmciStateMapLock.Lock()
55 if _, ok := OnuOmciStateMap[key]; !ok {
56 OnuOmciStateMap[key] = NewOnuOmciState()
57 }
58 OnuOmciStateMapLock.Unlock()
59
60 if _, ok := Handlers[msgType]; !ok {
61 log.WithFields(log.Fields{
62 "IntfId": intfId,
63 "OnuId": onuId,
64 "msgType": msgType,
65 }).Errorf("Ignoring omci msg (msgType %d not handled)", msgType)
66 return resp, &OmciError{"Unimplemented omci msg"}
67 }
68
69 resp, err = Handlers[msgType](class, content, key)
70 if err != nil {
71 log.WithFields(log.Fields{
72 "IntfId": intfId,
73 "OnuId": onuId,
74 "msgType": msgType,
75 }).Errorf("Unable to send a successful response, error: %s", err)
76 return resp, nil
77 }
78
79 // In the OMCI message, first 2-bytes is the Transaction Correlation ID
80 resp[0] = byte(transactionId >> 8)
81 resp[1] = byte(transactionId & 0xFF)
82 resp[2] = 0x2<<4 | byte(msgType) // Upper nibble 0x2 is fixed (0010), Lower nibbles defines the msg type (i.e., mib-upload, mib-upload-next, etc)
83 resp[3] = deviceId
84
85 // for create, get and set
86 if ((msgType & 0xFF) != MibUploadNext) && ((msgType & 0xFF) != MibReset) && ((msgType & 0xFF) != MibUpload) {
87 // Common fields for create, get, and set
88 resp[4] = byte(class >> 8)
89 resp[5] = byte(class & 0xFF)
90 resp[6] = byte(instance >> 8)
91 resp[7] = byte(instance & 0xFF)
92 resp[8] = 0 // Result: Command Processed Successfully
93
94 // Hardcoding class specific values for Get
95 if (class == 0x82) && ((msgType & 0x0F) == Get) {
96 resp[9] = 0
97 resp[10] = 0x78
98
99 } else if (class == 0x2F) && ((msgType & 0x0F) == Get) {
100 resp[9] = 0x0F
101 resp[10] = 0xB8
102 } else if (class == 0x138) && ((msgType & 0x0F) == Get) {
103 resp[9] = content[0] // 0xBE
104 resp[10] = 0x00
105 }
106 }
107
Matteo Scandolodf3f85d2020-01-15 12:50:48 -0800108 if (class == 11 && instance == 257 && msgType == Set) {
109 // This is a set on a PPTP instance 257 (lan port 1)
110 // Determine if its setting admin up or down and alarm appropriately
111
112 // attrmask for what specifically sets/gets is 2 bytes
113 attrmask := content[0:2]
114 // actual content is the rest, as specified by attrmask. but for this case we are only interested in 1 byte
115 firstattr := content[2:3]
116
117 // attribute bit 5 (admin state) in the PPTP is being set, its value is 1, lock
118 if (attrmask[0] == 0x08 && firstattr[0] == 0x01) {
119 log.Info("Send UNI Link Down Alarm on OMCI Sim channel")
120
121 linkMsgDown := []byte{
122 0x00, 0x00, 0x10, 0x0a, 0x00, 0x0b, 0x01, 0x01,
123 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
128
129 msg := OmciChMessage{
130 Type: UniLinkDown,
131 Data: OmciChMessageData{
132 OnuId: key.OnuId,
133 IntfId: key.IntfId,
134 },
135 Packet: linkMsgDown,
136 }
137 omciCh <- msg
Matteo Scandolo732c0752020-01-28 07:24:13 -0800138
139 OnuOmciStateMapLock.Lock()
140 if OnuOmciState, ok := OnuOmciStateMap[key]; ok {
141 OnuOmciState.state = LOCKED
142 }
143 OnuOmciStateMapLock.Unlock()
Matteo Scandolodf3f85d2020-01-15 12:50:48 -0800144 }
145
146 // attribute bit 5 (admin state) in the PPTP is being set, its value is 0, unlock
147 if (attrmask[0] == 0x08 && firstattr[0] == 0x00) {
148 log.Info("Send UNI Link Up Alarm on OMCI Sim channel")
149
150 linkMsgUp := []byte{
151 0x00, 0x00, 0x10, 0x0a, 0x00, 0x0b, 0x01, 0x01,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
157
158 msg := OmciChMessage{
159 Type: UniLinkUp,
160 Data: OmciChMessageData{
161 OnuId: key.OnuId,
162 IntfId: key.IntfId,
163 },
164 Packet: linkMsgUp,
165 }
166 omciCh <- msg
Matteo Scandolo732c0752020-01-28 07:24:13 -0800167
168 OnuOmciStateMapLock.Lock()
169 if OnuOmciState, ok := OnuOmciStateMap[key]; ok {
170 OnuOmciState.state = DONE
171 }
172 OnuOmciStateMapLock.Unlock()
Matteo Scandolodf3f85d2020-01-15 12:50:48 -0800173 }
174 }
175
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -0700176 log.WithFields(log.Fields{
177 "IntfId": intfId,
178 "OnuId": onuId,
179 "msgType": msgType.PrettyPrint(),
180 "omciMsg": fmt.Sprintf("%x", resp),
181 }).Tracef("OMCI-SIM Response")
182
183 return resp, nil
184}