blob: de23653eede90bb2b1f0b702b29b98c0eac07cc4 [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
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 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
17//Package adaptercore provides the utility for olt devices, flows and statistics
Phaneendra Manda4c62c802019-03-06 21:37:49 +053018package adaptercore
19
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
22 "errors"
23 "fmt"
24 "io"
25 "strconv"
26 "strings"
27 "sync"
28 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053029
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040030 "google.golang.org/grpc/codes"
31
cuilin20187b2a8c32019-03-26 19:52:28 -070032 "github.com/gogo/protobuf/proto"
33 "github.com/golang/protobuf/ptypes"
manikkaraj k9eb6cac2019-05-09 12:32:03 -040034 "github.com/mdlayher/ethernet"
cuilin20187b2a8c32019-03-26 19:52:28 -070035 com "github.com/opencord/voltha-go/adapters/common"
36 "github.com/opencord/voltha-go/common/log"
Girish Gowdru0c588b22019-04-23 23:24:56 -040037 rsrcMgr "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
manikkaraj kbf256be2019-03-25 00:13:48 +053038 "github.com/opencord/voltha-protos/go/common"
39 ic "github.com/opencord/voltha-protos/go/inter_container"
40 of "github.com/opencord/voltha-protos/go/openflow_13"
41 oop "github.com/opencord/voltha-protos/go/openolt"
manikkaraj kbf256be2019-03-25 00:13:48 +053042 "github.com/opencord/voltha-protos/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070043 "google.golang.org/grpc"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040044 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053045)
46
47//DeviceHandler will interact with the OLT device.
48type DeviceHandler struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070049 deviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -070050 deviceType string
Girish Gowdru5ba46c92019-04-25 05:00:05 -040051 adminState string
cuilin20187b2a8c32019-03-26 19:52:28 -070052 device *voltha.Device
53 coreProxy *com.CoreProxy
manikkaraj kbf256be2019-03-25 00:13:48 +053054 AdapterProxy *com.AdapterProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070055 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070056 exitChannel chan int
57 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053058 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070059 transitionMap *TransitionMap
60 clientCon *grpc.ClientConn
manikkaraj kbf256be2019-03-25 00:13:48 +053061 flowMgr *OpenOltFlowMgr
62 resourceMgr *rsrcMgr.OpenOltResourceMgr
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040063 discOnus map[string]bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -070064 onus map[string]*OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070065 nniIntfID int
Mahir Gunyela3f9add2019-06-06 15:13:19 -070066}
67
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070068//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -070069type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070070 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070071 deviceType string
72 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070073 onuID uint32
74 intfID uint32
75 proxyDeviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -070076}
77
78//NewOnuDevice creates a new Onu Device
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070079func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -070080 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070081 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -070082 device.deviceType = deviceTp
83 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070084 device.onuID = onuID
85 device.intfID = intfID
86 device.proxyDeviceID = proxyDevID
Mahir Gunyela3f9add2019-06-06 15:13:19 -070087 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +053088}
89
90//NewDeviceHandler creates a new device handler
cuilin20187b2a8c32019-03-26 19:52:28 -070091func NewDeviceHandler(cp *com.CoreProxy, ap *com.AdapterProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
92 var dh DeviceHandler
93 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -040094 dh.AdapterProxy = ap
cuilin20187b2a8c32019-03-26 19:52:28 -070095 cloned := (proto.Clone(device)).(*voltha.Device)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070096 dh.deviceID = cloned.Id
cuilin20187b2a8c32019-03-26 19:52:28 -070097 dh.deviceType = cloned.Type
Girish Gowdru5ba46c92019-04-25 05:00:05 -040098 dh.adminState = "up"
cuilin20187b2a8c32019-03-26 19:52:28 -070099 dh.device = cloned
100 dh.openOLT = adapter
101 dh.exitChannel = make(chan int, 1)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400102 dh.discOnus = make(map[string]bool)
cuilin20187b2a8c32019-03-26 19:52:28 -0700103 dh.lockDevice = sync.RWMutex{}
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700104 dh.onus = make(map[string]*OnuDevice)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700105 // The nniIntfID is initialized to -1 (invalid) and set to right value
Girish Gowdru1110ef22019-06-24 11:17:59 -0400106 // when the first IntfOperInd with status as "up" is received for
107 // any one of the available NNI port on the OLT device.
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108 dh.nniIntfID = -1
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530109
cuilin20187b2a8c32019-03-26 19:52:28 -0700110 //TODO initialize the support classes.
111 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530112}
113
114// start save the device to the data model
115func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700116 dh.lockDevice.Lock()
117 defer dh.lockDevice.Unlock()
118 log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
119 // Add the initial device to the local model
120 log.Debug("device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530121}
122
123// stop stops the device dh. Not much to do for now
124func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700125 dh.lockDevice.Lock()
126 defer dh.lockDevice.Unlock()
127 log.Debug("stopping-device-agent")
128 dh.exitChannel <- 1
129 log.Debug("device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530130}
131
132func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700133 slist := strings.Split(mac, ":")
134 result := make([]uint32, len(slist))
135 var err error
136 var tmp int64
137 for index, val := range slist {
138 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
139 return []uint32{1, 2, 3, 4, 5, 6}
140 }
141 result[index] = uint32(tmp)
142 }
143 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530144}
145
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700146//GetportLabel returns the label for the NNI and the PON port based on port number and port type
manikkaraj kbf256be2019-03-25 00:13:48 +0530147func GetportLabel(portNum uint32, portType voltha.Port_PortType) string {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530148
Girish Gowdru0c588b22019-04-23 23:24:56 -0400149 if portType == voltha.Port_ETHERNET_NNI {
150 return fmt.Sprintf("nni-%d", portNum)
151 } else if portType == voltha.Port_PON_OLT {
152 return fmt.Sprintf("pon-%d", portNum)
cuilin20187b2a8c32019-03-26 19:52:28 -0700153 } else if portType == voltha.Port_ETHERNET_UNI {
154 log.Errorw("local UNI management not supported", log.Fields{})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400155 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -0700156 }
157 return ""
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530158}
159
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700160func (dh *DeviceHandler) addPort(intfID uint32, portType voltha.Port_PortType, state string) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700161 var operStatus common.OperStatus_OperStatus
162 if state == "up" {
163 operStatus = voltha.OperStatus_ACTIVE
164 } else {
165 operStatus = voltha.OperStatus_DISCOVERED
166 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700167 portNum := IntfIDToPortNo(intfID, portType)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400168 label := GetportLabel(portNum, portType)
169 if len(label) == 0 {
170 log.Errorw("Invalid-port-label", log.Fields{"portNum": portNum, "portType": portType})
171 return
172 }
173 // Now create Port
174 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700175 PortNo: portNum,
176 Label: label,
177 Type: portType,
178 OperStatus: operStatus,
179 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400180 log.Debugw("Sending port update to core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700181 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700182 if err := dh.coreProxy.PortCreated(context.TODO(), dh.device.Id, port); err != nil {
183 log.Errorw("error-creating-nni-port", log.Fields{"deviceID": dh.device.Id, "portType": portType, "error": err})
Girish Gowdru1110ef22019-06-24 11:17:59 -0400184 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700185
Girish Gowdru1110ef22019-06-24 11:17:59 -0400186 // Once we have successfully added the NNI port to the core, if the
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700187 // locally cached nniIntfID is set to invalid (-1), set it to the right value.
188 if portType == voltha.Port_ETHERNET_NNI && dh.nniIntfID == -1 {
189 dh.nniIntfID = int(intfID)
cuilin20187b2a8c32019-03-26 19:52:28 -0700190 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530191}
192
193// readIndications to read the indications from the OLT device
194func (dh *DeviceHandler) readIndications() {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400195 indications, err := dh.Client.EnableIndication(context.Background(), new(oop.Empty))
cuilin20187b2a8c32019-03-26 19:52:28 -0700196 if err != nil {
197 log.Errorw("Failed to read indications", log.Fields{"err": err})
198 return
199 }
200 if indications == nil {
201 log.Errorw("Indications is nil", log.Fields{})
202 return
203 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400204 /* get device state */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700205 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400206 if err != nil || device == nil {
207 /*TODO: needs to handle error scenarios */
208 log.Errorw("Failed to fetch device info", log.Fields{"err": err})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700209 return
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400210 }
211 // When the device is in DISABLED and Adapter container restarts, we need to
212 // rebuild the locally maintained admin state.
213 if device.AdminState == voltha.AdminState_DISABLED {
214 dh.lockDevice.Lock()
215 dh.adminState = "down"
216 dh.lockDevice.Unlock()
217 }
218
cuilin20187b2a8c32019-03-26 19:52:28 -0700219 for {
220 indication, err := indications.Recv()
221 if err == io.EOF {
222 break
223 }
224 if err != nil {
225 log.Infow("Failed to read from indications", log.Fields{"err": err})
Girish Gowdrud4245152019-05-10 00:47:31 -0400226 dh.transitionMap.Handle(DeviceDownInd)
227 dh.transitionMap.Handle(DeviceInit)
228 break
cuilin20187b2a8c32019-03-26 19:52:28 -0700229 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400230 // When OLT is admin down, allow only NNI operation status change indications.
231 if dh.adminState == "down" {
232 _, isIntfOperInd := indication.Data.(*oop.Indication_IntfOperInd)
233 if isIntfOperInd {
234 intfOperInd := indication.GetIntfOperInd()
235 if intfOperInd.GetType() == "nni" {
236 log.Infow("olt is admin down, allow nni ind", log.Fields{})
237 }
238 } else {
239 log.Infow("olt is admin down, ignore indication", log.Fields{})
240 continue
241 }
242 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530243
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700244 dh.handleIndication(indication)
manikkaraj kbf256be2019-03-25 00:13:48 +0530245
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700246 }
247}
248
249func (dh *DeviceHandler) handleOltIndication(oltIndication *oop.OltIndication) {
250 if oltIndication.OperState == "up" {
251 dh.transitionMap.Handle(DeviceUpInd)
252 } else if oltIndication.OperState == "down" {
253 dh.transitionMap.Handle(DeviceDownInd)
254 }
255}
256
257func (dh *DeviceHandler) handleIndication(indication *oop.Indication) {
258 switch indication.Data.(type) {
259 case *oop.Indication_OltInd:
260 dh.handleOltIndication(indication.GetOltInd())
261 case *oop.Indication_IntfInd:
262 intfInd := indication.GetIntfInd()
263 go dh.addPort(intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState())
264 log.Infow("Received interface indication ", log.Fields{"InterfaceInd": intfInd})
265 case *oop.Indication_IntfOperInd:
266 intfOperInd := indication.GetIntfOperInd()
267 if intfOperInd.GetType() == "nni" {
268 go dh.addPort(intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState())
269 } else if intfOperInd.GetType() == "pon" {
270 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
271 // Handle pon port update
cuilin20187b2a8c32019-03-26 19:52:28 -0700272 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700273 log.Infow("Received interface oper indication ", log.Fields{"InterfaceOperInd": intfOperInd})
274 case *oop.Indication_OnuDiscInd:
275 onuDiscInd := indication.GetOnuDiscInd()
276 log.Infow("Received Onu discovery indication ", log.Fields{"OnuDiscInd": onuDiscInd})
277 //onuID,err := dh.resourceMgr.GetONUID(onuDiscInd.GetIntfId())
278 //onuID,err := dh.resourceMgr.GetONUID(onuDiscInd.GetIntfId())
279 // TODO Get onu ID from the resource manager
280 var onuID uint32 = 1
281 /*if err != nil{
282 log.Errorw("onu-id-unavailable",log.Fields{"intfID":onuDiscInd.GetIntfId()})
283 return
284 }*/
285
286 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
287 go dh.onuDiscIndication(onuDiscInd, onuID, sn)
288 case *oop.Indication_OnuInd:
289 onuInd := indication.GetOnuInd()
290 log.Infow("Received Onu indication ", log.Fields{"OnuInd": onuInd})
291 go dh.onuIndication(onuInd)
292 case *oop.Indication_OmciInd:
293 omciInd := indication.GetOmciInd()
294 log.Infow("Received Omci indication ", log.Fields{"OmciInd": omciInd})
295 if err := dh.omciIndication(omciInd); err != nil {
296 log.Errorw("send-omci-indication-errr", log.Fields{"error": err, "omciInd": omciInd})
297 }
298 case *oop.Indication_PktInd:
299 pktInd := indication.GetPktInd()
300 log.Infow("Received pakcet indication ", log.Fields{"PktInd": pktInd})
301 go dh.handlePacketIndication(pktInd)
302 case *oop.Indication_PortStats:
303 portStats := indication.GetPortStats()
304 log.Infow("Received port stats indication", log.Fields{"PortStats": portStats})
305 case *oop.Indication_FlowStats:
306 flowStats := indication.GetFlowStats()
307 log.Infow("Received flow stats", log.Fields{"FlowStats": flowStats})
308 case *oop.Indication_AlarmInd:
309 alarmInd := indication.GetAlarmInd()
310 log.Infow("Received alarm indication ", log.Fields{"AlarmInd": alarmInd})
cuilin20187b2a8c32019-03-26 19:52:28 -0700311 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530312}
313
314// doStateUp handle the olt up indication and update to voltha core
315func (dh *DeviceHandler) doStateUp() error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400316 // Synchronous call to update device state - this method is run in its own go routine
cuilin20187b2a8c32019-03-26 19:52:28 -0700317 if err := dh.coreProxy.DeviceStateUpdate(context.Background(), dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400318 voltha.OperStatus_ACTIVE); err != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700319 log.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400320 return err
321 }
322 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530323}
324
325// doStateDown handle the olt down indication
326func (dh *DeviceHandler) doStateDown() error {
Girish Gowdrud4245152019-05-10 00:47:31 -0400327 log.Debug("do-state-down-start")
328
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700329 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400330 if err != nil || device == nil {
331 /*TODO: needs to handle error scenarios */
332 log.Errorw("Failed to fetch device device", log.Fields{"err": err})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700333 return errors.New("failed to fetch device device")
Girish Gowdrud4245152019-05-10 00:47:31 -0400334 }
335
336 cloned := proto.Clone(device).(*voltha.Device)
337 // Update the all ports state on that device to disable
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700338 if er := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
339 log.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
340 return er
Girish Gowdrud4245152019-05-10 00:47:31 -0400341 }
342
343 //Update the device oper state and connection status
344 cloned.OperStatus = voltha.OperStatus_UNKNOWN
345 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
346 dh.device = cloned
347
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700348 if er := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
349 log.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
350 return er
Girish Gowdrud4245152019-05-10 00:47:31 -0400351 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400352
353 //get the child device for the parent device
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700354 onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400355 if err != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700356 log.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400357 return err
358 }
359 for _, onuDevice := range onuDevices.Items {
360
361 // Update onu state as down in onu adapter
362 onuInd := oop.OnuIndication{}
363 onuInd.OperState = "down"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700364 er := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
365 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
366 if er != nil {
367 log.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
368 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
369 return er
370 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400371 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700372 log.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700373 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530374}
375
376// doStateInit dial the grpc before going to init state
377func (dh *DeviceHandler) doStateInit() error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400378 var err error
Girish Gowdrud4245152019-05-10 00:47:31 -0400379 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock())
Girish Gowdru0c588b22019-04-23 23:24:56 -0400380 if err != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700381 log.Errorw("Failed to dial device", log.Fields{"DeviceId": dh.deviceID, "HostAndPort": dh.device.GetHostAndPort(), "err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400382 return err
383 }
384 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530385}
386
387// postInit create olt client instance to invoke RPC on the olt device
388func (dh *DeviceHandler) postInit() error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400389 dh.Client = oop.NewOpenoltClient(dh.clientCon)
390 dh.transitionMap.Handle(GrpcConnected)
391 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530392}
393
394// doStateConnected get the device info and update to voltha core
395func (dh *DeviceHandler) doStateConnected() error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400396 log.Debug("OLT device has been connected")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400397
398 // Case where OLT is disabled and then rebooted.
399 if dh.adminState == "down" {
400 log.Debugln("do-state-connected--device-admin-state-down")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700401 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400402 if err != nil || device == nil {
403 /*TODO: needs to handle error scenarios */
404 log.Errorw("Failed to fetch device device", log.Fields{"err": err})
405 }
406
407 cloned := proto.Clone(device).(*voltha.Device)
408 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
409 cloned.OperStatus = voltha.OperStatus_UNKNOWN
410 dh.device = cloned
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700411 if er := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
412 log.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.device.Id, "error": er})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400413 }
414
415 // Since the device was disabled before the OLT was rebooted, enfore the OLT to be Disabled after re-connection.
416 _, err = dh.Client.DisableOlt(context.Background(), new(oop.Empty))
417 if err != nil {
418 log.Errorw("Failed to disable olt ", log.Fields{"err": err})
419 }
420
421 // Start reading indications
422 go dh.readIndications()
423 return nil
424 }
425
Girish Gowdru0c588b22019-04-23 23:24:56 -0400426 deviceInfo, err := dh.Client.GetDeviceInfo(context.Background(), new(oop.Empty))
cuilin20187b2a8c32019-03-26 19:52:28 -0700427 if err != nil {
428 log.Errorw("Failed to fetch device info", log.Fields{"err": err})
429 return err
430 }
431 if deviceInfo == nil {
432 log.Errorw("Device info is nil", log.Fields{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700433 return errors.New("failed to get device info from OLT")
cuilin20187b2a8c32019-03-26 19:52:28 -0700434 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400435 log.Debugw("Fetched device info", log.Fields{"deviceInfo": deviceInfo})
cuilin20187b2a8c32019-03-26 19:52:28 -0700436 dh.device.Root = true
437 dh.device.Vendor = deviceInfo.Vendor
438 dh.device.Model = deviceInfo.Model
cuilin20187b2a8c32019-03-26 19:52:28 -0700439 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
440 dh.device.HardwareVersion = deviceInfo.HardwareVersion
441 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400442 // FIXME: Remove Hardcodings
cuilin20187b2a8c32019-03-26 19:52:28 -0700443 dh.device.MacAddress = "0a:0b:0c:0d:0e:0f"
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530444
cuilin20187b2a8c32019-03-26 19:52:28 -0700445 // Synchronous call to update device - this method is run in its own go routine
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700446 if er := dh.coreProxy.DeviceUpdate(context.TODO(), dh.device); er != nil {
447 log.Errorw("error-updating-device", log.Fields{"deviceID": dh.device.Id, "error": er})
cuilin20187b2a8c32019-03-26 19:52:28 -0700448 }
Girish Gowdrud4245152019-05-10 00:47:31 -0400449
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700450 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400451 if err != nil || device == nil {
452 /*TODO: needs to handle error scenarios */
453 log.Errorw("Failed to fetch device device", log.Fields{"err": err})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700454 return err
Girish Gowdrud4245152019-05-10 00:47:31 -0400455 }
456 cloned := proto.Clone(device).(*voltha.Device)
457 // Update the all ports (if available) on that device to ACTIVE.
458 // The ports do not normally exist, unless the device is coming back from a reboot
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700459 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
460 log.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": err})
Girish Gowdrud4245152019-05-10 00:47:31 -0400461 return err
462 }
463
Girish Gowdru0c588b22019-04-23 23:24:56 -0400464 KVStoreHostPort := fmt.Sprintf("%s:%d", dh.openOLT.KVStoreHost, dh.openOLT.KVStorePort)
465 // Instantiate resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700466 if dh.resourceMgr = rsrcMgr.NewResourceMgr(dh.deviceID, KVStoreHostPort, dh.openOLT.KVStoreType, dh.deviceType, deviceInfo); dh.resourceMgr == nil {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400467 log.Error("Error while instantiating resource manager")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700468 return errors.New("instantiating resource manager failed")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400469 }
470 // Instantiate flow manager
471 if dh.flowMgr = NewFlowManager(dh, dh.resourceMgr); dh.flowMgr == nil {
472 log.Error("Error while instantiating flow manager")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700473 return errors.New("instantiating flow manager failed")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400474 }
475 /* TODO: Instantiate Alarm , stats , BW managers */
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530476
cuilin20187b2a8c32019-03-26 19:52:28 -0700477 // Start reading indications
478 go dh.readIndications()
479 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530480}
481
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700482//AdoptDevice adopts the OLT device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530483func (dh *DeviceHandler) AdoptDevice(device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400484 dh.transitionMap = NewTransitionMap(dh)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700485 log.Infow("Adopt_device", log.Fields{"deviceID": device.Id, "Address": device.GetHostAndPort()})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400486 dh.transitionMap.Handle(DeviceInit)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530487}
488
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700489//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530490func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700491 return &ic.SwitchCapability{
492 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530493 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700494 HwDesc: "open_pon",
495 SwDesc: "open_pon",
496 SerialNum: dh.device.SerialNumber,
497 },
498 SwitchFeatures: &of.OfpSwitchFeatures{
499 NBuffers: 256,
500 NTables: 2,
501 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
502 of.OfpCapabilities_OFPC_TABLE_STATS |
503 of.OfpCapabilities_OFPC_PORT_STATS |
504 of.OfpCapabilities_OFPC_GROUP_STATS),
505 },
506 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530507}
508
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509//GetOfpPortInfo Get Ofp port information
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530510func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
cuilin20187b2a8c32019-03-26 19:52:28 -0700512 return &ic.PortCapability{
513 Port: &voltha.LogicalPort{
514 OfpPort: &of.OfpPort{
515 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
516 Config: 0,
517 State: uint32(of.OfpPortState_OFPPS_LIVE),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700518 Curr: capacity,
519 Advertised: capacity,
520 Peer: capacity,
cuilin20187b2a8c32019-03-26 19:52:28 -0700521 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
522 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
523 },
524 DeviceId: dh.device.Id,
525 DevicePortNo: uint32(portNo),
526 },
527 }, nil
528}
529
530func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700531 log.Debugw("omci indication", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700532 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 var deviceID string
534 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700535
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700536 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
537 if onuInCache, ok := dh.onus[onuKey]; !ok {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700538 log.Debugw("omci indication for a device not in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
539 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700540 kwargs := make(map[string]interface{})
541 kwargs["onu_id"] = omciInd.OnuId
542 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700543
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700544 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
545 if err != nil {
546 log.Errorw("onu not found", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700547 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700548 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700549 deviceType = onuDevice.Type
550 deviceID = onuDevice.Id
551 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
552 //if not exist in cache, then add to cache.
553 dh.onus[onuKey] = NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700554 } else {
555 //found in cache
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700556 log.Debugw("omci indication for a device in cache.", log.Fields{"intfID": omciInd.IntfId, "onuID": omciInd.OnuId})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700557 deviceType = onuInCache.deviceType
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 deviceID = onuInCache.deviceID
559 proxyDeviceID = onuInCache.proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700560 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700561
562 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
563 if sendErr := dh.AdapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
564 ic.InterAdapterMessageType_OMCI_REQUEST, dh.deviceType, deviceType,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700565 deviceID, proxyDeviceID, ""); sendErr != nil {
566 log.Errorw("send omci request error", log.Fields{"fromAdapter": dh.deviceType, "toAdapter": deviceType, "onuID": deviceID, "proxyDeviceID": proxyDeviceID})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700567 return sendErr
568 }
569 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530570}
571
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700572//ProcessInterAdapterMessage sends the proxied messages to the target device
573// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
574// is meant, and then send the unmarshalled omci message to this onu
575func (dh *DeviceHandler) ProcessInterAdapterMessage(msg *ic.InterAdapterMessage) error {
576 log.Debugw("Process_inter_adapter_message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700577 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700578 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -0700579 fromTopic := msg.Header.FromTopic
580 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700581 toDeviceID := msg.Header.ToDeviceId
582 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -0700583
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 log.Debugw("omci request message header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
cuilin20187b2a8c32019-03-26 19:52:28 -0700585
586 msgBody := msg.GetBody()
587
588 omciMsg := &ic.InterAdapterOmciMessage{}
589 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
590 log.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
591 return err
592 }
593
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700594 if omciMsg.GetProxyAddress() == nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700595 onuDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, toDeviceID)
596 if err != nil {
597 log.Errorw("onu not found", log.Fields{"onuDeviceId": toDeviceID, "error": err})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700598 return err
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700599 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700600 log.Debugw("device retrieved from core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
601 dh.sendProxiedMessage(onuDevice, omciMsg)
602
cuilin20187b2a8c32019-03-26 19:52:28 -0700603 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700604 log.Debugw("Proxy Address found in omci message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700605 dh.sendProxiedMessage(nil, omciMsg)
cuilin20187b2a8c32019-03-26 19:52:28 -0700606 }
607
608 } else {
609 log.Errorw("inter-adapter-unhandled-type", log.Fields{"msgType": msg.Header.Type})
610 }
611 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530612}
613
cuilin20187b2a8c32019-03-26 19:52:28 -0700614func (dh *DeviceHandler) sendProxiedMessage(onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 var intfID uint32
616 var onuID uint32
617 var connectStatus common.ConnectStatus_ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700618 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 intfID = onuDevice.ProxyAddress.GetChannelId()
620 onuID = onuDevice.ProxyAddress.GetOnuId()
621 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700622 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700623 intfID = omciMsg.GetProxyAddress().GetChannelId()
624 onuID = omciMsg.GetProxyAddress().GetOnuId()
625 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700626 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700627 if connectStatus != voltha.ConnectStatus_REACHABLE {
628 log.Debugw("ONU is not reachable, cannot send OMCI", log.Fields{"intfID": intfID, "onuID": onuID})
cuilin20187b2a8c32019-03-26 19:52:28 -0700629 return
630 }
631
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700632 omciMessage := &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: omciMsg.Message}
cuilin20187b2a8c32019-03-26 19:52:28 -0700633
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700634 _, err := dh.Client.OmciMsgOut(context.Background(), omciMessage)
635 if err != nil {
636 log.Errorw("unable to send omci-msg-out", log.Fields{"IntfID": intfID, "OnuID": onuID, "Msg": omciMessage})
637 return
638 }
639 log.Debugw("omci-message-sent", log.Fields{"intfID": intfID, "onuID": onuID, "omciMsg": string(omciMsg.GetMessage())})
cuilin20187b2a8c32019-03-26 19:52:28 -0700640}
641
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700642func (dh *DeviceHandler) activateONU(intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) {
643 log.Debugw("activate-onu", log.Fields{"intfID": intfID, "onuID": onuID, "serialNum": serialNum, "serialNumber": serialNumber})
644 dh.flowMgr.UpdateOnuInfo(intfID, uint32(onuID), serialNumber)
cuilin20187b2a8c32019-03-26 19:52:28 -0700645 // TODO: need resource manager
646 var pir uint32 = 1000000
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700647 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir}
manikkaraj kbf256be2019-03-25 00:13:48 +0530648 if _, err := dh.Client.ActivateOnu(context.Background(), &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400649 st, _ := status.FromError(err)
650 if st.Code() == codes.AlreadyExists {
651 log.Debug("ONU activation is in progress", log.Fields{"SerialNumber": serialNumber})
652 } else {
653 log.Errorw("activate-onu-failed", log.Fields{"Onu": Onu, "err ": err})
654 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700655 } else {
656 log.Infow("activated-onu", log.Fields{"SerialNumber": serialNumber})
657 }
658}
659
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700660func (dh *DeviceHandler) onuDiscIndication(onuDiscInd *oop.OnuDiscIndication, onuID uint32, sn string) error {
661 channelID := onuDiscInd.GetIntfId()
662 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400663 if _, ok := dh.discOnus[sn]; ok {
664 log.Debugw("onu-sn-is-already-being-processed", log.Fields{"sn": sn})
665 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700666 }
667
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400668 dh.lockDevice.Lock()
669 dh.discOnus[sn] = true
670 dh.lockDevice.Unlock()
671 // evict the onu serial number from local cache
672 defer func() {
673 delete(dh.discOnus, sn)
674 }()
675
cuilin20187b2a8c32019-03-26 19:52:28 -0700676 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400677 if sn != "" {
678 kwargs["serial_number"] = sn
679 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700680 kwargs["onu_id"] = onuID
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400681 kwargs["parent_port_no"] = parentPortNo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700682 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
683 if onuDevice == nil || err != nil {
684 if er := dh.coreProxy.ChildDeviceDetected(context.TODO(), dh.device.Id, int(parentPortNo),
685 "brcm_openomci_onu", int(channelID),
686 string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); er != nil {
687 log.Errorw("Create onu error",
688 log.Fields{"parent_id": dh.device.Id, "ponPort": onuDiscInd.GetIntfId(),
689 "onuID": onuID, "sn": sn, "error": er})
690 return er
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400691 }
692 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700693 onuDevice, err = dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400694 if err != nil {
695 log.Errorw("failed to get ONU device information", log.Fields{"err": err})
696 return err
697 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700698 er := dh.coreProxy.DeviceStateUpdate(context.TODO(), onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED)
699 if er != nil {
700 log.Errorw("Unable to update device state", log.Fields{"DeviceID": onuDevice.Id})
701 return er
702 }
703 log.Debugw("onu-discovered-reachable", log.Fields{"deviceID": onuDevice.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700704
705 for i := 0; i < 10; i++ {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700706 onuDevice, _ := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
707 if onuDevice != nil {
708 dh.activateONU(onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn)
cuilin20187b2a8c32019-03-26 19:52:28 -0700709 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700710 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700711 time.Sleep(1 * time.Second)
712 log.Debugln("Sleep 1 seconds to active onu, retry times ", i+1)
cuilin20187b2a8c32019-03-26 19:52:28 -0700713 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700714 log.Errorw("Cannot query onu, dont activate it.", log.Fields{"parent_id": dh.device.Id, "ponPort": onuDiscInd.GetIntfId(), "onuID": onuID, "sn": sn})
715 return errors.New("failed to activate onu")
cuilin20187b2a8c32019-03-26 19:52:28 -0700716}
717
718func (dh *DeviceHandler) onuIndication(onuInd *oop.OnuIndication) {
719 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
720
721 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700722 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
manikkaraj kbf256be2019-03-25 00:13:48 +0530723
cuilin20187b2a8c32019-03-26 19:52:28 -0700724 if serialNumber != "" {
725 kwargs["serial_number"] = serialNumber
726 } else {
727 kwargs["onu_id"] = onuInd.OnuId
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400728 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700729 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700730 if onuDevice, _ := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs); onuDevice != nil {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400731 if onuDevice.ParentPortNo != ponPort {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700732 //log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": intfIDFromPortNo(onuDevice.ParentPortNo), "currentIntfId": onuInd.GetIntfId()})
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400733 log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": onuDevice.ParentPortNo, "currentIntfId": ponPort})
cuilin20187b2a8c32019-03-26 19:52:28 -0700734 }
735
736 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
737 log.Warnw("ONU-id-mismatch, can happen if both voltha and the olt rebooted", log.Fields{"expected_onu_id": onuDevice.ProxyAddress.OnuId, "received_onu_id": onuInd.OnuId})
738 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700739 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
740 dh.onus[onuKey] = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700741 dh.updateOnuAdminState(onuInd)
742 dh.updateOnuStates(onuDevice, onuInd)
cuilin20187b2a8c32019-03-26 19:52:28 -0700743
cuilin20187b2a8c32019-03-26 19:52:28 -0700744 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700745 log.Errorw("onu not found", log.Fields{"intfID": onuInd.IntfId, "onuID": onuInd.OnuId})
cuilin20187b2a8c32019-03-26 19:52:28 -0700746 return
747 }
748
749}
750
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700751func (dh *DeviceHandler) updateOnuStates(onuDevice *voltha.Device, onuInd *oop.OnuIndication) {
752 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
753 dh.onus[onuKey] = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId)
754 dh.updateOnuAdminState(onuInd)
755 // operState
756 if onuInd.OperState == "down" {
757 if onuDevice.ConnectStatus != common.ConnectStatus_UNREACHABLE {
758 err := dh.coreProxy.DeviceStateUpdate(context.TODO(), onuDevice.Id, common.ConnectStatus_UNREACHABLE,
759 onuDevice.OperStatus)
760 if err != nil {
761 log.Errorw("unable to update onu state", log.Fields{"DeviceID": onuDevice.Id})
762 return
763 }
764 log.Debugln("onu-oper-state-is-down")
765 }
766 if onuDevice.OperStatus != common.OperStatus_DISCOVERED {
767 err := dh.coreProxy.DeviceStateUpdate(context.TODO(), onuDevice.Id, common.ConnectStatus_UNREACHABLE,
768 common.OperStatus_DISCOVERED)
769 if err != nil {
770 log.Errorw("unable to update onu state", log.Fields{"DeviceID": onuDevice.Id})
771 return
772 }
773 }
774 log.Debugw("inter-adapter-send-onu-ind", log.Fields{"onuIndication": onuInd})
775
776 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
777 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
778 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
779 if err != nil {
780 log.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
781 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
782 }
783 } else if onuInd.OperState == "up" {
784 if onuDevice.ConnectStatus != common.ConnectStatus_REACHABLE {
785 err := dh.coreProxy.DeviceStateUpdate(context.TODO(), onuDevice.Id, common.ConnectStatus_REACHABLE, onuDevice.OperStatus)
786 if err != nil {
787 log.Errorw("unable to update onu state", log.Fields{"DeviceID": onuDevice.Id})
788 return
789 }
790 }
791 if onuDevice.OperStatus != common.OperStatus_DISCOVERED {
792 log.Warnw("ignore onu indication", log.Fields{"intfID": onuInd.IntfId, "onuID": onuInd.OnuId, "operStatus": onuDevice.OperStatus, "msgOperStatus": onuInd.OperState})
793 return
794 }
795 err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
796 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
797 if err != nil {
798 log.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
799 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
800 return
801 }
802 } else {
803 log.Warnw("Not-implemented-or-invalid-value-of-oper-state", log.Fields{"operState": onuInd.OperState})
804 }
805}
806
807func (dh *DeviceHandler) updateOnuAdminState(onuInd *oop.OnuIndication) {
808 if onuInd.AdminState == "down" {
809 if onuInd.OperState != "down" {
810 log.Errorw("ONU-admin-state-down-and-oper-status-not-down", log.Fields{"operState": onuInd.OperState})
811 // Forcing the oper state change code to execute
812 onuInd.OperState = "down"
813 }
814 // Port and logical port update is taken care of by oper state block
815 } else if onuInd.AdminState == "up" {
816 log.Debugln("received-onu-admin-state up")
817 } else {
818 log.Errorw("Invalid-or-not-implemented-admin-state", log.Fields{"received-admin-state": onuInd.AdminState})
819 }
820 log.Debugln("admin-state-dealt-with")
821}
822
cuilin20187b2a8c32019-03-26 19:52:28 -0700823func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
824 if serialNum != nil {
825 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -0700826 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700827 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -0700828}
829
830func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
831 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700832 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -0700833 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
834 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
835 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
836 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
837 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
838 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
839 return tmp
840}
841
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700842//UpdateFlowsBulk upates the bulk flow
843func (dh *DeviceHandler) UpdateFlowsBulk() error {
844 return errors.New("unimplemented")
cuilin20187b2a8c32019-03-26 19:52:28 -0700845}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700846
847//GetChildDevice returns the child device for given parent port and onu id
848func (dh *DeviceHandler) GetChildDevice(parentPort, onuID uint32) *voltha.Device {
849 log.Debugw("GetChildDevice", log.Fields{"pon port": parentPort, "onuID": onuID})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400850 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700851 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -0400852 kwargs["parent_port_no"] = parentPort
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700853 onuDevice, err := dh.coreProxy.GetChildDevice(context.TODO(), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400854 if err != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700855 log.Errorw("onu not found", log.Fields{"intfID": parentPort, "onuID": onuID})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400856 return nil
857 }
858 log.Debugw("Successfully received child device from core", log.Fields{"child_device": *onuDevice})
859 return onuDevice
manikkaraj kbf256be2019-03-25 00:13:48 +0530860}
861
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700862// SendPacketInToCore sends packet-in to core
863// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
864// The adapter handling the device creates a device specific topic
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400865func (dh *DeviceHandler) SendPacketInToCore(logicalPort uint32, packetPayload []byte) {
866 log.Debugw("SendPacketInToCore", log.Fields{"port": logicalPort, "packetPayload": packetPayload})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700867 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPort, packetPayload); err != nil {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400868 log.Errorw("Error sending packetin to core", log.Fields{"error": err})
869 return
870 }
871 log.Debug("Sent packet-in to core successfully")
872}
873
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700874//UpdateFlowsIncrementally updates the device flow
manikkaraj kbf256be2019-03-25 00:13:48 +0530875func (dh *DeviceHandler) UpdateFlowsIncrementally(device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700876 log.Debugw("In Update_flows_incrementally", log.Fields{"deviceID": device.Id, "flows": flows, "groups": groups})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400877 if flows != nil {
878 for _, flow := range flows.ToAdd.Items {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400879 log.Debug("Adding flow", log.Fields{"deviceId": device.Id, "flowToAdd": flow})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400880 dh.flowMgr.AddFlow(flow)
881 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400882 for _, flow := range flows.ToRemove.Items {
883 log.Debug("Removing flow", log.Fields{"deviceId": device.Id, "flowToRemove": flow})
884 dh.flowMgr.RemoveFlow(flow)
885 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400886 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700887 if groups != nil && flows != nil {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400888 for _, flow := range flows.ToRemove.Items {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700889 log.Debug("Removing flow", log.Fields{"deviceID": device.Id, "flowToRemove": flow})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400890 // dh.flowMgr.RemoveFlow(flow)
891 }
892 }
893 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530894}
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400895
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700896//DisableDevice disables the given device
897//It marks the following for the given device:
898//Device-Handler Admin-State : down
899//Device Port-State: UNKNOWN
900//Device Oper-State: UNKNOWN
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400901func (dh *DeviceHandler) DisableDevice(device *voltha.Device) error {
902 if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
903 log.Errorw("Failed to disable olt ", log.Fields{"err": err})
904 return err
905 }
906 dh.lockDevice.Lock()
907 dh.adminState = "down"
908 dh.lockDevice.Unlock()
909 log.Debug("olt-disabled")
910
911 cloned := proto.Clone(device).(*voltha.Device)
912 // Update the all ports state on that device to disable
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700913 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
914 log.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": err})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400915 return err
916 }
917
918 //Update the device oper state
919 cloned.OperStatus = voltha.OperStatus_UNKNOWN
920 dh.device = cloned
921
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700922 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
923 log.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": err})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400924 return err
925 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700926 log.Debugw("Disable_device-end", log.Fields{"deviceID": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400927 return nil
928}
929
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700930//ReenableDevice re-enables the olt device after disable
931//It marks the following for the given device:
932//Device-Handler Admin-State : up
933//Device Port-State: ACTIVE
934//Device Oper-State: ACTIVE
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400935func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) error {
936 if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
937 log.Errorw("Failed to reenable olt ", log.Fields{"err": err})
938 return err
939 }
940
941 dh.lockDevice.Lock()
942 dh.adminState = "up"
943 dh.lockDevice.Unlock()
944 log.Debug("olt-reenabled")
945
946 cloned := proto.Clone(device).(*voltha.Device)
947 // Update the all ports state on that device to enable
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700948 if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_ACTIVE); err != nil {
949 log.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": err})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400950 return err
951 }
952
953 //Update the device oper status as ACTIVE
954 cloned.OperStatus = voltha.OperStatus_ACTIVE
955 dh.device = cloned
956
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700957 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
958 log.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": err})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400959 return err
960 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700961 log.Debugw("ReEnableDevice-end", log.Fields{"deviceID": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400962
963 return nil
964}
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400965
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700966//RebootDevice reboots the given device
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400967func (dh *DeviceHandler) RebootDevice(device *voltha.Device) error {
968 if _, err := dh.Client.Reboot(context.Background(), new(oop.Empty)); err != nil {
969 log.Errorw("Failed to reboot olt ", log.Fields{"err": err})
970 return err
971 }
972
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700973 log.Debugw("rebooted-device-successfully", log.Fields{"deviceID": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400974
975 return nil
976}
977
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400978func (dh *DeviceHandler) handlePacketIndication(packetIn *oop.PacketIndication) {
979 log.Debugw("Received packet-in", log.Fields{"packet-indication": *packetIn})
980 logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(packetIn)
981 if err != nil {
982 log.Errorw("Error getting logical port from packet-in", log.Fields{"error": err})
983 return
984 }
985 log.Debugw("sending packet-in to core", log.Fields{"logicalPortNum": logicalPortNum, "packet": *packetIn})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700986 if err := dh.coreProxy.SendPacketIn(context.TODO(), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400987 log.Errorw("Error sending packet-in to core", log.Fields{"error": err})
988 return
989 }
990 log.Debug("Success sending packet-in to core!")
991}
992
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700993// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
994func (dh *DeviceHandler) PacketOut(egressPortNo int, packet *of.OfpPacketOut) error {
995 log.Debugw("PacketOut", log.Fields{"deviceID": dh.deviceID, "egress_port_no": egressPortNo, "pkt-length": len(packet.Data)})
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400996 var etherFrame ethernet.Frame
997 err := (&etherFrame).UnmarshalBinary(packet.Data)
998 if err != nil {
999 log.Errorw("Failed to unmarshal into ethernet frame", log.Fields{"err": err, "pkt-length": len(packet.Data)})
1000 return err
1001 }
1002 log.Debugw("Ethernet Frame", log.Fields{"Frame": etherFrame})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001003 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001004 if egressPortType == voltha.Port_ETHERNET_UNI {
1005 if etherFrame.VLAN != nil { // If double tag, remove the outer tag
1006 nextEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
1007 if nextEthType == 0x8100 {
1008 etherFrame.VLAN = nil
1009 packet.Data, err = etherFrame.MarshalBinary()
1010 if err != nil {
1011 log.Fatalf("failed to marshal frame: %v", err)
1012 return err
1013 }
1014 if err := (&etherFrame).UnmarshalBinary(packet.Data); err != nil {
1015 log.Fatalf("failed to unmarshal frame: %v", err)
1016 return err
1017 }
1018 log.Debug("Double tagged packet , removed outer vlan", log.Fields{"New frame": etherFrame})
1019 }
1020 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001021 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1022 onuID := OnuIDFromPortNum(uint32(egressPortNo))
1023 uniID := UniIDFromPortNum(uint32(egressPortNo))
1024 /*gemPortId, err := dh.flowMgr.GetPacketOutGemPortId(intfID, onuID, uint32(egress_port_no))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001025 if err != nil{
1026 log.Errorw("Error while getting gemport to packet-out",log.Fields{"error": err})
1027 return err
1028 }*/
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001029 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), Pkt: packet.Data}
1030 log.Debug("sending-packet-to-ONU", log.Fields{"egress_port_no": egressPortNo, "IntfId": intfID, "onuID": onuID,
1031 "uniID": uniID, "packet": packet.Data})
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001032 if _, err := dh.Client.OnuPacketOut(context.Background(), &onuPkt); err != nil {
1033 log.Errorw("Error while sending packet-out to ONU", log.Fields{"error": err})
1034 return err
1035 }
1036 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001037 uplinkPkt := oop.UplinkPacket{IntfId: IntfIDFromNniPortNum(uint32(egressPortNo)), Pkt: packet.Data}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001038 log.Debug("sending-packet-to-uplink", log.Fields{"uplink_pkt": uplinkPkt})
1039 if _, err := dh.Client.UplinkPacketOut(context.Background(), &uplinkPkt); err != nil {
1040 log.Errorw("Error while sending packet-out to uplink", log.Fields{"error": err})
1041 return err
1042 }
1043 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001044 log.Warnw("Packet-out-to-this-interface-type-not-implemented", log.Fields{"egress_port_no": egressPortNo, "egressPortType": egressPortType})
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001045 }
1046 return nil
1047}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001048
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001049func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1050 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001051}