blob: e8d618c439db00fe927c1bc1259a120beed5ce25 [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 */
16package adaptercore
17
18import (
cuilin20187b2a8c32019-03-26 19:52:28 -070019 "context"
20 "errors"
21 "fmt"
22 "io"
23 "strconv"
24 "strings"
25 "sync"
26 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053027
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 com "github.com/opencord/voltha-go/adapters/common"
31 "github.com/opencord/voltha-go/common/log"
32 "github.com/opencord/voltha-go/protos/common"
33 ic "github.com/opencord/voltha-go/protos/inter_container"
34 of "github.com/opencord/voltha-go/protos/openflow_13"
35 oop "github.com/opencord/voltha-go/protos/openolt"
36 "github.com/opencord/voltha-go/protos/voltha"
37 "google.golang.org/grpc"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053038)
39
40//DeviceHandler will interact with the OLT device.
41type DeviceHandler struct {
cuilin20187b2a8c32019-03-26 19:52:28 -070042 deviceId string
43 deviceType string
44 device *voltha.Device
45 coreProxy *com.CoreProxy
46 adapterProxy *com.AdapterProxy
47 openOLT *OpenOLT
48 nniPort *voltha.Port
49 ponPort *voltha.Port
50 exitChannel chan int
51 lockDevice sync.RWMutex
52 client oop.OpenoltClient
53 transitionMap *TransitionMap
54 clientCon *grpc.ClientConn
Phaneendra Manda4c62c802019-03-06 21:37:49 +053055}
56
57//NewDeviceHandler creates a new device handler
cuilin20187b2a8c32019-03-26 19:52:28 -070058func NewDeviceHandler(cp *com.CoreProxy, ap *com.AdapterProxy, device *voltha.Device, adapter *OpenOLT) *DeviceHandler {
59 var dh DeviceHandler
60 dh.coreProxy = cp
61 dh.adapterProxy = ap
62 cloned := (proto.Clone(device)).(*voltha.Device)
63 dh.deviceId = cloned.Id
64 dh.deviceType = cloned.Type
65 dh.device = cloned
66 dh.openOLT = adapter
67 dh.exitChannel = make(chan int, 1)
68 dh.lockDevice = sync.RWMutex{}
Phaneendra Manda4c62c802019-03-06 21:37:49 +053069
cuilin20187b2a8c32019-03-26 19:52:28 -070070 //TODO initialize the support classes.
71 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +053072}
73
74// start save the device to the data model
75func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -070076 dh.lockDevice.Lock()
77 defer dh.lockDevice.Unlock()
78 log.Debugw("starting-device-agent", log.Fields{"device": dh.device})
79 // Add the initial device to the local model
80 log.Debug("device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +053081}
82
83// stop stops the device dh. Not much to do for now
84func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -070085 dh.lockDevice.Lock()
86 defer dh.lockDevice.Unlock()
87 log.Debug("stopping-device-agent")
88 dh.exitChannel <- 1
89 log.Debug("device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +053090}
91
92func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -070093 slist := strings.Split(mac, ":")
94 result := make([]uint32, len(slist))
95 var err error
96 var tmp int64
97 for index, val := range slist {
98 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
99 return []uint32{1, 2, 3, 4, 5, 6}
100 }
101 result[index] = uint32(tmp)
102 }
103 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530104}
105
106func portName(portNum uint32, portType voltha.Port_PortType, intfId uint32) string {
107
cuilin20187b2a8c32019-03-26 19:52:28 -0700108 if portType == voltha.Port_PON_OLT {
109 //return "pon-" + string(portNum)
110 return "pon-" + strconv.FormatInt(int64(intfId), 10)
111 } else if portType == voltha.Port_ETHERNET_NNI {
112 //return "nni-" + string(intfId)
113 return "nni-" + strconv.FormatInt(int64(intfId), 10)
114 } else if portType == voltha.Port_ETHERNET_UNI {
115 log.Errorw("local UNI management not supported", log.Fields{})
116 }
117 return ""
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530118}
119
120func (dh *DeviceHandler) addPort(intfId uint32, portType voltha.Port_PortType, state string) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700121 var operStatus common.OperStatus_OperStatus
122 if state == "up" {
123 operStatus = voltha.OperStatus_ACTIVE
124 } else {
125 operStatus = voltha.OperStatus_DISCOVERED
126 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530127
cuilin20187b2a8c32019-03-26 19:52:28 -0700128 // TODO
129 //portNum := platform.intfIdToPortNo(intfId, portType)
130 //portNum := intfIdToPortNo(intfId, portType)
131 portNum := intfId
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530132
cuilin20187b2a8c32019-03-26 19:52:28 -0700133 label := portName(portNum, portType, intfId)
134 // Now create the PON Port
135 ponPort := &voltha.Port{
136 PortNo: portNum,
137 Label: label,
138 Type: portType,
139 OperStatus: operStatus,
140 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530141
cuilin20187b2a8c32019-03-26 19:52:28 -0700142 // Synchronous call to update device - this method is run in its own go routine
143 if err := dh.coreProxy.PortCreated(nil, dh.device.Id, ponPort); err != nil {
144 log.Errorw("error-creating-nni-port", log.Fields{"deviceId": dh.device.Id, "error": err})
145 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530146}
147
148// readIndications to read the indications from the OLT device
149func (dh *DeviceHandler) readIndications() {
cuilin20187b2a8c32019-03-26 19:52:28 -0700150 indications, err := dh.client.EnableIndication(context.Background(), new(oop.Empty))
151 if err != nil {
152 log.Errorw("Failed to read indications", log.Fields{"err": err})
153 return
154 }
155 if indications == nil {
156 log.Errorw("Indications is nil", log.Fields{})
157 return
158 }
159 for {
160 indication, err := indications.Recv()
161 if err == io.EOF {
162 break
163 }
164 if err != nil {
165 log.Infow("Failed to read from indications", log.Fields{"err": err})
166 continue
167 }
168 switch indication.Data.(type) {
169 case *oop.Indication_OltInd:
170 oltInd := indication.GetOltInd()
171 if oltInd.OperState == "up" {
172 dh.transitionMap.Handle(DeviceUpInd)
173 } else if oltInd.OperState == "down" {
174 dh.transitionMap.Handle(DeviceDownInd)
175 }
176 case *oop.Indication_IntfInd:
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530177
cuilin20187b2a8c32019-03-26 19:52:28 -0700178 intfInd := indication.GetIntfInd()
179 go dh.addPort(intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState())
180 log.Infow("Received interface indication ", log.Fields{"InterfaceInd": intfInd})
181 case *oop.Indication_IntfOperInd:
182 intfOperInd := indication.GetIntfOperInd()
183 if intfOperInd.GetType() == "nni" {
184 go dh.addPort(intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState())
185 } else if intfOperInd.GetType() == "pon" {
186 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
187 // Handle pon port update
188 }
189 log.Infow("Received interface oper indication ", log.Fields{"InterfaceOperInd": intfOperInd})
190 case *oop.Indication_OnuDiscInd:
191 onuDiscInd := indication.GetOnuDiscInd()
192 log.Infow("Received Onu discovery indication ", log.Fields{"OnuDiscInd": onuDiscInd})
193 // TODO Get onu ID from the resource manager
194 var onuId uint32 = 1
195 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
196 go dh.onuDiscIndication(onuDiscInd, onuId, sn)
197 case *oop.Indication_OnuInd:
198 onuInd := indication.GetOnuInd()
199 log.Infow("Received Onu indication ", log.Fields{"OnuInd": onuInd})
200 go dh.onuIndication(onuInd)
201 case *oop.Indication_OmciInd:
202 omciInd := indication.GetOmciInd()
203 log.Infow("Received Omci indication ", log.Fields{"OmciInd": omciInd})
204 if err := dh.omciIndication(omciInd); err != nil {
205 log.Errorw("send-omci-indication-errr", log.Fields{"error": err, "omciInd": omciInd})
206 }
207 case *oop.Indication_PktInd:
208 pktInd := indication.GetPktInd()
209 log.Infow("Received pakcet indication ", log.Fields{"PktInd": pktInd})
210 case *oop.Indication_PortStats:
211 portStats := indication.GetPortStats()
212 log.Infow("Received port stats indication", log.Fields{"PortStats": portStats})
213 case *oop.Indication_FlowStats:
214 flowStats := indication.GetFlowStats()
215 log.Infow("Received flow stats", log.Fields{"FlowStats": flowStats})
216 case *oop.Indication_AlarmInd:
217 alarmInd := indication.GetAlarmInd()
218 log.Infow("Received alarm indication ", log.Fields{"AlarmInd": alarmInd})
219 }
220 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530221}
222
223// doStateUp handle the olt up indication and update to voltha core
224func (dh *DeviceHandler) doStateUp() error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700225 // Synchronous call to update device state - this method is run in its own go routine
226 if err := dh.coreProxy.DeviceStateUpdate(context.Background(), dh.device.Id, voltha.ConnectStatus_REACHABLE,
227 voltha.OperStatus_ACTIVE); err != nil {
228 log.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceId": dh.device.Id, "error": err})
229 return err
230 }
231 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530232}
233
234// doStateDown handle the olt down indication
235func (dh *DeviceHandler) doStateDown() error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700236 //TODO Handle oper state down
237 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530238}
239
240// doStateInit dial the grpc before going to init state
241func (dh *DeviceHandler) doStateInit() error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700242 var err error
243 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure())
244 if err != nil {
245 log.Errorw("Failed to dial device", log.Fields{"DeviceId": dh.deviceId, "HostAndPort": dh.device.GetHostAndPort(), "err": err})
246 return err
247 }
248 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530249}
250
251// postInit create olt client instance to invoke RPC on the olt device
252func (dh *DeviceHandler) postInit() error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700253 dh.client = oop.NewOpenoltClient(dh.clientCon)
254 dh.transitionMap.Handle(GrpcConnected)
255 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530256}
257
258// doStateConnected get the device info and update to voltha core
259func (dh *DeviceHandler) doStateConnected() error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700260 deviceInfo, err := dh.client.GetDeviceInfo(context.Background(), new(oop.Empty))
261 if err != nil {
262 log.Errorw("Failed to fetch device info", log.Fields{"err": err})
263 return err
264 }
265 if deviceInfo == nil {
266 log.Errorw("Device info is nil", log.Fields{})
267 return errors.New("Failed to get device info from OLT")
268 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530269
cuilin20187b2a8c32019-03-26 19:52:28 -0700270 dh.device.Root = true
271 dh.device.Vendor = deviceInfo.Vendor
272 dh.device.Model = deviceInfo.Model
273 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
274 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
275 dh.device.HardwareVersion = deviceInfo.HardwareVersion
276 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
277 // TODO : Check whether this MAC address is learnt from SDPON or need to send from device
278 dh.device.MacAddress = "0a:0b:0c:0d:0e:0f"
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530279
cuilin20187b2a8c32019-03-26 19:52:28 -0700280 // Synchronous call to update device - this method is run in its own go routine
281 if err := dh.coreProxy.DeviceUpdate(nil, dh.device); err != nil {
282 log.Errorw("error-updating-device", log.Fields{"deviceId": dh.device.Id, "error": err})
283 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530284
cuilin20187b2a8c32019-03-26 19:52:28 -0700285 // Start reading indications
286 go dh.readIndications()
287 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530288}
289
290// AdoptDevice adopts the OLT device
291func (dh *DeviceHandler) AdoptDevice(device *voltha.Device) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700292 dh.transitionMap = NewTransitionMap(dh)
293 log.Infow("AdoptDevice", log.Fields{"deviceId": device.Id, "Address": device.GetHostAndPort()})
294 dh.transitionMap.Handle(DeviceInit)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530295}
296
297// GetOfpDeviceInfo Get the Ofp device information
298func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700299 return &ic.SwitchCapability{
300 Desc: &of.OfpDesc{
301 HwDesc: "open_pon",
302 SwDesc: "open_pon",
303 SerialNum: dh.device.SerialNumber,
304 },
305 SwitchFeatures: &of.OfpSwitchFeatures{
306 NBuffers: 256,
307 NTables: 2,
308 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
309 of.OfpCapabilities_OFPC_TABLE_STATS |
310 of.OfpCapabilities_OFPC_PORT_STATS |
311 of.OfpCapabilities_OFPC_GROUP_STATS),
312 },
313 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530314}
315
316// GetOfpPortInfo Get Ofp port information
317func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device, portNo int64) (*ic.PortCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700318 cap := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
319 return &ic.PortCapability{
320 Port: &voltha.LogicalPort{
321 OfpPort: &of.OfpPort{
322 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
323 Config: 0,
324 State: uint32(of.OfpPortState_OFPPS_LIVE),
325 Curr: cap,
326 Advertised: cap,
327 Peer: cap,
328 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
329 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
330 },
331 DeviceId: dh.device.Id,
332 DevicePortNo: uint32(portNo),
333 },
334 }, nil
335}
336
337func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) error {
338 log.Debugw("omci indication", log.Fields{"intfId": omciInd.IntfId, "onuId": omciInd.OnuId})
339
340 kwargs := make(map[string]interface{})
341 kwargs["onu_id"] = omciInd.OnuId
342 kwargs["parent_port_no"] = omciInd.GetIntfId()
343
344 if onuDevice, err := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); err != nil {
345 log.Errorw("onu not found", log.Fields{"intfId": omciInd.IntfId, "onuId": omciInd.OnuId})
346 return err
347 } else {
348 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
349 if sendErr := dh.adapterProxy.SendInterAdapterMessage(context.Background(), omciMsg,
350 ic.InterAdapterMessageType_OMCI_REQUEST, dh.deviceType, onuDevice.Type,
351 onuDevice.Id, onuDevice.ProxyAddress.DeviceId, ""); sendErr != nil {
352 log.Errorw("send omci request error", log.Fields{"fromAdapter": dh.deviceType, "toAdapter": onuDevice.Type, "onuId": onuDevice.Id, "proxyDeviceId": onuDevice.ProxyAddress.DeviceId})
353 return sendErr
354 }
355 return nil
356 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530357}
358
359// Process_inter_adapter_message process inter adater message
360func (dh *DeviceHandler) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
cuilin20187b2a8c32019-03-26 19:52:28 -0700361 // TODO
362 log.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id})
363 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
364 msgId := msg.Header.Id
365 fromTopic := msg.Header.FromTopic
366 toTopic := msg.Header.ToTopic
367 toDeviceId := msg.Header.ToDeviceId
368 proxyDeviceId := msg.Header.ProxyDeviceId
369
370 log.Debugw("omci request message header", log.Fields{"msgId": msgId, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceId": toDeviceId, "proxyDeviceId": proxyDeviceId})
371
372 msgBody := msg.GetBody()
373
374 omciMsg := &ic.InterAdapterOmciMessage{}
375 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
376 log.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
377 return err
378 }
379
380 if onuDevice, err := dh.coreProxy.GetDevice(nil, dh.device.Id, toDeviceId); err != nil {
381 log.Errorw("onu not found", log.Fields{"onuDeviceId": toDeviceId, "error": err})
382 return err
383 } else {
384 dh.sendProxiedMessage(onuDevice, omciMsg)
385 }
386
387 } else {
388 log.Errorw("inter-adapter-unhandled-type", log.Fields{"msgType": msg.Header.Type})
389 }
390 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530391}
392
cuilin20187b2a8c32019-03-26 19:52:28 -0700393func (dh *DeviceHandler) sendProxiedMessage(onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) {
394 if onuDevice.ConnectStatus != voltha.ConnectStatus_REACHABLE {
395 log.Debugw("ONU is not reachable, cannot send OMCI", log.Fields{"serialNumber": onuDevice.SerialNumber, "intfId": onuDevice.ProxyAddress.GetChannelId(), "onuId": onuDevice.ProxyAddress.GetOnuId()})
396 return
397 }
398
399 omciMessage := &oop.OmciMsg{IntfId: onuDevice.ProxyAddress.GetChannelId(), OnuId: onuDevice.ProxyAddress.GetOnuId(), Pkt: omciMsg.Message}
400
401 dh.client.OmciMsgOut(context.Background(), omciMessage)
402 log.Debugw("omci-message-sent", log.Fields{"serialNumber": onuDevice.SerialNumber, "intfId": onuDevice.ProxyAddress.GetChannelId(), "omciMsg": string(omciMsg.Message)})
403}
404
405func (dh *DeviceHandler) activateONU(intfId uint32, onuId int64, serialNum *oop.SerialNumber, serialNumber string) {
406 log.Debugw("activate-onu", log.Fields{"intfId": intfId, "onuId": onuId, "serialNum": serialNum, "serialNumber": serialNumber})
407 // TODO: need resource manager
408 var pir uint32 = 1000000
409 Onu := oop.Onu{IntfId: intfId, OnuId: uint32(onuId), SerialNumber: serialNum, Pir: pir}
410 if _, err := dh.client.ActivateOnu(context.Background(), &Onu); err != nil {
411 log.Errorw("activate-onu-failed", log.Fields{"Onu": Onu})
412 } else {
413 log.Infow("activated-onu", log.Fields{"SerialNumber": serialNumber})
414 }
415}
416
417func (dh *DeviceHandler) onuDiscIndication(onuDiscInd *oop.OnuDiscIndication, onuId uint32, sn string) error {
418 if err := dh.coreProxy.ChildDeviceDetected(nil, dh.device.Id, int(onuDiscInd.GetIntfId()), "brcm_openomci_onu", int(onuDiscInd.GetIntfId()), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuId)); err != nil {
419 log.Errorw("Create onu error", log.Fields{"parent_id": dh.device.Id, "ponPort": onuDiscInd.GetIntfId(), "onuId": onuId, "sn": sn, "error": err})
420 return err
421 }
422
423 kwargs := make(map[string]interface{})
424 kwargs["onu_id"] = onuId
425 kwargs["parent_port_no"] = onuDiscInd.GetIntfId()
426
427 for i := 0; i < 10; i++ {
428 if onuDevice, _ := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); onuDevice != nil {
429 dh.activateONU(onuDiscInd.IntfId, int64(onuId), onuDiscInd.SerialNumber, sn)
430 return nil
431 } else {
432 time.Sleep(1 * time.Second)
433 log.Debugln("Sleep 1 seconds to active onu, retry times ", i+1)
434 }
435 }
436 log.Errorw("Cannot query onu, dont activate it.", log.Fields{"parent_id": dh.device.Id, "ponPort": onuDiscInd.GetIntfId(), "onuId": onuId, "sn": sn})
437 return errors.New("Failed to activate onu")
438}
439
440func (dh *DeviceHandler) onuIndication(onuInd *oop.OnuIndication) {
441 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
442
443 kwargs := make(map[string]interface{})
444 if serialNumber != "" {
445 kwargs["serial_number"] = serialNumber
446 } else {
447 kwargs["onu_id"] = onuInd.OnuId
448 kwargs["parent_port_no"] = onuInd.GetIntfId()
449 }
450 if onuDevice, _ := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); onuDevice != nil {
451 //if intfIdFromPortNo(onuDevice.ParentPortNo) != onuInd.GetIntfId() {
452 if onuDevice.ParentPortNo != onuInd.GetIntfId() {
453 //log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": intfIdFromPortNo(onuDevice.ParentPortNo), "currentIntfId": onuInd.GetIntfId()})
454 log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": onuDevice.ParentPortNo, "currentIntfId": onuInd.GetIntfId()})
455 }
456
457 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
458 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})
459 }
460
461 // adminState
462 if onuInd.AdminState == "down" {
463 if onuInd.OperState != "down" {
464 log.Errorw("ONU-admin-state-down-and-oper-status-not-down", log.Fields{"operState": onuInd.OperState})
465 // Forcing the oper state change code to execute
466 onuInd.OperState = "down"
467 }
468 // Port and logical port update is taken care of by oper state block
469 } else if onuInd.AdminState == "up" {
470 log.Debugln("received-onu-admin-state up")
471 } else {
472 log.Errorw("Invalid-or-not-implemented-admin-state", log.Fields{"received-admin-state": onuInd.AdminState})
473 }
474 log.Debugln("admin-state-dealt-with")
475
476 // operState
477 if onuInd.OperState == "down" {
478 if onuDevice.ConnectStatus != common.ConnectStatus_UNREACHABLE {
479 dh.coreProxy.DeviceStateUpdate(nil, onuDevice.Id, common.ConnectStatus_UNREACHABLE, onuDevice.OperStatus)
480 log.Debugln("onu-oper-state-is-down")
481 }
482 if onuDevice.OperStatus != common.OperStatus_DISCOVERED {
483 dh.coreProxy.DeviceStateUpdate(nil, onuDevice.Id, common.ConnectStatus_UNREACHABLE, common.OperStatus_DISCOVERED)
484 }
485 log.Debugw("inter-adapter-send-onu-ind", log.Fields{"onuIndication": onuInd})
486
487 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
488 dh.adapterProxy.SendInterAdapterMessage(nil, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST, "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
489 } else if onuInd.OperState == "up" {
490 if onuDevice.ConnectStatus != common.ConnectStatus_REACHABLE {
491 dh.coreProxy.DeviceStateUpdate(nil, onuDevice.Id, common.ConnectStatus_REACHABLE, onuDevice.OperStatus)
492
493 }
494 if onuDevice.OperStatus != common.OperStatus_DISCOVERED {
495 log.Warnw("ignore onu indication", log.Fields{"intfId": onuInd.IntfId, "onuId": onuInd.OnuId, "operStatus": onuDevice.OperStatus, "msgOperStatus": onuInd.OperState})
496 return
497 }
498 dh.adapterProxy.SendInterAdapterMessage(nil, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST, "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
499 } else {
500 log.Warnw("Not-implemented-or-invalid-value-of-oper-state", log.Fields{"operState": onuInd.OperState})
501 }
502 } else {
503 log.Errorw("onu not found", log.Fields{"intfId": onuInd.IntfId, "onuId": onuInd.OnuId})
504 return
505 }
506
507}
508
509func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
510 if serialNum != nil {
511 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
512 } else {
513 return ""
514 }
515}
516
517func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
518 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
519 fmt.Sprintf("%x", (uint32(vendorSpecific[0]&0x0f))) +
520 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
521 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
522 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
523 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
524 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
525 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
526 return tmp
527}
528
529// flows
530func (dh *DeviceHandler) Update_flows_bulk() error {
531 return errors.New("UnImplemented")
532}