blob: a0514cfc0547811b306880998187c04715fd8c6f [file] [log] [blame]
/*
* Copyright 2022-present Open Networking Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vpagent
import (
"context"
"time"
"voltha-go-controller/internal/pkg/intf"
"voltha-go-controller/log"
"github.com/golang/protobuf/ptypes/empty"
"github.com/opencord/voltha-protos/v5/go/voltha"
)
func (vpa *VPAgent) synchronizeDeviceList(ctx context.Context) {
// Send reconnection indication to the devices already known
for _, vpc := range vpa.clientMap {
vpc.ConnectInd(context.TODO(), intf.DeviceReDisc)
}
// Refresh once to get everything started
vpa.refreshDeviceList(ctx)
tick := time.NewTicker(vpa.DeviceListRefreshInterval)
loop:
for {
select {
case <-ctx.Done():
logger.Errorw(ctx, "Context Done", log.Fields{"Context": ctx})
break loop
case <-tick.C:
vpa.refreshDeviceList(ctx)
}
}
tick.Stop()
}
func (vpa *VPAgent) refreshDeviceList(cntx context.Context) {
// If we exit, assume disconnected
if vpa.volthaClient == nil {
logger.Fatal(ctx, "no-voltha-connection")
vpa.events <- vpaEventVolthaDisconnected
return
}
deviceList, err := vpa.volthaClient.Get().ListLogicalDevices(context.Background(), &empty.Empty{})
if err != nil {
logger.Errorw(ctx, "vpagent failed to query device list from voltha",
log.Fields{"error": err})
vpa.events <- vpaEventVolthaDisconnected
return
}
var toAdd []int
var toDel []string
var deviceIDMap = make(map[string]string)
for index, d := range deviceList.Items {
deviceID := d.Id
deviceIDMap[deviceID] = deviceID
if vpa.clientMap[deviceID] == nil {
toAdd = append(toAdd, index)
}
}
for key := range vpa.clientMap {
deviceID, ok := deviceIDMap[key]
if !ok || (ok && deviceID == "") {
toDel = append(toDel, key)
}
}
logger.Debugw(ctx, "Device Refresh", log.Fields{"ToAdd": toAdd, "ToDel": toDel})
for i := 0; i < len(toAdd); i++ {
device := deviceList.Items[toAdd[i]]
serialNum := device.Desc.SerialNum
// If the blocked device list contain device serial number, do not add VPClient.
if vpa.VPClientAgent.IsBlockedDevice(serialNum) {
logger.Debugw(ctx, "Device Serial Number is present in the blocked device list", log.Fields{"device-serial-number": serialNum})
} else {
vpa.addVPClient(device) // client is started in addVPClient
}
}
for i := 0; i < len(toDel); i++ {
vpa.VPClientAgent.DelDevice(cntx, toDel[i])
vpa.mapLock.Lock()
delete(vpa.clientMap, toDel[i])
vpa.mapLock.Unlock()
}
}
func (vpa *VPAgent) addVPClient(device *voltha.LogicalDevice) intf.IVPClient {
logger.Debugw(ctx, "GrpcClient addClient called ", log.Fields{"device-id": device.Id})
vpa.mapLock.Lock()
defer vpa.mapLock.Unlock()
var serialNum = "Unknown"
var mfrDesc = "Unknown"
var hwDesc = "Unknown"
var swDesc = "Unknown"
if device.Desc != nil {
serialNum = device.Desc.SerialNum
mfrDesc = device.Desc.MfrDesc
hwDesc = device.Desc.HwDesc
swDesc = device.Desc.SwDesc
}
vpc := vpa.clientMap[device.Id]
if vpc == nil {
vpa.VPClientAgent.AddNewDevice(&intf.VPClientCfg{
DeviceID: device.Id,
SerialNum: serialNum,
MfrDesc: mfrDesc,
HwDesc: hwDesc,
SwDesc: swDesc,
SouthBoundID: device.RootDeviceId,
TimeStamp: time.Now(),
VolthaClient: vpa.volthaClient,
PacketOutChannel: vpa.packetOutChannel,
})
}
logger.Debugw(ctx, "Finished with addClient", log.Fields{"deviceID": device.Id})
return vpc
}
// AddClientToClientMap - called by controller once device obj is created
func (vpa *VPAgent) AddClientToClientMap(deviceID string, vpc intf.IVPClient) {
vpa.mapLock.Lock()
defer vpa.mapLock.Unlock()
if vpc != nil {
vpa.clientMap[deviceID] = vpc
}
}
func (vpa *VPAgent) getVPClient(deviceID string) intf.IVPClient {
if vpc, ok := vpa.clientMap[deviceID]; ok {
return vpc
}
return nil
}