blob: 2879e99ba4392949971a368931678ecfa2973b22 [file] [log] [blame]
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001/*
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 {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400125 Onu string `json:"ONU"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400126 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 k9eb6cac2019-05-09 12:32:03 -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"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400187}
188type iGemPortAttribute struct {
manikkaraj k9eb6cac2019-05-09 12:32:03 -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"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400198}
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 k9eb6cac2019-05-09 12:32:03 -0400221 NumTconts uint32 `json:"num_of_tconts"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400222 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 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400385 log.Debugw("Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400386 if gemPorts, err = t.resourceMgr.GetResourceID(intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
387 log.Errorw("Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
388 return nil
389 }
390 log.Infow("Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
391 for index := 0; index < int(tp.NumGemPorts); index++ {
392 usGemPortAttributeList = append(usGemPortAttributeList,
393 iGemPortAttribute{GemportID: gemPorts[index],
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400394 MaxQueueSize: tp.UpstreamGemPortAttributeList[index].MaxQueueSize,
395 PbitMap: tp.UpstreamGemPortAttributeList[index].PbitMap,
396 AesEncryption: tp.UpstreamGemPortAttributeList[index].AesEncryption,
397 SchedulingPolicy: tp.UpstreamGemPortAttributeList[index].SchedulingPolicy,
398 PriorityQueue: tp.UpstreamGemPortAttributeList[index].PriorityQueue,
399 Weight: tp.UpstreamGemPortAttributeList[index].Weight,
400 DiscardPolicy: tp.UpstreamGemPortAttributeList[index].DiscardPolicy,
401 DiscardConfig: tp.UpstreamGemPortAttributeList[index].DiscardConfig})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400402 dsGemPortAttributeList = append(dsGemPortAttributeList,
403 iGemPortAttribute{GemportID: gemPorts[index],
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400404 MaxQueueSize: tp.DownstreamGemPortAttributeList[index].MaxQueueSize,
405 PbitMap: tp.DownstreamGemPortAttributeList[index].PbitMap,
406 AesEncryption: tp.DownstreamGemPortAttributeList[index].AesEncryption,
407 SchedulingPolicy: tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
408 PriorityQueue: tp.DownstreamGemPortAttributeList[index].PriorityQueue,
409 Weight: tp.DownstreamGemPortAttributeList[index].Weight,
410 DiscardPolicy: tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
411 DiscardConfig: tp.DownstreamGemPortAttributeList[index].DiscardConfig})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400412 }
413 return &TechProfile{
414 SubscriberIdentifier: uniPortName,
415 Name: tp.Name,
416 ProfileType: tp.ProfileType,
417 Version: tp.Version,
418 NumGemPorts: tp.NumGemPorts,
419 NumTconts: numOfTconts,
420 InstanceCtrl: tp.InstanceCtrl,
421 UsScheduler: iScheduler{
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400422 AllocID: tcontIDs[0],
423 Direction: tp.UsScheduler.Direction,
424 AdditionalBw: tp.UsScheduler.AdditionalBw,
425 Priority: tp.UsScheduler.Priority,
426 Weight: tp.UsScheduler.Weight,
427 QSchedPolicy: tp.UsScheduler.QSchedPolicy},
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400428 DsScheduler: iScheduler{
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400429 AllocID: tcontIDs[0],
430 Direction: tp.DsScheduler.Direction,
431 AdditionalBw: tp.DsScheduler.AdditionalBw,
432 Priority: tp.DsScheduler.Priority,
433 Weight: tp.DsScheduler.Weight,
434 QSchedPolicy: tp.DsScheduler.QSchedPolicy},
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400435 UpstreamGemPortAttributeList: usGemPortAttributeList,
436 DownstreamGemPortAttributeList: dsGemPortAttributeList}
437}
438
439func (t *TechProfileMgr) getDefaultTechProfile() *DefaultTechProfile {
440
441 var usGemPortAttributeList []GemPortAttribute
442 var dsGemPortAttributeList []GemPortAttribute
443
444 for _, pbit := range t.config.DefaultPbits {
445 usGemPortAttributeList = append(usGemPortAttributeList,
446 GemPortAttribute{
447 MaxQueueSize: defaultMaxQueueSize,
448 PbitMap: pbit,
449 AesEncryption: defaultAESEncryption,
450 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
451 PriorityQueue: defaultPriorityQueue,
452 Weight: defaultQueueWeight,
453 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
454 DiscardConfig: DiscardConfig{
455 MinThreshold: defaultMinThreshold,
456 MaxThreshold: defaultMaxThreshold,
457 MaxProbability: defaultMaxProbability}})
458 dsGemPortAttributeList = append(dsGemPortAttributeList,
459 GemPortAttribute{
460 MaxQueueSize: defaultMaxQueueSize,
461 PbitMap: pbit,
462 AesEncryption: defaultAESEncryption,
463 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
464 PriorityQueue: defaultPriorityQueue,
465 Weight: defaultQueueWeight,
466 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
467 DiscardConfig: DiscardConfig{
468 MinThreshold: defaultMinThreshold,
469 MaxThreshold: defaultMaxThreshold,
470 MaxProbability: defaultMaxProbability}})
471 }
472 return &DefaultTechProfile{
473 Name: t.config.DefaultTPName,
474 ProfileType: t.resourceMgr.GetTechnology(),
475 Version: t.config.TPVersion,
476 NumGemPorts: uint32(len(usGemPortAttributeList)),
477 InstanceCtrl: InstanceControl{
478 Onu: defaultOnuInstance,
479 Uni: defaultUniInstance,
480 MaxGemPayloadSize: defaultGemPayloadSize},
481 UsScheduler: Scheduler{
482 Direction: Direction_name[Direction_UPSTREAM],
483 AdditionalBw: AdditionalBW_name[defaultAddtionalBw],
484 Priority: defaultPriority,
485 Weight: defaultWeight,
486 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
487 DsScheduler: Scheduler{
488 Direction: Direction_name[Direction_DOWNSTREAM],
489 AdditionalBw: AdditionalBW_name[defaultAddtionalBw],
490 Priority: defaultPriority,
491 Weight: defaultWeight,
492 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
493 UpstreamGemPortAttributeList: usGemPortAttributeList,
494 DownstreamGemPortAttributeList: dsGemPortAttributeList}
495}
496
497func (t *TechProfileMgr) GetprotoBufParamValue(paramType string, paramKey string) int32 {
498 var result int32 = -1
499
500 if paramType == "direction" {
501 for key, val := range openolt_pb.Direction_value {
502 if key == paramKey {
503 result = val
504 }
505 }
506 } else if paramType == "discard_policy" {
507 for key, val := range openolt_pb.DiscardPolicy_value {
508 if key == paramKey {
509 result = val
510 }
511 }
512 } else if paramType == "sched_policy" {
513 for key, val := range openolt_pb.SchedulingPolicy_value {
514 if key == paramKey {
515 log.Debugw("Got value in proto", log.Fields{"key": key, "value": val})
516 result = val
517 }
518 }
519 } else if paramType == "additional_bw" {
520 for key, val := range openolt_pb.AdditionalBW_value {
521 if key == paramKey {
522 result = val
523 }
524 }
525 } else {
526 log.Error("Could not find proto parameter", log.Fields{"paramType": paramType, "key": paramKey})
527 return -1
528 }
529 log.Debugw("Got value in proto", log.Fields{"key": paramKey, "value": result})
530 return result
531}
532
533func (t *TechProfileMgr) GetUsScheduler(tpInstance *TechProfile) *openolt_pb.Scheduler {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400534 dir := openolt_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.UsScheduler.Direction))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400535 if dir == -1 {
536 log.Fatal("Error in getting Proto for direction for upstream scheduler")
537 return nil
538 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400539 bw := openolt_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.UsScheduler.AdditionalBw))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400540 if bw == -1 {
541 log.Fatal("Error in getting Proto for bandwidth for upstream scheduler")
542 return nil
543 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400544 policy := openolt_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.UsScheduler.QSchedPolicy))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400545 if policy == -1 {
546 log.Fatal("Error in getting Proto for scheduling policy for upstream scheduler")
547 return nil
548 }
549 return &openolt_pb.Scheduler{
550 Direction: dir,
551 AdditionalBw: bw,
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400552 Priority: tpInstance.UsScheduler.Priority,
553 Weight: tpInstance.UsScheduler.Weight,
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400554 SchedPolicy: policy}
555}
556
557func (t *TechProfileMgr) GetDsScheduler(tpInstance *TechProfile) *openolt_pb.Scheduler {
558
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400559 dir := openolt_pb.Direction(t.GetprotoBufParamValue("direction", tpInstance.DsScheduler.Direction))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400560 if dir == -1 {
561 log.Fatal("Error in getting Proto for direction for downstream scheduler")
562 return nil
563 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400564 bw := openolt_pb.AdditionalBW(t.GetprotoBufParamValue("additional_bw", tpInstance.DsScheduler.AdditionalBw))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400565 if bw == -1 {
566 log.Fatal("Error in getting Proto for bandwidth for downstream scheduler")
567 return nil
568 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400569 policy := openolt_pb.SchedulingPolicy(t.GetprotoBufParamValue("sched_policy", tpInstance.DsScheduler.QSchedPolicy))
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400570 if policy == -1 {
571 log.Fatal("Error in getting Proto for scheduling policy for downstream scheduler")
572 return nil
573 }
574
575 return &openolt_pb.Scheduler{
576 Direction: dir,
577 AdditionalBw: bw,
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400578 Priority: tpInstance.DsScheduler.Priority,
579 Weight: tpInstance.DsScheduler.Weight,
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400580 SchedPolicy: policy}
581}
582
583func (t *TechProfileMgr) GetTconts(tpInstance *TechProfile, usSched *openolt_pb.Scheduler, dsSched *openolt_pb.Scheduler) []*openolt_pb.Tcont {
584 if usSched == nil {
585 if usSched = t.GetUsScheduler(tpInstance); usSched == nil {
586 log.Fatal("Error in getting upstream scheduler from techprofile")
587 return nil
588 }
589 }
590 if dsSched == nil {
591 if dsSched = t.GetDsScheduler(tpInstance); dsSched == nil {
592 log.Fatal("Error in getting downstream scheduler from techprofile")
593 return nil
594 }
595 }
596 tconts := []*openolt_pb.Tcont{}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400597 // 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}