blob: ec25a1043fbf0781dc5ae93bdf00dce9f33c4ccf [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29:46 -07001/*
2 * Copyright 2018-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
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"
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080022 "google.golang.org/grpc/status"
rajeshf921f882020-03-06 18:24:28 +053023 "strings"
Matteo Scandolo88c204a2020-11-03 10:34:24 -080024 "time"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020025
Matteo Scandolo11006992019-08-28 11:29:46 -070026 "github.com/opencord/bbsim/api/bbsim"
27 "github.com/opencord/bbsim/internal/bbsim/devices"
Matteo Scandolo40e067f2019-10-16 16:59:41 -070028 "github.com/opencord/bbsim/internal/common"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070029 log "github.com/sirupsen/logrus"
Zdravko Bozakov681364d2019-11-10 14:28:46 +010030 "google.golang.org/grpc/codes"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070031)
32
33var logger = log.WithFields(log.Fields{
34 "module": "GrpcApiServer",
35})
36
37var (
Matteo Scandolo8df63df2019-09-12 10:34:32 -070038 version string
39 buildTime string
40 commitHash string
41 gitStatus string
Matteo Scandolo84f7d482019-08-08 19:00:47 -070042)
43
44type BBSimServer struct {
45}
46
Matteo Scandolo8df63df2019-09-12 10:34:32 -070047func (s BBSimServer) Version(ctx context.Context, req *bbsim.Empty) (*bbsim.VersionNumber, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +020048 // TODO add a flag to specify whether the tree was clean at this commit or not
Matteo Scandolo84f7d482019-08-08 19:00:47 -070049 return &bbsim.VersionNumber{
Matteo Scandolo8df63df2019-09-12 10:34:32 -070050 Version: version,
51 BuildTime: buildTime,
Matteo Scandolo84f7d482019-08-08 19:00:47 -070052 CommitHash: commitHash,
Matteo Scandolo8df63df2019-09-12 10:34:32 -070053 GitStatus: gitStatus,
Matteo Scandolo84f7d482019-08-08 19:00:47 -070054 }, nil
55}
56
57func (s BBSimServer) GetOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Olt, error) {
58 olt := devices.GetOLT()
59 nnis := []*bbsim.NNIPort{}
60 pons := []*bbsim.PONPort{}
61
62 for _, nni := range olt.Nnis {
63 n := bbsim.NNIPort{
Matteo Scandolo8df63df2019-09-12 10:34:32 -070064 ID: int32(nni.ID),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070065 OperState: nni.OperState.Current(),
Matteo Scandolo84f7d482019-08-08 19:00:47 -070066 }
67 nnis = append(nnis, &n)
68 }
69
70 for _, pon := range olt.Pons {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080071
72 allocatedOnuIds := []*bbsim.PonAllocatedResources{}
73 allocatedAllocIds := []*bbsim.PonAllocatedResources{}
74 allocatedGemPorts := []*bbsim.PonAllocatedResources{}
75
76 for k, v := range pon.AllocatedOnuIds {
77 resource := &bbsim.PonAllocatedResources{
78 SerialNumber: common.OnuSnToString(v),
79 Id: int32(k),
80 }
81 allocatedOnuIds = append(allocatedOnuIds, resource)
82 }
83
84 for k, v := range pon.AllocatedGemPorts {
85 resource := &bbsim.PonAllocatedResources{
86 SerialNumber: common.OnuSnToString(v),
87 Id: int32(k),
88 }
89 allocatedGemPorts = append(allocatedGemPorts, resource)
90 }
91
Andrea Campanellabef00d52022-02-04 09:47:52 +010092 for k, v := range pon.AllocatedAllocIds {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080093 resource := &bbsim.PonAllocatedResources{
Andrea Campanellabef00d52022-02-04 09:47:52 +010094 SerialNumber: common.OnuSnToString(v),
95 Id: int32(k),
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080096 }
97 allocatedAllocIds = append(allocatedAllocIds, resource)
98 }
99
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700100 p := bbsim.PONPort{
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800101 ID: int32(pon.ID),
102 OperState: pon.OperState.Current(),
103 InternalState: pon.InternalState.Current(),
104 PacketCount: pon.PacketCount,
105 AllocatedOnuIds: allocatedOnuIds,
106 AllocatedAllocIds: allocatedAllocIds,
107 AllocatedGemPorts: allocatedGemPorts,
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700108 }
109 pons = append(pons, &p)
110 }
111
Matteo Scandolo4a036262020-08-17 15:56:13 -0700112 oltAddress := strings.Split(common.Config.BBSim.OpenOltAddress, ":")[0]
rajeshf921f882020-03-06 18:24:28 +0530113 if oltAddress == "" {
114 oltAddress = getOltIP().String()
115 }
116
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700117 res := bbsim.Olt{
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700118 ID: int32(olt.ID),
119 SerialNumber: olt.SerialNumber,
120 OperState: olt.OperState.Current(),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700121 InternalState: olt.InternalState.Current(),
rajeshf921f882020-03-06 18:24:28 +0530122 IP: oltAddress,
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700123 NNIPorts: nnis,
124 PONPorts: pons,
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700125 }
126 return &res, nil
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700127}
128
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800129// takes a nested map and return a proto
130func resourcesMapToresourcesProto(resourceType bbsim.OltAllocatedResourceType_Type, resources map[uint32]map[uint32]map[uint32]map[int32]map[uint64]bool) *bbsim.OltAllocatedResources {
131 proto := &bbsim.OltAllocatedResources{
132 Resources: []*bbsim.OltAllocatedResource{},
133 }
134 for ponId, ponValues := range resources {
135 for onuId, onuValues := range ponValues {
136 for uniId, uniValues := range onuValues {
137 for allocId, flows := range uniValues {
138 for flow := range flows {
139 resource := &bbsim.OltAllocatedResource{
140 Type: resourceType.String(),
141 PonPortId: ponId,
142 OnuId: onuId,
143 PortNo: uniId,
144 ResourceId: allocId,
145 FlowId: flow,
146 }
147 proto.Resources = append(proto.Resources, resource)
148 }
149 }
150 }
151 }
152 }
153 return proto
154}
155
156func (s BBSimServer) GetOltAllocatedResources(ctx context.Context, req *bbsim.OltAllocatedResourceType) (*bbsim.OltAllocatedResources, error) {
157 o := devices.GetOLT()
158
159 switch req.Type {
160 case bbsim.OltAllocatedResourceType_UNKNOWN:
161 return nil, status.Errorf(codes.InvalidArgument, "resource-type-%s-is-invalid", req.Type)
162 case bbsim.OltAllocatedResourceType_ALLOC_ID:
163 return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_ALLOC_ID, o.AllocIDs), nil
164 case bbsim.OltAllocatedResourceType_GEM_PORT:
165 return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_GEM_PORT, o.GemPortIDs), nil
166 default:
167 return nil, status.Errorf(codes.InvalidArgument, "unkown-resource-type-%s", req.Type)
168 }
169}
170
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100171func (s BBSimServer) PoweronOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
172 res := &bbsim.Response{}
173 o := devices.GetOLT()
174
175 if err := o.InternalState.Event("initialize"); err != nil {
176 log.Errorf("Error initializing OLT: %v", err)
177 res.StatusCode = int32(codes.FailedPrecondition)
178 return res, err
179 }
180
181 res.StatusCode = int32(codes.OK)
182 return res, nil
183}
184
185func (s BBSimServer) ShutdownOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
186 res := &bbsim.Response{}
187 o := devices.GetOLT()
188
189 if err := o.InternalState.Event("disable"); err != nil {
190 log.Errorf("Error disabling OLT: %v", err)
191 res.StatusCode = int32(codes.FailedPrecondition)
192 return res, err
193 }
194
195 res.StatusCode = int32(codes.OK)
196 return res, nil
197}
198
199func (s BBSimServer) RebootOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
200 res := &bbsim.Response{}
201 o := devices.GetOLT()
Shrey Baid688b4242020-07-10 20:40:10 +0530202 go func() { _ = o.RestartOLT() }()
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100203 res.StatusCode = int32(codes.OK)
204 res.Message = fmt.Sprintf("OLT restart triggered.")
205 return res, nil
206}
207
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800208func (s BBSimServer) StopgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
209 res := &bbsim.Response{}
210 res.StatusCode = int32(codes.OK)
211 res.Message = fmt.Sprintf("Openolt gRPC server stopped")
212 o := devices.GetOLT()
213
214 logger.Infof("Received request to stop Openolt gRPC Server")
215
216 o.StopOltServer()
217
218 return res, nil
219}
220
221func (s BBSimServer) StartgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
222 res := &bbsim.Response{}
223 res.StatusCode = int32(codes.OK)
224 res.Message = fmt.Sprintf("Openolt gRPC server started")
225 o := devices.GetOLT()
226
227 logger.Infof("Received request to start Openolt gRPC Server")
228
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000229 if o.OltServer != nil {
230 return nil, fmt.Errorf("Openolt gRPC server already running.")
231 }
232
233 oltGrpcServer, err := o.StartOltServer()
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800234 if err != nil {
235 return nil, err
236 }
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000237 o.OltServer = oltGrpcServer
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800238
239 return res, nil
240}
241
242func (s BBSimServer) RestartgRPCServer(ctx context.Context, req *bbsim.Timeout) (*bbsim.Response, error) {
243 o := devices.GetOLT()
244 logger.Infof("Received request to restart Openolt gRPC Server in %v seconds", req.Delay)
245 o.StopOltServer()
246
247 res := &bbsim.Response{}
248 res.StatusCode = int32(codes.OK)
249 res.Message = fmt.Sprintf("Openolt gRPC server stopped, restarting in %v", req.Delay)
250
251 go func() {
252 time.Sleep(time.Duration(req.Delay) * time.Second)
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000253 oltGrpcServer, err := o.StartOltServer()
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800254 if err != nil {
255 logger.WithFields(log.Fields{
256 "err": err,
257 }).Error("Cannot restart Openolt gRPC server")
258 }
Hardik Windlassefdb4b62021-03-18 10:33:24 +0000259 o.OltServer = oltGrpcServer
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800260 logger.Infof("Openolt gRPC Server restarted after %v seconds", req.Delay)
261 }()
262
263 return res, nil
264}
265
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700266func (s BBSimServer) SetLogLevel(ctx context.Context, req *bbsim.LogLevel) (*bbsim.LogLevel, error) {
267
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700268 common.SetLogLevel(log.StandardLogger(), req.Level, req.Caller)
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700269
270 return &bbsim.LogLevel{
271 Level: log.StandardLogger().Level.String(),
272 Caller: log.StandardLogger().ReportCaller,
273 }, nil
274}
Scott Baker41724b82020-01-21 19:54:53 -0800275
Anand S Katti86552f92020-03-03 21:56:32 +0530276func (s BBSimServer) SetOnuAlarmIndication(ctx context.Context, req *bbsim.ONUAlarmRequest) (*bbsim.Response, error) {
Scott Baker41724b82020-01-21 19:54:53 -0800277 o := devices.GetOLT()
Matteo Scandolof9d43412021-01-12 11:11:34 -0800278
279 res := &bbsim.Response{}
280
281 onu, err := o.FindOnuBySn(req.SerialNumber)
Scott Baker41724b82020-01-21 19:54:53 -0800282 if err != nil {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800283 res.StatusCode = int32(codes.NotFound)
284 res.Message = err.Error()
Scott Baker41724b82020-01-21 19:54:53 -0800285 return nil, err
286 }
287
Matteo Scandolof9d43412021-01-12 11:11:34 -0800288 if err := onu.SetAlarm(req.AlarmType, req.Status); err != nil {
289 res.StatusCode = int32(codes.Internal)
290 res.Message = err.Error()
291 return nil, err
292 }
293
Scott Baker41724b82020-01-21 19:54:53 -0800294 res.StatusCode = int32(codes.OK)
Anand S Katti86552f92020-03-03 21:56:32 +0530295 res.Message = fmt.Sprintf("Onu Alarm Indication Sent.")
296 return res, nil
297}
298
299// SetOltAlarmIndication generates OLT Alarms for LOS
300func (s BBSimServer) SetOltAlarmIndication(ctx context.Context, req *bbsim.OLTAlarmRequest) (*bbsim.Response, error) {
301 o := devices.GetOLT()
Matteo Scandolof9d43412021-01-12 11:11:34 -0800302 res := &bbsim.Response{}
303
304 if err := o.SetAlarm(req.InterfaceID, req.InterfaceType, req.Status); err != nil {
305 res.StatusCode = int32(codes.Internal)
306 res.Message = err.Error()
Anand S Katti86552f92020-03-03 21:56:32 +0530307 return nil, err
308 }
309
Anand S Katti86552f92020-03-03 21:56:32 +0530310 res.StatusCode = int32(codes.OK)
311 res.Message = fmt.Sprintf("Olt Alarm Indication Sent.")
Scott Baker41724b82020-01-21 19:54:53 -0800312 return res, nil
313}