blob: 29c93b796aef1b627b7bdc5f7899ba9f1f02c726 [file] [log] [blame]
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +09001/*
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 (
Matteo Scandolo88e91892018-11-06 16:29:19 -080020 "net"
21
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090022 "github.com/google/gopacket"
23 "github.com/google/gopacket/layers"
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +090024 omci "github.com/opencord/omci-sim"
Zack Williams2abf3932019-08-05 14:07:05 -070025 "github.com/opencord/voltha-bbsim/common/logger"
26 "github.com/opencord/voltha-bbsim/device"
27 flowHandler "github.com/opencord/voltha-bbsim/flow"
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -040028 openolt "github.com/opencord/voltha-protos/go/openolt"
Zdravko Bozakov078a2712019-07-19 23:25:15 +020029 "github.com/opencord/voltha-protos/go/tech_profile"
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080030 log "github.com/sirupsen/logrus"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090031 "golang.org/x/net/context"
32 "google.golang.org/grpc"
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020033 "google.golang.org/grpc/codes"
34 "google.golang.org/grpc/status"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090035)
36
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020037// DisableOlt method sends OLT down indication
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090038func (s *Server) DisableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080039 logger.Debug("OLT receives DisableOLT()")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020040
41 err := flowHandler.PortDown(0)
42 if err != nil {
43 logger.Error("Failed in port down %v", err)
44 }
45
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090046 if s.EnableServer != nil {
47 if err := sendOltIndDown(*s.EnableServer); err != nil {
48 return new(openolt.Empty), err
49 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080050 logger.Debug("Successfuly sent OLT DOWN indication")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +090051 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090052 return new(openolt.Empty), nil
53}
54
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020055// ReenableOlt method sends OLT up indication for re-enabling OLT
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090056func (s *Server) ReenableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080057 logger.Debug("OLT receives Reenable()")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020058
59 err := flowHandler.PortUp(0)
60 if err != nil {
61 logger.Error("Failed in port up %v", err)
62 }
63
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020064 if s.EnableServer != nil {
Zdravko Bozakov078a2712019-07-19 23:25:15 +020065 s.Olt.OperState = "up"
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020066 if err := sendOltIndUp(*s.EnableServer, s.Olt); err != nil {
67 logger.Error("Failed to send OLT UP indication for reenable OLT: %v", err)
68 return new(openolt.Empty), err
69 }
70 logger.Debug("Successfuly sent OLT UP indication")
71 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090072 return new(openolt.Empty), nil
73}
74
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020075// CollectStatistics method invoked by VOLTHA to get OLT statistics
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090076func (s *Server) CollectStatistics(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080077 logger.Debug("OLT receives CollectStatistics()")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090078 return new(openolt.Empty), nil
79}
80
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020081// GetDeviceInfo returns OLT info
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090082func (s *Server) GetDeviceInfo(c context.Context, empty *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080083 logger.Debug("OLT receives GetDeviceInfo()")
84 devinfo := new(openolt.DeviceInfo)
85 devinfo.Vendor = "EdgeCore"
86 devinfo.Model = "asfvolt16"
87 devinfo.HardwareVersion = ""
88 devinfo.FirmwareVersion = ""
89 devinfo.Technology = "xgspon"
Shad Ansari704c6f22018-11-13 14:57:53 -080090 devinfo.PonPorts = 16
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080091 devinfo.OnuIdStart = 1
92 devinfo.OnuIdEnd = 255
93 devinfo.AllocIdStart = 1024
94 devinfo.AllocIdEnd = 16383
95 devinfo.GemportIdStart = 1024
96 devinfo.GemportIdEnd = 65535
97 devinfo.FlowIdStart = 1
98 devinfo.FlowIdEnd = 16383
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020099 devinfo.DeviceSerialNumber = s.Olt.SerialNumber
Shad Ansari010c1942018-11-08 09:32:24 -0800100
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900101 return devinfo, nil
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900102}
103
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200104// ActivateOnu method handles ONU activation request from VOLTHA
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900105func (s *Server) ActivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200106 logger.Trace("OLT receives ActivateONU()")
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200107
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200108 matched, exist := s.getOnuFromSNmap(onu.SerialNumber)
109 if !exist {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200110 logger.Error("ONU not found with serial nnumber %v", onu.SerialNumber)
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200111 return new(openolt.Empty), status.Errorf(codes.NotFound, "ONU not found with serial number %v", onu.SerialNumber)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900112 }
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200113 onuid := onu.OnuId
114 matched.OnuID = onuid
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200115 s.updateDevIntState(matched, device.OnuActive)
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200116 logger.Debug("ONU IntfID: %d OnuID: %d activated succesufully.", onu.IntfId, onu.OnuId)
Mahir Gunyel32dfd722019-08-05 16:18:06 +0300117 if err := sendOnuInd(*s.EnableServer, matched, "up", "up"); err != nil {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200118 logger.Error("Failed to send ONU Indication intfID %d, onuID %d", matched.IntfID, matched.OnuID)
119 return new(openolt.Empty), err
120 }
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200121
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900122 return new(openolt.Empty), nil
123}
124
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -0400125// CreateTrafficSchedulers method should handle TrafficScheduler creation
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200126func (s *Server) CreateTrafficSchedulers(c context.Context, traffScheduler *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
127 logger.Debug("OLT receives CreateTrafficSchedulers %v", traffScheduler)
128 onu, err := s.GetOnuByID(traffScheduler.OnuId, traffScheduler.IntfId)
129 if err != nil {
130 return new(openolt.Empty), err
131 }
132 onu.Tconts = traffScheduler
Shad Ansarifd298442019-01-08 16:19:35 -0800133 return new(openolt.Empty), nil
134}
135
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -0400136// RemoveTrafficSchedulers method should handle TrafficScheduler removal
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200137func (s *Server) RemoveTrafficSchedulers(c context.Context, traffScheduler *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
138 logger.Debug("OLT receives RemoveTrafficSchedulers %v", traffScheduler)
139 onu, err := s.GetOnuByID(traffScheduler.OnuId, traffScheduler.IntfId)
140 if err != nil {
141 return new(openolt.Empty), err
142 }
143 for _, tcont := range traffScheduler.TrafficScheds {
144 if _, exist := onu.GemPortMap[tcont.AllocId]; exist {
145 delete(onu.GemPortMap, tcont.AllocId)
146 }
147 }
148 onu.Tconts = nil
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -0400149 return new(openolt.Empty), nil
150}
151
152// CreateTrafficQueues method should handle TrafficQueues creation
153func (s *Server) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
154 logger.Debug("OLT receives CreateTrafficQueues()")
155 return new(openolt.Empty), nil
156}
157
158// RemoveTrafficQueues method should handle TrafficQueues removal
159func (s *Server) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
160 logger.Debug("OLT receives RemoveTrafficQueues()")
Shad Ansarifd298442019-01-08 16:19:35 -0800161 return new(openolt.Empty), nil
162}
163
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200164// DeactivateOnu method should handle ONU deactivation
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900165func (s *Server) DeactivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800166 logger.Debug("OLT receives DeactivateONU()")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900167 return new(openolt.Empty), nil
168}
169
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200170// DeleteOnu handles ONU deletion request from VOLTHA
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900171func (s *Server) DeleteOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200172 logger.Debug("OLT receives DeleteONU() intfID: %d, onuID: %d", onu.IntfId, onu.OnuId)
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200173 Onu, err := s.GetOnuByID(onu.OnuId, onu.IntfId)
174 if err != nil {
175 return new(openolt.Empty), err
176 }
177
178 // Mark ONU internal state as ONU_FREE and reset onuID
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200179 Onu.InternalState = device.OnuFree
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200180 Onu.OnuID = 0
181
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200182 // Get snMap key for the ONU serial number
183 snkey := stringifySerialNumber(Onu.SerialNumber)
184
185 // Delete Serial number entry from SNmap
186 logger.Info("Deleting serial number %s from SNmap", snkey)
187 s.SNmap.Delete(snkey)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900188 return new(openolt.Empty), nil
189}
190
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200191// GetOnuInfo returns ONU info to VOLTHA
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200192func (s *Server) GetOnuInfo(c context.Context, onu *openolt.Onu) (*openolt.OnuIndication, error) {
Anjali Thontakudi66659202019-07-03 23:14:02 +0000193 logger.Debug("Olt receives GetOnuInfo() intfID: %d, onuID: %d", onu.IntfId, onu.OnuId)
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200194 Onu, err := s.GetOnuByID(onu.OnuId, onu.IntfId)
195 if err != nil {
196 logger.Error("ONU not found intfID %d, onuID %d", onu.IntfId, onu.OnuId)
197 return new(openolt.OnuIndication), err
Anjali Thontakudi66659202019-07-03 23:14:02 +0000198 }
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200199 onuIndication := new(openolt.OnuIndication)
200 onuIndication.IntfId = Onu.IntfID
201 onuIndication.OnuId = Onu.OnuID
202 onuIndication.OperState = Onu.OperState
203
204 return onuIndication, nil
Anjali Thontakudi66659202019-07-03 23:14:02 +0000205}
206
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200207// OmciMsgOut receives OMCI messages from voltha
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900208func (s *Server) OmciMsgOut(c context.Context, msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800209 logger.Debug("OLT %d receives OmciMsgOut to IF %v (ONU-ID: %v) pkt:%x.", s.Olt.ID, msg.IntfId, msg.OnuId, msg.Pkt)
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200210 // Get ONU state
211 onu, err := s.GetOnuByID(msg.OnuId, msg.IntfId)
212 if err != nil {
213 logger.Error("ONU not found intfID %d, onuID %d", msg.IntfId, msg.OnuId)
214 return new(openolt.Empty), err
215 }
216 state := onu.GetIntState()
217 logger.Debug("ONU-ID: %v, ONU state: %d", msg.OnuId, state)
218
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200219 // If ONU is not ACTIVE drop OMCI message
220 if state < device.OnuActive {
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200221 logger.Info("ONU (IF %v ONU-ID: %v) is not ACTIVE, so not processing OmciMsg", msg.IntfId, msg.OnuId)
222 return new(openolt.Empty), nil
223 }
Shad Ansaria5c79892018-11-29 16:32:59 -0800224 s.omciOut <- *msg
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900225 return new(openolt.Empty), nil
226}
227
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200228// OnuPacketOut is used by voltha to send OnuPackets to BBSIM
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900229func (s *Server) OnuPacketOut(c context.Context, packet *openolt.OnuPacket) (*openolt.Empty, error) {
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200230 onu, err := s.GetOnuByID(packet.OnuId, packet.IntfId)
231 if err != nil {
232 logger.Error("Failed in OnuPacketOut, %v", err)
233 return new(openolt.Empty), err
234 }
Keita NISHIMOTO9617c852019-06-17 21:46:44 +0900235 device.LoggerWithOnu(onu).Debugf("OLT %d receives OnuPacketOut () to IF-ID:%d ONU-ID %d.", s.Olt.ID, packet.IntfId, packet.OnuId)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900236 onuid := packet.OnuId
237 intfid := packet.IntfId
238 rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
239 if err := s.onuPacketOut(intfid, onuid, rawpkt); err != nil {
Keita NISHIMOTO9617c852019-06-17 21:46:44 +0900240 device.LoggerWithOnu(onu).WithField("error", err).Errorf("OnuPacketOut Error ")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900241 return new(openolt.Empty), err
242 }
243 return new(openolt.Empty), nil
244}
245
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200246// UplinkPacketOut sends uplink packets to BBSIM
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900247func (s *Server) UplinkPacketOut(c context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800248 logger.Debug("OLT %d receives UplinkPacketOut().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900249 rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
250 if err := s.uplinkPacketOut(rawpkt); err != nil {
251 return new(openolt.Empty), err
252 }
253 return new(openolt.Empty), nil
254}
255
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200256// FlowAdd method should handle flows addition to datapath for OLT and ONU
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900257func (s *Server) FlowAdd(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200258 logger.Debug("OLT %d receives FlowAdd() %v", s.Olt.ID, flow)
259 // Check if flow already present
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200260 flowKey := device.FlowKey{
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200261 FlowID: flow.FlowId,
262 FlowDirection: flow.FlowType,
263 }
264 if _, exist := s.FlowMap[flowKey]; exist {
265 logger.Error("Flow already exists %v", flow)
266 return new(openolt.Empty), status.Errorf(codes.AlreadyExists, "Flow already exists")
267 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800268
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200269 // Send flow to flowHandler
270 err := flowHandler.AddFlow(flow)
271 if err != nil {
272 logger.Error("Error in pushing flow to datapath")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200273 }
274
275 // Update flowMap
276 s.FlowMap[flowKey] = flow
277
278 onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900279 if err == nil {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200280 exist := false
281 // check if gemport already present in ONU
282 for _, gemport := range onu.GemPortMap[uint32(flow.AllocId)] {
283 if gemport == uint32(flow.GemportId) {
284 exist = true
285 break
286 }
287 }
288 // if not present already, then append in gemport list
289 if !exist {
290 onu.GemPortMap[uint32(flow.AllocId)] = append(onu.GemPortMap[uint32(flow.AllocId)], uint32(flow.GemportId))
291 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800292
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900293 // EAPOL flow
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900294 if flow.Classifier.EthType == uint32(layers.EthernetTypeEAPOL) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700295 logger.WithFields(log.Fields{
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -0400296 "Classifier.OVid": flow.Classifier.OVid,
297 "Classifier.IVid": flow.Classifier.IVid,
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700298 "Classifier.EthType": flow.Classifier.EthType,
299 "Classifier.SrcPort": flow.Classifier.SrcPort,
300 "Classifier.DstPort": flow.Classifier.DstPort,
Matt Jeanneret7c9c5f22019-08-09 14:40:12 -0400301 "Action.OVid": flow.Action.OVid,
302 "Action.IVid": flow.Action.IVid,
303 "IntfID": flow.AccessIntfId,
304 "OltID": s.Olt.ID,
305 "OnuID": flow.OnuId,
306 "FlowId": flow.FlowId,
307 "UniID": flow.UniId,
308 "PortNo": flow.PortNo,
309 "FlowType": flow.FlowType,
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700310 }).Debug("OLT receives EAPOL flow")
311
312 if flow.Classifier.OVid == 4091 {
313 omcistate := omci.GetOnuOmciState(onu.IntfID, onu.OnuID)
314 if omcistate != omci.DONE {
315 logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
316 }
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200317 _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.OnuOmciActive)
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900318 }
319 }
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900320
321 // DHCP flow
322 if flow.Classifier.EthType == uint32(layers.EthernetTypeIPv4) {
323 logger.Debug("Received flow's srcPort:%d dstPort:%d", flow.Classifier.SrcPort, flow.Classifier.DstPort)
324 if flow.Classifier.SrcPort == uint32(68) && flow.Classifier.DstPort == uint32(67) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700325 logger.Debug("OLT %d receives DHCP flow IntfID:%d OnuID:%d EType:%x GemPortID:%d VLanIDs: %d/%d",
326 s.Olt.ID, flow.AccessIntfId, flow.OnuId, flow.Classifier.EthType, flow.GemportId, flow.Classifier.OVid, flow.Classifier.IVid)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900327 omcistate := omci.GetOnuOmciState(onu.IntfID, onu.OnuID)
328 if omcistate != omci.DONE {
329 logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
330 }
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200331 _ = s.updateOnuIntState(onu.IntfID, onu.OnuID, device.OnuAuthenticated)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900332 }
333 }
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200334 // Update flows in ONU object
335 onu.Flows = append(onu.Flows, flowKey)
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900336 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900337 return new(openolt.Empty), nil
338}
339
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200340// FlowRemove handles flow deletion from datapath
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900341func (s *Server) FlowRemove(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200342 logger.Debug("OLT %d receives FlowRemove(): %v", s.Olt.ID, flow)
343
344 // Check if flow exists
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200345 flowKey := device.FlowKey{
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200346 FlowID: flow.FlowId,
347 FlowDirection: flow.FlowType,
348 }
349 if _, exist := s.FlowMap[flowKey]; !exist {
350 logger.Error("Flow %v not found", flow)
351 return new(openolt.Empty), status.Errorf(codes.NotFound, "Flow not found")
352 }
353
354 flow = s.FlowMap[flowKey]
355 // Send delete flow to flowHandler
356 err := flowHandler.DeleteFlow(flow)
357 if err != nil {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200358 logger.Error("failed to delete flow")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200359 }
360
Keita NISHIMOTO7057aa62019-05-28 01:24:08 +0900361 onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200362 if err != nil {
363 logger.Warn("Failed flow remove %v", err)
364 } else {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200365 // Delete flows from onu
366 onu.DeleteFlow(flowKey)
367 logger.Debug("Flows %v in onu %d", onu.Flows, onu.OnuID)
Keita NISHIMOTO7057aa62019-05-28 01:24:08 +0900368 }
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200369
370 // Delete flow from flowMap
371 delete(s.FlowMap, flowKey)
372
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900373 return new(openolt.Empty), nil
374}
375
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200376// HeartbeatCheck is currently not used by voltha
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900377func (s *Server) HeartbeatCheck(c context.Context, empty *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800378 logger.Debug("OLT %d receives HeartbeatCheck().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900379 signature := new(openolt.Heartbeat)
380 signature.HeartbeatSignature = s.Olt.HeartbeatSignature
381 return signature, nil
382}
383
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200384// EnablePonIf enables pon interfaces at BBSIM
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900385func (s *Server) EnablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800386 logger.Debug("OLT %d receives EnablePonIf().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900387 return new(openolt.Empty), nil
388}
389
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200390// GetPonIf returns interface info to VOLTHA
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200391func (s *Server) GetPonIf(c context.Context, intf *openolt.Interface) (*openolt.IntfIndication, error) {
Anjali Thontakudib871c502019-07-03 18:26:12 +0000392 logger.Debug("OLT %d receives GetPonIf().", s.Olt.ID)
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200393 stat := new(openolt.IntfIndication)
Anjali Thontakudib871c502019-07-03 18:26:12 +0000394
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200395 if intf.IntfId > (s.Olt.NumPonIntf - 1) {
Anjali Thontakudib871c502019-07-03 18:26:12 +0000396 logger.Error("PON ID %d out of bounds. %d ports total", intf.IntfId, s.Olt.NumPonIntf)
397 return stat, status.Errorf(codes.OutOfRange, "PON ID %d out of bounds. %d ports total (indexing starts at 0)", intf.IntfId, s.Olt.NumPonIntf)
Anjali Thontakudib871c502019-07-03 18:26:12 +0000398 }
Zdravko Bozakovd975d302019-07-19 22:52:44 +0200399 stat.IntfId = intf.IntfId
400 stat.OperState = s.Olt.PonIntfs[intf.IntfId].OperState
401 return stat, nil
402
Anjali Thontakudib871c502019-07-03 18:26:12 +0000403}
404
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200405// DisablePonIf disables pon interface at BBSIM
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900406func (s *Server) DisablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800407 logger.Debug("OLT %d receives DisablePonIf().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900408 return new(openolt.Empty), nil
409}
410
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200411// Reboot method handles reboot of OLT
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900412func (s *Server) Reboot(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800413 logger.Debug("OLT %d receives Reboot ().", s.Olt.ID)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900414 // Initialize OLT & Env
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900415 logger.Debug("Initialized by Reboot")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200416 s.handleOLTReboot()
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900417 return new(openolt.Empty), nil
418}
419
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200420// EnableIndication starts sending indications for OLT and ONU
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900421func (s *Server) EnableIndication(empty *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800422 logger.Debug("OLT receives EnableInd.")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900423 defer func() {
424 logger.Debug("grpc EnableIndication Done")
425 }()
426 if err := s.Enable(&stream); err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800427 logger.Error("Failed to Enable Core: %v", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900428 return err
429 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900430 return nil
431}
432
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200433// NewGrpcServer starts openolt gRPC server
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900434func NewGrpcServer(addrport string) (l net.Listener, g *grpc.Server, e error) {
Zdravko Bozakov078a2712019-07-19 23:25:15 +0200435 logger.Info("OpenOLT gRPC server listening %s ...", addrport)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900436 g = grpc.NewServer()
437 l, e = net.Listen("tcp", addrport)
438 return
439}