blob: c971d5473733ade4daff793c02db3f273c9c0a27 [file] [log] [blame]
Shad Ansari1106b022019-01-16 22:22:35 -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
Matteo Scandoloa0026812019-08-20 11:01:32 -070019import (
20 "fmt"
21 log "github.com/sirupsen/logrus"
22)
Shad Ansari1106b022019-01-16 22:22:35 -080023
Matteo Scandolo1e8500f2020-01-15 12:52:41 -080024var omciCh = make(chan OmciChMessage, 4096)
Matteo Scandolo203314b2019-08-26 14:28:42 -070025
26func GetChannel() chan OmciChMessage {
27 return omciCh
28}
29
Shad Ansari1106b022019-01-16 22:22:35 -080030func OmciSim(intfId uint32, onuId uint32, request []byte) ([]byte, error) {
31 var resp []byte
32
33 transactionId, deviceId, msgType, class, instance, content, err := ParsePkt(request)
34 if err != nil {
Matteo Scandoloa0026812019-08-20 11:01:32 -070035 log.WithFields(log.Fields{
36 "IntfId": intfId,
37 "OnuId": onuId,
38 }).Errorf("Cannot parse OMCI msg")
39 return resp, &OmciError{"Cannot parse OMCI msg"}
Shad Ansari1106b022019-01-16 22:22:35 -080040 }
41
Matteo Scandoloa0026812019-08-20 11:01:32 -070042 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 Scandolo1e8500f2020-01-15 12:52:41 -080051 }).Tracef("Processing OMCI packet")
Shad Ansari1106b022019-01-16 22:22:35 -080052
53 key := OnuKey{intfId, onuId}
William Kurkian3687c572019-10-11 15:29:17 -040054 OnuOmciStateMapLock.Lock()
Shad Ansari1106b022019-01-16 22:22:35 -080055 if _, ok := OnuOmciStateMap[key]; !ok {
56 OnuOmciStateMap[key] = NewOnuOmciState()
57 }
William Kurkian3687c572019-10-11 15:29:17 -040058 OnuOmciStateMapLock.Unlock()
Shad Ansari1106b022019-01-16 22:22:35 -080059
60 if _, ok := Handlers[msgType]; !ok {
Matteo Scandoloa0026812019-08-20 11:01:32 -070061 log.WithFields(log.Fields{
62 "IntfId": intfId,
63 "OnuId": onuId,
64 "msgType": msgType,
65 }).Errorf("Ignoring omci msg (msgType %d not handled)", msgType)
Shad Ansari1106b022019-01-16 22:22:35 -080066 return resp, &OmciError{"Unimplemented omci msg"}
67 }
68
69 resp, err = Handlers[msgType](class, content, key)
70 if err != nil {
Matteo Scandoloa0026812019-08-20 11:01:32 -070071 log.WithFields(log.Fields{
72 "IntfId": intfId,
73 "OnuId": onuId,
74 "msgType": msgType,
75 }).Errorf("Unable to send a successful response, error: %s", err)
Keita NISHIMOTO21853b32019-01-25 19:29:59 +090076 return resp, nil
Shad Ansari1106b022019-01-16 22:22:35 -080077 }
Keita NISHIMOTO21853b32019-01-25 19:29:59 +090078
Zdravko Bozakovf56cca42019-04-29 10:06:47 +020079 // In the OMCI message, first 2-bytes is the Transaction Correlation ID
Shad Ansari1106b022019-01-16 22:22:35 -080080 resp[0] = byte(transactionId >> 8)
81 resp[1] = byte(transactionId & 0xFF)
Zdravko Bozakovf56cca42019-04-29 10:06:47 +020082 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)
Shad Ansari1106b022019-01-16 22:22:35 -080083 resp[3] = deviceId
84
Zdravko Bozakovf56cca42019-04-29 10:06:47 +020085 // for create, get and set
86 if ((msgType & 0xFF) != MibUploadNext) && ((msgType & 0xFF) != MibReset) && ((msgType & 0xFF) != MibUpload) {
Zdravko Bozakovf56cca42019-04-29 10:06:47 +020087 // 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 Scandolo1e8500f2020-01-15 12:52:41 -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
138 }
139
140 // attribute bit 5 (admin state) in the PPTP is being set, its value is 0, unlock
141 if (attrmask[0] == 0x08 && firstattr[0] == 0x00) {
142 log.Info("Send UNI Link Up Alarm on OMCI Sim channel")
143
144 linkMsgUp := []byte{
145 0x00, 0x00, 0x10, 0x0a, 0x00, 0x0b, 0x01, 0x01,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
151
152 msg := OmciChMessage{
153 Type: UniLinkUp,
154 Data: OmciChMessageData{
155 OnuId: key.OnuId,
156 IntfId: key.IntfId,
157 },
158 Packet: linkMsgUp,
159 }
160 omciCh <- msg
161 }
162 }
163
Matteo Scandoloa0026812019-08-20 11:01:32 -0700164 log.WithFields(log.Fields{
165 "IntfId": intfId,
166 "OnuId": onuId,
167 "msgType": msgType.PrettyPrint(),
168 "omciMsg": fmt.Sprintf("%x", resp),
Matteo Scandolo203314b2019-08-26 14:28:42 -0700169 }).Tracef("OMCI-SIM Response")
Zdravko Bozakovf56cca42019-04-29 10:06:47 +0200170
Shad Ansari1106b022019-01-16 22:22:35 -0800171 return resp, nil
William Kurkian3687c572019-10-11 15:29:17 -0400172}