blob: 2c3a15da92ce112ab8245fdbded80dae5a55657f [file] [log] [blame]
Keita NISHIMOTO26dab092018-07-06 09:52:45 +09001/*
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
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090017package main
18
19import (
20 "./openolt"
21 "log"
22 "net"
23 "google.golang.org/grpc"
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090024 "fmt"
25 "flag"
26 "reflect"
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090027 "strings"
28 "strconv"
29 "sync"
30)
31
32type server struct{
33 olt olt
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090034 onus map[uint32]map[uint32]*onu
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090035}
36
37
38type oltState int
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090039type onuState int
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090040
41const(
42 PRE_ENABLE oltState = iota
43 OLT_UP
44 PONIF_UP
45 ONU_DISCOVERED
46)
47
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090048const(
49 ONU_PRE_ACTIVATED onuState = iota
50 ONU_ACTIVATED
51)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090052
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090053type olt struct {
54 ID uint32
55 NumPonIntf uint32
56 NumNniIntf uint32
57 Mac string
58 SerialNumber string
59 Manufacture string
60 Name string
61 internalState oltState
62 OperState string
63 Intfs []intf
64 HeartbeatSignature uint32
65}
66
67type intf struct{
68 Type string
69 IntfID uint32
70 OperState string
71}
72
73type onu struct{
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090074 internalState onuState
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090075 IntfID uint32
76 OperState string
77 SerialNumber *openolt.SerialNumber
78}
79
80func createOlt(oltid uint32, npon uint32, nnni uint32) olt{
81 olt := olt {}
82 olt.ID = oltid
83 olt.NumPonIntf = npon
84 olt.NumNniIntf = nnni
85 olt.Name = "BBSIM OLT"
86 olt.internalState = PRE_ENABLE
87 olt.OperState = "up"
88 olt.Intfs = make([]intf, olt.NumPonIntf + olt.NumNniIntf)
89 olt.HeartbeatSignature = oltid
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090090 for i := uint32(0); i < olt.NumNniIntf; i ++ {
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +090091 olt.Intfs[i].IntfID = i
92 olt.Intfs[i].OperState = "up"
93 olt.Intfs[i].Type = "nni"
94 }
Keita NISHIMOTO26dab092018-07-06 09:52:45 +090095 for i := uint32(olt.NumNniIntf); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
96 olt.Intfs[i].IntfID = i
97 olt.Intfs[i].OperState = "up"
98 olt.Intfs[i].Type = "pon"
99 }
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900100 return olt
101}
102
103func createSN(oltid uint32, intfid uint32, onuid uint32) string{
104 sn := fmt.Sprintf("%X%X%02X", oltid, intfid, onuid)
105 return sn
106}
107
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900108func createOnus(oltid uint32, intfid uint32, nonus uint32, nnni uint32) map[uint32] *onu {
109 onus := make(map[uint32] *onu ,nonus)
110 for onuid := uint32(1 + (intfid - nnni) * nonus); onuid <= (intfid - nnni + 1) * nonus; onuid ++ {
111 onu := onu{}
112 onu.internalState = ONU_PRE_ACTIVATED
113 onu.IntfID = intfid
114 onu.OperState = "up"
115 onu.SerialNumber = new(openolt.SerialNumber)
116 onu.SerialNumber.VendorId = []byte("BRCM")
117 onu.SerialNumber.VendorSpecific = []byte(createSN(oltid, intfid, uint32(onuid))) //FIX
118 onus[onuid] = &onu
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900119 }
120 return onus
121}
122
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900123func validateONU(targetonu openolt.Onu, regonus map[uint32]map[uint32] *onu) bool{
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900124 for _, onus := range regonus{
125 for _, onu := range onus{
126 if validateSN(*targetonu.SerialNumber, *onu.SerialNumber){
127 return true
128 }
129 }
130 }
131 return false
132}
133
134func validateSN(sn1 openolt.SerialNumber, sn2 openolt.SerialNumber) bool{
135 return reflect.DeepEqual(sn1.VendorId, sn2.VendorId) && reflect.DeepEqual(sn1.VendorSpecific, sn2.VendorSpecific)
136}
137
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900138func isAllONUActive(regonus map[uint32]map[uint32] *onu ) bool{
139 for _, onus := range regonus{
140 for _, onu := range onus{
141 if onu.internalState != ONU_ACTIVATED{
142 return false
143 }
144 }
145 }
146 return true
147}
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900148
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900149func updateOnusOpStatus(ponif uint32, onus map[uint32] *onu, opstatus string){
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900150 for i, onu := range onus{
151 onu.OperState = "up"
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900152 log.Printf("(PONIF:%d) ONU [%d] discovered.\n", ponif, i)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900153 }
154}
155
156func activateOLT(s *server, stream openolt.Openolt_EnableIndicationServer) error{
157 // Activate OLT
158 olt := &s.olt
159 onus := s.onus
160 if err := sendOltInd(stream, olt); err != nil {
161 return err
162 }
163 olt.OperState = "up"
164 olt.internalState = OLT_UP
165 log.Printf("OLT %s sent OltInd.\n", olt.Name)
166
167
168 // OLT sends Interface Indication to Adapter
169 if err := sendIntfInd(stream, olt); err != nil {
170 return err
171 }
172 log.Printf("OLT %s sent IntfInd.\n", olt.Name)
173
174 // OLT sends Operation Indication to Adapter after activating each interface
175 //time.Sleep(IF_UP_TIME * time.Second)
176 olt.internalState = PONIF_UP
177 if err := sendOperInd(stream, olt); err != nil {
178 return err
179 }
180 log.Printf("OLT %s sent OperInd.\n", olt.Name)
181
182 // OLT sends ONU Discover Indication to Adapter after ONU discovery
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900183 for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900184 updateOnusOpStatus(intfid, onus[intfid], "up")
185 }
186
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900187 for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900188 sendOnuDiscInd(stream, onus[intfid])
189 log.Printf("OLT id:%d sent ONUDiscInd.\n", olt.ID)
190 }
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900191
192 for{
193 //log.Printf("stop %v\n", s.onus)
194 if isAllONUActive(s.onus){
195 //log.Printf("break! %v\n", s.onus)
196 break
197 }
198 }
199 for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
200 sendOnuInd(stream, onus[intfid])
201 log.Printf("OLT id:%d sent ONUInd.\n", olt.ID)
202 }
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900203 return nil
204}
205
206func sendOltInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
207 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: "up"}}
208 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
209 log.Printf("Failed to send OLT indication: %v\n", err)
210 return err
211 }
212 return nil
213}
214
215func sendIntfInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
216 for i := uint32(0); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
217 intf := olt.Intfs[i]
218 data := &openolt.Indication_IntfInd{&openolt.IntfIndication{IntfId: intf.IntfID, OperState: intf.OperState}}
219 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
220 log.Printf("Failed to send Intf [id: %d] indication : %v\n", i, err)
221 return err
222 }
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900223 log.Printf("SendIntfInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900224 }
225 return nil
226}
227
228func sendOperInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
229 for i := uint32(0); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
230 intf := olt.Intfs[i]
231 data := &openolt.Indication_IntfOperInd{&openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
232 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
233 log.Printf("Failed to send IntfOper [id: %d] indication : %v\n", i, err)
234 return err
235 }
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900236 log.Printf("SendOperInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900237 }
238 return nil
239}
240
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900241func sendOnuDiscInd(stream openolt.Openolt_EnableIndicationServer, onus map[uint32] *onu) error{
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900242 for i, onu := range onus {
243 data := &openolt.Indication_OnuDiscInd{&openolt.OnuDiscIndication{IntfId: onu.IntfID, SerialNumber:onu.SerialNumber}}
244 log.Printf("sendONUDiscInd Onuid: %d\n", i)
245 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
246 log.Printf("Failed to send ONUDiscInd [id: %d]: %v\n", i, err)
247 return err
248 }
249 }
250 return nil
251}
252
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900253func sendOnuInd(stream openolt.Openolt_EnableIndicationServer, onus map[uint32] *onu) error{
254 for i, onu := range onus {
255 data := &openolt.Indication_OnuInd{&openolt.OnuIndication{IntfId: onu.IntfID, OnuId: uint32(i), OperState: "up", AdminState: "up", SerialNumber:onu.SerialNumber}}
256 log.Printf("sendONUInd Onuid: %d\n", i)
257 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
258 log.Printf("Failed to send ONUInd [id: %d]: %v\n", i, err)
259 return err
260 }
261 }
262 return nil
263}
264
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900265func newServer(oltid uint32, npon uint32, nonus uint32) *server{
266 s := new(server)
267 s.olt = createOlt(oltid, npon, 1)
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900268 nnni := s.olt.NumNniIntf
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900269 log.Printf("OLT ID: %d was retrieved.\n", s.olt.ID)
270
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900271 s.onus = make(map[uint32]map[uint32] *onu)
272 for intfid := nnni; intfid < npon + nnni; intfid ++ {
273 s.onus[intfid] = createOnus(oltid, intfid, nonus, nnni)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900274 }
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900275 //log.Printf("s.onus: %v\n", s.onus)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900276 return s
277}
278
279func printBanner(){
280 log.Println(" ________ _______ ________ ")
281 log.Println(" / ____ | / ____ | / ______/ __ ")
282 log.Println(" / /____/ / / /____/ / / /_____ /_/ ")
283 log.Println(" / _____ | / _____ | /______ | __ __________ ")
284 log.Println(" / /____/ / / /____/ / _______/ / / / / __ __ / ")
285 log.Println("/________/ /________/ /________/ /_/ /_/ /_/ /_/ ")
286}
287
288func getOptions()(string, uint32, uint32, uint32, uint32){
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900289 addressport := flag.String("H","127.0.0.1:50060","IP address:port")
290 nolts := flag.Int("N", 1, "Number of OLTs")
291 nports := flag.Int("i", 1, "Number of PON-IF ports")
292 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900293 flag.Parse()
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900294 fmt.Printf("%v\n", *addressport)
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900295 //fmt.Println("nports:", *nports, "nonus:", *nonus)
Keita NISHIMOTO26dab092018-07-06 09:52:45 +0900296 address := strings.Split(*addressport, ":")[0]
297 port,_ := strconv.Atoi(strings.Split(*addressport, ":")[1])
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900298 return address, uint32(port), uint32(*nolts), uint32(*nports), uint32(*nonus)
299}
300
301
Keita NISHIMOTOd771cd12018-06-07 08:37:24 +0900302func main() {
303 printBanner()
304 ipaddress, baseport, nolts, npon, nonus := getOptions()
305 log.Printf("ip:%s, baseport:%d, nolts:%d, npon:%d, nonus:%d\n", ipaddress, baseport, nolts, npon, nonus)
306 servers := make([] *server, nolts)
307 grpcservers := make([] *grpc.Server, nolts)
308 lis := make([] net.Listener, nolts)
309 var wg sync.WaitGroup
310 wg.Add(int(nolts))
311 for oltid := uint32(0); oltid < nolts; oltid ++ {
312 portnum := baseport + oltid
313 addressport := ipaddress + ":" + strconv.Itoa(int(portnum))
314 log.Printf("Listening %s ...", addressport)
315 lis[oltid], _ = net.Listen("tcp", addressport)
316 servers[oltid] = newServer(oltid, npon, nonus)
317 grpcservers[oltid] = grpc.NewServer()
318 openolt.RegisterOpenoltServer(grpcservers[oltid], servers[oltid])
319 go grpcservers[oltid].Serve(lis[oltid])
320 }
321 wg.Wait()
322}