Girish Gowdra | 6450343 | 2020-01-07 10:59:10 +0530 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019-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 resourcemanager provides the utility for managing resources |
| 18 | package core |
| 19 | |
| 20 | import ( |
| 21 | "errors" |
| 22 | "fmt" |
| 23 | "strconv" |
| 24 | "strings" |
| 25 | |
| 26 | "github.com/opencord/voltha-lib-go/v2/pkg/log" |
| 27 | ponrmgr "github.com/opencord/voltha-lib-go/v2/pkg/ponresourcemanager" |
| 28 | "github.com/opencord/voltha-protos/v2/go/openolt" |
| 29 | ) |
| 30 | |
| 31 | func init() { |
| 32 | _, _ = log.AddPackage(log.JSON, log.DebugLevel, nil) |
| 33 | } |
| 34 | |
| 35 | // OpenOltResourceMgr holds resource related information as provided below for each field |
| 36 | type OpenOltResourceMgr struct { |
| 37 | deviceInfo *openolt.DeviceInfo |
| 38 | // array of pon resource managers per interface technology |
| 39 | ResourceMgrs map[uint32]*ponrmgr.PONResourceManager |
| 40 | } |
| 41 | |
| 42 | // NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager |
| 43 | // instances according to technology. Initializes the default resource ranges for all |
| 44 | // the resources. |
| 45 | func NewResourceMgr(deviceID string, KVStoreHostPort string, kvStoreType string, deviceType string, devInfo *openolt.DeviceInfo) *OpenOltResourceMgr { |
| 46 | var ResourceMgr OpenOltResourceMgr |
| 47 | log.Debugf("Init new resource manager") |
| 48 | |
| 49 | ResourceMgr.deviceInfo = devInfo |
| 50 | |
| 51 | Ranges := make(map[string]*openolt.DeviceInfo_DeviceResourceRanges) |
| 52 | RsrcMgrsByTech := make(map[string]*ponrmgr.PONResourceManager) |
| 53 | ResourceMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager) |
| 54 | |
| 55 | // TODO self.args = registry('main').get_args() |
| 56 | |
| 57 | /* |
| 58 | If a legacy driver returns protobuf without any ranges,s synthesize one from |
| 59 | the legacy global per-device information. This, in theory, is temporary until |
| 60 | the legacy drivers are upgrade to support pool ranges. |
| 61 | */ |
| 62 | if devInfo.Ranges == nil { |
| 63 | var ranges openolt.DeviceInfo_DeviceResourceRanges |
| 64 | ranges.Technology = devInfo.GetTechnology() |
| 65 | |
| 66 | NumPONPorts := devInfo.GetPonPorts() |
| 67 | var index uint32 |
| 68 | for index = 0; index < NumPONPorts; index++ { |
| 69 | ranges.IntfIds = append(ranges.IntfIds, index) |
| 70 | } |
| 71 | |
| 72 | var Pool openolt.DeviceInfo_DeviceResourceRanges_Pool |
| 73 | Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID |
| 74 | Pool.Start = devInfo.OnuIdStart |
| 75 | Pool.End = devInfo.OnuIdEnd |
| 76 | Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF |
| 77 | onuPool := Pool |
| 78 | ranges.Pools = append(ranges.Pools, &onuPool) |
| 79 | |
| 80 | Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID |
| 81 | Pool.Start = devInfo.AllocIdStart |
| 82 | Pool.End = devInfo.AllocIdEnd |
| 83 | Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH |
| 84 | allocPool := Pool |
| 85 | ranges.Pools = append(ranges.Pools, &allocPool) |
| 86 | |
| 87 | Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID |
| 88 | Pool.Start = devInfo.GemportIdStart |
| 89 | Pool.End = devInfo.GemportIdEnd |
| 90 | Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH |
| 91 | gemPool := Pool |
| 92 | ranges.Pools = append(ranges.Pools, &gemPool) |
| 93 | |
| 94 | Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID |
| 95 | Pool.Start = devInfo.FlowIdStart |
| 96 | Pool.End = devInfo.FlowIdEnd |
| 97 | Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH |
| 98 | ranges.Pools = append(ranges.Pools, &Pool) |
| 99 | // Add to device info |
| 100 | devInfo.Ranges = append(devInfo.Ranges, &ranges) |
| 101 | } |
| 102 | |
| 103 | // Create a separate Resource Manager instance for each range. This assumes that |
| 104 | // each technology is represented by only a single range |
| 105 | var GlobalPONRsrcMgr *ponrmgr.PONResourceManager |
| 106 | var err error |
| 107 | IPPort := strings.Split(KVStoreHostPort, ":") |
| 108 | for _, TechRange := range devInfo.Ranges { |
| 109 | technology := TechRange.Technology |
| 110 | log.Debugf("Device info technology %s", technology) |
| 111 | Ranges[technology] = TechRange |
| 112 | port, _ := strconv.Atoi(IPPort[1]) |
| 113 | RsrcMgrsByTech[technology], err = ponrmgr.NewPONResourceManager(technology, deviceType, deviceID, |
| 114 | kvStoreType, IPPort[0], port) |
| 115 | if err != nil { |
| 116 | log.Errorf("Failed to create pon resource manager instance for technology %s", technology) |
| 117 | return nil |
| 118 | } |
| 119 | // resource_mgrs_by_tech[technology] = resource_mgr |
| 120 | if GlobalPONRsrcMgr == nil { |
| 121 | GlobalPONRsrcMgr = RsrcMgrsByTech[technology] |
| 122 | } |
| 123 | for _, IntfID := range TechRange.IntfIds { |
| 124 | ResourceMgr.ResourceMgrs[(IntfID)] = RsrcMgrsByTech[technology] |
| 125 | } |
| 126 | // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange) |
| 127 | InitializeDeviceResourceRangeAndPool(RsrcMgrsByTech[technology], GlobalPONRsrcMgr, |
| 128 | TechRange, devInfo) |
| 129 | } |
| 130 | // After we have initialized resource ranges, initialize the |
| 131 | // resource pools accordingly. |
| 132 | for _, PONRMgr := range RsrcMgrsByTech { |
| 133 | _ = PONRMgr.InitDeviceResourcePool() |
| 134 | } |
| 135 | log.Info("Initialization of resource manager success!") |
| 136 | return &ResourceMgr |
| 137 | } |
| 138 | |
| 139 | // InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply |
| 140 | // device specific information. If KV doesn't exist |
| 141 | // or is broader than the device, the device's information will |
| 142 | // dictate the range limits |
| 143 | func InitializeDeviceResourceRangeAndPool(ponRMgr *ponrmgr.PONResourceManager, globalPONRMgr *ponrmgr.PONResourceManager, |
| 144 | techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) { |
| 145 | |
| 146 | // init the resource range pool according to the sharing type |
| 147 | |
| 148 | log.Debugf("Resource range pool init for technology %s", ponRMgr.Technology) |
| 149 | // first load from KV profiles |
| 150 | status := ponRMgr.InitResourceRangesFromKVStore() |
| 151 | if !status { |
| 152 | log.Debugf("Failed to load resource ranges from KV store for tech %s", ponRMgr.Technology) |
| 153 | } |
| 154 | |
| 155 | /* |
| 156 | Then apply device specific information. If KV doesn't exist |
| 157 | or is broader than the device, the device's information will |
| 158 | dictate the range limits |
| 159 | */ |
| 160 | log.Debugf("Using device info to init pon resource ranges for tech", ponRMgr.Technology) |
| 161 | |
| 162 | ONUIDStart := devInfo.OnuIdStart |
| 163 | ONUIDEnd := devInfo.OnuIdEnd |
| 164 | ONUIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF |
| 165 | ONUIDSharedPoolID := uint32(0) |
| 166 | AllocIDStart := devInfo.AllocIdStart |
| 167 | AllocIDEnd := devInfo.AllocIdEnd |
| 168 | AllocIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation |
| 169 | AllocIDSharedPoolID := uint32(0) |
| 170 | GEMPortIDStart := devInfo.GemportIdStart |
| 171 | GEMPortIDEnd := devInfo.GemportIdEnd |
| 172 | GEMPortIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation |
| 173 | GEMPortIDSharedPoolID := uint32(0) |
| 174 | FlowIDStart := devInfo.FlowIdStart |
| 175 | FlowIDEnd := devInfo.FlowIdEnd |
| 176 | FlowIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation |
| 177 | FlowIDSharedPoolID := uint32(0) |
| 178 | |
| 179 | var FirstIntfPoolID uint32 |
| 180 | var SharedPoolID uint32 |
| 181 | |
| 182 | /* |
| 183 | * As a zero check is made against SharedPoolID to check whether the resources are shared across all intfs |
| 184 | * if resources are shared across interfaces then SharedPoolID is given a positive number. |
| 185 | */ |
| 186 | for _, FirstIntfPoolID = range techRange.IntfIds { |
| 187 | // skip the intf id 0 |
| 188 | if FirstIntfPoolID == 0 { |
| 189 | continue |
| 190 | } |
| 191 | break |
| 192 | } |
| 193 | |
| 194 | for _, RangePool := range techRange.Pools { |
| 195 | if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH { |
| 196 | SharedPoolID = FirstIntfPoolID |
| 197 | } else if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_SAME_TECH { |
| 198 | SharedPoolID = FirstIntfPoolID |
| 199 | } else { |
| 200 | SharedPoolID = 0 |
| 201 | } |
| 202 | if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID { |
| 203 | ONUIDStart = RangePool.Start |
| 204 | ONUIDEnd = RangePool.End |
| 205 | ONUIDShared = RangePool.Sharing |
| 206 | ONUIDSharedPoolID = SharedPoolID |
| 207 | } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID { |
| 208 | AllocIDStart = RangePool.Start |
| 209 | AllocIDEnd = RangePool.End |
| 210 | AllocIDShared = RangePool.Sharing |
| 211 | AllocIDSharedPoolID = SharedPoolID |
| 212 | } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID { |
| 213 | GEMPortIDStart = RangePool.Start |
| 214 | GEMPortIDEnd = RangePool.End |
| 215 | GEMPortIDShared = RangePool.Sharing |
| 216 | GEMPortIDSharedPoolID = SharedPoolID |
| 217 | } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID { |
| 218 | FlowIDStart = RangePool.Start |
| 219 | FlowIDEnd = RangePool.End |
| 220 | FlowIDShared = RangePool.Sharing |
| 221 | FlowIDSharedPoolID = SharedPoolID |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | log.Debugw("Device info init", log.Fields{"technology": techRange.Technology, |
| 226 | "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd, "onu_id_shared_pool_id": ONUIDSharedPoolID, |
| 227 | "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd, |
| 228 | "alloc_id_shared_pool_id": AllocIDSharedPoolID, |
| 229 | "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd, |
| 230 | "gemport_id_shared_pool_id": GEMPortIDSharedPoolID, |
| 231 | "flow_id_start": FlowIDStart, |
| 232 | "flow_id_end_idx": FlowIDEnd, |
| 233 | "flow_id_shared_pool_id": FlowIDSharedPoolID, |
| 234 | "intf_ids": techRange.IntfIds, |
| 235 | "uni_id_start": 0, |
| 236 | "uni_id_end_idx": 1, /*MaxUNIIDperONU()*/ |
| 237 | }) |
| 238 | |
| 239 | ponRMgr.InitDefaultPONResourceRanges(ONUIDStart, ONUIDEnd, ONUIDSharedPoolID, |
| 240 | AllocIDStart, AllocIDEnd, AllocIDSharedPoolID, |
| 241 | GEMPortIDStart, GEMPortIDEnd, GEMPortIDSharedPoolID, |
| 242 | FlowIDStart, FlowIDEnd, FlowIDSharedPoolID, 0, 1, |
| 243 | devInfo.PonPorts, techRange.IntfIds) |
| 244 | |
| 245 | // For global sharing, make sure to refresh both local and global resource manager instances' range |
| 246 | |
| 247 | if ONUIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH { |
| 248 | globalPONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd, |
| 249 | "", 0, nil) |
| 250 | ponRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd, |
| 251 | "", 0, globalPONRMgr) |
| 252 | } |
| 253 | if AllocIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH { |
| 254 | globalPONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd, |
| 255 | "", 0, nil) |
| 256 | |
| 257 | ponRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd, |
| 258 | "", 0, globalPONRMgr) |
| 259 | } |
| 260 | if GEMPortIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH { |
| 261 | globalPONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd, |
| 262 | "", 0, nil) |
| 263 | ponRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd, |
| 264 | "", 0, globalPONRMgr) |
| 265 | } |
| 266 | if FlowIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH { |
| 267 | globalPONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd, |
| 268 | "", 0, nil) |
| 269 | ponRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd, |
| 270 | "", 0, globalPONRMgr) |
| 271 | } |
| 272 | |
| 273 | // Make sure loaded range fits the platform bit encoding ranges |
| 274 | ponRMgr.UpdateRanges(ponrmgr.UNI_ID_START_IDX, 0, ponrmgr.UNI_ID_END_IDX /* TODO =OpenOltPlatform.MAX_UNIS_PER_ONU-1*/, 1, "", 0, nil) |
| 275 | } |
| 276 | |
| 277 | // Delete clears used resources for the particular olt device being deleted |
| 278 | func (RsrcMgr *OpenOltResourceMgr) Delete() error { |
| 279 | /* TODO |
| 280 | def __del__(self): |
| 281 | self.log.info("clearing-device-resource-pool") |
| 282 | for key, resource_mgr in self.resource_mgrs.iteritems(): |
| 283 | resource_mgr.clear_device_resource_pool() |
| 284 | |
| 285 | def assert_pon_id_limit(self, pon_intf_id): |
| 286 | assert pon_intf_id in self.resource_mgrs |
| 287 | |
| 288 | def assert_onu_id_limit(self, pon_intf_id, onu_id): |
| 289 | self.assert_pon_id_limit(pon_intf_id) |
| 290 | self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID) |
| 291 | |
| 292 | @property |
| 293 | def max_uni_id_per_onu(self): |
| 294 | return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni |
| 295 | |
| 296 | def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id): |
| 297 | self.assert_onu_id_limit(pon_intf_id, onu_id) |
| 298 | self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID) |
| 299 | */ |
| 300 | for _, rsrcMgr := range RsrcMgr.ResourceMgrs { |
| 301 | if err := rsrcMgr.ClearDeviceResourcePool(); err != nil { |
| 302 | log.Debug("Failed to clear device resource pool") |
| 303 | return err |
| 304 | } |
| 305 | } |
| 306 | log.Debug("Cleared device resource pool") |
| 307 | return nil |
| 308 | } |
| 309 | |
| 310 | // GetONUID returns the available OnuID for the given pon-port |
| 311 | func (RsrcMgr *OpenOltResourceMgr) GetONUID(ponIntfID uint32) (uint32, error) { |
| 312 | // Check if Pon Interface ID is present in Resource-manager-map |
| 313 | if _, ok := RsrcMgr.ResourceMgrs[ponIntfID]; !ok { |
| 314 | err := errors.New("invalid-pon-interface-" + strconv.Itoa(int(ponIntfID))) |
| 315 | return 0, err |
| 316 | } |
| 317 | // Get ONU id for a provided pon interface ID. |
| 318 | ONUID, err := RsrcMgr.ResourceMgrs[ponIntfID].GetResourceID(ponIntfID, |
| 319 | ponrmgr.ONU_ID, 1) |
| 320 | if err != nil { |
| 321 | log.Errorf("Failed to get resource for interface %d for type %s", |
| 322 | ponIntfID, ponrmgr.ONU_ID) |
| 323 | return 0, err |
| 324 | } |
| 325 | if ONUID != nil { |
| 326 | RsrcMgr.ResourceMgrs[ponIntfID].InitResourceMap(fmt.Sprintf("%d,%d", ponIntfID, ONUID[0])) |
| 327 | return ONUID[0], err |
| 328 | } |
| 329 | |
| 330 | return 0, err // return OnuID 0 on error |
| 331 | } |
| 332 | |
| 333 | // GetAllocID return the first Alloc ID for a given pon interface id and onu id and then update the resource map on |
| 334 | // the KV store with the list of alloc_ids allocated for the pon_intf_onu_id tuple |
| 335 | // Currently of all the alloc_ids available, it returns the first alloc_id in the list for tha given ONU |
| 336 | func (RsrcMgr *OpenOltResourceMgr) GetAllocID(intfID uint32, onuID uint32, uniID uint32) uint32 { |
| 337 | |
| 338 | var err error |
| 339 | IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID) |
| 340 | AllocID := RsrcMgr.ResourceMgrs[intfID].GetCurrentAllocIDForOnu(IntfOnuIDUniID) |
| 341 | if AllocID != nil { |
| 342 | // Since we support only one alloc_id for the ONU at the moment, |
| 343 | // return the first alloc_id in the list, if available, for that |
| 344 | // ONU. |
| 345 | log.Debugw("Retrieved alloc ID from pon resource mgr", log.Fields{"AllocID": AllocID}) |
| 346 | return AllocID[0] |
| 347 | } |
| 348 | AllocID, err = RsrcMgr.ResourceMgrs[intfID].GetResourceID(intfID, |
| 349 | ponrmgr.ALLOC_ID, 1) |
| 350 | |
| 351 | if AllocID == nil || err != nil { |
| 352 | log.Error("Failed to allocate alloc id") |
| 353 | return 0 |
| 354 | } |
| 355 | // update the resource map on KV store with the list of alloc_id |
| 356 | // allocated for the pon_intf_onu_id tuple |
| 357 | err = RsrcMgr.ResourceMgrs[intfID].UpdateAllocIdsForOnu(IntfOnuIDUniID, AllocID) |
| 358 | if err != nil { |
| 359 | log.Error("Failed to update Alloc ID") |
| 360 | return 0 |
| 361 | } |
| 362 | log.Debugw("Allocated new Tcont from pon resource mgr", log.Fields{"AllocID": AllocID}) |
| 363 | return AllocID[0] |
| 364 | } |
| 365 | |
| 366 | // GetGEMPortID gets gem port id for a particular pon port, onu id and uni id and then update the resource map on |
| 367 | // the KV store with the list of gemport_id allocated for the pon_intf_onu_id tuple |
| 368 | func (RsrcMgr *OpenOltResourceMgr) GetGEMPortID(ponPort uint32, onuID uint32, |
| 369 | uniID uint32, NumOfPorts uint32) ([]uint32, error) { |
| 370 | |
| 371 | /* Get gem port id for a particular pon port, onu id |
| 372 | and uni id. |
| 373 | */ |
| 374 | |
| 375 | var err error |
| 376 | IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID) |
| 377 | |
| 378 | GEMPortList := RsrcMgr.ResourceMgrs[ponPort].GetCurrentGEMPortIDsForOnu(IntfOnuIDUniID) |
| 379 | if GEMPortList != nil { |
| 380 | return GEMPortList, nil |
| 381 | } |
| 382 | |
| 383 | GEMPortList, err = RsrcMgr.ResourceMgrs[ponPort].GetResourceID(ponPort, |
| 384 | ponrmgr.GEMPORT_ID, NumOfPorts) |
| 385 | if err != nil && GEMPortList == nil { |
| 386 | log.Errorf("Failed to get gem port id for %s", IntfOnuIDUniID) |
| 387 | return nil, err |
| 388 | } |
| 389 | |
| 390 | // update the resource map on KV store with the list of gemport_id |
| 391 | // allocated for the pon_intf_onu_id tuple |
| 392 | err = RsrcMgr.ResourceMgrs[ponPort].UpdateGEMPortIDsForOnu(IntfOnuIDUniID, |
| 393 | GEMPortList) |
| 394 | if err != nil { |
| 395 | log.Errorf("Failed to update GEM ports to kv store for %s", IntfOnuIDUniID) |
| 396 | return nil, err |
| 397 | } |
| 398 | |
| 399 | return GEMPortList, err |
| 400 | } |
| 401 | |
| 402 | // FreeFlowID returns the free flow id for a given interface, onu id and uni id |
| 403 | func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(IntfID uint32, onuID int32, |
| 404 | uniID int32, FlowID uint32) { |
| 405 | var IntfONUID string |
| 406 | var err error |
| 407 | FlowIds := make([]uint32, 0) |
| 408 | |
| 409 | FlowIds = append(FlowIds, FlowID) |
| 410 | IntfONUID = fmt.Sprintf("%d,%d,%d", IntfID, onuID, uniID) |
| 411 | err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(IntfONUID, FlowID, false) |
| 412 | if err != nil { |
| 413 | log.Errorw("Failed to Update flow id for", log.Fields{"intf": IntfONUID}) |
| 414 | } |
| 415 | RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(IntfONUID, FlowID) |
| 416 | RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.FLOW_ID, FlowIds) |
| 417 | } |
| 418 | |
| 419 | // FreeFlowIDs releases the flow Ids |
| 420 | func (RsrcMgr *OpenOltResourceMgr) FreeFlowIDs(IntfID uint32, onuID uint32, |
| 421 | uniID uint32, FlowID []uint32) { |
| 422 | |
| 423 | RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.FLOW_ID, FlowID) |
| 424 | |
| 425 | var IntfOnuIDUniID string |
| 426 | var err error |
| 427 | for _, flow := range FlowID { |
| 428 | IntfOnuIDUniID = fmt.Sprintf("%d,%d,%d", IntfID, onuID, uniID) |
| 429 | err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(IntfOnuIDUniID, flow, false) |
| 430 | if err != nil { |
| 431 | log.Errorw("Failed to Update flow id for", log.Fields{"intf": IntfOnuIDUniID}) |
| 432 | } |
| 433 | RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(IntfOnuIDUniID, flow) |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | // FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association |
| 438 | // for the given OLT device. |
| 439 | func (RsrcMgr *OpenOltResourceMgr) FreeAllocID(IntfID uint32, allocID uint32) { |
| 440 | allocIDs := make([]uint32, 0) |
| 441 | allocIDs = append(allocIDs, allocID) |
| 442 | RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.ALLOC_ID, allocIDs) |
| 443 | } |
| 444 | |
| 445 | // FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association |
| 446 | // for the given OLT device. |
| 447 | func (RsrcMgr *OpenOltResourceMgr) FreeGemPortID(IntfID uint32, gemPortID uint32) { |
| 448 | gemPortIDs := make([]uint32, 0) |
| 449 | gemPortIDs = append(gemPortIDs, gemPortID) |
| 450 | RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.GEMPORT_ID, gemPortIDs) |
| 451 | } |