blob: cb1ee95a591fcadbfe58c032914eb4b5dd33fea8 [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
22 "gerrit.opencord.org/voltha-bbsim/common/logger"
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080023 "gerrit.opencord.org/voltha-bbsim/common/utils"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090024 "gerrit.opencord.org/voltha-bbsim/device"
Mahir Gunyel9897f6e2019-05-22 14:54:05 -070025 "gerrit.opencord.org/voltha-bbsim/protos"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090026 "github.com/google/gopacket"
27 "github.com/google/gopacket/layers"
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +090028 omci "github.com/opencord/omci-sim"
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080029 log "github.com/sirupsen/logrus"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090030 "golang.org/x/net/context"
31 "google.golang.org/grpc"
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020032 "google.golang.org/grpc/codes"
33 "google.golang.org/grpc/status"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090034)
35
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020036// DisableOlt method sends OLT down indication
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090037func (s *Server) DisableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080038 logger.Debug("OLT receives DisableOLT()")
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090039 if s.EnableServer != nil {
40 if err := sendOltIndDown(*s.EnableServer); err != nil {
41 return new(openolt.Empty), err
42 }
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080043 logger.Debug("Successfuly sent OLT DOWN indication")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +090044 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090045 return new(openolt.Empty), nil
46}
47
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020048// ReenableOlt method sends OLT up indication for re-enabling OLT
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090049func (s *Server) ReenableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080050 logger.Debug("OLT receives Reenable()")
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020051 if s.EnableServer != nil {
52 if err := sendOltIndUp(*s.EnableServer, s.Olt); err != nil {
53 logger.Error("Failed to send OLT UP indication for reenable OLT: %v", err)
54 return new(openolt.Empty), err
55 }
56 logger.Debug("Successfuly sent OLT UP indication")
57 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090058 return new(openolt.Empty), nil
59}
60
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020061// CollectStatistics method invoked by VOLTHA to get OLT statistics
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090062func (s *Server) CollectStatistics(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080063 logger.Debug("OLT receives CollectStatistics()")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090064 return new(openolt.Empty), nil
65}
66
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020067// GetDeviceInfo returns OLT info
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090068func (s *Server) GetDeviceInfo(c context.Context, empty *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080069 logger.Debug("OLT receives GetDeviceInfo()")
70 devinfo := new(openolt.DeviceInfo)
71 devinfo.Vendor = "EdgeCore"
72 devinfo.Model = "asfvolt16"
73 devinfo.HardwareVersion = ""
74 devinfo.FirmwareVersion = ""
75 devinfo.Technology = "xgspon"
Shad Ansari704c6f22018-11-13 14:57:53 -080076 devinfo.PonPorts = 16
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080077 devinfo.OnuIdStart = 1
78 devinfo.OnuIdEnd = 255
79 devinfo.AllocIdStart = 1024
80 devinfo.AllocIdEnd = 16383
81 devinfo.GemportIdStart = 1024
82 devinfo.GemportIdEnd = 65535
83 devinfo.FlowIdStart = 1
84 devinfo.FlowIdEnd = 16383
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020085 devinfo.DeviceSerialNumber = s.Olt.SerialNumber
Shad Ansari010c1942018-11-08 09:32:24 -080086
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090087 return devinfo, nil
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090088}
89
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020090// ActivateOnu method handles ONU activation request from VOLTHA
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090091func (s *Server) ActivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -080092 logger.Debug("OLT receives ActivateONU()")
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020093
94 matched, err := getOnuBySN(s.Onumap, onu.SerialNumber)
95 if err != nil {
96 logger.Fatal("%s", err)
97 return new(openolt.Empty), status.Errorf(codes.NotFound, "ONU not found with serial number %v", onu.SerialNumber)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090098 }
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020099 onuid := onu.OnuId
100 matched.OnuID = onuid
101 s.updateDevIntState(matched, device.ONU_ACTIVE)
Mahir Gunyel9897f6e2019-05-22 14:54:05 -0700102 s.Activate(matched)
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200103 logger.Debug("ONU IntfID: %d OnuID: %d activated succesufully.", onu.IntfId, onu.OnuId)
104
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900105 return new(openolt.Empty), nil
106}
107
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200108// CreateTconts method should handle Tcont creation
Shad Ansarifd298442019-01-08 16:19:35 -0800109func (s *Server) CreateTconts(c context.Context, tconts *openolt.Tconts) (*openolt.Empty, error) {
110 logger.Debug("OLT receives CreateTconts()")
111 return new(openolt.Empty), nil
112}
113
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200114// RemoveTconts method should handle t-cont removal
Shad Ansarifd298442019-01-08 16:19:35 -0800115func (s *Server) RemoveTconts(c context.Context, tconts *openolt.Tconts) (*openolt.Empty, error) {
116 logger.Debug("OLT receives RemoveTconts()")
117 return new(openolt.Empty), nil
118}
119
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200120// DeactivateOnu method should handle ONU deactivation
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900121func (s *Server) DeactivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800122 logger.Debug("OLT receives DeactivateONU()")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900123 return new(openolt.Empty), nil
124}
125
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200126// DeleteOnu handles ONU deletion request from VOLTHA
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900127func (s *Server) DeleteOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800128 logger.Debug("OLT receives DeleteONU()")
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200129 Onu, err := s.GetOnuByID(onu.OnuId, onu.IntfId)
130 if err != nil {
131 return new(openolt.Empty), err
132 }
133
134 // Mark ONU internal state as ONU_FREE and reset onuID
135 Onu.InternalState = device.ONU_FREE
136 Onu.OnuID = 0
137
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900138 return new(openolt.Empty), nil
139}
140
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200141// OmciMsgOut receives OMCI messages from voltha
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900142func (s *Server) OmciMsgOut(c context.Context, msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800143 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 +0200144 // Get ONU state
145 onu, err := s.GetOnuByID(msg.OnuId, msg.IntfId)
146 if err != nil {
147 logger.Error("ONU not found intfID %d, onuID %d", msg.IntfId, msg.OnuId)
148 return new(openolt.Empty), err
149 }
150 state := onu.GetIntState()
151 logger.Debug("ONU-ID: %v, ONU state: %d", msg.OnuId, state)
152
153 // If ONU is ONU_INACTIVE or ONU_FREE do not send omci response
154 if state == device.ONU_INACTIVE || state == device.ONU_FREE {
155 logger.Info("ONU (IF %v ONU-ID: %v) is not ACTIVE, so not processing OmciMsg", msg.IntfId, msg.OnuId)
156 return new(openolt.Empty), nil
157 }
Shad Ansaria5c79892018-11-29 16:32:59 -0800158 s.omciOut <- *msg
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900159 return new(openolt.Empty), nil
160}
161
162func (s *Server) OnuPacketOut(c context.Context, packet *openolt.OnuPacket) (*openolt.Empty, error) {
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200163 onu, err := s.GetOnuByID(packet.OnuId, packet.IntfId)
164 if err != nil {
165 logger.Error("Failed in OnuPacketOut, %v", err)
166 return new(openolt.Empty), err
167 }
Matteo Scandolo2a659142018-11-15 11:23:45 -0800168 utils.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 +0900169 onuid := packet.OnuId
170 intfid := packet.IntfId
171 rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
172 if err := s.onuPacketOut(intfid, onuid, rawpkt); err != nil {
Matteo Scandoloa286c742018-11-20 08:10:04 -0800173 utils.LoggerWithOnu(onu).WithField("error", err).Errorf("OnuPacketOut Error ")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900174 return new(openolt.Empty), err
175 }
176 return new(openolt.Empty), nil
177}
178
179func (s *Server) UplinkPacketOut(c context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800180 logger.Debug("OLT %d receives UplinkPacketOut().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900181 rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
182 if err := s.uplinkPacketOut(rawpkt); err != nil {
183 return new(openolt.Empty), err
184 }
185 return new(openolt.Empty), nil
186}
187
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200188// FlowAdd method should handle flows addition to datapath for OLT and ONU
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900189func (s *Server) FlowAdd(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Keita NISHIMOTO26ebaa82019-03-07 10:00:35 +0900190 logger.Debug("OLT %d receives FlowAdd() IntfID:%d OnuID:%d EType:%x GemPortID:%d", s.Olt.ID, flow.AccessIntfId, flow.OnuId, flow.Classifier.EthType, flow.GemportId)
Zdravko Bozakovedb65322019-04-11 14:49:32 +0200191 onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800192
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900193 if err == nil {
194 intfid := onu.IntfID
195 onuid := onu.OnuID
Keita NISHIMOTO26ebaa82019-03-07 10:00:35 +0900196 onu.GemportID = uint16(flow.GemportId)
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800197
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900198 utils.LoggerWithOnu(onu).WithFields(log.Fields{
199 "olt": s.Olt.ID,
200 "c_tag": flow.Action.IVid,
201 }).Debug("OLT receives FlowAdd().")
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800202
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900203
204 // EAPOL flow
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900205 if flow.Classifier.EthType == uint32(layers.EthernetTypeEAPOL) {
Keita NISHIMOTO42db49e2019-01-29 07:49:41 +0900206 omcistate := omci.GetOnuOmciState(onu.IntfID, onu.OnuID)
Keita NISHIMOTO26ebaa82019-03-07 10:00:35 +0900207 if omcistate != omci.DONE {
208 logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900209 }
Keita NISHIMOTO26ebaa82019-03-07 10:00:35 +0900210 s.updateOnuIntState(intfid, onuid, device.ONU_OMCIACTIVE)
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900211 }
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900212
213 // DHCP flow
214 if flow.Classifier.EthType == uint32(layers.EthernetTypeIPv4) {
215 logger.Debug("Received flow's srcPort:%d dstPort:%d", flow.Classifier.SrcPort, flow.Classifier.DstPort)
216 if flow.Classifier.SrcPort == uint32(68) && flow.Classifier.DstPort == uint32(67) {
217 logger.Debug("OLT %d receives DHCP flow IntfID:%d OnuID:%d EType:%x GemPortID:%d", s.Olt.ID, flow.AccessIntfId, flow.OnuId, flow.Classifier.EthType, flow.GemportId)
218 omcistate := omci.GetOnuOmciState(onu.IntfID, onu.OnuID)
219 if omcistate != omci.DONE {
220 logger.Warn("FlowAdd() OMCI state %d is not \"DONE\"", omci.GetOnuOmciState(onu.OnuID, onu.IntfID))
221 }
222 s.updateOnuIntState(intfid, onuid, device.ONU_AUTHENTICATED)
223 }
224 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900225 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900226 return new(openolt.Empty), nil
227}
228
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200229// FlowRemove should handle flow deletion from datapath
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900230func (s *Server) FlowRemove(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Keita NISHIMOTO7057aa62019-05-28 01:24:08 +0900231 logger.Debug("OLT %d receives FlowRemove()", s.Olt.ID)
232 onu, err := s.GetOnuByID(uint32(flow.OnuId), uint32(flow.AccessIntfId))
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900233 if err == nil {
Keita NISHIMOTO7057aa62019-05-28 01:24:08 +0900234 utils.LoggerWithOnu(onu).WithFields(log.Fields{
235 "olt": s.Olt.ID,
236 "c_tag": flow.Action.IVid,
237 }).Debug("OLT receives FlowRemove().")
238 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900239 return new(openolt.Empty), nil
240}
241
242func (s *Server) HeartbeatCheck(c context.Context, empty *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800243 logger.Debug("OLT %d receives HeartbeatCheck().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900244 signature := new(openolt.Heartbeat)
245 signature.HeartbeatSignature = s.Olt.HeartbeatSignature
246 return signature, nil
247}
248
249func (s *Server) EnablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800250 logger.Debug("OLT %d receives EnablePonIf().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900251 return new(openolt.Empty), nil
252}
253
254func (s *Server) DisablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800255 logger.Debug("OLT %d receives DisablePonIf().", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900256 return new(openolt.Empty), nil
257}
258
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200259// Reboot method handles reboot of OLT
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900260func (s *Server) Reboot(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800261 logger.Debug("OLT %d receives Reboot ().", s.Olt.ID)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900262 // Initialize OLT & Env
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900263 logger.Debug("Initialized by Reboot")
264 s.Disable()
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900265 return new(openolt.Empty), nil
266}
267
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200268// EnableIndication starts sending indications for OLT and ONU
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900269func (s *Server) EnableIndication(empty *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800270 logger.Debug("OLT receives EnableInd.")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900271 defer func() {
272 logger.Debug("grpc EnableIndication Done")
273 }()
274 if err := s.Enable(&stream); err != nil {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800275 logger.Error("Failed to Enable Core: %v", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900276 return err
277 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900278 return nil
279}
280
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200281// NewGrpcServer starts openolt gRPC server
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900282func NewGrpcServer(addrport string) (l net.Listener, g *grpc.Server, e error) {
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800283 logger.Debug("Listening %s ...", addrport)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900284 g = grpc.NewServer()
285 l, e = net.Listen("tcp", addrport)
286 return
287}