blob: f0d9eccf7dfc6f1d325093f7514d9e7da963d2b2 [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
Girish Gowdrae95687a2021-09-08 16:30:58 -070082 maxConcurrentFlowsPerUni int
Holger Hildebrandtfa074992020-03-27 15:42:06 +000083}
84
85//NewOpenONUAC returns a new instance of OpenONU_AC
khenaidoo7d3c5582021-08-11 18:09:44 -040086func NewOpenONUAC(ctx context.Context, coreClient *vgrpc.Client, eventProxy eventif.EventProxy,
87 kvClient kvstore.Client, cfg *config.AdapterFlags, cm *conf.ConfigManager) *OpenONUAC {
Holger Hildebrandtfa074992020-03-27 15:42:06 +000088 var openOnuAc OpenONUAC
89 openOnuAc.exitChannel = make(chan int, 1)
Himani Chawla6d2ae152020-09-02 13:11:20 +053090 openOnuAc.deviceHandlers = make(map[string]*deviceHandler)
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +000091 openOnuAc.deviceHandlersCreateChan = make(map[string]chan bool)
khenaidoo7d3c5582021-08-11 18:09:44 -040092 openOnuAc.parentAdapterClients = make(map[string]*vgrpc.Client)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000093 openOnuAc.mutexDeviceHandlersMap = sync.RWMutex{}
Holger Hildebrandtfa074992020-03-27 15:42:06 +000094 openOnuAc.config = cfg
Matteo Scandolof1f39a72020-11-24 12:08:11 -080095 openOnuAc.cm = cm
khenaidoo7d3c5582021-08-11 18:09:44 -040096 openOnuAc.coreClient = coreClient
Holger Hildebrandtfa074992020-03-27 15:42:06 +000097 openOnuAc.numOnus = cfg.OnuNumber
Holger Hildebrandtfa074992020-03-27 15:42:06 +000098 openOnuAc.eventProxy = eventProxy
mpagenkoaf801632020-07-03 10:00:42 +000099 openOnuAc.kvClient = kvClient
Matteo Scandolo127c59d2021-01-28 11:31:18 -0800100 openOnuAc.KVStoreAddress = cfg.KVStoreAddress
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000101 openOnuAc.KVStoreType = cfg.KVStoreType
mpagenkoaf801632020-07-03 10:00:42 +0000102 openOnuAc.KVStoreTimeout = cfg.KVStoreTimeout
Holger Hildebrandt61b24d02020-11-16 13:36:40 +0000103 openOnuAc.mibTemplatesGenerated = make(map[string]bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000104 openOnuAc.mutexMibTemplateGenerated = sync.RWMutex{}
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000105 openOnuAc.HeartbeatCheckInterval = cfg.HeartbeatCheckInterval
106 openOnuAc.HeartbeatFailReportInterval = cfg.HeartbeatFailReportInterval
mpagenkodff5dda2020-08-28 11:52:01 +0000107 openOnuAc.AcceptIncrementalEvto = cfg.AccIncrEvto
Himani Chawlad96df182020-09-28 11:12:02 +0530108 openOnuAc.maxTimeoutInterAdapterComm = cfg.MaxTimeoutInterAdapterComm
Holger Hildebrandt38985dc2021-02-18 16:25:20 +0000109 openOnuAc.maxTimeoutReconciling = cfg.MaxTimeoutReconciling
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000110 //openOnuAc.GrpcTimeoutInterval = cfg.GrpcTimeoutInterval
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000111 openOnuAc.MetricsEnabled = cfg.MetricsEnabled
Holger Hildebrandte3677f12021-02-05 14:50:56 +0000112 openOnuAc.mibAuditInterval = cfg.MibAuditInterval
Girish Gowdra0b235842021-03-09 13:06:46 -0800113 // since consumers of OMCI timeout value everywhere in code is in "int seconds", do this useful conversion
114 openOnuAc.omciTimeout = int(cfg.OmciTimeout.Seconds())
Himani Chawla075f1642021-03-15 19:23:24 +0530115 openOnuAc.alarmAuditInterval = cfg.AlarmAuditInterval
mpagenkoc26d4c02021-05-06 14:27:57 +0000116 openOnuAc.dlToOnuTimeout4M = cfg.DownloadToOnuTimeout4MB
khenaidoo7d3c5582021-08-11 18:09:44 -0400117 openOnuAc.rpcTimeout = cfg.RPCTimeout
Girish Gowdrae95687a2021-09-08 16:30:58 -0700118 openOnuAc.maxConcurrentFlowsPerUni = cfg.MaxConcurrentFlowsPerUni
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000120 openOnuAc.pSupportedFsms = &cmn.OmciDeviceFsms{
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000121 "mib-synchronizer": {
122 //mibSyncFsm, // Implements the MIB synchronization state machine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123 DatabaseClass: mibDbVolatileDictImpl, // Implements volatile ME MIB database
Himani Chawla4d908332020-08-31 12:30:20 +0530124 //true, // Advertise events on OpenOMCI event bus
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125 AuditInterval: openOnuAc.mibAuditInterval, // Time to wait between MIB audits. 0 to disable audits.
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000126 // map[string]func() error{
127 // "mib-upload": onuDeviceEntry.MibUploadTask,
128 // "mib-template": onuDeviceEntry.MibTemplateTask,
129 // "get-mds": onuDeviceEntry.GetMdsTask,
130 // "mib-audit": onuDeviceEntry.GetMdsTask,
131 // "mib-resync": onuDeviceEntry.MibResyncTask,
132 // "mib-reconcile": onuDeviceEntry.MibReconcileTask,
133 // },
134 },
135 }
136
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000137 openOnuAc.pDownloadManager = swupg.NewAdapterDownloadManager(ctx)
138 openOnuAc.pFileManager = swupg.NewFileDownloadManager(ctx)
mpagenkoc26d4c02021-05-06 14:27:57 +0000139 openOnuAc.pFileManager.SetDownloadTimeout(ctx, cfg.DownloadToAdapterTimeout)
mpagenkoc8bba412021-01-15 15:38:44 +0000140
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000141 return &openOnuAc
142}
143
144//Start starts (logs) the adapter
145func (oo *OpenONUAC) Start(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000146 logger.Info(ctx, "starting-openonu-adapter")
mpagenkoc8bba412021-01-15 15:38:44 +0000147
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000148 return nil
149}
150
Himani Chawla6d2ae152020-09-02 13:11:20 +0530151/*
152//stop terminates the session
153func (oo *OpenONUAC) stop(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000154 logger.Info(ctx,"stopping-device-manager")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000155 oo.exitChannel <- 1
dbainbri4d3a0dc2020-12-02 00:33:42 +0000156 logger.Info(ctx,"device-manager-stopped")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000157 return nil
158}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530159*/
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000160
Himani Chawla6d2ae152020-09-02 13:11:20 +0530161func (oo *OpenONUAC) addDeviceHandlerToMap(ctx context.Context, agent *deviceHandler) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000162 oo.mutexDeviceHandlersMap.Lock()
163 defer oo.mutexDeviceHandlersMap.Unlock()
164 if _, exist := oo.deviceHandlers[agent.DeviceID]; !exist {
165 oo.deviceHandlers[agent.DeviceID] = agent
166 oo.deviceHandlers[agent.DeviceID].start(ctx)
167 if _, exist := oo.deviceHandlersCreateChan[agent.DeviceID]; exist {
168 logger.Debugw(ctx, "deviceHandler created - trigger processing of pending ONU_IND_REQUEST", log.Fields{"device-id": agent.DeviceID})
169 oo.deviceHandlersCreateChan[agent.DeviceID] <- true
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000170 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000171 }
172}
173
Himani Chawla6d2ae152020-09-02 13:11:20 +0530174func (oo *OpenONUAC) deleteDeviceHandlerToMap(agent *deviceHandler) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000175 oo.mutexDeviceHandlersMap.Lock()
176 defer oo.mutexDeviceHandlersMap.Unlock()
177 delete(oo.deviceHandlers, agent.DeviceID)
178 delete(oo.deviceHandlersCreateChan, agent.DeviceID)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000179}
180
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000181//getDeviceHandler gets the ONU deviceHandler and may wait until it is created
dbainbri4d3a0dc2020-12-02 00:33:42 +0000182func (oo *OpenONUAC) getDeviceHandler(ctx context.Context, deviceID string, aWait bool) *deviceHandler {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000183 oo.mutexDeviceHandlersMap.Lock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000184 agent, ok := oo.deviceHandlers[deviceID]
185 if aWait && !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000186 logger.Infow(ctx, "Race condition: deviceHandler not present - wait for creation or timeout",
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000187 log.Fields{"device-id": deviceID})
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000188 if _, exist := oo.deviceHandlersCreateChan[deviceID]; !exist {
189 oo.deviceHandlersCreateChan[deviceID] = make(chan bool, 1)
190 }
Girish Gowdra7407a4d2020-11-12 12:44:53 -0800191 deviceCreateChan := oo.deviceHandlersCreateChan[deviceID]
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000192 //keep the read sema short to allow for subsequent write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000193 oo.mutexDeviceHandlersMap.Unlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000194 // based on concurrent processing the deviceHandler creation may not yet be finished at his point
195 // so it might be needed to wait here for that event with some timeout
196 select {
197 case <-time.After(1 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000198 logger.Warnw(ctx, "No valid deviceHandler created after max WaitTime", log.Fields{"device-id": deviceID})
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000199 return nil
Girish Gowdra7407a4d2020-11-12 12:44:53 -0800200 case <-deviceCreateChan:
dbainbri4d3a0dc2020-12-02 00:33:42 +0000201 logger.Debugw(ctx, "deviceHandler is ready now - continue", log.Fields{"device-id": deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000202 oo.mutexDeviceHandlersMap.RLock()
203 defer oo.mutexDeviceHandlersMap.RUnlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000204 return oo.deviceHandlers[deviceID]
205 }
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000206 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000207 oo.mutexDeviceHandlersMap.Unlock()
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000208 return agent
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000209}
210
khenaidoo7d3c5582021-08-11 18:09:44 -0400211// GetHealthStatus is used as a service readiness validation as a grpc connection
212func (oo *OpenONUAC) GetHealthStatus(ctx context.Context, empty *empty.Empty) (*voltha.HealthStatus, error) {
213 return &voltha.HealthStatus{State: voltha.HealthStatus_HEALTHY}, nil
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000214}
215
khenaidoo7d3c5582021-08-11 18:09:44 -0400216// AdoptDevice creates a new device handler if not present already and then adopts the device
217func (oo *OpenONUAC) AdoptDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000218 if device == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000219 logger.Warn(ctx, "voltha-device-is-nil")
khenaidoo7d3c5582021-08-11 18:09:44 -0400220 return nil, errors.New("nil-device")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000221 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000222 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id})
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223 var handler *deviceHandler
dbainbri4d3a0dc2020-12-02 00:33:42 +0000224 if handler = oo.getDeviceHandler(ctx, device.Id, false); handler == nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400225 handler := newDeviceHandler(ctx, oo.coreClient, oo.eventProxy, device, oo)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000226 oo.addDeviceHandlerToMap(ctx, handler)
khenaidoo7d3c5582021-08-11 18:09:44 -0400227
228 // Setup the grpc communication with the parent adapter
229 if err := oo.setupParentInterAdapterClient(ctx, device.ProxyAddress.AdapterEndpoint); err != nil {
230 // TODO: Cleanup on failure needed
231 return nil, err
232 }
233
234 go handler.adoptOrReconcileDevice(log.WithSpanFromContext(context.Background(), ctx), device)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000235 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400236 return &empty.Empty{}, nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000237}
238
khenaidoo7d3c5582021-08-11 18:09:44 -0400239//ReconcileDevice is called once when the adapter needs to re-create device - usually on core restart
240func (oo *OpenONUAC) ReconcileDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000241 if device == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000242 logger.Warn(ctx, "reconcile-device-voltha-device-is-nil")
khenaidoo7d3c5582021-08-11 18:09:44 -0400243 return nil, errors.New("nil-device")
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000244 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000245 logger.Infow(ctx, "reconcile-device", log.Fields{"device-id": device.Id})
Himani Chawla6d2ae152020-09-02 13:11:20 +0530246 var handler *deviceHandler
dbainbri4d3a0dc2020-12-02 00:33:42 +0000247 if handler = oo.getDeviceHandler(ctx, device.Id, false); handler == nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400248 handler := newDeviceHandler(ctx, oo.coreClient, oo.eventProxy, device, oo)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000249 oo.addDeviceHandlerToMap(ctx, handler)
250 handler.device = device
khenaidoo7d3c5582021-08-11 18:09:44 -0400251 if err := handler.updateDeviceStateInCore(log.WithSpanFromContext(context.Background(), ctx), &ic.DeviceStateFilter{
252 DeviceId: device.Id,
253 OperStatus: voltha.OperStatus_RECONCILING,
254 ConnStatus: device.ConnectStatus,
255 }); err != nil {
256 return nil, fmt.Errorf("not able to update device state to reconciling. Err : %s", err.Error())
Maninderb5187552021-03-23 22:23:42 +0530257 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400258 // Setup the grpc communication with the parent adapter
259 if err := oo.setupParentInterAdapterClient(ctx, device.ProxyAddress.AdapterEndpoint); err != nil {
260 // TODO: Cleanup on failure needed
261 return nil, err
262 }
263
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000264 handler.StartReconciling(log.WithSpanFromContext(context.Background(), ctx), false)
khenaidoo7d3c5582021-08-11 18:09:44 -0400265 go handler.adoptOrReconcileDevice(log.WithSpanFromContext(context.Background(), ctx), handler.device)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000266 // reconcilement will be continued after onu-device entry is added
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000267 } else {
khenaidoo7d3c5582021-08-11 18:09:44 -0400268 return nil, fmt.Errorf(fmt.Sprintf("device-already-reconciled-or-active-%s", device.Id))
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000269 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400270 return &empty.Empty{}, nil
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000271}
272
khenaidoo7d3c5582021-08-11 18:09:44 -0400273//DisableDevice disables the given device
274func (oo *OpenONUAC) DisableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000275 logger.Infow(ctx, "disable-device", log.Fields{"device-id": device.Id})
276 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400277 go handler.disableDevice(log.WithSpanFromContext(context.Background(), ctx), device)
278 return &empty.Empty{}, nil
ozgecanetsiafce57b12020-05-25 14:39:35 +0300279 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Warnw(ctx, "no handler found for device-disable", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400281 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000282}
283
khenaidoo7d3c5582021-08-11 18:09:44 -0400284//ReEnableDevice enables the onu device after disable
285func (oo *OpenONUAC) ReEnableDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000286 logger.Infow(ctx, "reenable-device", log.Fields{"device-id": device.Id})
287 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400288 go handler.reEnableDevice(log.WithSpanFromContext(context.Background(), ctx), device)
289 return &empty.Empty{}, nil
ozgecanetsiafce57b12020-05-25 14:39:35 +0300290 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000291 logger.Warnw(ctx, "no handler found for device-reenable", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400292 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000293}
294
khenaidoo7d3c5582021-08-11 18:09:44 -0400295//RebootDevice reboots the given device
296func (oo *OpenONUAC) RebootDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": device.Id})
298 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400299 go handler.rebootDevice(log.WithSpanFromContext(context.Background(), ctx), true, device) //reboot request with device checking
300 return &empty.Empty{}, nil
ozgecanetsiae11479f2020-07-06 09:44:47 +0300301 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000302 logger.Warnw(ctx, "no handler found for device-reboot", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400303 return nil, fmt.Errorf("handler-not-found-for-device: %s", device.Id)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000304}
305
khenaidoo7d3c5582021-08-11 18:09:44 -0400306// DeleteDevice deletes the given device
307func (oo *OpenONUAC) DeleteDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
308 nctx := log.WithSpanFromContext(context.Background(), ctx)
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000309
khenaidoo7d3c5582021-08-11 18:09:44 -0400310 logger.Infow(ctx, "delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber, "ctx": ctx, "nctx": nctx})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 if handler := oo.getDeviceHandler(ctx, device.Id, false); handler != nil {
Girish Gowdra0e533642021-03-02 22:02:51 -0800312 var errorsList []error
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000313
314 handler.mutexDeletionInProgressFlag.Lock()
315 handler.deletionInProgress = true
316 handler.mutexDeletionInProgressFlag.Unlock()
317
Girish Gowdra0e533642021-03-02 22:02:51 -0800318 if err := handler.deleteDevicePersistencyData(ctx); err != nil {
319 errorsList = append(errorsList, err)
320 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700321
322 // Stop PM, Alarm and Self Test event handler routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000323 if handler.GetCollectorIsRunning() {
Girish Gowdra10123c02021-08-30 11:52:06 -0700324 handler.stopCollector <- true
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700325 logger.Debugw(ctx, "sent stop signal to metric collector routine", log.Fields{"device-id": device.Id})
Girish Gowdra10123c02021-08-30 11:52:06 -0700326
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700327 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328 if handler.GetAlarmManagerIsRunning(ctx) {
Girish Gowdra10123c02021-08-30 11:52:06 -0700329 handler.stopAlarmManager <- true
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700330 logger.Debugw(ctx, "sent stop signal to alarm manager", log.Fields{"device-id": device.Id})
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700331 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700332 if handler.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 handler.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -0700334 logger.Debugw(ctx, "sent stop signal to self test handler module", log.Fields{"device-id": device.Id})
335 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700336 for _, uni := range handler.uniEntityMap {
337 if handler.GetFlowMonitoringIsRunning(uni.UniID) {
338 handler.stopFlowMonitoringRoutine[uni.UniID] <- true
339 logger.Debugw(ctx, "sent stop signal to self flow monitoring routine", log.Fields{"device-id": device.Id})
340 }
341 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700342
343 // Clear PM data on the KV store
Girish Gowdra0e533642021-03-02 22:02:51 -0800344 if handler.pOnuMetricsMgr != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 if err := handler.pOnuMetricsMgr.ClearAllPmData(ctx); err != nil {
Girish Gowdra0e533642021-03-02 22:02:51 -0800346 errorsList = append(errorsList, err)
347 }
348 }
Girish Gowdra10123c02021-08-30 11:52:06 -0700349
Holger Hildebrandtf07b44a2020-11-10 13:07:54 +0000350 //don't leave any garbage - even in error case
351 oo.deleteDeviceHandlerToMap(handler)
Girish Gowdra0e533642021-03-02 22:02:51 -0800352 if len(errorsList) > 0 {
353 logger.Errorw(ctx, "one-or-more-error-during-device-delete", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400354 return nil, fmt.Errorf("one-or-more-error-during-device-delete, errors:%v", errorsList)
Girish Gowdra0e533642021-03-02 22:02:51 -0800355 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400356 return &empty.Empty{}, nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000357 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Warnw(ctx, "no handler found for device-deletion", log.Fields{"device-id": device.Id})
khenaidoo7d3c5582021-08-11 18:09:44 -0400359 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000360}
361
khenaidoo7d3c5582021-08-11 18:09:44 -0400362//UpdateFlowsIncrementally updates (add/remove) the flows on a given device
363func (oo *OpenONUAC) UpdateFlowsIncrementally(ctx context.Context, incrFlows *ic.IncrementalFlows) (*empty.Empty, error) {
364 logger.Infow(ctx, "update-flows-incrementally", log.Fields{"device-id": incrFlows.Device.Id})
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000365
mpagenkofc4f56e2020-11-04 17:17:49 +0000366 //flow config is relayed to handler even if the device might be in some 'inactive' state
367 // let the handler or related FSM's decide, what to do with the modified flow state info
368 // 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 +0000369
370 // For now, there is no support for group changes (as in the actual Py-adapter code)
mpagenkofc4f56e2020-11-04 17:17:49 +0000371 // but processing is continued for flowUpdate possibly also set in the request
khenaidoo7d3c5582021-08-11 18:09:44 -0400372 if incrFlows.Groups.ToAdd != nil && incrFlows.Groups.ToAdd.Items != nil {
373 logger.Warnw(ctx, "Update-flow-incr: group add not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000374 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400375 if incrFlows.Groups.ToRemove != nil && incrFlows.Groups.ToRemove.Items != nil {
376 logger.Warnw(ctx, "Update-flow-incr: group remove not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000377 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400378 if incrFlows.Groups.ToUpdate != nil && incrFlows.Groups.ToUpdate.Items != nil {
379 logger.Warnw(ctx, "Update-flow-incr: group update not supported (ignored)", log.Fields{"device-id": incrFlows.Device.Id})
mpagenkodff5dda2020-08-28 11:52:01 +0000380 }
381
khenaidoo7d3c5582021-08-11 18:09:44 -0400382 if handler := oo.getDeviceHandler(ctx, incrFlows.Device.Id, false); handler != nil {
383 if err := handler.FlowUpdateIncremental(log.WithSpanFromContext(context.Background(), ctx), incrFlows.Flows, incrFlows.Groups, incrFlows.FlowMetadata); err != nil {
384 return nil, err
385 }
386 return &empty.Empty{}, nil
mpagenkodff5dda2020-08-28 11:52:01 +0000387 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400388 logger.Warnw(ctx, "no handler found for incremental flow update", log.Fields{"device-id": incrFlows.Device.Id})
389 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", incrFlows.Device.Id))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000390}
391
khenaidoo7d3c5582021-08-11 18:09:44 -0400392//UpdatePmConfig returns PmConfigs nil or error
393func (oo *OpenONUAC) UpdatePmConfig(ctx context.Context, configs *ic.PmConfigsInfo) (*empty.Empty, error) {
394 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": configs.DeviceId})
395 if handler := oo.getDeviceHandler(ctx, configs.DeviceId, false); handler != nil {
396 if err := handler.updatePmConfig(log.WithSpanFromContext(context.Background(), ctx), configs.PmConfigs); err != nil {
397 return nil, err
398 }
399 return &empty.Empty{}, nil
Girish Gowdrae09a6202021-01-12 18:10:59 -0800400 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400401 logger.Warnw(ctx, "no handler found for update-pm-config", log.Fields{"device-id": configs.DeviceId})
402 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", configs.DeviceId))
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000403}
404
khenaidoo7d3c5582021-08-11 18:09:44 -0400405//DownloadImage requests downloading some image according to indications as given in request
Andrea Campanella71e546a2021-02-26 11:09:33 +0100406//The ImageDownload needs to be called `request`due to library reflection requirements
khenaidoo7d3c5582021-08-11 18:09:44 -0400407func (oo *OpenONUAC) DownloadImage(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
408 ctx = log.WithSpanFromContext(context.Background(), ctx)
409 if imageInfo != nil && imageInfo.Image != nil && imageInfo.Image.Name != "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000410 if !oo.pDownloadManager.ImageExists(ctx, imageInfo.Image) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400411 logger.Debugw(ctx, "start image download", log.Fields{"image-description": imageInfo.Image})
mpagenko15ff4a52021-03-02 10:09:20 +0000412 // Download_image is not supposed to be blocking, anyway let's call the DownloadManager still synchronously to detect 'fast' problems
413 // the download itself is later done in background
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000414 if err := oo.pDownloadManager.StartDownload(ctx, imageInfo.Image); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400415 return nil, err
416 }
417 return imageInfo.Image, nil
mpagenko15ff4a52021-03-02 10:09:20 +0000418 }
419 // image already exists
khenaidoo7d3c5582021-08-11 18:09:44 -0400420 logger.Debugw(ctx, "image already downloaded", log.Fields{"image-description": imageInfo.Image})
421 return imageInfo.Image, nil
mpagenkoc8bba412021-01-15 15:38:44 +0000422 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400423
424 return nil, errors.New("invalid image definition")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000425}
426
mpagenko59862f02021-10-11 08:53:18 +0000427//ActivateImageUpdate requests downloading some Onu Software image to the ONU via OMCI
Andrea Campanella71e546a2021-02-26 11:09:33 +0100428// according to indications as given in request and on success activate the image on the ONU
429//The ImageDownload needs to be called `request`due to library reflection requirements
khenaidoo7d3c5582021-08-11 18:09:44 -0400430func (oo *OpenONUAC) ActivateImageUpdate(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
431 if imageInfo != nil && imageInfo.Image != nil && imageInfo.Image.Name != "" {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000432 if oo.pDownloadManager.ImageLocallyDownloaded(ctx, imageInfo.Image) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400433 if handler := oo.getDeviceHandler(ctx, imageInfo.Device.Id, false); handler != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000434 logger.Debugw(ctx, "image download on omci requested", log.Fields{
khenaidoo7d3c5582021-08-11 18:09:44 -0400435 "image-description": imageInfo.Image, "device-id": imageInfo.Device.Id})
436 if err := handler.doOnuSwUpgrade(ctx, imageInfo.Image, oo.pDownloadManager); err != nil {
437 return nil, err
438 }
439 return imageInfo.Image, nil
mpagenko15ff4a52021-03-02 10:09:20 +0000440 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400441 logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": imageInfo.Device.Id})
442 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found - device-id: %s", imageInfo.Device.Id))
mpagenko057889c2021-01-21 16:51:58 +0000443 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400444 logger.Debugw(ctx, "image not yet downloaded on activate request", log.Fields{"image-description": imageInfo.Image})
445 return nil, fmt.Errorf(fmt.Sprintf("image-not-yet-downloaded - device-id: %s", imageInfo.Device.Id))
mpagenkoc8bba412021-01-15 15:38:44 +0000446 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400447 return nil, errors.New("invalid image definition")
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000448}
449
khenaidoo7d3c5582021-08-11 18:09:44 -0400450//GetSingleValue handles the core request to retrieve uni status
451func (oo *OpenONUAC) GetSingleValue(ctx context.Context, request *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
kesavandfdf77632021-01-26 23:40:33 -0500452 logger.Infow(ctx, "Single_get_value_request", log.Fields{"request": request})
453
454 if handler := oo.getDeviceHandler(ctx, request.TargetId, false); handler != nil {
455 switch reqType := request.GetRequest().GetRequest().(type) {
456 case *extension.GetValueRequest_UniInfo:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000457 return handler.GetUniPortStatus(ctx, reqType.UniInfo), nil
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700458 case *extension.GetValueRequest_OnuOpticalInfo:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000459 CommChan := make(chan cmn.Message)
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700460 respChan := make(chan extension.SingleGetValueResponse)
461 // Initiate the self test request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 if err := handler.pSelfTestHdlr.SelfTestRequestStart(ctx, *request, CommChan, respChan); err != nil {
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700463 return &extension.SingleGetValueResponse{
464 Response: &extension.GetValueResponse{
465 Status: extension.GetValueResponse_ERROR,
466 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
467 },
468 }, err
469 }
470 // The timeout handling is already implemented in omci_self_test_handler module
471 resp := <-respChan
472 return &resp, nil
Himani Chawla43f95ff2021-06-03 00:24:12 +0530473 case *extension.GetValueRequest_OnuInfo:
474 return handler.getOnuOMCICounters(ctx, reqType.OnuInfo), nil
kesavandfdf77632021-01-26 23:40:33 -0500475 default:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000476 return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_UNSUPPORTED), nil
kesavandfdf77632021-01-26 23:40:33 -0500477
478 }
479 }
480 logger.Errorw(ctx, "Single_get_value_request failed ", log.Fields{"request": request})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_INVALID_DEVICE_ID), nil
mpagenkoc8bba412021-01-15 15:38:44 +0000482}
483
mpagenko83144272021-04-27 10:06:22 +0000484//if update >= 4.3.0
mpagenkoc26d4c02021-05-06 14:27:57 +0000485// Note: already with the implementation of the 'old' download interface problems were detected when the argument name used here is not the same
486// as defined in the adapter interface file. That sounds strange and the effects were strange as well.
487// The reason for that was never finally investigated.
488// To be on the safe side argument names are left here always as defined in iAdapter.go .
mpagenko83144272021-04-27 10:06:22 +0000489
khenaidoo7d3c5582021-08-11 18:09:44 -0400490// DownloadOnuImage downloads (and optionally activates and commits) the indicated ONU image to the requested ONU(s)
mpagenko83144272021-04-27 10:06:22 +0000491// if the image is not yet present on the adapter it has to be automatically downloaded
khenaidoo7d3c5582021-08-11 18:09:44 -0400492func (oo *OpenONUAC) DownloadOnuImage(ctx context.Context, request *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000493 if request != nil && len((*request).DeviceId) > 0 && (*request).Image.Version != "" {
494 loResponse := voltha.DeviceImageResponse{}
495 imageIdentifier := (*request).Image.Version
mpagenko38662d02021-08-11 09:45:19 +0000496 downloadedToAdapter := false
mpagenkoc26d4c02021-05-06 14:27:57 +0000497 firstDevice := true
498 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000499 var onuVolthaDevice *voltha.Device
500 var devErr error
mpagenkoc26d4c02021-05-06 14:27:57 +0000501 for _, pCommonID := range (*request).DeviceId {
mpagenko38662d02021-08-11 09:45:19 +0000502 vendorIDMatch := true
mpagenkoc26d4c02021-05-06 14:27:57 +0000503 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000504 loDeviceImageState := voltha.DeviceImageState{}
505 loDeviceImageState.DeviceId = loDeviceID
506 loImageState := voltha.ImageState{}
507 loDeviceImageState.ImageState = &loImageState
508 loDeviceImageState.ImageState.Version = (*request).Image.Version
mpagenko38662d02021-08-11 09:45:19 +0000509
mpagenko59862f02021-10-11 08:53:18 +0000510 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400511 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000512 if handler != nil {
513 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
514 } else {
515 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
516 devErr = errors.New("no handler found for device-id")
khenaidoo7d3c5582021-08-11 18:09:44 -0400517 }
mpagenko59862f02021-10-11 08:53:18 +0000518 if devErr != nil || onuVolthaDevice == nil {
519 logger.Warnw(ctx, "Failed to fetch ONU device for image download",
520 log.Fields{"device-id": loDeviceID, "err": devErr})
mpagenko38662d02021-08-11 09:45:19 +0000521 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
522 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //proto restriction, better option: 'INVALID_DEVICE'
mpagenkoc26d4c02021-05-06 14:27:57 +0000523 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000524 } else {
mpagenko38662d02021-08-11 09:45:19 +0000525 if firstDevice {
526 //start/verify download of the image to the adapter based on first found device only
527 // use the OnuVendor identification from first given device
528 firstDevice = false
529 vendorID = onuVolthaDevice.VendorId
530 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
531 logger.Debugw(ctx, "download request for file", log.Fields{"image-id": imageIdentifier})
532
533 if !oo.pFileManager.ImageExists(ctx, imageIdentifier) {
534 logger.Debugw(ctx, "start image download", log.Fields{"image-description": request})
535 // Download_image is not supposed to be blocking, anyway let's call the DownloadManager still synchronously to detect 'fast' problems
536 // the download itself is later done in background
537 if err := oo.pFileManager.StartDownload(ctx, imageIdentifier, (*request).Image.Url); err == nil {
538 downloadedToAdapter = true
539 }
540 //else: treat any error here as 'INVALID_URL' (even though it might as well be some issue on local FS, eg. 'INSUFFICIENT_SPACE')
541 // otherwise a more sophisticated error evaluation is needed
542 } else {
543 // image already exists
544 downloadedToAdapter = true
545 logger.Debugw(ctx, "image already downloaded", log.Fields{"image-description": imageIdentifier})
546 // note: If the image (with vendorId+name) has already been downloaded before from some other
547 // valid URL, the current URL is just ignored. If the operators want to ensure that the new URL
548 // is really used, then they first have to use the 'abort' API to remove the existing image!
549 // (abort API can be used also after some successful download to just remove the image from adapter)
550 }
551 } else {
552 //for all following devices verify the matching vendorID
553 if onuVolthaDevice.VendorId != vendorID {
554 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
555 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
556 vendorIDMatch = false
557 }
558 }
559 if downloadedToAdapter && vendorIDMatch {
560 // start the ONU download activity for each possible device
mpagenko59862f02021-10-11 08:53:18 +0000561 logger.Debugw(ctx, "image download on omci requested", log.Fields{
562 "image-id": imageIdentifier, "device-id": loDeviceID})
563 //onu upgrade handling called in background without immediate error evaluation here
564 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
565 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
566 go handler.onuSwUpgradeAfterDownload(ctx, request, oo.pFileManager, imageIdentifier)
567 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_STARTED
568 loDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
569 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +0000570 } else {
571 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
572 if !downloadedToAdapter {
573 loDeviceImageState.ImageState.Reason = voltha.ImageState_INVALID_URL
574 } else { //only logical option is !vendorIDMatch
575 loDeviceImageState.ImageState.Reason = voltha.ImageState_VENDOR_DEVICE_MISMATCH
576 }
577 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
578 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000579 }
mpagenko2f2f2362021-06-07 08:25:22 +0000580 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000581 } //for all requested devices
mpagenkoc26d4c02021-05-06 14:27:57 +0000582 pImageResp := &loResponse
583 return pImageResp, nil
584 }
585 return nil, errors.New("invalid image download parameters")
mpagenko83144272021-04-27 10:06:22 +0000586}
587
khenaidoo7d3c5582021-08-11 18:09:44 -0400588// GetOnuImageStatus delivers the adapter-related information about the download/activation/commitment
mpagenko83144272021-04-27 10:06:22 +0000589// status for the requested image
khenaidoo7d3c5582021-08-11 18:09:44 -0400590func (oo *OpenONUAC) GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000591 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
592 loResponse := voltha.DeviceImageResponse{}
mpagenkoaa3afe92021-05-21 16:20:58 +0000593 imageIdentifier := (*in).Version
mpagenko38662d02021-08-11 09:45:19 +0000594 var vendorIDSet bool
mpagenkoaa3afe92021-05-21 16:20:58 +0000595 firstDevice := true
596 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000597 var onuVolthaDevice *voltha.Device
598 var devErr error
mpagenkoaa3afe92021-05-21 16:20:58 +0000599 for _, pCommonID := range (*in).DeviceId {
600 loDeviceID := (*pCommonID).Id
khenaidoo7d3c5582021-08-11 18:09:44 -0400601 pDeviceImageState := &voltha.DeviceImageState{DeviceId: loDeviceID}
mpagenko59862f02021-10-11 08:53:18 +0000602 vendorIDSet = false
603 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400604 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000605 if handler != nil {
606 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
607 } else {
608 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
609 devErr = errors.New("no handler found for device-id")
mpagenko38662d02021-08-11 09:45:19 +0000610 }
mpagenko59862f02021-10-11 08:53:18 +0000611 if devErr != nil || onuVolthaDevice == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +0000612 logger.Warnw(ctx, "Failed to fetch Onu device to get image status",
mpagenko59862f02021-10-11 08:53:18 +0000613 log.Fields{"device-id": loDeviceID, "err": devErr})
mpagenko38662d02021-08-11 09:45:19 +0000614 pImageState := &voltha.ImageState{
615 Version: (*in).Version,
616 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN, //no statement about last activity possible
617 Reason: voltha.ImageState_UNKNOWN_ERROR, //something like "DEVICE_NOT_EXISTS" would be better (proto def)
618 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
mpagenkoaa3afe92021-05-21 16:20:58 +0000619 }
mpagenko38662d02021-08-11 09:45:19 +0000620 pDeviceImageState.ImageState = pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +0000621 } else {
mpagenko38662d02021-08-11 09:45:19 +0000622 if firstDevice {
623 //start/verify download of the image to the adapter based on first found device only
624 // use the OnuVendor identification from first given device
625 firstDevice = false
626 vendorID = onuVolthaDevice.VendorId
627 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
628 vendorIDSet = true
629 logger.Debugw(ctx, "status request for image", log.Fields{"image-id": imageIdentifier})
630 } else {
631 //for all following devices verify the matching vendorID
632 if onuVolthaDevice.VendorId != vendorID {
633 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
634 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
635 } else {
636 vendorIDSet = true
637 }
638 }
639 if !vendorIDSet {
640 pImageState := &voltha.ImageState{
641 Version: (*in).Version,
642 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN, //can't be sure that download for this device was really tried
643 Reason: voltha.ImageState_VENDOR_DEVICE_MISMATCH,
644 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
645 }
646 pDeviceImageState.ImageState = pImageState
647 } else {
khenaidoo7d3c5582021-08-11 18:09:44 -0400648 logger.Debugw(ctx, "image status request for", log.Fields{
649 "image-id": imageIdentifier, "device-id": loDeviceID})
650 //status request is called synchronously to collect the indications for all concerned devices
651 pDeviceImageState.ImageState = handler.requestOnuSwUpgradeState(ctx, imageIdentifier, (*in).Version)
mpagenko38662d02021-08-11 09:45:19 +0000652 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000653 }
654 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000655 } //for all requested devices
mpagenkoaa3afe92021-05-21 16:20:58 +0000656 pImageResp := &loResponse
657 return pImageResp, nil
658 }
659 return nil, errors.New("invalid image status request parameters")
mpagenko83144272021-04-27 10:06:22 +0000660}
661
khenaidoo7d3c5582021-08-11 18:09:44 -0400662// AbortOnuImageUpgrade stops the actual download/activation/commitment process (on next possibly step)
663func (oo *OpenONUAC) AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoaa3afe92021-05-21 16:20:58 +0000664 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
665 loResponse := voltha.DeviceImageResponse{}
666 imageIdentifier := (*in).Version
667 firstDevice := true
668 var vendorID string
mpagenko59862f02021-10-11 08:53:18 +0000669 var vendorIDSet bool
670 var onuVolthaDevice *voltha.Device
671 var devErr error
mpagenkoaa3afe92021-05-21 16:20:58 +0000672 for _, pCommonID := range (*in).DeviceId {
673 loDeviceID := (*pCommonID).Id
khenaidoo7d3c5582021-08-11 18:09:44 -0400674 pDeviceImageState := &voltha.DeviceImageState{}
675 loImageState := voltha.ImageState{}
676 pDeviceImageState.ImageState = &loImageState
mpagenko59862f02021-10-11 08:53:18 +0000677 vendorIDSet = false
678 onuVolthaDevice = nil
khenaidoo7d3c5582021-08-11 18:09:44 -0400679 handler := oo.getDeviceHandler(ctx, loDeviceID, false)
mpagenko59862f02021-10-11 08:53:18 +0000680 if handler != nil {
681 onuVolthaDevice, devErr = handler.getDeviceFromCore(ctx, loDeviceID)
682 } else {
683 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
684 devErr = errors.New("no handler found for device-id")
685 }
686 if devErr != nil || onuVolthaDevice == nil {
687 logger.Warnw(ctx, "Failed to fetch Onu device to abort its download",
688 log.Fields{"device-id": loDeviceID, "err": devErr})
khenaidoo7d3c5582021-08-11 18:09:44 -0400689 pDeviceImageState.DeviceId = loDeviceID
690 pDeviceImageState.ImageState.Version = (*in).Version
mpagenko59862f02021-10-11 08:53:18 +0000691 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
692 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST //something better could be considered (MissingHandler) - proto
khenaidoo7d3c5582021-08-11 18:09:44 -0400693 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenkoaa3afe92021-05-21 16:20:58 +0000694 } else {
mpagenko59862f02021-10-11 08:53:18 +0000695 if firstDevice {
696 //start/verify download of the image to the adapter based on first found device only
697 // use the OnuVendor identification from first given device
698 firstDevice = false
699 vendorID = onuVolthaDevice.VendorId
700 vendorIDSet = true
701 imageIdentifier = vendorID + imageIdentifier //head on vendor ID of the ONU
702 logger.Debugw(ctx, "abort request for file", log.Fields{"image-id": imageIdentifier})
703 } else {
704 //for all following devices verify the matching vendorID
705 if onuVolthaDevice.VendorId != vendorID {
706 logger.Warnw(ctx, "onu vendor id does not match image vendor id, device ignored",
707 log.Fields{"onu-vendor-id": onuVolthaDevice.VendorId, "image-vendor-id": vendorID})
708 pDeviceImageState.DeviceId = loDeviceID
709 pDeviceImageState.ImageState.Version = (*in).Version
710 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
711 pDeviceImageState.ImageState.Reason = voltha.ImageState_VENDOR_DEVICE_MISMATCH
712 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
713 } else {
714 vendorIDSet = true
715 }
716 }
717 if vendorIDSet {
718 // cancel the ONU upgrade activity for each possible device
719 logger.Debugw(ctx, "image upgrade abort requested", log.Fields{
720 "image-id": imageIdentifier, "device-id": loDeviceID})
721 //upgrade cancel is called synchronously to collect the imageResponse indications for all concerned devices
722 handler.cancelOnuSwUpgrade(ctx, imageIdentifier, (*in).Version, pDeviceImageState)
mpagenkoaa3afe92021-05-21 16:20:58 +0000723 }
724 }
mpagenkoaa3afe92021-05-21 16:20:58 +0000725 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, pDeviceImageState)
mpagenko59862f02021-10-11 08:53:18 +0000726 } //for all requested devices
mpagenkoaa3afe92021-05-21 16:20:58 +0000727 if !firstDevice {
728 //if at least one valid device was found cancel also a possibly running download to adapter and remove the image
729 // this is to be done after the upgradeOnu cancel activities in order to not subduct the file for still running processes
730 oo.pFileManager.CancelDownload(ctx, imageIdentifier)
731 }
732 pImageResp := &loResponse
733 return pImageResp, nil
734 }
735 return nil, errors.New("invalid image upgrade abort parameters")
mpagenko83144272021-04-27 10:06:22 +0000736}
737
khenaidoo7d3c5582021-08-11 18:09:44 -0400738// GetOnuImages retrieves the ONU SW image status information via OMCI
739func (oo *OpenONUAC) GetOnuImages(ctx context.Context, id *common.ID) (*voltha.OnuImages, error) {
740 logger.Infow(ctx, "Get_onu_images", log.Fields{"device-id": id.Id})
741 if handler := oo.getDeviceHandler(ctx, id.Id, false); handler != nil {
Himani Chawla69992ab2021-07-08 15:13:02 +0530742 images, err := handler.getOnuImages(ctx)
743 if err == nil {
Holger Hildebrandtfb402a62021-05-26 14:40:49 +0000744 return images, nil
745 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400746 return nil, fmt.Errorf(fmt.Sprintf("%s-%s", err, id.Id))
Holger Hildebrandtfb402a62021-05-26 14:40:49 +0000747 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400748 logger.Warnw(ctx, "no handler found for Get_onu_images", log.Fields{"device-id": id.Id})
749 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", id.Id))
mpagenko83144272021-04-27 10:06:22 +0000750}
751
khenaidoo7d3c5582021-08-11 18:09:44 -0400752// ActivateOnuImage initiates the activation of the image for the requested ONU(s)
mpagenkoc26d4c02021-05-06 14:27:57 +0000753// precondition: image downloaded and not yet activated or image refers to current inactive image
khenaidoo7d3c5582021-08-11 18:09:44 -0400754func (oo *OpenONUAC) ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000755 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
756 loResponse := voltha.DeviceImageResponse{}
757 imageIdentifier := (*in).Version
758 //let the deviceHandler find the adequate way of requesting the image activation
759 for _, pCommonID := range (*in).DeviceId {
760 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000761 loDeviceImageState := voltha.DeviceImageState{}
762 loDeviceImageState.DeviceId = loDeviceID
763 loImageState := voltha.ImageState{}
764 loDeviceImageState.ImageState = &loImageState
765 loDeviceImageState.ImageState.Version = imageIdentifier
mpagenkoc26d4c02021-05-06 14:27:57 +0000766 //compared to download procedure the vendorID (from device) is secondary here
767 // and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
768 // start image activation activity for each possible device
769 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
770 if handler := oo.getDeviceHandler(ctx, loDeviceID, false); handler != nil {
771 logger.Debugw(ctx, "onu image activation requested", log.Fields{
772 "image-id": imageIdentifier, "device-id": loDeviceID})
773 //onu activation handling called in background without immediate error evaluation here
774 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
775 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
mpagenko183647c2021-06-08 15:25:04 +0000776 if pImageStates, err := handler.onuSwActivateRequest(ctx, imageIdentifier, (*in).CommitOnSuccess); err != nil {
777 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
778 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
779 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
780 } else {
781 loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
782 loDeviceImageState.ImageState.Reason = pImageStates.Reason
783 loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
784 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000785 } else {
786 //cannot start SW activation for requested device
787 logger.Warnw(ctx, "no handler found for image activation", log.Fields{"device-id": loDeviceID})
mpagenko183647c2021-06-08 15:25:04 +0000788 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000789 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
790 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_ACTIVATION_ABORTED
mpagenkoc26d4c02021-05-06 14:27:57 +0000791 }
mpagenko2f2f2362021-06-07 08:25:22 +0000792 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenkoc26d4c02021-05-06 14:27:57 +0000793 }
794 pImageResp := &loResponse
795 return pImageResp, nil
796 }
797 return nil, errors.New("invalid image activation parameters")
mpagenko83144272021-04-27 10:06:22 +0000798}
799
khenaidoo7d3c5582021-08-11 18:09:44 -0400800// CommitOnuImage enforces the commitment of the image for the requested ONU(s)
mpagenko83144272021-04-27 10:06:22 +0000801// precondition: image activated and not yet committed
khenaidoo7d3c5582021-08-11 18:09:44 -0400802func (oo *OpenONUAC) CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +0000803 if in != nil && len((*in).DeviceId) > 0 && (*in).Version != "" {
804 loResponse := voltha.DeviceImageResponse{}
805 imageIdentifier := (*in).Version
806 //let the deviceHandler find the adequate way of requesting the image activation
807 for _, pCommonID := range (*in).DeviceId {
808 loDeviceID := (*pCommonID).Id
mpagenko2f2f2362021-06-07 08:25:22 +0000809 loDeviceImageState := voltha.DeviceImageState{}
810 loDeviceImageState.DeviceId = loDeviceID
811 loImageState := voltha.ImageState{}
812 loDeviceImageState.ImageState = &loImageState
813 loDeviceImageState.ImageState.Version = imageIdentifier
mpagenkoc26d4c02021-05-06 14:27:57 +0000814 //compared to download procedure the vendorID (from device) is secondary here
815 // and only needed in case the upgrade process is based on some ongoing download process (and can be retrieved in deviceHandler if needed)
816 // start image activation activity for each possible device
817 // assumption here is, that the concerned device was already created (automatic start after device creation not supported)
818 if handler := oo.getDeviceHandler(ctx, loDeviceID, false); handler != nil {
819 logger.Debugw(ctx, "onu image commitment requested", log.Fields{
820 "image-id": imageIdentifier, "device-id": loDeviceID})
821 //onu commitment handling called in background without immediate error evaluation here
822 // as the processing can be done for multiple ONU's and an error on one ONU should not stop processing for others
823 // state/progress/success of the request has to be verified using the Get_onu_image_status() API
mpagenko183647c2021-06-08 15:25:04 +0000824 if pImageStates, err := handler.onuSwCommitRequest(ctx, imageIdentifier); err != nil {
mpagenko38662d02021-08-11 09:45:19 +0000825 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_FAILED
826 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR //can be multiple reasons here
mpagenko183647c2021-06-08 15:25:04 +0000827 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
828 } else {
829 loDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
830 loDeviceImageState.ImageState.Reason = pImageStates.Reason
831 loDeviceImageState.ImageState.ImageState = pImageStates.ImageState
832 }
mpagenkoc26d4c02021-05-06 14:27:57 +0000833 } else {
834 //cannot start SW commitment for requested device
835 logger.Warnw(ctx, "no handler found for image commitment", log.Fields{"device-id": loDeviceID})
mpagenko183647c2021-06-08 15:25:04 +0000836 loDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenkoc26d4c02021-05-06 14:27:57 +0000837 loDeviceImageState.ImageState.Reason = voltha.ImageState_UNKNOWN_ERROR
838 loDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMIT_ABORTED
mpagenkoc26d4c02021-05-06 14:27:57 +0000839 }
mpagenko2f2f2362021-06-07 08:25:22 +0000840 loResponse.DeviceImageStates = append(loResponse.DeviceImageStates, &loDeviceImageState)
mpagenkoc26d4c02021-05-06 14:27:57 +0000841 }
842 pImageResp := &loResponse
843 return pImageResp, nil
844 }
845 return nil, errors.New("invalid image commitment parameters")
mpagenko83144272021-04-27 10:06:22 +0000846}
847
Holger Hildebrandtfa074992020-03-27 15:42:06 +0000848// Adapter interface required methods ################ end #########
849// #################################################################
khenaidoo7d3c5582021-08-11 18:09:44 -0400850
851/*
852 *
853 * ONU inter adapter service
854 *
855 */
856
857// OnuIndication is part of the ONU Inter-adapter service API.
858func (oo *OpenONUAC) OnuIndication(ctx context.Context, onuInd *ic.OnuIndicationMessage) (*empty.Empty, error) {
859 logger.Debugw(ctx, "onu-indication", log.Fields{"onu-indication": onuInd})
860
861 if onuInd == nil || onuInd.OnuIndication == nil {
862 return nil, fmt.Errorf("invalid-onu-indication-%v", onuInd)
863 }
864
865 onuIndication := onuInd.OnuIndication
866 onuOperstate := onuIndication.GetOperState()
867 waitForDhInstPresent := false
868 if onuOperstate == "up" {
869 //Race condition (relevant in BBSIM-environment only): Due to unsynchronized processing of olt-adapter and rw_core,
870 //ONU_IND_REQUEST msg by olt-adapter could arrive a little bit earlier than rw_core was able to announce the corresponding
871 //ONU by RPC of Adopt_device(). Therefore it could be necessary to wait with processing of ONU_IND_REQUEST until call of
872 //Adopt_device() arrived and DeviceHandler instance was created
873 waitForDhInstPresent = true
874 }
875 if handler := oo.getDeviceHandler(ctx, onuInd.DeviceId, waitForDhInstPresent); handler != nil {
876 logger.Infow(ctx, "onu-ind-request", log.Fields{"device-id": onuInd.DeviceId,
877 "OnuId": onuIndication.GetOnuId(),
878 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
879 "SNR": onuIndication.GetSerialNumber()})
880
881 if onuOperstate == "up" {
882 if err := handler.createInterface(ctx, onuIndication); err != nil {
883 return nil, err
884 }
885 return &empty.Empty{}, nil
886 } else if (onuOperstate == "down") || (onuOperstate == "unreachable") {
887 return nil, handler.updateInterface(ctx, onuIndication)
888 } else {
889 logger.Errorw(ctx, "unknown-onu-ind-request operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
890 return nil, fmt.Errorf("invalidOperState: %s, %s", onuOperstate, onuInd.DeviceId)
891 }
892 }
893 logger.Warnw(ctx, "no handler found for received onu-ind-request", log.Fields{
894 "msgToDeviceId": onuInd.DeviceId})
895 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", onuInd.DeviceId))
896}
897
898// OmciIndication is part of the ONU Inter-adapter service API.
899func (oo *OpenONUAC) OmciIndication(ctx context.Context, msg *ic.OmciMessage) (*empty.Empty, error) {
900 logger.Debugw(ctx, "omci-response", log.Fields{"parent-device-id": msg.ParentDeviceId, "child-device-id": msg.ChildDeviceId})
901
902 if handler := oo.getDeviceHandler(ctx, msg.ChildDeviceId, false); handler != nil {
903 if err := handler.handleOMCIIndication(log.WithSpanFromContext(context.Background(), ctx), msg); err != nil {
904 return nil, err
905 }
906 return &empty.Empty{}, nil
907 }
908 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", msg.ChildDeviceId))
909}
910
911// DownloadTechProfile is part of the ONU Inter-adapter service API.
912func (oo *OpenONUAC) DownloadTechProfile(ctx context.Context, tProfile *ic.TechProfileDownloadMessage) (*empty.Empty, error) {
913 logger.Debugw(ctx, "download-tech-profile", log.Fields{"uni-id": tProfile.UniId})
914
915 if handler := oo.getDeviceHandler(ctx, tProfile.DeviceId, false); handler != nil {
916 if err := handler.handleTechProfileDownloadRequest(log.WithSpanFromContext(context.Background(), ctx), tProfile); err != nil {
917 return nil, err
918 }
919 return &empty.Empty{}, nil
920 }
921 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", tProfile.DeviceId))
922}
923
924// DeleteGemPort is part of the ONU Inter-adapter service API.
925func (oo *OpenONUAC) DeleteGemPort(ctx context.Context, gPort *ic.DeleteGemPortMessage) (*empty.Empty, error) {
926 logger.Debugw(ctx, "delete-gem-port", log.Fields{"device-id": gPort.DeviceId, "uni-id": gPort.UniId})
927
928 if handler := oo.getDeviceHandler(ctx, gPort.DeviceId, false); handler != nil {
929 if err := handler.handleDeleteGemPortRequest(log.WithSpanFromContext(context.Background(), ctx), gPort); err != nil {
930 return nil, err
931 }
932 return &empty.Empty{}, nil
933 }
934 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", gPort.DeviceId))
935}
936
937// DeleteTCont is part of the ONU Inter-adapter service API.
938func (oo *OpenONUAC) DeleteTCont(ctx context.Context, tConf *ic.DeleteTcontMessage) (*empty.Empty, error) {
939 logger.Debugw(ctx, "delete-tcont", log.Fields{"tconf": tConf})
940
941 if handler := oo.getDeviceHandler(ctx, tConf.DeviceId, false); handler != nil {
942 if err := handler.handleDeleteTcontRequest(log.WithSpanFromContext(context.Background(), ctx), tConf); err != nil {
943 return nil, err
944 }
945 return &empty.Empty{}, nil
946 }
947 return nil, fmt.Errorf(fmt.Sprintf("handler-not-found-%s", tConf.DeviceId))
948}
949
950/*
951 * Parent GRPC clients
952 */
953
954func (oo *OpenONUAC) setupParentInterAdapterClient(ctx context.Context, endpoint string) error {
955 logger.Infow(ctx, "setting-parent-adapter-connection", log.Fields{"parent-endpoint": endpoint})
956 oo.lockParentAdapterClients.Lock()
957 defer oo.lockParentAdapterClients.Unlock()
958 if _, ok := oo.parentAdapterClients[endpoint]; ok {
959 return nil
960 }
961
962 childClient, err := vgrpc.NewClient(endpoint,
963 oo.oltAdapterRestarted,
964 vgrpc.ActivityCheck(true))
965
966 if err != nil {
967 return err
968 }
969
970 oo.parentAdapterClients[endpoint] = childClient
971
972 go oo.parentAdapterClients[endpoint].Start(log.WithSpanFromContext(context.TODO(), ctx), setAndTestAdapterServiceHandler)
973
974 // Wait until we have a connection to the child adapter.
975 // Unlimited retries or until context expires
976 subCtx := log.WithSpanFromContext(context.TODO(), ctx)
977 backoff := vgrpc.NewBackoff(oo.config.MinBackoffRetryDelay, oo.config.MaxBackoffRetryDelay, 0)
978 for {
979 client, err := oo.parentAdapterClients[endpoint].GetOltInterAdapterServiceClient()
980 if err == nil && client != nil {
981 logger.Infow(subCtx, "connected-to-parent-adapter", log.Fields{"parent-endpoint": endpoint})
982 break
983 }
984 logger.Warnw(subCtx, "connection-to-parent-adapter-not-ready", log.Fields{"error": err, "parent-endpoint": endpoint})
985 // Backoff
986 if err = backoff.Backoff(subCtx); err != nil {
987 logger.Errorw(subCtx, "received-error-on-backoff", log.Fields{"error": err, "parent-endpoint": endpoint})
988 break
989 }
990 }
991 return nil
992}
993
994func (oo *OpenONUAC) getParentAdapterServiceClient(endpoint string) (adapter_services.OltInterAdapterServiceClient, error) {
995 // First check from cache
996 oo.lockParentAdapterClients.RLock()
997 if pgClient, ok := oo.parentAdapterClients[endpoint]; ok {
998 oo.lockParentAdapterClients.RUnlock()
999 return pgClient.GetOltInterAdapterServiceClient()
1000 }
1001 oo.lockParentAdapterClients.RUnlock()
1002
1003 // Set the parent connection - can occur on restarts
1004 ctx, cancel := context.WithTimeout(context.Background(), oo.config.RPCTimeout)
1005 err := oo.setupParentInterAdapterClient(ctx, endpoint)
1006 cancel()
1007 if err != nil {
1008 return nil, err
1009 }
1010
1011 // Get the parent client now
1012 oo.lockParentAdapterClients.RLock()
1013 defer oo.lockParentAdapterClients.RUnlock()
1014 if pgClient, ok := oo.parentAdapterClients[endpoint]; ok {
1015 return pgClient.GetOltInterAdapterServiceClient()
1016 }
1017
1018 return nil, fmt.Errorf("no-client-for-endpoint-%s", endpoint)
1019}
1020
1021// TODO: Any action the adapter needs to do following an olt adapter restart?
1022func (oo *OpenONUAC) oltAdapterRestarted(ctx context.Context, endPoint string) error {
1023 logger.Errorw(ctx, "olt-adapter-restarted", log.Fields{"endpoint": endPoint})
1024 return nil
1025}
1026
1027// setAndTestAdapterServiceHandler is used to test whether the remote gRPC service is up
1028func setAndTestAdapterServiceHandler(ctx context.Context, conn *grpc.ClientConn) interface{} {
1029 svc := adapter_services.NewOltInterAdapterServiceClient(conn)
1030 if h, err := svc.GetHealthStatus(ctx, &empty.Empty{}); err != nil || h.State != voltha.HealthStatus_HEALTHY {
1031 return nil
1032 }
1033 return svc
1034}
1035
1036/*
1037 *
1038 * Unimplemented APIs
1039 *
1040 */
1041
1042//GetOfpDeviceInfo returns OFP information for the given device. Method not implemented as per [VOL-3202].
1043// OF port info is now to be delivered within UniPort create cmp changes in onu_uni_port.go::CreateVolthaPort()
1044//
1045func (oo *OpenONUAC) GetOfpDeviceInfo(ctx context.Context, device *voltha.Device) (*ic.SwitchCapability, error) {
1046 return nil, errors.New("unImplemented")
1047}
1048
1049//SimulateAlarm is unimplemented
1050func (oo *OpenONUAC) SimulateAlarm(context.Context, *ic.SimulateAlarmMessage) (*common.OperationResp, error) {
1051 return nil, errors.New("unImplemented")
1052}
1053
1054//SetExtValue is unimplemented
1055func (oo *OpenONUAC) SetExtValue(context.Context, *ic.SetExtValueMessage) (*empty.Empty, error) {
1056 return nil, errors.New("unImplemented")
1057}
1058
1059//SetSingleValue is unimplemented
1060func (oo *OpenONUAC) SetSingleValue(context.Context, *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error) {
1061 return nil, errors.New("unImplemented")
1062}
1063
1064//StartOmciTest not implemented
1065func (oo *OpenONUAC) StartOmciTest(ctx context.Context, test *ic.OMCITest) (*voltha.TestResponse, error) {
1066 return nil, errors.New("unImplemented")
1067}
1068
1069//SuppressEvent unimplemented
1070func (oo *OpenONUAC) SuppressEvent(ctx context.Context, filter *voltha.EventFilter) (*empty.Empty, error) {
1071 return nil, errors.New("unImplemented")
1072}
1073
1074//UnSuppressEvent unimplemented
1075func (oo *OpenONUAC) UnSuppressEvent(ctx context.Context, filter *voltha.EventFilter) (*empty.Empty, error) {
1076 return nil, errors.New("unImplemented")
1077}
1078
1079//GetImageDownloadStatus is unimplemented
1080func (oo *OpenONUAC) GetImageDownloadStatus(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1081 return nil, errors.New("unImplemented")
1082}
1083
1084//CancelImageDownload is unimplemented
1085func (oo *OpenONUAC) CancelImageDownload(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1086 return nil, errors.New("unImplemented")
1087}
1088
1089//RevertImageUpdate is unimplemented
1090func (oo *OpenONUAC) RevertImageUpdate(ctx context.Context, imageInfo *ic.ImageDownloadMessage) (*voltha.ImageDownload, error) {
1091 return nil, errors.New("unImplemented")
1092}
1093
1094// UpdateFlowsBulk is unimplemented
1095func (oo *OpenONUAC) UpdateFlowsBulk(ctx context.Context, flows *ic.BulkFlows) (*empty.Empty, error) {
1096 return nil, errors.New("unImplemented")
1097}
1098
1099//SelfTestDevice unimplented
1100func (oo *OpenONUAC) SelfTestDevice(ctx context.Context, device *voltha.Device) (*empty.Empty, error) {
1101 return nil, errors.New("unImplemented")
1102}
1103
1104//SendPacketOut sends packet out to the device
1105func (oo *OpenONUAC) SendPacketOut(ctx context.Context, packet *ic.PacketOut) (*empty.Empty, error) {
1106 return nil, errors.New("unImplemented")
1107}
1108
1109// EnablePort to Enable PON/NNI interface - seems not to be used/required according to python code
1110func (oo *OpenONUAC) EnablePort(ctx context.Context, port *voltha.Port) (*empty.Empty, error) {
1111 return nil, errors.New("unImplemented")
1112}
1113
1114// DisablePort to Disable pon/nni interface - seems not to be used/required according to python code
1115func (oo *OpenONUAC) DisablePort(ctx context.Context, port *voltha.Port) (*empty.Empty, error) {
1116 return nil, errors.New("unImplemented")
1117}
1118
1119// GetExtValue - unimplemented
1120func (oo *OpenONUAC) GetExtValue(ctx context.Context, extInfo *ic.GetExtValueMessage) (*voltha.ReturnValues, error) {
1121 return nil, errors.New("unImplemented")
1122}
1123
1124// ChildDeviceLost - unimplemented
1125func (oo *OpenONUAC) ChildDeviceLost(ctx context.Context, childDevice *voltha.Device) (*empty.Empty, error) {
1126 return nil, errors.New("unImplemented")
1127}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001128
1129// GetSupportedFsms - TODO: add comment
1130func (oo *OpenONUAC) GetSupportedFsms() *cmn.OmciDeviceFsms {
1131 return oo.pSupportedFsms
1132}
1133
1134// LockMutexMibTemplateGenerated - TODO: add comment
1135func (oo *OpenONUAC) LockMutexMibTemplateGenerated() {
1136 oo.mutexMibTemplateGenerated.Lock()
1137}
1138
1139// UnlockMutexMibTemplateGenerated - TODO: add comment
1140func (oo *OpenONUAC) UnlockMutexMibTemplateGenerated() {
1141 oo.mutexMibTemplateGenerated.Unlock()
1142}
1143
1144// GetMibTemplatesGenerated - TODO: add comment
1145func (oo *OpenONUAC) GetMibTemplatesGenerated(mibTemplatePath string) (value bool, exist bool) {
1146 value, exist = oo.mibTemplatesGenerated[mibTemplatePath]
1147 return value, exist
1148}
1149
1150// SetMibTemplatesGenerated - TODO: add comment
1151func (oo *OpenONUAC) SetMibTemplatesGenerated(mibTemplatePath string, value bool) {
1152 oo.mibTemplatesGenerated[mibTemplatePath] = value
1153}
1154
1155// RLockMutexDeviceHandlersMap - TODO: add comment
1156func (oo *OpenONUAC) RLockMutexDeviceHandlersMap() {
1157 oo.mutexDeviceHandlersMap.RLock()
1158}
1159
1160// RUnlockMutexDeviceHandlersMap - TODO: add comment
1161func (oo *OpenONUAC) RUnlockMutexDeviceHandlersMap() {
1162 oo.mutexDeviceHandlersMap.RUnlock()
1163}
1164
1165// GetDeviceHandler - TODO: add comment
1166func (oo *OpenONUAC) GetDeviceHandler(deviceID string) (value cmn.IdeviceHandler, exist bool) {
1167 value, exist = oo.deviceHandlers[deviceID]
1168 return value, exist
1169}