blob: c14655eac6f81c3c989df4ebfd255ce4e4baed9b [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001/*
2 * Copyright 2020-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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package core
Holger Hildebrandtfa074992020-03-27 15:42:06 +000019
20import (
21 "context"
22 "errors"
23 "fmt"
24 "sync"
25 "time"
26
khenaidoo7d3c5582021-08-11 18:09:44 -040027 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
28 "github.com/opencord/voltha-protos/v5/go/adapter_services"
dbainbri4d3a0dc2020-12-02 00:33:42 +000029
khenaidoo7d3c5582021-08-11 18:09:44 -040030 conf "github.com/opencord/voltha-lib-go/v7/pkg/config"
31 "github.com/opencord/voltha-protos/v5/go/common"
32 "google.golang.org/grpc"
33
34 "github.com/golang/protobuf/ptypes/empty"
35 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
36 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
38 "github.com/opencord/voltha-protos/v5/go/extension"
39 ic "github.com/opencord/voltha-protos/v5/go/inter_container"
40 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000041
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000042 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
Matteo Scandolo761f7512020-11-23 15:52:40 -080043 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000044 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
45 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
Holger Hildebrandtfa074992020-03-27 15:42:06 +000046)
47
48//OpenONUAC structure holds the ONU core information
49type OpenONUAC struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +053050 deviceHandlers map[string]*deviceHandler
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +000051 deviceHandlersCreateChan map[string]chan bool //channels for deviceHandler create events
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000052 mutexDeviceHandlersMap sync.RWMutex
khenaidoo7d3c5582021-08-11 18:09:44 -040053 coreClient *vgrpc.Client
54 parentAdapterClients map[string]*vgrpc.Client
55 lockParentAdapterClients sync.RWMutex
Himani Chawlac07fda02020-12-09 16:21:21 +053056 eventProxy eventif.EventProxy
mpagenkoaf801632020-07-03 10:00:42 +000057 kvClient kvstore.Client
Matteo Scandolof1f39a72020-11-24 12:08:11 -080058 cm *conf.ConfigManager
Holger Hildebrandtfa074992020-03-27 15:42:06 +000059 config *config.AdapterFlags
60 numOnus int
Matteo Scandolo127c59d2021-01-28 11:31:18 -080061 KVStoreAddress string
Holger Hildebrandtfa074992020-03-27 15:42:06 +000062 KVStoreType string
mpagenkoaf801632020-07-03 10:00:42 +000063 KVStoreTimeout time.Duration
Holger Hildebrandt61b24d02020-11-16 13:36:40 +000064 mibTemplatesGenerated map[string]bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000065 mutexMibTemplateGenerated sync.RWMutex
Holger Hildebrandtfa074992020-03-27 15:42:06 +000066 exitChannel chan int
67 HeartbeatCheckInterval time.Duration
68 HeartbeatFailReportInterval time.Duration
mpagenkodff5dda2020-08-28 11:52:01 +000069 AcceptIncrementalEvto bool
Holger Hildebrandtfa074992020-03-27 15:42:06 +000070 //GrpcTimeoutInterval time.Duration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000071 pSupportedFsms *cmn.OmciDeviceFsms
Himani Chawlad96df182020-09-28 11:12:02 +053072 maxTimeoutInterAdapterComm time.Duration
Holger Hildebrandt38985dc2021-02-18 16:25:20 +000073 maxTimeoutReconciling time.Duration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000074 pDownloadManager *swupg.AdapterDownloadManager
75 pFileManager *swupg.FileDownloadManager //let coexist 'old and new' DownloadManager as long as 'old' does not get obsolete
76 MetricsEnabled bool
Holger Hildebrandte3677f12021-02-05 14:50:56 +000077 mibAuditInterval time.Duration
Girish Gowdra0b235842021-03-09 13:06:46 -080078 omciTimeout int // in seconds
Himani Chawla075f1642021-03-15 19:23:24 +053079 alarmAuditInterval time.Duration
mpagenkoc26d4c02021-05-06 14:27:57 +000080 dlToOnuTimeout4M time.Duration
khenaidoo7d3c5582021-08-11 18:09:44 -040081 rpcTimeout time.Duration
Holger Hildebrandtfa074992020-03-27 15:42:06 +000082}
83
84//NewOpenONUAC returns a new instance of OpenONU_AC
khenaidoo7d3c5582021-08-11 18:09:44 -040085func NewOpenONUAC(ctx context.Context, coreClient *vgrpc.Client, eventProxy eventif.EventProxy,
86 kvClient kvstore.Client, cfg *config.AdapterFlags, cm *conf.ConfigManager) *OpenONUAC {
Holger Hildebrandtfa074992020-03-27 15:42:06 +000087 var openOnuAc OpenONUAC
88 openOnuAc.exitChannel = make(chan int, 1)
Himani Chawla6d2ae152020-09-02 13:11:20 +053089 openOnuAc.deviceHandlers = make(map[string]*deviceHandler)
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +000090 openOnuAc.deviceHandlersCreateChan = make(map[string]chan bool)
khenaidoo7d3c5582021-08-11 18:09:44 -040091 openOnuAc.parentAdapterClients = make(map[string]*vgrpc.Client)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000092 openOnuAc.mutexDeviceHandlersMap = sync.RWMutex{}
Holger Hildebrandtfa074992020-03-27 15:42:06 +000093 openOnuAc.config = cfg
Matteo Scandolof1f39a72020-11-24 12:08:11 -080094 openOnuAc.cm = cm
khenaidoo7d3c5582021-08-11 18:09:44 -040095 openOnuAc.coreClient = coreClient
Holger Hildebrandtfa074992020-03-27 15:42:06 +000096 openOnuAc.numOnus = cfg.OnuNumber
Holger Hildebrandtfa074992020-03-27 15:42:06 +000097 openOnuAc.eventProxy = eventProxy
mpagenkoaf801632020-07-03 10:00:42 +000098 openOnuAc.kvClient = kvClient
Matteo Scandolo127c59d2021-01-28 11:31:18 -080099 openOnuAc.KVStoreAddress = cfg.KVStoreAddress
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000100 openOnuAc.KVStoreType = cfg.KVStoreType
mpagenkoaf801632020-07-03 10:00:42 +0000101 openOnuAc.KVStoreTimeout = cfg.KVStoreTimeout
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000102 openOnuAc.mibTemplatesGenerated = make(map[string]bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000103 openOnuAc.mutexMibTemplateGenerated = sync.RWMutex{}
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000104 openOnuAc.HeartbeatCheckInterval = cfg.HeartbeatCheckInterval
105 openOnuAc.HeartbeatFailReportInterval = cfg.HeartbeatFailReportInterval
mpagenkodff5dda2020-08-28 11:52:01 +0000106 openOnuAc.AcceptIncrementalEvto = cfg.AccIncrEvto
Himani Chawlad96df182020-09-28 11:12:02 +0530107 openOnuAc.maxTimeoutInterAdapterComm = cfg.MaxTimeoutInterAdapterComm
Holger Hildebrandt38985dc2021-02-18 16:25:20 +0000108 openOnuAc.maxTimeoutReconciling = cfg.MaxTimeoutReconciling
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000109 //openOnuAc.GrpcTimeoutInterval = cfg.GrpcTimeoutInterval
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000110 openOnuAc.MetricsEnabled = cfg.MetricsEnabled
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000111 openOnuAc.mibAuditInterval = cfg.MibAuditInterval
Girish Gowdra0b235842021-03-09 13:06:46 -0800112 // since consumers of OMCI timeout value everywhere in code is in "int seconds", do this useful conversion
113 openOnuAc.omciTimeout = int(cfg.OmciTimeout.Seconds())
Himani Chawla075f1642021-03-15 19:23:24 +0530114 openOnuAc.alarmAuditInterval = cfg.AlarmAuditInterval
mpagenkoc26d4c02021-05-06 14:27:57 +0000115 openOnuAc.dlToOnuTimeout4M = cfg.DownloadToOnuTimeout4MB
khenaidoo7d3c5582021-08-11 18:09:44 -0400116 openOnuAc.rpcTimeout = cfg.RPCTimeout
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000117
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 openOnuAc.pSupportedFsms = &cmn.OmciDeviceFsms{
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000119 "mib-synchronizer": {
120 //mibSyncFsm, // Implements the MIB synchronization state machine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121 DatabaseClass: mibDbVolatileDictImpl, // Implements volatile ME MIB database
Himani Chawla4d908332020-08-31 12:30:20 +0530122 //true, // Advertise events on OpenOMCI event bus
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123 AuditInterval: openOnuAc.mibAuditInterval, // Time to wait between MIB audits. 0 to disable audits.
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000124 // map[string]func() error{
125 // "mib-upload": onuDeviceEntry.MibUploadTask,
126 // "mib-template": onuDeviceEntry.MibTemplateTask,
127 // "get-mds": onuDeviceEntry.GetMdsTask,
128 // "mib-audit": onuDeviceEntry.GetMdsTask,
129 // "mib-resync": onuDeviceEntry.MibResyncTask,
130 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
131 // },
132 },
133 }
134
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000135 openOnuAc.pDownloadManager = swupg.NewAdapterDownloadManager(ctx)
136 openOnuAc.pFileManager = swupg.NewFileDownloadManager(ctx)
mpagenkoc26d4c02021-05-06 14:27:57 +0000137 openOnuAc.pFileManager.SetDownloadTimeout(ctx, cfg.DownloadToAdapterTimeout)
mpagenkoc8bba412021-01-15 15:38:44 +0000138
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000139 return &openOnuAc
140}
141
142//Start starts (logs) the adapter
143func (oo *OpenONUAC) Start(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000144 logger.Info(ctx, "starting-openonu-adapter")
mpagenkoc8bba412021-01-15 15:38:44 +0000145
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000146 return nil
147}
148
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149/*
150//stop terminates the session
151func (oo *OpenONUAC) stop(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000152 logger.Info(ctx,"stopping-device-manager")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000153 oo.exitChannel <- 1
dbainbri4d3a0dc2020-12-02 00:33:42 +0000154 logger.Info(ctx,"device-manager-stopped")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000155 return nil
156}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530157*/
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000158
Himani Chawla6d2ae152020-09-02 13:11:20 +0530159func (oo *OpenONUAC) addDeviceHandlerToMap(ctx context.Context, agent *deviceHandler) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000160 oo.mutexDeviceHandlersMap.Lock()
161 defer oo.mutexDeviceHandlersMap.Unlock()
162 if _, exist := oo.deviceHandlers[agent.DeviceID]; !exist {
163 oo.deviceHandlers[agent.DeviceID] = agent
164 oo.deviceHandlers[agent.DeviceID].start(ctx)
165 if _, exist := oo.deviceHandlersCreateChan[agent.DeviceID]; exist {
166 logger.Debugw(ctx, "deviceHandler created - trigger processing of pending ONU_IND_REQUEST", log.Fields{"device-id": agent.DeviceID})
167 oo.deviceHandlersCreateChan[agent.DeviceID] <- true
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000168 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000169 }
170}
171
Himani Chawla6d2ae152020-09-02 13:11:20 +0530172func (oo *OpenONUAC) deleteDeviceHandlerToMap(agent *deviceHandler) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000173 oo.mutexDeviceHandlersMap.Lock()
174 defer oo.mutexDeviceHandlersMap.Unlock()
175 delete(oo.deviceHandlers, agent.DeviceID)
176 delete(oo.deviceHandlersCreateChan, agent.DeviceID)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000177}
178
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000179//getDeviceHandler gets the ONU deviceHandler and may wait until it is created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000180func (oo *OpenONUAC) getDeviceHandler(ctx context.Context, deviceID string, aWait bool) *deviceHandler {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000181 oo.mutexDeviceHandlersMap.Lock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000182 agent, ok := oo.deviceHandlers[deviceID]
183 if aWait && !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000184 logger.Infow(ctx, "Race condition: deviceHandler not present - wait for creation or timeout",
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000185 log.Fields{"device-id": deviceID})
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000186 if _, exist := oo.deviceHandlersCreateChan[deviceID]; !exist {
187 oo.deviceHandlersCreateChan[deviceID] = make(chan bool, 1)
188 }
Girish Gowdra7407a4d2020-11-12 12:44:53 -0800189 deviceCreateChan := oo.deviceHandlersCreateChan[deviceID]
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000190 //keep the read sema short to allow for subsequent write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000191 oo.mutexDeviceHandlersMap.Unlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000192 // based on concurrent processing the deviceHandler creation may not yet be finished at his point
193 // so it might be needed to wait here for that event with some timeout
194 select {
195 case <-time.After(1 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000196 logger.Warnw(ctx, "No valid deviceHandler created after max WaitTime", log.Fields{"device-id": deviceID})
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000197 return nil
Girish Gowdra7407a4d2020-11-12 12:44:53 -0800198 case <-deviceCreateChan:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000199 logger.Debugw(ctx, "deviceHandler is ready now - continue", log.Fields{"device-id": deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000200 oo.mutexDeviceHandlersMap.RLock()
201 defer oo.mutexDeviceHandlersMap.RUnlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000202 return oo.deviceHandlers[deviceID]
203 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000204 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000205 oo.mutexDeviceHandlersMap.Unlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000206 return agent
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000207}
208
khenaidoo7d3c5582021-08-11 18:09:44 -0400209// GetHealthStatus is used as a service readiness validation as a grpc connection
210func (oo *OpenONUAC) GetHealthStatus(ctx context.Context, empty *empty.Empty) (*voltha.HealthStatus, error) {
211 return &voltha.HealthStatus{State: voltha.HealthStatus_HEALTHY}, nil
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000212}
213
khenaidoo7d3c5582021-08-11 18:09:44 -0400214// AdoptDevice creates a new device handler if not present already and then adopts the device
215func (oo *OpenONUAC) AdoptDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000216 if device == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000217 logger.Warn(ctx, "voltha-device-is-nil")
khenaidoo7d3c5582021-08-11 18:09:44 -0400218 return nil, errors.New("nil-device")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000219 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000220 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id})
Himani Chawla6d2ae152020-09-02 13:11:20 +0530221 var handler *deviceHandler
dbainbri4d3a0dc2020-12-02 00:33:42 +0000222 if handler = oo.getDeviceHandler(ctx, device.Id, false); handler == nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400223 handler := newDeviceHandler(ctx, oo.coreClient, oo.eventProxy, device, oo)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000224 oo.addDeviceHandlerToMap(ctx, handler)
khenaidoo7d3c5582021-08-11 18:09:44 -0400225
226 // Setup the grpc communication with the parent adapter
227 if err := oo.setupParentInterAdapterClient(ctx, device.ProxyAddress.AdapterEndpoint); err != nil {
228 // TODO: Cleanup on failure needed
229 return nil, err
230 }
231
232 go handler.adoptOrReconcileDevice(log.WithSpanFromContext(context.Background(), ctx), device)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000233 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400234 return &empty.Empty{}, nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000235}
236
khenaidoo7d3c5582021-08-11 18:09:44 -0400237//ReconcileDevice is called once when the adapter needs to re-create device - usually on core restart
238func (oo *OpenONUAC) ReconcileDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000239 if device == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000240 logger.Warn(ctx, "reconcile-device-voltha-device-is-nil")
khenaidoo7d3c5582021-08-11 18:09:44 -0400241 return nil, errors.New("nil-device")
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000242 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000243 logger.Infow(ctx, "reconcile-device", log.Fields{"device-id": device.Id})
Himani Chawla6d2ae152020-09-02 13:11:20 +0530244 var handler *deviceHandler
dbainbri4d3a0dc2020-12-02 00:33:42 +0000245 if handler = oo.getDeviceHandler(ctx, device.Id, false); handler == nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400246 handler := newDeviceHandler(ctx, oo.coreClient, oo.eventProxy, device, oo)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000247 oo.addDeviceHandlerToMap(ctx, handler)
248 handler.device = device
khenaidoo7d3c5582021-08-11 18:09:44 -0400249 if err := handler.updateDeviceStateInCore(log.WithSpanFromContext(context.Background(), ctx), &ic.DeviceStateFilter{
250 DeviceId: device.Id,
251 OperStatus: voltha.OperStatus_RECONCILING,
252 ConnStatus: device.ConnectStatus,
253 }); err != nil {
254 return nil, fmt.Errorf("not able to update device state to reconciling. Err : %s", err.Error())
Maninderb5187552021-03-23 22:23:42 +0530255 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400256 // Setup the grpc communication with the parent adapter
257 if err := oo.setupParentInterAdapterClient(ctx, device.ProxyAddress.AdapterEndpoint); err != nil {
258 // TODO: Cleanup on failure needed
259 return nil, err
260 }
261
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000262 handler.StartReconciling(log.WithSpanFromContext(context.Background(), ctx), false)
khenaidoo7d3c5582021-08-11 18:09:44 -0400263 go handler.adoptOrReconcileDevice(log.WithSpanFromContext(context.Background(), ctx), handler.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000264 // reconcilement will be continued after onu-device entry is added
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000265 } else {
khenaidoo7d3c5582021-08-11 18:09:44 -0400266 return nil, fmt.Errorf(fmt.Sprintf("device-already-reconciled-or-active-%s", device.Id))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000267 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400268 return &empty.Empty{}, nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000269}
270
khenaidoo7d3c5582021-08-11 18:09:44 -0400271//DisableDevice disables the given device
272func (oo *OpenONUAC) DisableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000273 logger.Infow(ctx, "disable-device", log.Fields{"device-id": device.Id})
274 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400275 go handler.disableDevice(log.WithSpanFromContext(context.Background(), ctx), device)
276 return &empty.Empty{}, nil
ozgecanetsiafce57b12020-05-25 14:39:35 +0300277 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Warnw(ctx, "no handler found for device-disable", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400279 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000280}
281
khenaidoo7d3c5582021-08-11 18:09:44 -0400282//ReEnableDevice enables the onu device after disable
283func (oo *OpenONUAC) ReEnableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Infow(ctx, "reenable-device", log.Fields{"device-id": device.Id})
285 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400286 go handler.reEnableDevice(log.WithSpanFromContext(context.Background(), ctx), device)
287 return &empty.Empty{}, nil
ozgecanetsiafce57b12020-05-25 14:39:35 +0300288 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 logger.Warnw(ctx, "no handler found for device-reenable", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400290 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000291}
292
khenaidoo7d3c5582021-08-11 18:09:44 -0400293//RebootDevice reboots the given device
294func (oo *OpenONUAC) RebootDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": device.Id})
296 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400297 go handler.rebootDevice(log.WithSpanFromContext(context.Background(), ctx), true, device) //reboot request with device checking
298 return &empty.Empty{}, nil
ozgecanetsiae11479f2020-07-06 09:44:47 +0300299 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000300 logger.Warnw(ctx, "no handler found for device-reboot", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400301 return nil, fmt.Errorf("handler-not-found-for-device: %s", device.Id)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000302}
303
khenaidoo7d3c5582021-08-11 18:09:44 -0400304// DeleteDevice deletes the given device
305func (oo *OpenONUAC) DeleteDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
306 nctx := log.WithSpanFromContext(context.Background(), ctx)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000307
khenaidoo7d3c5582021-08-11 18:09:44 -0400308 logger.Infow(ctx, "delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber, "ctx": ctx, "nctx": nctx})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000309 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
Girish Gowdra0e533642021-03-02 22:02:51 -0800310 var errorsList []error
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000311
312 handler.mutexDeletionInProgressFlag.Lock()
313 handler.deletionInProgress = true
314 handler.mutexDeletionInProgressFlag.Unlock()
315
Girish Gowdra0e533642021-03-02 22:02:51 -0800316 if err := handler.deleteDevicePersistencyData(ctx); err != nil {
317 errorsList = append(errorsList, err)
318 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700319
320 // Stop PM, Alarm and Self Test event handler routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000321 if handler.GetCollectorIsRunning() {
Girish Gowdra10123c02021-08-30 11:52:06 -0700322 handler.stopCollector <- true
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700323 logger.Debugw(ctx, "sent stop signal to metric collector routine", log.Fields{"device-id": device.Id})
Girish Gowdra10123c02021-08-30 11:52:06 -0700324
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700325 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000326 if handler.GetAlarmManagerIsRunning(ctx) {
Girish Gowdra10123c02021-08-30 11:52:06 -0700327 handler.stopAlarmManager <- true
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700328 logger.Debugw(ctx, "sent stop signal to alarm manager", log.Fields{"device-id": device.Id})
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700329 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700330 if handler.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000331 handler.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -0700332 logger.Debugw(ctx, "sent stop signal to self test handler module", log.Fields{"device-id": device.Id})
333 }
334
335 // Clear PM data on the KV store
Girish Gowdra0e533642021-03-02 22:02:51 -0800336 if handler.pOnuMetricsMgr != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 if err := handler.pOnuMetricsMgr.ClearAllPmData(ctx); err != nil {
Girish Gowdra0e533642021-03-02 22:02:51 -0800338 errorsList = append(errorsList, err)
339 }
340 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700341
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000342 //don't leave any garbage - even in error case
343 oo.deleteDeviceHandlerToMap(handler)
Girish Gowdra0e533642021-03-02 22:02:51 -0800344 if len(errorsList) > 0 {
345 logger.Errorw(ctx, "one-or-more-error-during-device-delete", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400346 return nil, fmt.Errorf("one-or-more-error-during-device-delete, errors:%v", errorsList)
Girish Gowdra0e533642021-03-02 22:02:51 -0800347 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400348 return &empty.Empty{}, nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000349 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 logger.Warnw(ctx, "no handler found for device-deletion", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400351 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000352}
353
khenaidoo7d3c5582021-08-11 18:09:44 -0400354//UpdateFlowsIncrementally updates (add/remove) the flows on a given device
355func (oo *OpenONUAC) UpdateFlowsIncrementally(ctx context.Context, incrFlows *ic.IncrementalFlows) (*empty.Empty, error) {
356 logger.Infow(ctx, "update-flows-incrementally", log.Fields{"device-id": incrFlows.Device.Id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000357
mpagenkofc4f56e2020-11-04 17:17:49 +0000358 //flow config is relayed to handler even if the device might be in some 'inactive' state
359 // let the handler or related FSM's decide, what to do with the modified flow state info
360 // at least the flow-remove must be done in respect to internal data, while OMCI activity might not be needed here
mpagenkodff5dda2020-08-28 11:52:01 +0000361
362 // For now, there is no support for group changes (as in the actual Py-adapter code)
mpagenkofc4f56e2020-11-04 17:17:49 +0000363 // but processing is continued for flowUpdate possibly also set in the request
khenaidoo7d3c5582021-08-11 18:09:44 -0400364 if incrFlows.Groups.ToAdd != nil && incrFlows.Groups.ToAdd.Items != nil {
365 logger.Warnw(ctx, "Update-flow-incr: group add not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000366 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400367 if incrFlows.Groups.ToRemove != nil && incrFlows.Groups.ToRemove.Items != nil {
368 logger.Warnw(ctx, "Update-flow-incr: group remove not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000369 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400370 if incrFlows.Groups.ToUpdate != nil && incrFlows.Groups.ToUpdate.Items != nil {
371 logger.Warnw(ctx, "Update-flow-incr: group update not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000372 }
373
khenaidoo7d3c5582021-08-11 18:09:44 -0400374 if handler := oo.getDeviceHandler(ctx, incrFlows.Device.Id, false); handler != nil {
375 if err := handler.FlowUpdateIncremental(log.WithSpanFromContext(context.Background(), ctx), incrFlows.Flows, incrFlows.Groups, incrFlows.FlowMetadata); err != nil {
376 return nil, err
377 }
378 return &empty.Empty{}, nil
mpagenkodff5dda2020-08-28 11:52:01 +0000379 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400380 logger.Warnw(ctx, "no handler found for incremental flow update", log.Fields{"device-id": incrFlows.Device.Id})
381 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", incrFlows.Device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000382}
383
khenaidoo7d3c5582021-08-11 18:09:44 -0400384//UpdatePmConfig returns PmConfigs nil or error
385func (oo *OpenONUAC) UpdatePmConfig(ctx context.Context, configs *ic.PmConfigsInfo) (*empty.Empty, error) {
386 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": configs.DeviceId})
387 if handler := oo.getDeviceHandler(ctx, configs.DeviceId, false); handler != nil {
388 if err := handler.updatePmConfig(log.WithSpanFromContext(context.Background(), ctx), configs.PmConfigs); err != nil {
389 return nil, err
390 }
391 return &empty.Empty{}, nil
Girish Gowdrae09a6202021-01-12 18:10:59 -0800392 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400393 logger.Warnw(ctx, "no handler found for update-pm-config", log.Fields{"device-id": configs.DeviceId})
394 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", configs.DeviceId))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000395}
396
khenaidoo7d3c5582021-08-11 18:09:44 -0400397//DownloadImage requests downloading some image according to indications as given in request
Andrea Campanella71e546a2021-02-26 11:09:33 +0100398//The ImageDownload needs to be called `request`due to library reflection requirements
khenaidoo7d3c5582021-08-11 18:09:44 -0400399func (oo *OpenONUAC) DownloadImage(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
400 ctx = log.WithSpanFromContext(context.Background(), ctx)
401 if imageInfo != nil && imageInfo.Image != nil && imageInfo.Image.Name != "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000402 if !oo.pDownloadManager.ImageExists(ctx, imageInfo.Image) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400403 logger.Debugw(ctx, "start image download", log.Fields{"image-description": imageInfo.Image})
mpagenko15ff4a52021-03-02 10:09:20 +0000404 // Download_image is not supposed to be blocking, anyway let's call the DownloadManager still synchronously to detect 'fast' problems
405 // the download itself is later done in background
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 if err := oo.pDownloadManager.StartDownload(ctx, imageInfo.Image); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400407 return nil, err
408 }
409 return imageInfo.Image, nil
mpagenko15ff4a52021-03-02 10:09:20 +0000410 }
411 // image already exists
khenaidoo7d3c5582021-08-11 18:09:44 -0400412 logger.Debugw(ctx, "image already downloaded", log.Fields{"image-description": imageInfo.Image})
413 return imageInfo.Image, nil
mpagenkoc8bba412021-01-15 15:38:44 +0000414 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400415
416 return nil, errors.New("invalid image definition")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000417}
418
mpagenko59862f02021-10-11 08:53:18 +0000419//ActivateImageUpdate requests downloading some Onu Software image to the ONU via OMCI
Andrea Campanella71e546a2021-02-26 11:09:33 +0100420// according to indications as given in request and on success activate the image on the ONU
421//The ImageDownload needs to be called `request`due to library reflection requirements
khenaidoo7d3c5582021-08-11 18:09:44 -0400422func (oo *OpenONUAC) ActivateImageUpdate(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
423 if imageInfo != nil && imageInfo.Image != nil && imageInfo.Image.Name != "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000424 if oo.pDownloadManager.ImageLocallyDownloaded(ctx, imageInfo.Image) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400425 if handler := oo.getDeviceHandler(ctx, imageInfo.Device.Id, false); handler != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000426 logger.Debugw(ctx, "image download on omci requested", log.Fields{
khenaidoo7d3c5582021-08-11 18:09:44 -0400427 "image-description": imageInfo.Image, "device-id": imageInfo.Device.Id})
428 if err := handler.doOnuSwUpgrade(ctx, imageInfo.Image, oo.pDownloadManager); err != nil {
429 return nil, err
430 }
431 return imageInfo.Image, nil
mpagenko15ff4a52021-03-02 10:09:20 +0000432 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400433 logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": imageInfo.Device.Id})
434 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found - device-id: %s", imageInfo.Device.Id))
mpagenko057889c2021-01-21 16:51:58 +0000435 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400436 logger.Debugw(ctx, "image not yet downloaded on activate request", log.Fields{"image-description": imageInfo.Image})
437 return nil, fmt.Errorf(fmt.Sprintf("image-not-yet-downloaded - device-id: %s", imageInfo.Device.Id))
mpagenkoc8bba412021-01-15 15:38:44 +0000438 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400439 return nil, errors.New("invalid image definition")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000440}
441
khenaidoo7d3c5582021-08-11 18:09:44 -0400442//GetSingleValue handles the core request to retrieve uni status
443func (oo *OpenONUAC) GetSingleValue(ctx context.Context, request *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
kesavandfdf77632021-01-26 23:40:33 -0500444 logger.Infow(ctx, "Single_get_value_request", log.Fields{"request": request})
445
446 if handler := oo.getDeviceHandler(ctx, request.TargetId, false); handler != nil {
447 switch reqType := request.GetRequest().GetRequest().(type) {
448 case *extension.GetValueRequest_UniInfo:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 return handler.GetUniPortStatus(ctx, reqType.UniInfo), nil
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700450 case *extension.GetValueRequest_OnuOpticalInfo:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 CommChan := make(chan cmn.Message)
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700452 respChan := make(chan extension.SingleGetValueResponse)
453 // Initiate the self test request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000454 if err := handler.pSelfTestHdlr.SelfTestRequestStart(ctx, *request, CommChan, respChan); err != nil {
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700455 return &extension.SingleGetValueResponse{
456 Response: &extension.GetValueResponse{
457 Status: extension.GetValueResponse_ERROR,
458 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
459 },
460 }, err
461 }
462 // The timeout handling is already implemented in omci_self_test_handler module
463 resp := <-respChan
464 return &resp, nil
Himani Chawla43f95ff2021-06-03 00:24:12 +0530465 case *extension.GetValueRequest_OnuInfo:
466 return handler.getOnuOMCICounters(ctx, reqType.OnuInfo), nil
kesavandfdf77632021-01-26 23:40:33 -0500467 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_UNSUPPORTED), nil
kesavandfdf77632021-01-26 23:40:33 -0500469
470 }
471 }
472 logger.Errorw(ctx, "Single_get_value_request failed ", log.Fields{"request": request})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000473 return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_INVALID_DEVICE_ID), nil
mpagenkoc8bba412021-01-15 15:38:44 +0000474}
475
mpagenko83144272021-04-27 10:06:22 +0000476//if update >= 4.3.0
mpagenkoc26d4c02021-05-06 14:27:57 +0000477// Note: already with the implementation of the 'old' download interface problems were detected when the argument name used here is not the same
478// as defined in the adapter interface file. That sounds strange and the effects were strange as well.
479// The reason for that was never finally investigated.
480// To be on the safe side argument names are left here always as defined in iAdapter.go .
mpagenko83144272021-04-27 10:06:22 +0000481
khenaidoo7d3c5582021-08-11 18:09:44 -0400482// DownloadOnuImage downloads (and optionally activates and commits) the indicated ONU image to the requested ONU(s)
mpagenko83144272021-04-27 10:06:22 +0000483// if the image is not yet present on the adapter it has to be automatically downloaded
khenaidoo7d3c5582021-08-11 18:09:44 -0400484func (oo *OpenONUAC) DownloadOnuImage(ctx context.Context, request *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000485 if request != nil && len((*request).DeviceId) > 0 && (*request).Image.Version != "" {
486 loResponse := voltha.DeviceImageResponse{}
487 imageIdentifier := (*request).Image.Version
mpagenko38662d02021-08-11 09:45:19 +0000488 downloadedToAdapter := false
mpagenkoc26d4c02021-05-06 14:27:57 +0000489 firstDevice := true
490 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000491 var onuVolthaDevice *voltha.Device
492 var devErr error
mpagenkoc26d4c02021-05-06 14:27:57 +0000493 for _, pCommonID := range (*request).DeviceId {
mpagenko38662d02021-08-11 09:45:19 +0000494 vendorIDMatch := true
mpagenkoc26d4c02021-05-06 14:27:57 +0000495 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000496 loDeviceImageState := voltha.DeviceImageState{}
497 loDeviceImageState.DeviceId = loDeviceID
498 loImageState := voltha.ImageState{}
499 loDeviceImageState.ImageState = &loImageState
500 loDeviceImageState.ImageState.Version = (*request).Image.Version
mpagenko38662d02021-08-11 09:45:19 +0000501
mpagenko59862f02021-10-11 08:53:18 +0000502 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400503 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000504 if handler != nil {
505 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
506 } else {
507 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
508 devErr = errors.New("no handler found for device-id")
khenaidoo7d3c5582021-08-11 18:09:44 -0400509 }
mpagenko59862f02021-10-11 08:53:18 +0000510 if devErr != nil || onuVolthaDevice == nil {
511 logger.Warnw(ctx, "Failed to fetch ONU device for image download",
512 log.Fields{"device-id": loDeviceID, "err": devErr})
mpagenko38662d02021-08-11 09:45:19 +0000513 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
514 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //proto restriction, better option: 'INVALID_DEVICE'
mpagenkoc26d4c02021-05-06 14:27:57 +0000515 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000516 } else {
mpagenko38662d02021-08-11 09:45:19 +0000517 if firstDevice {
518 //start/verify download of the image to the adapter based on first found device only
519 // use the OnuVendor identification from first given device
520 firstDevice = false
521 vendorID = onuVolthaDevice.VendorId
522 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
523 logger.Debugw(ctx, "download request for file", log.Fields{"image-id": imageIdentifier})
524
525 if !oo.pFileManager.ImageExists(ctx, imageIdentifier) {
526 logger.Debugw(ctx, "start image download", log.Fields{"image-description": request})
527 // Download_image is not supposed to be blocking, anyway let's call the DownloadManager still synchronously to detect 'fast' problems
528 // the download itself is later done in background
529 if err := oo.pFileManager.StartDownload(ctx, imageIdentifier, (*request).Image.Url); err == nil {
530 downloadedToAdapter = true
531 }
532 //else: treat any error here as 'INVALID_URL' (even though it might as well be some issue on local FS, eg. 'INSUFFICIENT_SPACE')
533 // otherwise a more sophisticated error evaluation is needed
534 } else {
535 // image already exists
536 downloadedToAdapter = true
537 logger.Debugw(ctx, "image already downloaded", log.Fields{"image-description": imageIdentifier})
538 // note: If the image (with vendorId+name) has already been downloaded before from some other
539 // valid URL, the current URL is just ignored. If the operators want to ensure that the new URL
540 // is really used, then they first have to use the 'abort' API to remove the existing image!
541 // (abort API can be used also after some successful download to just remove the image from adapter)
542 }
543 } else {
544 //for all following devices verify the matching vendorID
545 if onuVolthaDevice.VendorId != vendorID {
546 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
547 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
548 vendorIDMatch = false
549 }
550 }
551 if downloadedToAdapter && vendorIDMatch {
552 // start the ONU download activity for each possible device
mpagenko59862f02021-10-11 08:53:18 +0000553 logger.Debugw(ctx, "image download on omci requested", log.Fields{
554 "image-id": imageIdentifier, "device-id": loDeviceID})
555 //onu upgrade handling called in background without immediate error evaluation here
556 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
557 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
558 go handler.onuSwUpgradeAfterDownload(ctx, request, oo.pFileManager, imageIdentifier)
559 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_STARTED
560 loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
561 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +0000562 } else {
563 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
564 if !downloadedToAdapter {
565 loDeviceImageState.ImageState.Reason = voltha.ImageState_INVALID_URL
566 } else { //only logical option is !vendorIDMatch
567 loDeviceImageState.ImageState.Reason = voltha.ImageState_VENDOR_DEVICE_MISMATCH
568 }
569 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
570 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000571 }
mpagenko2f2f2362021-06-07 08:25:22 +0000572 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000573 } //for all requested devices
mpagenkoc26d4c02021-05-06 14:27:57 +0000574 pImageResp := &loResponse
575 return pImageResp, nil
576 }
577 return nil, errors.New("invalid image download parameters")
mpagenko83144272021-04-27 10:06:22 +0000578}
579
khenaidoo7d3c5582021-08-11 18:09:44 -0400580// GetOnuImageStatus delivers the adapter-related information about the download/activation/commitment
mpagenko83144272021-04-27 10:06:22 +0000581// status for the requested image
khenaidoo7d3c5582021-08-11 18:09:44 -0400582func (oo *OpenONUAC) GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000583 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
584 loResponse := voltha.DeviceImageResponse{}
mpagenkoaa3afe92021-05-21 16:20:58 +0000585 imageIdentifier := (*in).Version
mpagenko38662d02021-08-11 09:45:19 +0000586 var vendorIDSet bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000587 firstDevice := true
588 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000589 var onuVolthaDevice *voltha.Device
590 var devErr error
mpagenkoaa3afe92021-05-21 16:20:58 +0000591 for _, pCommonID := range (*in).DeviceId {
592 loDeviceID := (*pCommonID).Id
khenaidoo7d3c5582021-08-11 18:09:44 -0400593 pDeviceImageState := &voltha.DeviceImageState{DeviceId: loDeviceID}
mpagenko59862f02021-10-11 08:53:18 +0000594 vendorIDSet = false
595 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400596 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000597 if handler != nil {
598 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
599 } else {
600 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
601 devErr = errors.New("no handler found for device-id")
mpagenko38662d02021-08-11 09:45:19 +0000602 }
mpagenko59862f02021-10-11 08:53:18 +0000603 if devErr != nil || onuVolthaDevice == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +0000604 logger.Warnw(ctx, "Failed to fetch Onu device to get image status",
mpagenko59862f02021-10-11 08:53:18 +0000605 log.Fields{"device-id": loDeviceID, "err": devErr})
mpagenko38662d02021-08-11 09:45:19 +0000606 pImageState := &voltha.ImageState{
607 Version: (*in).Version,
608 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN, //no statement about last activity possible
609 Reason: voltha.ImageState_UNKNOWN_ERROR, //something like "DEVICE_NOT_EXISTS" would be better (proto def)
610 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
mpagenkoaa3afe92021-05-21 16:20:58 +0000611 }
mpagenko38662d02021-08-11 09:45:19 +0000612 pDeviceImageState.ImageState = pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +0000613 } else {
mpagenko38662d02021-08-11 09:45:19 +0000614 if firstDevice {
615 //start/verify download of the image to the adapter based on first found device only
616 // use the OnuVendor identification from first given device
617 firstDevice = false
618 vendorID = onuVolthaDevice.VendorId
619 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
620 vendorIDSet = true
621 logger.Debugw(ctx, "status request for image", log.Fields{"image-id": imageIdentifier})
622 } else {
623 //for all following devices verify the matching vendorID
624 if onuVolthaDevice.VendorId != vendorID {
625 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
626 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
627 } else {
628 vendorIDSet = true
629 }
630 }
631 if !vendorIDSet {
632 pImageState := &voltha.ImageState{
633 Version: (*in).Version,
634 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN, //can't be sure that download for this device was really tried
635 Reason: voltha.ImageState_VENDOR_DEVICE_MISMATCH,
636 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
637 }
638 pDeviceImageState.ImageState = pImageState
639 } else {
khenaidoo7d3c5582021-08-11 18:09:44 -0400640 logger.Debugw(ctx, "image status request for", log.Fields{
641 "image-id": imageIdentifier, "device-id": loDeviceID})
642 //status request is called synchronously to collect the indications for all concerned devices
643 pDeviceImageState.ImageState = handler.requestOnuSwUpgradeState(ctx, imageIdentifier, (*in).Version)
mpagenko38662d02021-08-11 09:45:19 +0000644 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000645 }
646 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000647 } //for all requested devices
mpagenkoaa3afe92021-05-21 16:20:58 +0000648 pImageResp := &loResponse
649 return pImageResp, nil
650 }
651 return nil, errors.New("invalid image status request parameters")
mpagenko83144272021-04-27 10:06:22 +0000652}
653
khenaidoo7d3c5582021-08-11 18:09:44 -0400654// AbortOnuImageUpgrade stops the actual download/activation/commitment process (on next possibly step)
655func (oo *OpenONUAC) AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000656 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
657 loResponse := voltha.DeviceImageResponse{}
658 imageIdentifier := (*in).Version
659 firstDevice := true
660 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000661 var vendorIDSet bool
662 var onuVolthaDevice *voltha.Device
663 var devErr error
mpagenkoaa3afe92021-05-21 16:20:58 +0000664 for _, pCommonID := range (*in).DeviceId {
665 loDeviceID := (*pCommonID).Id
khenaidoo7d3c5582021-08-11 18:09:44 -0400666 pDeviceImageState := &voltha.DeviceImageState{}
667 loImageState := voltha.ImageState{}
668 pDeviceImageState.ImageState = &loImageState
mpagenko59862f02021-10-11 08:53:18 +0000669 vendorIDSet = false
670 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400671 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000672 if handler != nil {
673 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
674 } else {
675 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
676 devErr = errors.New("no handler found for device-id")
677 }
678 if devErr != nil || onuVolthaDevice == nil {
679 logger.Warnw(ctx, "Failed to fetch Onu device to abort its download",
680 log.Fields{"device-id": loDeviceID, "err": devErr})
khenaidoo7d3c5582021-08-11 18:09:44 -0400681 pDeviceImageState.DeviceId = loDeviceID
682 pDeviceImageState.ImageState.Version = (*in).Version
mpagenko59862f02021-10-11 08:53:18 +0000683 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
684 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST //something better could be considered (MissingHandler) - proto
khenaidoo7d3c5582021-08-11 18:09:44 -0400685 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenkoaa3afe92021-05-21 16:20:58 +0000686 } else {
mpagenko59862f02021-10-11 08:53:18 +0000687 if firstDevice {
688 //start/verify download of the image to the adapter based on first found device only
689 // use the OnuVendor identification from first given device
690 firstDevice = false
691 vendorID = onuVolthaDevice.VendorId
692 vendorIDSet = true
693 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
694 logger.Debugw(ctx, "abort request for file", log.Fields{"image-id": imageIdentifier})
695 } else {
696 //for all following devices verify the matching vendorID
697 if onuVolthaDevice.VendorId != vendorID {
698 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
699 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
700 pDeviceImageState.DeviceId = loDeviceID
701 pDeviceImageState.ImageState.Version = (*in).Version
702 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
703 pDeviceImageState.ImageState.Reason = voltha.ImageState_VENDOR_DEVICE_MISMATCH
704 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
705 } else {
706 vendorIDSet = true
707 }
708 }
709 if vendorIDSet {
710 // cancel the ONU upgrade activity for each possible device
711 logger.Debugw(ctx, "image upgrade abort requested", log.Fields{
712 "image-id": imageIdentifier, "device-id": loDeviceID})
713 //upgrade cancel is called synchronously to collect the imageResponse indications for all concerned devices
714 handler.cancelOnuSwUpgrade(ctx, imageIdentifier, (*in).Version, pDeviceImageState)
mpagenkoaa3afe92021-05-21 16:20:58 +0000715 }
716 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000717 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000718 } //for all requested devices
mpagenkoaa3afe92021-05-21 16:20:58 +0000719 if !firstDevice {
720 //if at least one valid device was found cancel also a possibly running download to adapter and remove the image
721 // this is to be done after the upgradeOnu cancel activities in order to not subduct the file for still running processes
722 oo.pFileManager.CancelDownload(ctx, imageIdentifier)
723 }
724 pImageResp := &loResponse
725 return pImageResp, nil
726 }
727 return nil, errors.New("invalid image upgrade abort parameters")
mpagenko83144272021-04-27 10:06:22 +0000728}
729
khenaidoo7d3c5582021-08-11 18:09:44 -0400730// GetOnuImages retrieves the ONU SW image status information via OMCI
731func (oo *OpenONUAC) GetOnuImages(ctx context.Context, id *common.ID) (*voltha.OnuImages, error) {
732 logger.Infow(ctx, "Get_onu_images", log.Fields{"device-id": id.Id})
733 if handler := oo.getDeviceHandler(ctx, id.Id, false); handler != nil {
Himani Chawla69992ab2021-07-08 15:13:02 +0530734 images, err := handler.getOnuImages(ctx)
735 if err == nil {
Holger Hildebrandtfb402a62021-05-26 14:40:49 +0000736 return images, nil
737 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400738 return nil, fmt.Errorf(fmt.Sprintf("%s-%s", err, id.Id))
Holger Hildebrandtfb402a62021-05-26 14:40:49 +0000739 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400740 logger.Warnw(ctx, "no handler found for Get_onu_images", log.Fields{"device-id": id.Id})
741 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", id.Id))
mpagenko83144272021-04-27 10:06:22 +0000742}
743
khenaidoo7d3c5582021-08-11 18:09:44 -0400744// ActivateOnuImage initiates the activation of the image for the requested ONU(s)
mpagenkoc26d4c02021-05-06 14:27:57 +0000745// precondition: image downloaded and not yet activated or image refers to current inactive image
khenaidoo7d3c5582021-08-11 18:09:44 -0400746func (oo *OpenONUAC) ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000747 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
748 loResponse := voltha.DeviceImageResponse{}
749 imageIdentifier := (*in).Version
750 //let the deviceHandler find the adequate way of requesting the image activation
751 for _, pCommonID := range (*in).DeviceId {
752 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000753 loDeviceImageState := voltha.DeviceImageState{}
754 loDeviceImageState.DeviceId = loDeviceID
755 loImageState := voltha.ImageState{}
756 loDeviceImageState.ImageState = &loImageState
757 loDeviceImageState.ImageState.Version = imageIdentifier
mpagenkoc26d4c02021-05-06 14:27:57 +0000758 //compared to download procedure the vendorID (from device) is secondary here
759 // and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
760 // start image activation activity for each possible device
761 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
762 if handler := oo.getDeviceHandler(ctx, loDeviceID, false); handler != nil {
763 logger.Debugw(ctx, "onu image activation requested", log.Fields{
764 "image-id": imageIdentifier, "device-id": loDeviceID})
765 //onu activation handling called in background without immediate error evaluation here
766 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
767 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
mpagenko183647c2021-06-08 15:25:04 +0000768 if pImageStates, err := handler.onuSwActivateRequest(ctx, imageIdentifier, (*in).CommitOnSuccess); err != nil {
769 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
770 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
771 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
772 } else {
773 loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
774 loDeviceImageState.ImageState.Reason = pImageStates.Reason
775 loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
776 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000777 } else {
778 //cannot start SW activation for requested device
779 logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": loDeviceID})
mpagenko183647c2021-06-08 15:25:04 +0000780 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000781 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
782 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
mpagenkoc26d4c02021-05-06 14:27:57 +0000783 }
mpagenko2f2f2362021-06-07 08:25:22 +0000784 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenkoc26d4c02021-05-06 14:27:57 +0000785 }
786 pImageResp := &loResponse
787 return pImageResp, nil
788 }
789 return nil, errors.New("invalid image activation parameters")
mpagenko83144272021-04-27 10:06:22 +0000790}
791
khenaidoo7d3c5582021-08-11 18:09:44 -0400792// CommitOnuImage enforces the commitment of the image for the requested ONU(s)
mpagenko83144272021-04-27 10:06:22 +0000793// precondition: image activated and not yet committed
khenaidoo7d3c5582021-08-11 18:09:44 -0400794func (oo *OpenONUAC) CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000795 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
796 loResponse := voltha.DeviceImageResponse{}
797 imageIdentifier := (*in).Version
798 //let the deviceHandler find the adequate way of requesting the image activation
799 for _, pCommonID := range (*in).DeviceId {
800 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000801 loDeviceImageState := voltha.DeviceImageState{}
802 loDeviceImageState.DeviceId = loDeviceID
803 loImageState := voltha.ImageState{}
804 loDeviceImageState.ImageState = &loImageState
805 loDeviceImageState.ImageState.Version = imageIdentifier
mpagenkoc26d4c02021-05-06 14:27:57 +0000806 //compared to download procedure the vendorID (from device) is secondary here
807 // and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
808 // start image activation activity for each possible device
809 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
810 if handler := oo.getDeviceHandler(ctx, loDeviceID, false); handler != nil {
811 logger.Debugw(ctx, "onu image commitment requested", log.Fields{
812 "image-id": imageIdentifier, "device-id": loDeviceID})
813 //onu commitment handling called in background without immediate error evaluation here
814 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
815 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
mpagenko183647c2021-06-08 15:25:04 +0000816 if pImageStates, err := handler.onuSwCommitRequest(ctx, imageIdentifier); err != nil {
mpagenko38662d02021-08-11 09:45:19 +0000817 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
818 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //can be multiple reasons here
mpagenko183647c2021-06-08 15:25:04 +0000819 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
820 } else {
821 loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
822 loDeviceImageState.ImageState.Reason = pImageStates.Reason
823 loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
824 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000825 } else {
826 //cannot start SW commitment for requested device
827 logger.Warnw(ctx, "no handler found for image commitment", log.Fields{"device-id": loDeviceID})
mpagenko183647c2021-06-08 15:25:04 +0000828 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000829 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
830 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
mpagenkoc26d4c02021-05-06 14:27:57 +0000831 }
mpagenko2f2f2362021-06-07 08:25:22 +0000832 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenkoc26d4c02021-05-06 14:27:57 +0000833 }
834 pImageResp := &loResponse
835 return pImageResp, nil
836 }
837 return nil, errors.New("invalid image commitment parameters")
mpagenko83144272021-04-27 10:06:22 +0000838}
839
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000840// Adapter interface required methods ################ end #########
841// #################################################################
khenaidoo7d3c5582021-08-11 18:09:44 -0400842
843/*
844 *
845 * ONU inter adapter service
846 *
847 */
848
849// OnuIndication is part of the ONU Inter-adapter service API.
850func (oo *OpenONUAC) OnuIndication(ctx context.Context, onuInd *ic.OnuIndicationMessage) (*empty.Empty, error) {
851 logger.Debugw(ctx, "onu-indication", log.Fields{"onu-indication": onuInd})
852
853 if onuInd == nil || onuInd.OnuIndication == nil {
854 return nil, fmt.Errorf("invalid-onu-indication-%v", onuInd)
855 }
856
857 onuIndication := onuInd.OnuIndication
858 onuOperstate := onuIndication.GetOperState()
859 waitForDhInstPresent := false
860 if onuOperstate == "up" {
861 //Race condition (relevant in BBSIM-environment only): Due to unsynchronized processing of olt-adapter and rw_core,
862 //ONU_IND_REQUEST msg by olt-adapter could arrive a little bit earlier than rw_core was able to announce the corresponding
863 //ONU by RPC of Adopt_device(). Therefore it could be necessary to wait with processing of ONU_IND_REQUEST until call of
864 //Adopt_device() arrived and DeviceHandler instance was created
865 waitForDhInstPresent = true
866 }
867 if handler := oo.getDeviceHandler(ctx, onuInd.DeviceId, waitForDhInstPresent); handler != nil {
868 logger.Infow(ctx, "onu-ind-request", log.Fields{"device-id": onuInd.DeviceId,
869 "OnuId": onuIndication.GetOnuId(),
870 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
871 "SNR": onuIndication.GetSerialNumber()})
872
873 if onuOperstate == "up" {
874 if err := handler.createInterface(ctx, onuIndication); err != nil {
875 return nil, err
876 }
877 return &empty.Empty{}, nil
878 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
879 return nil, handler.updateInterface(ctx, onuIndication)
880 } else {
881 logger.Errorw(ctx, "unknown-onu-ind-request operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
882 return nil, fmt.Errorf("invalidOperState: %s, %s", onuOperstate, onuInd.DeviceId)
883 }
884 }
885 logger.Warnw(ctx, "no handler found for received onu-ind-request", log.Fields{
886 "msgToDeviceId": onuInd.DeviceId})
887 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", onuInd.DeviceId))
888}
889
890// OmciIndication is part of the ONU Inter-adapter service API.
891func (oo *OpenONUAC) OmciIndication(ctx context.Context, msg *ic.OmciMessage) (*empty.Empty, error) {
892 logger.Debugw(ctx, "omci-response", log.Fields{"parent-device-id": msg.ParentDeviceId, "child-device-id": msg.ChildDeviceId})
893
894 if handler := oo.getDeviceHandler(ctx, msg.ChildDeviceId, false); handler != nil {
895 if err := handler.handleOMCIIndication(log.WithSpanFromContext(context.Background(), ctx), msg); err != nil {
896 return nil, err
897 }
898 return &empty.Empty{}, nil
899 }
900 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", msg.ChildDeviceId))
901}
902
903// DownloadTechProfile is part of the ONU Inter-adapter service API.
904func (oo *OpenONUAC) DownloadTechProfile(ctx context.Context, tProfile *ic.TechProfileDownloadMessage) (*empty.Empty, error) {
905 logger.Debugw(ctx, "download-tech-profile", log.Fields{"uni-id": tProfile.UniId})
906
907 if handler := oo.getDeviceHandler(ctx, tProfile.DeviceId, false); handler != nil {
908 if err := handler.handleTechProfileDownloadRequest(log.WithSpanFromContext(context.Background(), ctx), tProfile); err != nil {
909 return nil, err
910 }
911 return &empty.Empty{}, nil
912 }
913 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", tProfile.DeviceId))
914}
915
916// DeleteGemPort is part of the ONU Inter-adapter service API.
917func (oo *OpenONUAC) DeleteGemPort(ctx context.Context, gPort *ic.DeleteGemPortMessage) (*empty.Empty, error) {
918 logger.Debugw(ctx, "delete-gem-port", log.Fields{"device-id": gPort.DeviceId, "uni-id": gPort.UniId})
919
920 if handler := oo.getDeviceHandler(ctx, gPort.DeviceId, false); handler != nil {
921 if err := handler.handleDeleteGemPortRequest(log.WithSpanFromContext(context.Background(), ctx), gPort); err != nil {
922 return nil, err
923 }
924 return &empty.Empty{}, nil
925 }
926 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", gPort.DeviceId))
927}
928
929// DeleteTCont is part of the ONU Inter-adapter service API.
930func (oo *OpenONUAC) DeleteTCont(ctx context.Context, tConf *ic.DeleteTcontMessage) (*empty.Empty, error) {
931 logger.Debugw(ctx, "delete-tcont", log.Fields{"tconf": tConf})
932
933 if handler := oo.getDeviceHandler(ctx, tConf.DeviceId, false); handler != nil {
934 if err := handler.handleDeleteTcontRequest(log.WithSpanFromContext(context.Background(), ctx), tConf); err != nil {
935 return nil, err
936 }
937 return &empty.Empty{}, nil
938 }
939 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", tConf.DeviceId))
940}
941
942/*
943 * Parent GRPC clients
944 */
945
946func (oo *OpenONUAC) setupParentInterAdapterClient(ctx context.Context, endpoint string) error {
947 logger.Infow(ctx, "setting-parent-adapter-connection", log.Fields{"parent-endpoint": endpoint})
948 oo.lockParentAdapterClients.Lock()
949 defer oo.lockParentAdapterClients.Unlock()
950 if _, ok := oo.parentAdapterClients[endpoint]; ok {
951 return nil
952 }
953
954 childClient, err := vgrpc.NewClient(endpoint,
955 oo.oltAdapterRestarted,
956 vgrpc.ActivityCheck(true))
957
958 if err != nil {
959 return err
960 }
961
962 oo.parentAdapterClients[endpoint] = childClient
963
964 go oo.parentAdapterClients[endpoint].Start(log.WithSpanFromContext(context.TODO(), ctx), setAndTestAdapterServiceHandler)
965
966 // Wait until we have a connection to the child adapter.
967 // Unlimited retries or until context expires
968 subCtx := log.WithSpanFromContext(context.TODO(), ctx)
969 backoff := vgrpc.NewBackoff(oo.config.MinBackoffRetryDelay, oo.config.MaxBackoffRetryDelay, 0)
970 for {
971 client, err := oo.parentAdapterClients[endpoint].GetOltInterAdapterServiceClient()
972 if err == nil && client != nil {
973 logger.Infow(subCtx, "connected-to-parent-adapter", log.Fields{"parent-endpoint": endpoint})
974 break
975 }
976 logger.Warnw(subCtx, "connection-to-parent-adapter-not-ready", log.Fields{"error": err, "parent-endpoint": endpoint})
977 // Backoff
978 if err = backoff.Backoff(subCtx); err != nil {
979 logger.Errorw(subCtx, "received-error-on-backoff", log.Fields{"error": err, "parent-endpoint": endpoint})
980 break
981 }
982 }
983 return nil
984}
985
986func (oo *OpenONUAC) getParentAdapterServiceClient(endpoint string) (adapter_services.OltInterAdapterServiceClient, error) {
987 // First check from cache
988 oo.lockParentAdapterClients.RLock()
989 if pgClient, ok := oo.parentAdapterClients[endpoint]; ok {
990 oo.lockParentAdapterClients.RUnlock()
991 return pgClient.GetOltInterAdapterServiceClient()
992 }
993 oo.lockParentAdapterClients.RUnlock()
994
995 // Set the parent connection - can occur on restarts
996 ctx, cancel := context.WithTimeout(context.Background(), oo.config.RPCTimeout)
997 err := oo.setupParentInterAdapterClient(ctx, endpoint)
998 cancel()
999 if err != nil {
1000 return nil, err
1001 }
1002
1003 // Get the parent client now
1004 oo.lockParentAdapterClients.RLock()
1005 defer oo.lockParentAdapterClients.RUnlock()
1006 if pgClient, ok := oo.parentAdapterClients[endpoint]; ok {
1007 return pgClient.GetOltInterAdapterServiceClient()
1008 }
1009
1010 return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
1011}
1012
1013// TODO: Any action the adapter needs to do following an olt adapter restart?
1014func (oo *OpenONUAC) oltAdapterRestarted(ctx context.Context, endPoint string) error {
1015 logger.Errorw(ctx, "olt-adapter-restarted", log.Fields{"endpoint": endPoint})
1016 return nil
1017}
1018
1019// setAndTestAdapterServiceHandler is used to test whether the remote gRPC service is up
1020func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
1021 svc := adapter_services.NewOltInterAdapterServiceClient(conn)
1022 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != voltha.HealthStatus_HEALTHY {
1023 return nil
1024 }
1025 return svc
1026}
1027
1028/*
1029 *
1030 * Unimplemented APIs
1031 *
1032 */
1033
1034//GetOfpDeviceInfo returns OFP information for the given device. Method not implemented as per [VOL-3202].
1035// OF port info is now to be delivered within UniPort create cmp changes in onu_uni_port.go::CreateVolthaPort()
1036//
1037func (oo *OpenONUAC) GetOfpDeviceInfo(ctx context.Context, device *voltha.Device) (*ic.SwitchCapability, error) {
1038 return nil, errors.New("unImplemented")
1039}
1040
1041//SimulateAlarm is unimplemented
1042func (oo *OpenONUAC) SimulateAlarm(context.Context, *ic.SimulateAlarmMessage) (*common.OperationResp, error) {
1043 return nil, errors.New("unImplemented")
1044}
1045
1046//SetExtValue is unimplemented
1047func (oo *OpenONUAC) SetExtValue(context.Context, *ic.SetExtValueMessage) (*empty.Empty, error) {
1048 return nil, errors.New("unImplemented")
1049}
1050
1051//SetSingleValue is unimplemented
1052func (oo *OpenONUAC) SetSingleValue(context.Context, *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error) {
1053 return nil, errors.New("unImplemented")
1054}
1055
1056//StartOmciTest not implemented
1057func (oo *OpenONUAC) StartOmciTest(ctx context.Context, test *ic.OMCITest) (*voltha.TestResponse, error) {
1058 return nil, errors.New("unImplemented")
1059}
1060
1061//SuppressEvent unimplemented
1062func (oo *OpenONUAC) SuppressEvent(ctx context.Context, filter *voltha.EventFilter) (*empty.Empty, error) {
1063 return nil, errors.New("unImplemented")
1064}
1065
1066//UnSuppressEvent unimplemented
1067func (oo *OpenONUAC) UnSuppressEvent(ctx context.Context, filter *voltha.EventFilter) (*empty.Empty, error) {
1068 return nil, errors.New("unImplemented")
1069}
1070
1071//GetImageDownloadStatus is unimplemented
1072func (oo *OpenONUAC) GetImageDownloadStatus(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1073 return nil, errors.New("unImplemented")
1074}
1075
1076//CancelImageDownload is unimplemented
1077func (oo *OpenONUAC) CancelImageDownload(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1078 return nil, errors.New("unImplemented")
1079}
1080
1081//RevertImageUpdate is unimplemented
1082func (oo *OpenONUAC) RevertImageUpdate(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1083 return nil, errors.New("unImplemented")
1084}
1085
1086// UpdateFlowsBulk is unimplemented
1087func (oo *OpenONUAC) UpdateFlowsBulk(ctx context.Context, flows *ic.BulkFlows) (*empty.Empty, error) {
1088 return nil, errors.New("unImplemented")
1089}
1090
1091//SelfTestDevice unimplented
1092func (oo *OpenONUAC) SelfTestDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
1093 return nil, errors.New("unImplemented")
1094}
1095
1096//SendPacketOut sends packet out to the device
1097func (oo *OpenONUAC) SendPacketOut(ctx context.Context, packet *ic.PacketOut) (*empty.Empty, error) {
1098 return nil, errors.New("unImplemented")
1099}
1100
1101// EnablePort to Enable PON/NNI interface - seems not to be used/required according to python code
1102func (oo *OpenONUAC) EnablePort(ctx context.Context, port *voltha.Port) (*empty.Empty, error) {
1103 return nil, errors.New("unImplemented")
1104}
1105
1106// DisablePort to Disable pon/nni interface - seems not to be used/required according to python code
1107func (oo *OpenONUAC) DisablePort(ctx context.Context, port *voltha.Port) (*empty.Empty, error) {
1108 return nil, errors.New("unImplemented")
1109}
1110
1111// GetExtValue - unimplemented
1112func (oo *OpenONUAC) GetExtValue(ctx context.Context, extInfo *ic.GetExtValueMessage) (*voltha.ReturnValues, error) {
1113 return nil, errors.New("unImplemented")
1114}
1115
1116// ChildDeviceLost - unimplemented
1117func (oo *OpenONUAC) ChildDeviceLost(ctx context.Context, childDevice *voltha.Device) (*empty.Empty, error) {
1118 return nil, errors.New("unImplemented")
1119}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120
1121// GetSupportedFsms - TODO: add comment
1122func (oo *OpenONUAC) GetSupportedFsms() *cmn.OmciDeviceFsms {
1123 return oo.pSupportedFsms
1124}
1125
1126// LockMutexMibTemplateGenerated - TODO: add comment
1127func (oo *OpenONUAC) LockMutexMibTemplateGenerated() {
1128 oo.mutexMibTemplateGenerated.Lock()
1129}
1130
1131// UnlockMutexMibTemplateGenerated - TODO: add comment
1132func (oo *OpenONUAC) UnlockMutexMibTemplateGenerated() {
1133 oo.mutexMibTemplateGenerated.Unlock()
1134}
1135
1136// GetMibTemplatesGenerated - TODO: add comment
1137func (oo *OpenONUAC) GetMibTemplatesGenerated(mibTemplatePath string) (value bool, exist bool) {
1138 value, exist = oo.mibTemplatesGenerated[mibTemplatePath]
1139 return value, exist
1140}
1141
1142// SetMibTemplatesGenerated - TODO: add comment
1143func (oo *OpenONUAC) SetMibTemplatesGenerated(mibTemplatePath string, value bool) {
1144 oo.mibTemplatesGenerated[mibTemplatePath] = value
1145}
1146
1147// RLockMutexDeviceHandlersMap - TODO: add comment
1148func (oo *OpenONUAC) RLockMutexDeviceHandlersMap() {
1149 oo.mutexDeviceHandlersMap.RLock()
1150}
1151
1152// RUnlockMutexDeviceHandlersMap - TODO: add comment
1153func (oo *OpenONUAC) RUnlockMutexDeviceHandlersMap() {
1154 oo.mutexDeviceHandlersMap.RUnlock()
1155}
1156
1157// GetDeviceHandler - TODO: add comment
1158func (oo *OpenONUAC) GetDeviceHandler(deviceID string) (value cmn.IdeviceHandler, exist bool) {
1159 value, exist = oo.deviceHandlers[deviceID]
1160 return value, exist
1161}