blob: e8366fd46eaeaf9c5a553c9889cbbfcacffb4e00 [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29:46 -07001/*
Joey Armstrong2c039362024-02-04 18:51:52 -05002 * Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandolo11006992019-08-28 11:29:46 -07003
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
Matteo Scandolo82c16d02019-09-24 09:34:32 -070017package api
Matteo Scandolo84f7d482019-08-08 19:00:47 -070018
19import (
20 "context"
Zdravko Bozakov681364d2019-11-10 14:28:46 +010021 "fmt"
rajeshf921f882020-03-06 18:24:28 +053022 "strings"
Matteo Scandolo88c204a2020-11-03 10:34:24 -080023 "time"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020024
Elia Battiston67e9e4c2022-02-15 16:38:40 +010025 "google.golang.org/grpc/status"
26
Matteo Scandolo11006992019-08-28 11:29:46 -070027 "github.com/opencord/bbsim/api/bbsim"
28 "github.com/opencord/bbsim/internal/bbsim/devices"
Matteo Scandolo40e067f2019-10-16 16:59:41 -070029 "github.com/opencord/bbsim/internal/common"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070030 log "github.com/sirupsen/logrus"
Zdravko Bozakov681364d2019-11-10 14:28:46 +010031 "google.golang.org/grpc/codes"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070032)
33
34var logger = log.WithFields(log.Fields{
35 "module": "GrpcApiServer",
36})
37
38var (
Matteo Scandolo8df63df2019-09-12 10:34:32 -070039 version string
40 buildTime string
41 commitHash string
42 gitStatus string
Matteo Scandolo84f7d482019-08-08 19:00:47 -070043)
44
45type BBSimServer struct {
46}
47
Matteo Scandolo8df63df2019-09-12 10:34:32 -070048func (s BBSimServer) Version(ctx context.Context, req *bbsim.Empty) (*bbsim.VersionNumber, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +020049 // TODO add a flag to specify whether the tree was clean at this commit or not
Matteo Scandolo84f7d482019-08-08 19:00:47 -070050 return &bbsim.VersionNumber{
Matteo Scandolo8df63df2019-09-12 10:34:32 -070051 Version: version,
52 BuildTime: buildTime,
Matteo Scandolo84f7d482019-08-08 19:00:47 -070053 CommitHash: commitHash,
Matteo Scandolo8df63df2019-09-12 10:34:32 -070054 GitStatus: gitStatus,
Matteo Scandolo84f7d482019-08-08 19:00:47 -070055 }, nil
56}
57
58func (s BBSimServer) GetOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Olt, error) {
59 olt := devices.GetOLT()
60 nnis := []*bbsim.NNIPort{}
61 pons := []*bbsim.PONPort{}
62
63 for _, nni := range olt.Nnis {
64 n := bbsim.NNIPort{
Matteo Scandolo8df63df2019-09-12 10:34:32 -070065 ID: int32(nni.ID),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070066 OperState: nni.OperState.Current(),
Matteo Scandolo84f7d482019-08-08 19:00:47 -070067 }
68 nnis = append(nnis, &n)
69 }
70
71 for _, pon := range olt.Pons {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080072
73 allocatedOnuIds := []*bbsim.PonAllocatedResources{}
74 allocatedAllocIds := []*bbsim.PonAllocatedResources{}
75 allocatedGemPorts := []*bbsim.PonAllocatedResources{}
76
77 for k, v := range pon.AllocatedOnuIds {
78 resource := &bbsim.PonAllocatedResources{
79 SerialNumber: common.OnuSnToString(v),
80 Id: int32(k),
81 }
82 allocatedOnuIds = append(allocatedOnuIds, resource)
83 }
84
85 for k, v := range pon.AllocatedGemPorts {
86 resource := &bbsim.PonAllocatedResources{
87 SerialNumber: common.OnuSnToString(v),
88 Id: int32(k),
89 }
90 allocatedGemPorts = append(allocatedGemPorts, resource)
91 }
92
Girish Gowdra574834a2022-02-04 15:15:15 -080093 for _, v := range pon.AllocatedAllocIds {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080094 resource := &bbsim.PonAllocatedResources{
Girish Gowdra574834a2022-02-04 15:15:15 -080095 SerialNumber: common.OnuSnToString(v.OnuSn),
96 Id: int32(v.AllocID),
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080097 }
98 allocatedAllocIds = append(allocatedAllocIds, resource)
99 }
100
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700101 p := bbsim.PONPort{
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800102 ID: int32(pon.ID),
Elia Battistonb7bea222022-02-18 16:25:00 +0100103 Technology: pon.Technology.String(),
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800104 OperState: pon.OperState.Current(),
105 InternalState: pon.InternalState.Current(),
106 PacketCount: pon.PacketCount,
107 AllocatedOnuIds: allocatedOnuIds,
108 AllocatedAllocIds: allocatedAllocIds,
109 AllocatedGemPorts: allocatedGemPorts,
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700110 }
111 pons = append(pons, &p)
112 }
113
Matteo Scandolo4a036262020-08-17 15:56:13 -0700114 oltAddress := strings.Split(common.Config.BBSim.OpenOltAddress, ":")[0]
rajeshf921f882020-03-06 18:24:28 +0530115 if oltAddress == "" {
116 oltAddress = getOltIP().String()
117 }
118
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700119 res := bbsim.Olt{
Andrea Campanella6f5f3552022-03-10 17:14:25 +0100120 ID: int32(olt.ID),
121 SerialNumber: olt.SerialNumber,
122 OperState: olt.OperState.Current(),
123 InternalState: olt.InternalState.Current(),
124 IP: oltAddress,
125 NNIPorts: nnis,
126 PONPorts: pons,
127 NniDhcpTrapVid: int32(olt.NniDhcpTrapVid),
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700128 }
129 return &res, nil
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700130}
131
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800132// takes a nested map and return a proto
133func resourcesMapToresourcesProto(resourceType bbsim.OltAllocatedResourceType_Type, resources map[uint32]map[uint32]map[uint32]map[int32]map[uint64]bool) *bbsim.OltAllocatedResources {
134 proto := &bbsim.OltAllocatedResources{
135 Resources: []*bbsim.OltAllocatedResource{},
136 }
137 for ponId, ponValues := range resources {
138 for onuId, onuValues := range ponValues {
139 for uniId, uniValues := range onuValues {
140 for allocId, flows := range uniValues {
141 for flow := range flows {
142 resource := &bbsim.OltAllocatedResource{
143 Type: resourceType.String(),
144 PonPortId: ponId,
145 OnuId: onuId,
146 PortNo: uniId,
147 ResourceId: allocId,
148 FlowId: flow,
149 }
150 proto.Resources = append(proto.Resources, resource)
151 }
152 }
153 }
154 }
155 }
156 return proto
157}
158
159func (s BBSimServer) GetOltAllocatedResources(ctx context.Context, req *bbsim.OltAllocatedResourceType) (*bbsim.OltAllocatedResources, error) {
160 o := devices.GetOLT()
161
162 switch req.Type {
163 case bbsim.OltAllocatedResourceType_UNKNOWN:
164 return nil, status.Errorf(codes.InvalidArgument, "resource-type-%s-is-invalid", req.Type)
165 case bbsim.OltAllocatedResourceType_ALLOC_ID:
166 return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_ALLOC_ID, o.AllocIDs), nil
167 case bbsim.OltAllocatedResourceType_GEM_PORT:
168 return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_GEM_PORT, o.GemPortIDs), nil
169 default:
170 return nil, status.Errorf(codes.InvalidArgument, "unkown-resource-type-%s", req.Type)
171 }
172}
173
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100174func (s BBSimServer) PoweronOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
175 res := &bbsim.Response{}
176 o := devices.GetOLT()
177
Elia Battiston67e9e4c2022-02-15 16:38:40 +0100178 if err := o.InternalState.Event(devices.OltInternalTxInitialize); err != nil {
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100179 log.Errorf("Error initializing OLT: %v", err)
180 res.StatusCode = int32(codes.FailedPrecondition)
181 return res, err
182 }
183
184 res.StatusCode = int32(codes.OK)
185 return res, nil
186}
187
188func (s BBSimServer) ShutdownOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
189 res := &bbsim.Response{}
190 o := devices.GetOLT()
191
Elia Battiston67e9e4c2022-02-15 16:38:40 +0100192 if err := o.InternalState.Event(devices.OltInternalTxDisable); err != nil {
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100193 log.Errorf("Error disabling OLT: %v", err)
194 res.StatusCode = int32(codes.FailedPrecondition)
195 return res, err
196 }
197
198 res.StatusCode = int32(codes.OK)
199 return res, nil
200}
201
202func (s BBSimServer) RebootOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
203 res := &bbsim.Response{}
204 o := devices.GetOLT()
Shrey Baid688b4242020-07-10 20:40:10 +0530205 go func() { _ = o.RestartOLT() }()
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100206 res.StatusCode = int32(codes.OK)
207 res.Message = fmt.Sprintf("OLT restart triggered.")
208 return res, nil
209}
210
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800211func (s BBSimServer) StopgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
212 res := &bbsim.Response{}
213 res.StatusCode = int32(codes.OK)
214 res.Message = fmt.Sprintf("Openolt gRPC server stopped")
215 o := devices.GetOLT()
216
217 logger.Infof("Received request to stop Openolt gRPC Server")
218
219 o.StopOltServer()
220
221 return res, nil
222}
223
224func (s BBSimServer) StartgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
225 res := &bbsim.Response{}
226 res.StatusCode = int32(codes.OK)
227 res.Message = fmt.Sprintf("Openolt gRPC server started")
228 o := devices.GetOLT()
229
230 logger.Infof("Received request to start Openolt gRPC Server")
231
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000232 if o.OltServer != nil {
233 return nil, fmt.Errorf("Openolt gRPC server already running.")
234 }
235
236 oltGrpcServer, err := o.StartOltServer()
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800237 if err != nil {
238 return nil, err
239 }
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000240 o.OltServer = oltGrpcServer
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800241
242 return res, nil
243}
244
245func (s BBSimServer) RestartgRPCServer(ctx context.Context, req *bbsim.Timeout) (*bbsim.Response, error) {
246 o := devices.GetOLT()
247 logger.Infof("Received request to restart Openolt gRPC Server in %v seconds", req.Delay)
248 o.StopOltServer()
249
250 res := &bbsim.Response{}
251 res.StatusCode = int32(codes.OK)
252 res.Message = fmt.Sprintf("Openolt gRPC server stopped, restarting in %v", req.Delay)
253
254 go func() {
255 time.Sleep(time.Duration(req.Delay) * time.Second)
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000256 oltGrpcServer, err := o.StartOltServer()
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800257 if err != nil {
258 logger.WithFields(log.Fields{
259 "err": err,
260 }).Error("Cannot restart Openolt gRPC server")
261 }
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000262 o.OltServer = oltGrpcServer
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800263 logger.Infof("Openolt gRPC Server restarted after %v seconds", req.Delay)
264 }()
265
266 return res, nil
267}
268
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700269func (s BBSimServer) SetLogLevel(ctx context.Context, req *bbsim.LogLevel) (*bbsim.LogLevel, error) {
270
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700271 common.SetLogLevel(log.StandardLogger(), req.Level, req.Caller)
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700272
273 return &bbsim.LogLevel{
274 Level: log.StandardLogger().Level.String(),
275 Caller: log.StandardLogger().ReportCaller,
276 }, nil
277}
Scott Baker41724b82020-01-21 19:54:53 -0800278
Anand S Katti86552f92020-03-03 21:56:32 +0530279func (s BBSimServer) SetOnuAlarmIndication(ctx context.Context, req *bbsim.ONUAlarmRequest) (*bbsim.Response, error) {
Scott Baker41724b82020-01-21 19:54:53 -0800280 o := devices.GetOLT()
Matteo Scandolof9d43412021-01-12 11:11:34 -0800281
282 res := &bbsim.Response{}
283
284 onu, err := o.FindOnuBySn(req.SerialNumber)
Scott Baker41724b82020-01-21 19:54:53 -0800285 if err != nil {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800286 res.StatusCode = int32(codes.NotFound)
287 res.Message = err.Error()
Scott Baker41724b82020-01-21 19:54:53 -0800288 return nil, err
289 }
290
Matteo Scandolof9d43412021-01-12 11:11:34 -0800291 if err := onu.SetAlarm(req.AlarmType, req.Status); err != nil {
292 res.StatusCode = int32(codes.Internal)
293 res.Message = err.Error()
294 return nil, err
295 }
296
Scott Baker41724b82020-01-21 19:54:53 -0800297 res.StatusCode = int32(codes.OK)
Anand S Katti86552f92020-03-03 21:56:32 +0530298 res.Message = fmt.Sprintf("Onu Alarm Indication Sent.")
299 return res, nil
300}
301
302// SetOltAlarmIndication generates OLT Alarms for LOS
303func (s BBSimServer) SetOltAlarmIndication(ctx context.Context, req *bbsim.OLTAlarmRequest) (*bbsim.Response, error) {
304 o := devices.GetOLT()
Matteo Scandolof9d43412021-01-12 11:11:34 -0800305 res := &bbsim.Response{}
306
307 if err := o.SetAlarm(req.InterfaceID, req.InterfaceType, req.Status); err != nil {
308 res.StatusCode = int32(codes.Internal)
309 res.Message = err.Error()
Anand S Katti86552f92020-03-03 21:56:32 +0530310 return nil, err
311 }
312
Anand S Katti86552f92020-03-03 21:56:32 +0530313 res.StatusCode = int32(codes.OK)
314 res.Message = fmt.Sprintf("Olt Alarm Indication Sent.")
Scott Baker41724b82020-01-21 19:54:53 -0800315 return res, nil
316}