blob: 57a5034a10a5548271c6420416d444df19d05bed [file] [log] [blame]
Zdravko Bozakov958d81c2019-12-13 22:09:48 +01001/*
Joey Armstrong14628cd2023-01-10 08:38:31 -05002 * Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
Zdravko Bozakov958d81c2019-12-13 22:09:48 +01003
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 sadis
18
19import (
20 "encoding/json"
Matteo Scandolo8a574812021-05-20 15:18:53 -070021 "fmt"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010022 "net/http"
Matteo Scandolo8a574812021-05-20 15:18:53 -070023 "strconv"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010024 "strings"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010025
26 "github.com/gorilla/mux"
27 "github.com/opencord/bbsim/internal/bbsim/devices"
28 "github.com/opencord/bbsim/internal/common"
29 log "github.com/sirupsen/logrus"
30)
31
32var sadisLogger = log.WithFields(log.Fields{
33 "module": "SADIS",
34})
35
Matteo Scandolo8a574812021-05-20 15:18:53 -070036const (
37 BaseConfigUrl = "/{version}/cfg"
38 StaticConfigUrl = "/{version}/static"
39 SadisEntryUrl = "/{version}/subscribers/{ID}"
40 SadisBwUrl = "/{version}/bandwidthprofiles/{ID}"
41)
42
Matteo Scandolocedde462021-03-09 17:37:16 -080043type SadisServer struct {
44 Olt *devices.OltDevice
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010045}
46
47// bandwidthProfiles contains some dummy profiles
Matteo Scandolo94967142021-05-28 11:37:06 -070048var bandwidthProfiles = map[string][]*SadisBWPEntry{
49 common.BP_FORMAT_MEF: {
50 {ID: "User_Bandwidth1", AIR: 100000, CBS: 10000, CIR: 30000, EBS: 1000, EIR: 100000},
51 {ID: "User_Bandwidth2", AIR: 100000, CBS: 5000, CIR: 100000, EBS: 5000, EIR: 100000},
52 {ID: "User_Bandwidth3", AIR: 100000, CBS: 5000, CIR: 1000000, EBS: 5000, EIR: 1000000},
53 {ID: "Default", AIR: 100000, CBS: 30, CIR: 600, EBS: 30, EIR: 400},
54 },
55 common.BP_FORMAT_IETF: {
56 {ID: "User_Bandwidth1", CBS: 10000, CIR: 30000, GIR: 100000, PIR: 20000, PBS: 1000},
57 {ID: "User_Bandwidth2", CBS: 5000, CIR: 100000, GIR: 100000, PIR: 30000, PBS: 5000},
58 {ID: "User_Bandwidth3", CBS: 5000, CIR: 1000000, GIR: 100000, PIR: 40000, PBS: 5000},
59 {ID: "Default", CBS: 30, CIR: 600, GIR: 0, PIR: 32000, PBS: 30},
60 },
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010061}
62
63// SadisConfig is the top-level SADIS configuration struct
64type SadisConfig struct {
65 Sadis SadisEntries `json:"sadis"`
66 BandwidthProfile BandwidthProfileEntries `json:"bandwidthprofile"`
67}
68
69type SadisEntries struct {
70 Integration SadisIntegration `json:"integration"`
71 Entries []interface{} `json:"entries,omitempty"`
72}
73type BandwidthProfileEntries struct {
74 Integration SadisIntegration `json:"integration"`
Matteo Scandolo51d6a312020-03-12 15:54:43 -070075 Entries []*SadisBWPEntry `json:"entries,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010076}
77
78type SadisIntegration struct {
79 URL string `json:"url,omitempty"`
80 Cache struct {
81 Enabled bool `json:"enabled"`
82 MaxSize int `json:"maxsize"`
83 TTL string `json:"ttl"`
84 } `json:"cache"`
85}
86
87type SadisOltEntry struct {
88 ID string `json:"id"`
89 HardwareIdentifier string `json:"hardwareIdentifier"`
90 IPAddress string `json:"ipAddress"`
91 NasID string `json:"nasId"`
92 UplinkPort int `json:"uplinkPort"`
Andrea Campanella6f5f3552022-03-10 17:14:25 +010093 NniDhcpTrapVid int `json:"nniDhcpTrapVid,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010094}
95
Anand S Kattib409ee02020-02-20 20:10:00 +053096type SadisOnuEntryV2 struct {
97 ID string `json:"id"`
98 NasPortID string `json:"nasPortId"`
99 CircuitID string `json:"circuitId"`
100 RemoteID string `json:"remoteId"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700101 UniTagList []SadisUniTag `json:"uniTagList"` // this can be SadisUniTagAtt, SadisUniTagDt
Anand S Kattib409ee02020-02-20 20:10:00 +0530102}
103
Matteo Scandolo4a036262020-08-17 15:56:13 -0700104type SadisUniTag struct {
105 UniTagMatch int `json:"uniTagMatch,omitempty"`
Shrey Baid688b4242020-07-10 20:40:10 +0530106 PonCTag int `json:"ponCTag,omitempty"`
107 PonSTag int `json:"ponSTag,omitempty"`
108 TechnologyProfileID int `json:"technologyProfileId,omitempty"`
109 UpstreamBandwidthProfile string `json:"upstreamBandwidthProfile,omitempty"`
110 DownstreamBandwidthProfile string `json:"downstreamBandwidthProfile,omitempty"`
111 IsDhcpRequired bool `json:"isDhcpRequired,omitempty"`
112 IsIgmpRequired bool `json:"isIgmpRequired,omitempty"`
Andrea Campanella29890452022-02-03 16:00:19 +0100113 IsPPPoERequired bool `json:"isPppoeRequired,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700114 ConfiguredMacAddress string `json:"configuredMacAddress,omitempty"`
Andrea Campanella29890452022-02-03 16:00:19 +0100115 EnableMacLearning bool `json:"enableMacLearning,omitempty"`
Matteo Scandolo8d281372020-09-03 16:23:37 -0700116 UsPonCTagPriority uint8 `json:"usPonCTagPriority,omitempty"`
117 UsPonSTagPriority uint8 `json:"usPonSTagPriority,omitempty"`
118 DsPonCTagPriority uint8 `json:"dsPonCTagPriority,omitempty"`
119 DsPonSTagPriority uint8 `json:"dsPonSTagPriority,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700120 ServiceName string `json:"serviceName,omitempty"`
Matteo Scandolof65e6872020-04-15 15:18:43 -0700121}
122
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100123// SADIS BandwithProfile Entry
124type SadisBWPEntry struct {
Matteo Scandolo94967142021-05-28 11:37:06 -0700125 // common attributes
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100126 ID string `json:"id"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100127 CBS int `json:"cbs"`
128 CIR int `json:"cir"`
Matteo Scandolo94967142021-05-28 11:37:06 -0700129 // MEF attributes
130 AIR int `json:"air,omitempty"`
131 EBS int `json:"ebs,omitempty"`
132 EIR int `json:"eir,omitempty"`
133 // IETF attributes
134 GIR int `json:"gir,omitempty"`
135 PIR int `json:"pir,omitempty"`
136 PBS int `json:"pbs,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100137}
138
139// GetSadisConfig returns a full SADIS configuration struct ready to be marshalled into JSON
Anand S Kattib409ee02020-02-20 20:10:00 +0530140func GetSadisConfig(olt *devices.OltDevice, version string) *SadisConfig {
141 sadisEntries, _ := GetSadisEntries(olt, version)
142 bwpEntries := getBWPEntries(version)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100143
144 conf := &SadisConfig{}
145 conf.Sadis = *sadisEntries
146 conf.BandwidthProfile = *bwpEntries
147
148 return conf
149}
150
Anand S Kattib409ee02020-02-20 20:10:00 +0530151func GetSadisEntries(olt *devices.OltDevice, version string) (*SadisEntries, error) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100152 solt, _ := GetOltEntry(olt)
153
154 entries := []interface{}{}
155 entries = append(entries, solt)
156
Matteo Scandolo4a036262020-08-17 15:56:13 -0700157 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100158 port := a[len(a)-1]
159
160 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530161 integration.URL = "http://bbsim:" + port + "/" + version + "/subscribers/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100162 integration.Cache.Enabled = false
163 integration.Cache.MaxSize = 50
164 integration.Cache.TTL = "PT0m"
165
166 sadis := &SadisEntries{
167 integration,
168 entries,
169 }
170
171 return sadis, nil
172}
173
174func GetOltEntry(olt *devices.OltDevice) (*SadisOltEntry, error) {
175 ip, _ := common.GetIPAddr("nni") // TODO verify which IP to report
176 solt := &SadisOltEntry{
177 ID: olt.SerialNumber,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700178 HardwareIdentifier: common.Config.Olt.DeviceId,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100179 IPAddress: ip,
180 NasID: olt.SerialNumber,
Girish Gowdra95005602021-10-22 11:33:01 -0700181 UplinkPort: 16777216, // TODO currently assumes we only have one NNI port
Andrea Campanella6f5f3552022-03-10 17:14:25 +0100182 NniDhcpTrapVid: olt.NniDhcpTrapVid,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100183 }
184 return solt, nil
185}
186
Matteo Scandolo8a574812021-05-20 15:18:53 -0700187func GetOnuEntryV2(olt *devices.OltDevice, onu *devices.Onu, uniStr string) (*SadisOnuEntryV2, error) {
188 uniSuffix := "-" + uniStr
Anand S Kattib409ee02020-02-20 20:10:00 +0530189
190 sonuv2 := &SadisOnuEntryV2{
Matteo Scandolodf080442020-10-09 11:57:38 -0700191 ID: onu.Sn() + uniSuffix,
Anand S Kattib409ee02020-02-20 20:10:00 +0530192 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700193
Matteo Scandolo8a574812021-05-20 15:18:53 -0700194 uniId, err := strconv.ParseUint(uniStr, 10, 32)
195 if err != nil {
196 return nil, err
197 }
198
199 // find the correct UNI
200 // NOTE that in SADIS uni.Id 0 corresponds to BBSM00000101-1
201 uni, err := onu.FindUniById(uint32(uniId - 1))
202 if err != nil {
203 return nil, err
204 }
205
Matteo Scandolo4a036262020-08-17 15:56:13 -0700206 // createUniTagList
Matteo Scandolo8a574812021-05-20 15:18:53 -0700207 for _, s := range uni.Services {
Matteo Scandolof65e6872020-04-15 15:18:43 -0700208
Matteo Scandolo4a036262020-08-17 15:56:13 -0700209 service := s.(*devices.Service)
210
211 tag := SadisUniTag{
212 ServiceName: service.Name,
213 IsIgmpRequired: service.NeedsIgmp,
214 IsDhcpRequired: service.NeedsDhcp,
Andrea Campanella29890452022-02-03 16:00:19 +0100215 IsPPPoERequired: service.NeedsPPPoE,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700216 TechnologyProfileID: service.TechnologyProfileID,
217 UpstreamBandwidthProfile: "User_Bandwidth1",
218 DownstreamBandwidthProfile: "User_Bandwidth2",
Andrea Campanella29890452022-02-03 16:00:19 +0100219 EnableMacLearning: service.EnableMacLearning,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700220 PonCTag: service.CTag,
221 PonSTag: service.STag,
Matteo Scandolof65e6872020-04-15 15:18:43 -0700222 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700223
224 if service.UniTagMatch != 0 {
225 tag.UniTagMatch = service.UniTagMatch
Matteo Scandolof65e6872020-04-15 15:18:43 -0700226 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700227
228 if service.ConfigureMacAddress {
229 tag.ConfiguredMacAddress = service.HwAddress.String()
230 }
231
232 if service.UsPonCTagPriority != 0 {
233 tag.UsPonCTagPriority = service.UsPonCTagPriority
234 }
235
236 if service.UsPonSTagPriority != 0 {
237 tag.UsPonSTagPriority = service.UsPonSTagPriority
238 }
239
240 if service.DsPonCTagPriority != 0 {
241 tag.DsPonCTagPriority = service.DsPonCTagPriority
242 }
243
244 if service.DsPonSTagPriority != 0 {
245 tag.DsPonSTagPriority = service.DsPonSTagPriority
246 }
247
248 sonuv2.UniTagList = append(sonuv2.UniTagList, tag)
Anand S Kattib409ee02020-02-20 20:10:00 +0530249 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700250
Anand S Kattib409ee02020-02-20 20:10:00 +0530251 return sonuv2, nil
252}
253
254func getBWPEntries(version string) *BandwidthProfileEntries {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700255 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100256 port := a[len(a)-1]
257
258 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530259 integration.URL = "http://bbsim:" + port + "/" + version + "/bandwidthprofiles/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100260 integration.Cache.Enabled = true
261 integration.Cache.MaxSize = 40
262 integration.Cache.TTL = "PT1m"
263
264 bwp := &BandwidthProfileEntries{
265 Integration: integration,
266 }
267
268 return bwp
269}
270
Matteo Scandolocedde462021-03-09 17:37:16 -0800271func (s *SadisServer) ServeBaseConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100272 w.Header().Set("Content-Type", "application/json")
273 w.WriteHeader(http.StatusOK)
Anand S Kattib409ee02020-02-20 20:10:00 +0530274 vars := mux.Vars(r)
275
276 if vars["version"] != "v1" && vars["version"] != "v2" {
277 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530278 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530279 return
280 }
281
Matteo Scandolocedde462021-03-09 17:37:16 -0800282 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100283
284 sadisJSON, _ := json.Marshal(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100285
Shrey Baid688b4242020-07-10 20:40:10 +0530286 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100287
288}
289
Matteo Scandolocedde462021-03-09 17:37:16 -0800290func (s *SadisServer) ServeStaticConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100291 w.Header().Set("Content-Type", "application/json")
Matteo Scandolo8a574812021-05-20 15:18:53 -0700292
Anand S Kattib409ee02020-02-20 20:10:00 +0530293 vars := mux.Vars(r)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700294
295 if vars["version"] == "v1" {
296 // TODO format error
297 http.Error(w, fmt.Sprintf("api-v1-unsupported"), http.StatusBadRequest)
298 return
299 }
300
301 w.WriteHeader(http.StatusOK)
302
Matteo Scandolocedde462021-03-09 17:37:16 -0800303 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100304
305 sadisConf.Sadis.Integration.URL = ""
Matteo Scandolocedde462021-03-09 17:37:16 -0800306 for i := range s.Olt.Pons {
307 for _, onu := range s.Olt.Pons[i].Onus {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700308 if vars["version"] == "v2" {
Matteo Scandolo8a574812021-05-20 15:18:53 -0700309 for _, u := range onu.UniPorts {
310 uni := u.(*devices.UniPort)
311 sonuV2, _ := GetOnuEntryV2(s.Olt, onu, fmt.Sprintf("%d", uni.ID+1))
312 sadisConf.Sadis.Entries = append(sadisConf.Sadis.Entries, sonuV2)
313 }
Anand S Kattib409ee02020-02-20 20:10:00 +0530314 }
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100315 }
316 }
317
318 sadisConf.BandwidthProfile.Integration.URL = ""
Matteo Scandolo94967142021-05-28 11:37:06 -0700319 sadisConf.BandwidthProfile.Entries = bandwidthProfiles[common.Config.BBSim.BandwidthProfileFormat]
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100320
321 sadisJSON, _ := json.Marshal(sadisConf)
322 sadisLogger.Tracef("SADIS JSON: %s", sadisJSON)
323
Shrey Baid688b4242020-07-10 20:40:10 +0530324 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100325
326}
327
Matteo Scandolocedde462021-03-09 17:37:16 -0800328func (s *SadisServer) ServeEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100329 w.Header().Set("Content-Type", "application/json")
330 vars := mux.Vars(r)
331
332 // check if the requested ID is for the OLT
Matteo Scandolocedde462021-03-09 17:37:16 -0800333 if s.Olt.SerialNumber == vars["ID"] {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100334 sadisLogger.WithFields(log.Fields{
Matteo Scandolocedde462021-03-09 17:37:16 -0800335 "OltSn": s.Olt.SerialNumber,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100336 }).Debug("Received SADIS OLT request")
337
Matteo Scandolocedde462021-03-09 17:37:16 -0800338 sadisConf, _ := GetOltEntry(s.Olt)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100339
340 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530341 _ = json.NewEncoder(w).Encode(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100342 return
343 }
344
345 i := strings.Split(vars["ID"], "-") // split ID to get serial number and uni port
346 if len(i) != 2 {
347 w.WriteHeader(http.StatusUnprocessableEntity)
Shrey Baid688b4242020-07-10 20:40:10 +0530348 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530349 sadisLogger.Warnf("Received invalid SADIS SubscriberId: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100350 return
351 }
352 sn, uni := i[0], i[len(i)-1]
353
Matteo Scandolocedde462021-03-09 17:37:16 -0800354 onu, err := s.Olt.FindOnuBySn(sn)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100355 if err != nil {
356 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530357 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100358 sadisLogger.WithFields(log.Fields{
359 "OnuSn": sn,
360 "OnuId": "NA",
Anand S Kattib409ee02020-02-20 20:10:00 +0530361 }).Warnf("Requested Subscriber entry not found for OnuSn: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100362 return
363 }
364
365 sadisLogger.WithFields(log.Fields{
Matteo Scandolo8a574812021-05-20 15:18:53 -0700366 "OnuId": onu.ID,
367 "OnuSn": sn,
368 "UniId": uni,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100369 }).Debug("Received SADIS request")
370
Anand S Kattib409ee02020-02-20 20:10:00 +0530371 if vars["version"] == "v1" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700372 // TODO format error
373 w.WriteHeader(http.StatusBadRequest)
374 _ = json.NewEncoder(w).Encode("Sadis v1 is not supported anymore, please go back to an earlier BBSim version")
Anand S Kattib409ee02020-02-20 20:10:00 +0530375 } else if vars["version"] == "v2" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700376 w.WriteHeader(http.StatusOK)
Matteo Scandolocedde462021-03-09 17:37:16 -0800377 sadisConf, _ := GetOnuEntryV2(s.Olt, onu, uni)
Shrey Baid688b4242020-07-10 20:40:10 +0530378 _ = json.NewEncoder(w).Encode(sadisConf)
Anand S Kattib409ee02020-02-20 20:10:00 +0530379 }
380
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100381}
382
Matteo Scandolocedde462021-03-09 17:37:16 -0800383func (s *SadisServer) ServeBWPEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100384 w.Header().Set("Content-Type", "application/json")
385 vars := mux.Vars(r)
386 id := vars["ID"]
Anand S Kattib409ee02020-02-20 20:10:00 +0530387
388 if vars["version"] != "v1" && vars["version"] != "v2" {
389 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530390 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530391 return
392 }
393
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100394 sadisLogger.Debugf("Received request for SADIS bandwidth profile %s", id)
395
Matteo Scandolo94967142021-05-28 11:37:06 -0700396 for _, bwpEntry := range bandwidthProfiles[common.Config.BBSim.BandwidthProfileFormat] {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100397 if bwpEntry.ID == id {
398 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530399 _ = json.NewEncoder(w).Encode(bwpEntry)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100400 return
401 }
402 }
403
404 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530405 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100406}