blob: 1539b9a85448725b30b9882edd9a8e56dc0888f0 [file] [log] [blame]
mpagenkoaf801632020-07-03 10:00:42 +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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/json"
23 "sync"
24
25 "github.com/opencord/voltha-lib-go/v3/pkg/db"
26 "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore"
27 "github.com/opencord/voltha-lib-go/v3/pkg/log"
28 tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
29)
30
31const cBasePathTechProfileKVStore = "service/voltha/technology_profiles"
32
33type resourceEntry int
34
35const (
36 cResourceGemPort resourceEntry = 1
37 cResourceTcont resourceEntry = 2
38)
39
40type onuSerialNumber struct {
41 sliceVendorID []byte
42 sliceVendorSpecific []byte
43}
44
45type onuPersistentData struct {
46 persOnuID uint32
47 persIntfID uint32
48 persSnr onuSerialNumber
49 persAdminState string
50 persOperState string
51 persUniTpPath map[uint32]string
52 persUniTpData map[uint32]tp.TechProfile
53}
54
55//OnuUniTechProf structure holds information about the TechProfiles attached to Uni Ports of the ONU
56type OnuUniTechProf struct {
57 deviceID string
58 baseDeviceHandler *DeviceHandler
59 tpProcMutex sync.RWMutex
60 sOnuPersistentData onuPersistentData
61 techProfileKVStore *db.Backend
62}
63
64//NewOnuUniTechProf returns the instance of a OnuUniTechProf
65//(one instance per ONU/deviceHandler for all possible UNI's)
66func NewOnuUniTechProf(ctx context.Context, aDeviceID string, aDeviceHandler *DeviceHandler) *OnuUniTechProf {
67 logger.Infow("init-OnuUniTechProf", log.Fields{"deviceId": aDeviceID})
68 var onuTP OnuUniTechProf
69 onuTP.deviceID = aDeviceID
70 onuTP.baseDeviceHandler = aDeviceHandler
71 onuTP.tpProcMutex = sync.RWMutex{}
72 onuTP.sOnuPersistentData.persUniTpPath = make(map[uint32]string)
73 onuTP.sOnuPersistentData.persUniTpData = make(map[uint32]tp.TechProfile)
74
75 onuTP.techProfileKVStore = aDeviceHandler.SetBackend(cBasePathTechProfileKVStore)
76 if onuTP.techProfileKVStore == nil {
77 logger.Errorw("Can't access techProfileKVStore - no backend connection to service",
78 log.Fields{"deviceID": aDeviceID, "service": cBasePathTechProfileKVStore})
79 }
80 return &onuTP
81}
82
83// lockTpProcMutex locks OnuUniTechProf processing mutex
84func (onuTP *OnuUniTechProf) lockTpProcMutex() {
85 onuTP.tpProcMutex.Lock()
86}
87
88// unlockTpProcMutex unlocks OnuUniTechProf processing mutex
89func (onuTP *OnuUniTechProf) unlockTpProcMutex() {
90 onuTP.tpProcMutex.Unlock()
91}
92
93// updateOnuUniTpPath verifies and updates changes in the kvStore onuUniTpPath
94func (onuTP *OnuUniTechProf) updateOnuUniTpPath(aUniID uint32, aPathString string) bool {
95 /* within some specific InterAdapter processing request write/read access to data is ensured to be sequentially,
96 as also the complete sequence is ensured to 'run to completion' before some new request is accepted
97 no specific concurrency protection to sOnuPersistentData is required here
98 */
99 if existingPath, present := onuTP.sOnuPersistentData.persUniTpPath[aUniID]; present {
100 // uni entry already exists
101 //logger.Debugw(" already exists", log.Fields{"for InstanceId": a_uniInstNo})
102 if existingPath != aPathString {
103 if aPathString == "" {
104 //existing entry to be deleted
105 logger.Debugw("UniTp path delete", log.Fields{
106 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
107 delete(onuTP.sOnuPersistentData.persUniTpPath, aUniID)
108 } else {
109 //existing entry to be modified
110 logger.Debugw("UniTp path modify", log.Fields{
111 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
112 onuTP.sOnuPersistentData.persUniTpPath[aUniID] = aPathString
113 }
114 return true
115 }
116 //entry already exists
117 logger.Debugw("UniTp path already exists", log.Fields{
118 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
119 return false
120 }
121 //uni entry does not exist
122 if aPathString == "" {
123 //delete request in non-existing state , accept as no change
124 logger.Debugw("UniTp path already removed", log.Fields{
125 "deviceID": onuTP.deviceID, "uniID": aUniID})
126 return false
127 }
128 //new entry to be set
129 logger.Debugw("New UniTp path set", log.Fields{
130 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
131 onuTP.sOnuPersistentData.persUniTpPath[aUniID] = aPathString
132 return true
133}
134
135func (onuTP *OnuUniTechProf) configureUniTp(aUniID uint32, aPathString string, wg *sync.WaitGroup) {
136 defer wg.Done()
137 logger.Debugw("configure the Uni according to TpPath", log.Fields{
138 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString})
139
140 //TODO!!!
141 // reaction on existing tp, deletion of tp, start the corresponding OMCI configuation of the UNI port
142
143 if onuTP.techProfileKVStore == nil {
144 logger.Debug("techProfileKVStore not set - abort")
145 return
146 }
147
148 Value, err := onuTP.techProfileKVStore.Get(context.TODO(), aPathString)
149 if err == nil {
150 if Value != nil {
151 logger.Debugw("tech-profile read",
152 log.Fields{"Key": Value.Key, "Value": Value.Value})
153 tpTmpBytes, _ := kvstore.ToByte(Value.Value)
154
155 var tpInst tp.TechProfile
156 if err = json.Unmarshal(tpTmpBytes, &tpInst); err != nil {
157 logger.Errorw("TechProf - Failed to unmarshal tech-profile into tpInst",
158 log.Fields{"error": err, "device-id": onuTP.deviceID})
159 } else {
160 logger.Debugw("TechProf - tpInst", log.Fields{"tpInst": tpInst})
161 onuTP.sOnuPersistentData.persUniTpData[aUniID] = tpInst
162
163 // access examples
164 logger.Debugw("TechProf - name",
165 log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].Name": onuTP.sOnuPersistentData.persUniTpData[aUniID].Name})
166 //
167 logger.Debugw("TechProf - instance_control.max_gem_payload_size",
168 log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].InstanceCtrl.MaxGemPayloadSize": onuTP.sOnuPersistentData.persUniTpData[aUniID].InstanceCtrl.MaxGemPayloadSize})
169 //
170 logger.Debugw("TechProf - downstream_gem_port_attribute_list.discard_config.max_threshold",
171 log.Fields{"onuTP.sOnuPersistentData.persUniTpData[aUniID].DownstreamGemPortAttributeList[0].DiscardConfig.MaxThreshold": onuTP.sOnuPersistentData.persUniTpData[aUniID].DownstreamGemPortAttributeList[0].DiscardConfig.MaxThreshold})
172 }
173 } else {
174 logger.Debugw("No tech-profile found", log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
175 }
176 } else {
177 logger.Errorw("kvstore-get failed for path",
178 log.Fields{"path": aPathString, "device-id": onuTP.deviceID})
179 }
180}
181
182func (onuTP *OnuUniTechProf) updateOnuTpPathKvStore(wg *sync.WaitGroup) {
183 defer wg.Done()
184 logger.Debugw("this would update the ONU's TpPath in KVStore", log.Fields{
185 "deviceID": onuTP.deviceID})
186 //TODO!!!
187 //make use of onuTP.sOnuPersistentData to store the TpPath to KVStore
188}
189
190// deleteTpRessource removes ressources from the ONU's specified Uni
191func (onuTP *OnuUniTechProf) deleteTpRessource(aUniID uint32, aPathString string,
192 aRessource resourceEntry, aEntryID uint32, wg *sync.WaitGroup) {
193 defer wg.Done()
194 logger.Debugw("this would remove TP resources from ONU's UNI", log.Fields{
195 "deviceID": onuTP.deviceID, "uniID": aUniID, "path": aPathString, "ressource": aRessource})
196 //TODO!!!
197}
198
199func (onuTP *OnuUniTechProf) waitForTpCompletion(wg *sync.WaitGroup) {
200 wg.Wait()
201 logger.Debug("some TechProfile Processing completed")
202 onuTP.tpProcMutex.Unlock() //allow further TP related processing
203}