blob: 00cfdc18ca88b66f6e3e8cd0f64a30e312d30c5c [file] [log] [blame]
Mannikraj Kodilingam23798822019-04-10 14:34:01 +05301/*
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
17package techprofile
18
19import (
20 "encoding/json"
21 "errors"
22 "fmt"
23 "strconv"
24
25 "github.com/opencord/voltha-go/common/log"
26 "github.com/opencord/voltha-go/db/kvstore"
27 "github.com/opencord/voltha-go/db/model"
28 openolt_pb "github.com/opencord/voltha-protos/go/openolt"
29)
30
31// Interface to pon resource manager APIs
32type iPonResourceMgr interface {
33 GetResourceID(IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error)
34 GetResourceTypeAllocID() string
35 GetResourceTypeGemPortID() string
36 GetTechnology() string
37}
38
39type Direction int32
40
41const (
42 Direction_UPSTREAM Direction = 0
43 Direction_DOWNSTREAM Direction = 1
44 Direction_BIDIRECTIONAL Direction = 2
45)
46
47var Direction_name = map[Direction]string{
48 0: "UPSTREAM",
49 1: "DOWNSTREAM",
50 2: "BIDIRECTIONAL",
51}
52
53type SchedulingPolicy int32
54
55const (
56 SchedulingPolicy_WRR SchedulingPolicy = 0
57 SchedulingPolicy_StrictPriority SchedulingPolicy = 1
58 SchedulingPolicy_Hybrid SchedulingPolicy = 2
59)
60
61var SchedulingPolicy_name = map[SchedulingPolicy]string{
62 0: "WRR",
63 1: "StrictPriority",
64 2: "Hybrid",
65}
66
67type AdditionalBW int32
68
69const (
70 AdditionalBW_AdditionalBW_None AdditionalBW = 0
71 AdditionalBW_AdditionalBW_NA AdditionalBW = 1
72 AdditionalBW_AdditionalBW_BestEffort AdditionalBW = 2
73 AdditionalBW_AdditionalBW_Auto AdditionalBW = 3
74)
75
76var AdditionalBW_name = map[AdditionalBW]string{
77 0: "AdditionalBW_None",
78 1: "AdditionalBW_NA",
79 2: "AdditionalBW_BestEffort",
80 3: "AdditionalBW_Auto",
81}
82
83type DiscardPolicy int32
84
85const (
86 DiscardPolicy_TailDrop DiscardPolicy = 0
87 DiscardPolicy_WTailDrop DiscardPolicy = 1
88 DiscardPolicy_Red DiscardPolicy = 2
89 DiscardPolicy_WRed DiscardPolicy = 3
90)
91
92var DiscardPolicy_name = map[DiscardPolicy]string{
93 0: "TailDrop",
94 1: "WTailDrop",
95 2: "Red",
96 3: "WRed",
97}
98
99/*
100type InferredAdditionBWIndication int32
101
102const (
103 InferredAdditionBWIndication_InferredAdditionBWIndication_None InferredAdditionBWIndication = 0
104 InferredAdditionBWIndication_InferredAdditionBWIndication_Assured InferredAdditionBWIndication = 1
105 InferredAdditionBWIndication_InferredAdditionBWIndication_BestEffort InferredAdditionBWIndication = 2
106)
107
108var InferredAdditionBWIndication_name = map[int32]string{
109 0: "InferredAdditionBWIndication_None",
110 1: "InferredAdditionBWIndication_Assured",
111 2: "InferredAdditionBWIndication_BestEffort",
112}
113*/
114// instance control defaults
115const (
116 defaultOnuInstance = "multi-instance"
117 defaultUniInstance = "single-instance"
118 defaultNumGemPorts = 1
119 defaultGemPayloadSize = "auto"
120)
121
122const MAX_GEM_PAYLOAD = "max_gem_payload_size"
123
124type InstanceControl struct {
Kent Hagerman0ab4cb22019-04-24 13:13:35 -0400125 Onu string `json:"ONU"`
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530126 Uni string `json:"uni"`
127 MaxGemPayloadSize string `json:"max_gem_payload_size"`
128}
129
130// default discard config constants
131const (
132 defaultMinThreshold = 0
133 defaultMaxThreshold = 0
134 defaultMaxProbability = 0
135)
136
137type DiscardConfig struct {
138 MinThreshold int `json:"min_threshold"`
139 MaxThreshold int `json:"max_threshold"`
140 MaxProbability int `json:"max_probability"`
141}
142
143// default scheduler contants
144const (
145 defaultAddtionalBw = AdditionalBW_AdditionalBW_Auto
146 defaultPriority = 0
147 defaultWeight = 0
148 defaultQueueSchedPolicy = SchedulingPolicy_Hybrid
149)
150
151type Scheduler struct {
152 Direction string `json:"direction"`
153 AdditionalBw string `json:"additional_bw"`
154 Priority uint32 `json:"priority"`
155 Weight uint32 `json:"weight"`
156 QSchedPolicy string `json:"q_sched_policy"`
157}
158
159// default GEM attribute constants
160const (
161 defaultAESEncryption = "True"
162 defaultPriorityQueue = 0
163 defaultQueueWeight = 0
164 defaultMaxQueueSize = "auto"
165 defaultdropPolicy = DiscardPolicy_TailDrop
166 defaultSchedulePolicy = SchedulingPolicy_WRR
167)
168
169type GemPortAttribute struct {
170 MaxQueueSize string `json:"max_q_size"`
171 PbitMap string `json:"pbit_map"`
172 AesEncryption string `json:"aes_encryption"`
173 SchedulingPolicy string `json:"scheduling_policy"`
174 PriorityQueue int `json:"priority_q"`
175 Weight int `json:"weight"`
176 DiscardPolicy string `json:"discard_policy"`
177 DiscardConfig DiscardConfig `json:"discard_config"`
178}
179
180type iScheduler struct {
manikkaraj k259a6f72019-05-06 09:55:44 -0400181 AllocID uint32 `json:"alloc_id"`
182 Direction string `json:"direction"`
183 AdditionalBw string `json:"additional_bw"`
184 Priority uint32 `json:"priority"`
185 Weight uint32 `json:"weight"`
186 QSchedPolicy string `json:"q_sched_policy"`
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530187}
188type iGemPortAttribute struct {
manikkaraj k259a6f72019-05-06 09:55:44 -0400189 GemportID uint32 `json:"gemport_id"`
190 MaxQueueSize string `json:"max_q_size"`
191 PbitMap string `json:"pbit_map"`
192 AesEncryption string `json:"aes_encryption"`
193 SchedulingPolicy string `json:"scheduling_policy"`
194 PriorityQueue int `json:"priority_q"`
195 Weight int `json:"weight"`
196 DiscardPolicy string `json:"discard_policy"`
197 DiscardConfig DiscardConfig `json:"discard_config"`
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530198}
199
200type TechProfileMgr struct {
201 config *TechProfileFlags
202 resourceMgr iPonResourceMgr
203}
204type DefaultTechProfile struct {
205 Name string `json:"name"`
206 ProfileType string `json:"profile_type"`
207 Version int `json:"version"`
208 NumGemPorts uint32 `json:"num_gem_ports"`
209 InstanceCtrl InstanceControl `json:"instance_control"`
210 UsScheduler Scheduler `json:"us_scheduler"`
211 DsScheduler Scheduler `json:"ds_scheduler"`
212 UpstreamGemPortAttributeList []GemPortAttribute `json:"upstream_gem_port_attribute_list"`
213 DownstreamGemPortAttributeList []GemPortAttribute `json:"downstream_gem_port_attribute_list"`
214}
215type TechProfile struct {
216 Name string `json:"name"`
217 SubscriberIdentifier string `json:"subscriber_identifier"`
218 ProfileType string `json:"profile_type"`
219 Version int `json:"version"`
220 NumGemPorts uint32 `json:"num_gem_ports"`
manikkaraj k259a6f72019-05-06 09:55:44 -0400221 NumTconts uint32 `json:"num_of_tconts"`
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530222 InstanceCtrl InstanceControl `json:"instance_control"`
223 UsScheduler iScheduler `json:"us_scheduler"`
224 DsScheduler iScheduler `json:"ds_scheduler"`
225 UpstreamGemPortAttributeList []iGemPortAttribute `json:"upstream_gem_port_attribute_list"`
226 DownstreamGemPortAttributeList []iGemPortAttribute `json:"downstream_gem_port_attribute_list"`
227}
228
229func (t *TechProfileMgr) SetKVClient() *model.Backend {
230 addr := t.config.KVStoreHost + ":" + strconv.Itoa(t.config.KVStorePort)
231 kvClient, err := newKVClient(t.config.KVStoreType, addr, t.config.KVStoreTimeout)
232 if err != nil {
233 log.Errorw("failed-to-create-kv-client",
234 log.Fields{
235 "type": t.config.KVStoreType, "host": t.config.KVStoreHost, "port": t.config.KVStorePort,
236 "timeout": t.config.KVStoreTimeout, "prefix": t.config.TPKVPathPrefix,
237 "error": err.Error(),
238 })
239 return nil
240 }
241 return &model.Backend{
242 Client: kvClient,
243 StoreType: t.config.KVStoreType,
244 Host: t.config.KVStoreHost,
245 Port: t.config.KVStorePort,
246 Timeout: t.config.KVStoreTimeout,
247 PathPrefix: t.config.TPKVPathPrefix}
248
249 /* TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
250 issue between kv store and backend , core is not calling NewBackend directly
251 kv := model.NewBackend(t.config.KVStoreType, t.config.KVStoreHost, t.config.KVStorePort,
252 t.config.KVStoreTimeout, kvStoreTechProfilePathPrefix)
253 */
254}
255
256func newKVClient(storeType string, address string, timeout int) (kvstore.Client, error) {
257
258 log.Infow("kv-store-type", log.Fields{"store": storeType})
259 switch storeType {
260 case "consul":
261 return kvstore.NewConsulClient(address, timeout)
262 case "etcd":
263 return kvstore.NewEtcdClient(address, timeout)
264 }
265 return nil, errors.New("unsupported-kv-store")
266}
267
268func NewTechProfile(resourceMgr iPonResourceMgr) (*TechProfileMgr, error) {
269 var techprofileObj TechProfileMgr
270 log.Debug("Initializing techprofile Manager")
271 techprofileObj.config = NewTechProfileFlags()
272 techprofileObj.config.KVBackend = techprofileObj.SetKVClient()
273 if techprofileObj.config.KVBackend == nil {
274 log.Error("Failed to initialize KV backend\n")
275 return nil, errors.New("KV backend init failed")
276 }
277 techprofileObj.resourceMgr = resourceMgr
278 log.Debug("Initializing techprofile object instance success")
279 return &techprofileObj, nil
280}
281
282func (t *TechProfileMgr) GetTechProfileInstanceKVPath(techProfiletblID uint32, uniPortName string) string {
283 return fmt.Sprintf(t.config.TPInstanceKVPath, t.resourceMgr.GetTechnology(), techProfiletblID, uniPortName)
284}
285
286func (t *TechProfileMgr) GetTPInstanceFromKVStore(techProfiletblID uint32, path string) (*TechProfile, error) {
287 var KvTpIns TechProfile
288 var resPtr *TechProfile = &KvTpIns
289 var err error
290 /*path := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)*/
291 log.Infow("Getting tech profile instance from KV store", log.Fields{"path": path})
292 kvresult, err := t.config.KVBackend.Get(path)
293 if err != nil {
294 log.Errorw("Error while fetching tech-profile instance from KV backend", log.Fields{"key": path})
295 return nil, err
296 }
297 if kvresult == nil {
298 log.Infow("Tech profile does not exist in KV store", log.Fields{"key": path})
299 resPtr = nil
300 } else {
301 if value, err := kvstore.ToByte(kvresult.Value); err == nil {
302 if err = json.Unmarshal(value, resPtr); err != nil {
303 log.Errorw("Error while unmarshal KV result", log.Fields{"key": path, "value": value})
304 }
305 }
306 }
307 return resPtr, err
308}
309
310func (t *TechProfileMgr) addTechProfInstanceToKVStore(techProfiletblID uint32, uniPortName string, tpInstance *TechProfile) error {
311 path := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)
312 log.Debugw("Adding techprof instance to kvstore", log.Fields{"key": path, "tpinstance": tpInstance})
313 tpInstanceJson, err := json.Marshal(*tpInstance)
314 if err == nil {
315 // Backend will convert JSON byte array into string format
316 log.Debugw("Storing tech profile instance to KV Store", log.Fields{"key": path, "val": tpInstanceJson})
317 err = t.config.KVBackend.Put(path, tpInstanceJson)
318 } else {
319 log.Errorw("Error in marshaling into Json format", log.Fields{"key": path, "tpinstance": tpInstance})
320 }
321 return err
322}
323func (t *TechProfileMgr) getTPFromKVStore(techProfiletblID uint32) *DefaultTechProfile {
324 var kvtechprofile DefaultTechProfile
325 key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
326 log.Debugw("Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
327 kvresult, err := t.config.KVBackend.Get(key)
328 if err != nil {
329 log.Errorw("Error while fetching value from KV store", log.Fields{"key": key})
330 return nil
331 }
332 if kvresult != nil {
333 /* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
334 if value, err := kvstore.ToByte(kvresult.Value); err == nil {
335 if err = json.Unmarshal(value, &kvtechprofile); err == nil {
336 log.Debugw("Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
337 return &kvtechprofile
338 }
339 }
340 }
341 return nil
342}
343func (t *TechProfileMgr) CreateTechProfInstance(techProfiletblID uint32, uniPortName string, intfId uint32) *TechProfile {
344 var tpInstance *TechProfile
345 log.Infow("Creating tech profile instance ", log.Fields{"tableid": techProfiletblID, "uni": uniPortName, "intId": intfId})
346 tp := t.getTPFromKVStore(techProfiletblID)
347 if tp != nil {
348 log.Infow("Creating tech profile instance with profile from KV store", log.Fields{"tpid": techProfiletblID})
349 } else {
350 tp = t.getDefaultTechProfile()
351 log.Infow("Creating tech profile instance with default values", log.Fields{"tpid": techProfiletblID})
352 }
353 tpInstance = t.allocateTPInstance(uniPortName, tp, intfId, t.config.DefaultNumTconts)
354 if err := t.addTechProfInstanceToKVStore(techProfiletblID, uniPortName, tpInstance); err != nil {
355 log.Errorw("Error in adding tech profile instance to KV ", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
356 return nil
357 }
358 log.Infow("Added tech profile instance to KV store successfully ",
359 log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
360 return tpInstance
361}
362
363func (t *TechProfileMgr) DeleteTechProfileInstance(techProfiletblID uint32, uniPortName string) error {
364 path := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)
365 return t.config.KVBackend.Delete(path)
366}
367
368func (t *TechProfileMgr) allocateTPInstance(uniPortName string, tp *DefaultTechProfile, intfId uint32, numOfTconts uint32) *TechProfile {
369
370 var usGemPortAttributeList []iGemPortAttribute
371 var dsGemPortAttributeList []iGemPortAttribute
372 var tcontIDs []uint32
373 var gemPorts []uint32
374 var err error
375
376 log.Infow("Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numOfTconts": numOfTconts, "numGem": tp.NumGemPorts})
377 if numOfTconts > 1 {
378 log.Errorw("Multiple Tconts not supported currently", log.Fields{"uniPortName": uniPortName, "intfId": intfId})
379 return nil
380 }
381 if tcontIDs, err = t.resourceMgr.GetResourceID(intfId, t.resourceMgr.GetResourceTypeAllocID(), numOfTconts); err != nil {
382 log.Errorw("Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId, "numTconts": numOfTconts})
383 return nil
384 }
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530385 if gemPorts, err = t.resourceMgr.GetResourceID(intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
386 log.Errorw("Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
387 return nil
388 }
389 log.Infow("Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
390 for index := 0; index < int(tp.NumGemPorts); index++ {
391 usGemPortAttributeList = append(usGemPortAttributeList,
392 iGemPortAttribute{GemportID: gemPorts[index],
manikkaraj k259a6f72019-05-06 09:55:44 -0400393 MaxQueueSize: tp.UpstreamGemPortAttributeList[index].MaxQueueSize,
394 PbitMap: tp.UpstreamGemPortAttributeList[index].PbitMap,
395 AesEncryption: tp.UpstreamGemPortAttributeList[index].AesEncryption,
396 SchedulingPolicy: tp.UpstreamGemPortAttributeList[index].SchedulingPolicy,
397 PriorityQueue: tp.UpstreamGemPortAttributeList[index].PriorityQueue,
398 Weight: tp.UpstreamGemPortAttributeList[index].Weight,
399 DiscardPolicy: tp.UpstreamGemPortAttributeList[index].DiscardPolicy,
400 DiscardConfig: tp.UpstreamGemPortAttributeList[index].DiscardConfig})
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530401 dsGemPortAttributeList = append(dsGemPortAttributeList,
402 iGemPortAttribute{GemportID: gemPorts[index],
manikkaraj k259a6f72019-05-06 09:55:44 -0400403 MaxQueueSize: tp.DownstreamGemPortAttributeList[index].MaxQueueSize,
404 PbitMap: tp.DownstreamGemPortAttributeList[index].PbitMap,
405 AesEncryption: tp.DownstreamGemPortAttributeList[index].AesEncryption,
406 SchedulingPolicy: tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
407 PriorityQueue: tp.DownstreamGemPortAttributeList[index].PriorityQueue,
408 Weight: tp.DownstreamGemPortAttributeList[index].Weight,
409 DiscardPolicy: tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
410 DiscardConfig: tp.DownstreamGemPortAttributeList[index].DiscardConfig})
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530411 }
412 return &TechProfile{
413 SubscriberIdentifier: uniPortName,
414 Name: tp.Name,
415 ProfileType: tp.ProfileType,
416 Version: tp.Version,
417 NumGemPorts: tp.NumGemPorts,
418 NumTconts: numOfTconts,
419 InstanceCtrl: tp.InstanceCtrl,
420 UsScheduler: iScheduler{
manikkaraj k259a6f72019-05-06 09:55:44 -0400421 AllocID: tcontIDs[0],
422 Direction: tp.UsScheduler.Direction,
423 AdditionalBw: tp.UsScheduler.AdditionalBw,
424 Priority: tp.UsScheduler.Priority,
425 Weight: tp.UsScheduler.Weight,
426 QSchedPolicy: tp.UsScheduler.QSchedPolicy},
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530427 DsScheduler: iScheduler{
manikkaraj k259a6f72019-05-06 09:55:44 -0400428 AllocID: tcontIDs[0],
429 Direction: tp.DsScheduler.Direction,
430 AdditionalBw: tp.DsScheduler.AdditionalBw,
431 Priority: tp.DsScheduler.Priority,
432 Weight: tp.DsScheduler.Weight,
433 QSchedPolicy: tp.DsScheduler.QSchedPolicy},
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530434 UpstreamGemPortAttributeList: usGemPortAttributeList,
435 DownstreamGemPortAttributeList: dsGemPortAttributeList}
436}
437
438func (t *TechProfileMgr) getDefaultTechProfile() *DefaultTechProfile {
439
440 var usGemPortAttributeList []GemPortAttribute
441 var dsGemPortAttributeList []GemPortAttribute
442
443 for _, pbit := range t.config.DefaultPbits {
444 usGemPortAttributeList = append(usGemPortAttributeList,
445 GemPortAttribute{
446 MaxQueueSize: defaultMaxQueueSize,
447 PbitMap: pbit,
448 AesEncryption: defaultAESEncryption,
449 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
450 PriorityQueue: defaultPriorityQueue,
451 Weight: defaultQueueWeight,
452 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
453 DiscardConfig: DiscardConfig{
454 MinThreshold: defaultMinThreshold,
455 MaxThreshold: defaultMaxThreshold,
456 MaxProbability: defaultMaxProbability}})
457 dsGemPortAttributeList = append(dsGemPortAttributeList,
458 GemPortAttribute{
459 MaxQueueSize: defaultMaxQueueSize,
460 PbitMap: pbit,
461 AesEncryption: defaultAESEncryption,
462 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
463 PriorityQueue: defaultPriorityQueue,
464 Weight: defaultQueueWeight,
465 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
466 DiscardConfig: DiscardConfig{
467 MinThreshold: defaultMinThreshold,
468 MaxThreshold: defaultMaxThreshold,
469 MaxProbability: defaultMaxProbability}})
470 }
471 return &DefaultTechProfile{
472 Name: t.config.DefaultTPName,
473 ProfileType: t.resourceMgr.GetTechnology(),
474 Version: t.config.TPVersion,
475 NumGemPorts: uint32(len(usGemPortAttributeList)),
476 InstanceCtrl: InstanceControl{
477 Onu: defaultOnuInstance,
478 Uni: defaultUniInstance,
479 MaxGemPayloadSize: defaultGemPayloadSize},
480 UsScheduler: Scheduler{
481 Direction: Direction_name[Direction_UPSTREAM],
482 AdditionalBw: AdditionalBW_name[defaultAddtionalBw],
483 Priority: defaultPriority,
484 Weight: defaultWeight,
485 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
486 DsScheduler: Scheduler{
487 Direction: Direction_name[Direction_DOWNSTREAM],
488 AdditionalBw: AdditionalBW_name[defaultAddtionalBw],
489 Priority: defaultPriority,
490 Weight: defaultWeight,
491 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
492 UpstreamGemPortAttributeList: usGemPortAttributeList,
493 DownstreamGemPortAttributeList: dsGemPortAttributeList}
494}
495
496func (t *TechProfileMgr) GetprotoBufParamValue(paramType string, paramKey string) int32 {
497 var result int32 = -1
498
499 if paramType == "direction" {
500 for key, val := range openolt_pb.Direction_value {
501 if key == paramKey {
502 result = val
503 }
504 }
505 } else if paramType == "discard_policy" {
506 for key, val := range openolt_pb.DiscardPolicy_value {
507 if key == paramKey {
508 result = val
509 }
510 }
511 } else if paramType == "sched_policy" {
512 for key, val := range openolt_pb.SchedulingPolicy_value {
513 if key == paramKey {
514 log.Debugw("Got value in proto", log.Fields{"key": key, "value": val})
515 result = val
516 }
517 }
518 } else if paramType == "additional_bw" {
519 for key, val := range openolt_pb.AdditionalBW_value {
520 if key == paramKey {
521 result = val
522 }
523 }
524 } else {
525 log.Error("Could not find proto parameter", log.Fields{"paramType": paramType, "key": paramKey})
526 return -1
527 }
528 log.Debugw("Got value in proto", log.Fields{"key": paramKey, "value": result})
529 return result
530}
531
532func (t *TechProfileMgr) GetUsScheduler(tpInstance *TechProfile) *openolt_pb.Scheduler {
manikkaraj k259a6f72019-05-06 09:55:44 -0400533 dir := openolt_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.UsScheduler.Direction))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530534 if dir == -1 {
535 log.Fatal("Error in getting Proto for direction for upstream scheduler")
536 return nil
537 }
manikkaraj k259a6f72019-05-06 09:55:44 -0400538 bw := openolt_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.UsScheduler.AdditionalBw))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530539 if bw == -1 {
540 log.Fatal("Error in getting Proto for bandwidth for upstream scheduler")
541 return nil
542 }
manikkaraj k259a6f72019-05-06 09:55:44 -0400543 policy := openolt_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.UsScheduler.QSchedPolicy))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530544 if policy == -1 {
545 log.Fatal("Error in getting Proto for scheduling policy for upstream scheduler")
546 return nil
547 }
548 return &openolt_pb.Scheduler{
549 Direction: dir,
550 AdditionalBw: bw,
manikkaraj k259a6f72019-05-06 09:55:44 -0400551 Priority: tpInstance.UsScheduler.Priority,
552 Weight: tpInstance.UsScheduler.Weight,
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530553 SchedPolicy: policy}
554}
555
556func (t *TechProfileMgr) GetDsScheduler(tpInstance *TechProfile) *openolt_pb.Scheduler {
557
manikkaraj k259a6f72019-05-06 09:55:44 -0400558 dir := openolt_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.DsScheduler.Direction))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530559 if dir == -1 {
560 log.Fatal("Error in getting Proto for direction for downstream scheduler")
561 return nil
562 }
manikkaraj k259a6f72019-05-06 09:55:44 -0400563 bw := openolt_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.DsScheduler.AdditionalBw))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530564 if bw == -1 {
565 log.Fatal("Error in getting Proto for bandwidth for downstream scheduler")
566 return nil
567 }
manikkaraj k259a6f72019-05-06 09:55:44 -0400568 policy := openolt_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.DsScheduler.QSchedPolicy))
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530569 if policy == -1 {
570 log.Fatal("Error in getting Proto for scheduling policy for downstream scheduler")
571 return nil
572 }
573
574 return &openolt_pb.Scheduler{
575 Direction: dir,
576 AdditionalBw: bw,
manikkaraj k259a6f72019-05-06 09:55:44 -0400577 Priority: tpInstance.DsScheduler.Priority,
578 Weight: tpInstance.DsScheduler.Weight,
Mannikraj Kodilingam23798822019-04-10 14:34:01 +0530579 SchedPolicy: policy}
580}
581
582func (t *TechProfileMgr) GetTconts(tpInstance *TechProfile, usSched *openolt_pb.Scheduler, dsSched *openolt_pb.Scheduler) []*openolt_pb.Tcont {
583 if usSched == nil {
584 if usSched = t.GetUsScheduler(tpInstance); usSched == nil {
585 log.Fatal("Error in getting upstream scheduler from techprofile")
586 return nil
587 }
588 }
589 if dsSched == nil {
590 if dsSched = t.GetDsScheduler(tpInstance); dsSched == nil {
591 log.Fatal("Error in getting downstream scheduler from techprofile")
592 return nil
593 }
594 }
595 tconts := []*openolt_pb.Tcont{}
596 // TODO: Fix me , UPSTREAM direction is not proper
597 // upstream scheduler
598 tcont_us := &openolt_pb.Tcont{
599 Direction: usSched.Direction,
600 AllocId: tpInstance.UsScheduler.AllocID,
601 Scheduler: usSched} /*TrafficShapingInfo: ? */
602 tconts = append(tconts, tcont_us)
603
604 // downstream scheduler
605 tcont_ds := &openolt_pb.Tcont{
606 Direction: dsSched.Direction,
607 AllocId: tpInstance.DsScheduler.AllocID,
608 Scheduler: dsSched}
609
610 tconts = append(tconts, tcont_ds)
611 return tconts
612}