blob: bfedd429ea6b971b99df1258c3fb2feeeba8845d [file] [log] [blame]
Matteo Scandolo4a036262020-08-17 15:56:13 -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
17package devices
18
19import (
Matteo Scandolo618a6582020-09-09 12:21:29 -070020 "encoding/hex"
Matteo Scandolo4a036262020-08-17 15:56:13 -070021 "github.com/looplab/fsm"
22 "github.com/opencord/bbsim/internal/bbsim/packetHandlers"
23 "github.com/opencord/bbsim/internal/bbsim/responders/dhcp"
24 "github.com/opencord/bbsim/internal/bbsim/responders/eapol"
Matteo Scandolo618a6582020-09-09 12:21:29 -070025 "github.com/opencord/bbsim/internal/bbsim/responders/igmp"
Matteo Scandolo4a036262020-08-17 15:56:13 -070026 bbsimTypes "github.com/opencord/bbsim/internal/bbsim/types"
27 log "github.com/sirupsen/logrus"
28 "net"
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070029 "time"
Matteo Scandolo4a036262020-08-17 15:56:13 -070030)
31
32var serviceLogger = log.WithFields(log.Fields{
33 "module": "SERVICE",
34})
35
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070036// time to wait before fail EAPOL/DHCP
37// (it's a variable and not a constant so it can be overridden in the tests)
Matteo Scandolo24a88c42020-09-17 14:55:28 -070038var eapolWaitTime = 60 * time.Second
39var dhcpWaitTime = 60 * time.Second
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070040
Matteo Scandolo4a036262020-08-17 15:56:13 -070041type ServiceIf interface {
Matteo Scandolobd875b32020-09-18 17:46:31 -070042 HandlePackets() // start listening on the PacketCh
43 HandleAuth() // Sends the EapoStart packet
44 HandleDhcp(pbit uint8, cTag int) // Sends the DHCPDiscover packet
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070045
Matteo Scandoloadc72a82020-09-08 18:46:08 -070046 Initialize(stream bbsimTypes.Stream)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070047 Disable()
Matteo Scandolo4a036262020-08-17 15:56:13 -070048}
49
50type Service struct {
51 Name string
52 HwAddress net.HardwareAddr
53 Onu *Onu
54 CTag int
55 STag int
56 NeedsEapol bool
57 NeedsDhcp bool
58 NeedsIgmp bool
59 TechnologyProfileID int
60 UniTagMatch int
61 ConfigureMacAddress bool
Matteo Scandolo8d281372020-09-03 16:23:37 -070062 UsPonCTagPriority uint8
63 UsPonSTagPriority uint8
64 DsPonCTagPriority uint8
65 DsPonSTagPriority uint8
Matteo Scandolo4a036262020-08-17 15:56:13 -070066
67 // state
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070068 GemPort uint32
69 InternalState *fsm.FSM
70 EapolState *fsm.FSM
71 DHCPState *fsm.FSM
Matteo Scandolo618a6582020-09-09 12:21:29 -070072 IGMPState *fsm.FSM
Matteo Scandoloadc72a82020-09-08 18:46:08 -070073 Channel chan Message // drive Service lifecycle
74 PacketCh chan OnuPacketMessage // handle packets
75 Stream bbsimTypes.Stream // the gRPC stream to communicate with the adapter, created in the initialize transition
Matteo Scandolo4a036262020-08-17 15:56:13 -070076}
77
78func NewService(name string, hwAddress net.HardwareAddr, onu *Onu, cTag int, sTag int,
79 needsEapol bool, needsDchp bool, needsIgmp bool, tpID int, uniTagMatch int, configMacAddress bool,
Matteo Scandolo8d281372020-09-03 16:23:37 -070080 usPonCTagPriority uint8, usPonSTagPriority uint8, dsPonCTagPriority uint8, dsPonSTagPriority uint8) (*Service, error) {
Matteo Scandolo4a036262020-08-17 15:56:13 -070081
82 service := Service{
83 Name: name,
84 HwAddress: hwAddress,
85 Onu: onu,
86 CTag: cTag,
87 STag: sTag,
88 NeedsEapol: needsEapol,
89 NeedsDhcp: needsDchp,
90 NeedsIgmp: needsIgmp,
91 TechnologyProfileID: tpID,
92 UniTagMatch: uniTagMatch,
93 ConfigureMacAddress: configMacAddress,
94 UsPonCTagPriority: usPonCTagPriority,
95 UsPonSTagPriority: usPonSTagPriority,
96 DsPonCTagPriority: dsPonCTagPriority,
97 DsPonSTagPriority: dsPonSTagPriority,
Matteo Scandolo4a036262020-08-17 15:56:13 -070098 }
99
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700100 service.InternalState = fsm.NewFSM(
101 "created",
102 fsm.Events{
103 {Name: "initialized", Src: []string{"created", "disabled"}, Dst: "initialized"},
104 {Name: "disabled", Src: []string{"initialized"}, Dst: "disabled"},
105 },
106 fsm.Callbacks{
107 "enter_state": func(e *fsm.Event) {
108 service.logStateChange("InternalState", e.Src, e.Dst)
109 },
110 "enter_initialized": func(e *fsm.Event) {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700111
112 stream, ok := e.Args[0].(bbsimTypes.Stream)
113 if !ok {
114 serviceLogger.Fatal("initialize invoke with wrong arguments")
115 }
116
117 service.Stream = stream
118
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700119 service.PacketCh = make(chan OnuPacketMessage)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700120 service.Channel = make(chan Message)
121
122 go service.HandlePackets()
123 go service.HandleChannel()
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700124 },
125 "enter_disabled": func(e *fsm.Event) {
126 // reset the state machines
127 service.EapolState.SetState("created")
128 service.DHCPState.SetState("created")
129
130 // stop listening for packets
131 close(service.PacketCh)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700132 close(service.Channel)
133
134 service.PacketCh = nil
135 service.Channel = nil
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700136 },
137 },
138 )
139
Matteo Scandolo4a036262020-08-17 15:56:13 -0700140 service.EapolState = fsm.NewFSM(
141 "created",
142 fsm.Events{
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700143 {Name: "start_auth", Src: []string{"created", "eap_response_success_received", "auth_failed"}, Dst: "auth_started"},
Matteo Scandolo4a036262020-08-17 15:56:13 -0700144 {Name: "eap_start_sent", Src: []string{"auth_started"}, Dst: "eap_start_sent"},
145 {Name: "eap_response_identity_sent", Src: []string{"eap_start_sent"}, Dst: "eap_response_identity_sent"},
146 {Name: "eap_response_challenge_sent", Src: []string{"eap_response_identity_sent"}, Dst: "eap_response_challenge_sent"},
147 {Name: "eap_response_success_received", Src: []string{"eap_response_challenge_sent"}, Dst: "eap_response_success_received"},
148 {Name: "auth_failed", Src: []string{"auth_started", "eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent"}, Dst: "auth_failed"},
149 },
150 fsm.Callbacks{
151 "enter_state": func(e *fsm.Event) {
152 service.logStateChange("EapolState", e.Src, e.Dst)
153 },
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700154 "before_start_auth": func(e *fsm.Event) {
155 msg := Message{
156 Type: StartEAPOL,
157 }
158 service.Channel <- msg
159 },
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700160 "enter_auth_started": func(e *fsm.Event) {
161 go func() {
162
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700163 for {
164 select {
165 case <-service.Onu.PonPort.Olt.enableContext.Done():
166 // if the OLT is disabled, then cancel
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700167 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700168 case <-time.After(eapolWaitTime):
169 if service.EapolState.Current() != "eap_response_success_received" {
170 serviceLogger.WithFields(log.Fields{
171 "OnuId": service.Onu.ID,
172 "IntfId": service.Onu.PonPortID,
173 "OnuSn": service.Onu.Sn(),
174 "Name": service.Name,
175 "EapolState": service.EapolState.Current(),
176 }).Warn("EAPOL failed, resetting EAPOL State")
177 _ = service.EapolState.Event("auth_failed")
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700178 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700179 }
180 }
181
182 }
183 }()
184 },
Matteo Scandolo4a036262020-08-17 15:56:13 -0700185 },
186 )
187
188 service.DHCPState = fsm.NewFSM(
189 "created",
190 fsm.Events{
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700191 // TODO only allow transitions to dhcp_start from success or failure, not in-between states
192 // TODO forcefully fail DHCP if we don't get an ack in X seconds
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700193 {Name: "start_dhcp", Src: []string{"created", "dhcp_ack_received", "dhcp_failed"}, Dst: "dhcp_started"},
Matteo Scandolo4a036262020-08-17 15:56:13 -0700194 {Name: "dhcp_discovery_sent", Src: []string{"dhcp_started"}, Dst: "dhcp_discovery_sent"},
195 {Name: "dhcp_request_sent", Src: []string{"dhcp_discovery_sent"}, Dst: "dhcp_request_sent"},
196 {Name: "dhcp_ack_received", Src: []string{"dhcp_request_sent"}, Dst: "dhcp_ack_received"},
197 {Name: "dhcp_failed", Src: []string{"dhcp_started", "dhcp_discovery_sent", "dhcp_request_sent"}, Dst: "dhcp_failed"},
198 },
199 fsm.Callbacks{
200 "enter_state": func(e *fsm.Event) {
201 service.logStateChange("DHCPState", e.Src, e.Dst)
202 },
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700203 "before_start_dhcp": func(e *fsm.Event) {
204 msg := Message{
205 Type: StartDHCP,
206 }
207 service.Channel <- msg
208 },
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700209 "enter_dhcp_started": func(e *fsm.Event) {
210 go func() {
211
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700212 for {
213 select {
214 case <-service.Onu.PonPort.Olt.enableContext.Done():
215 // if the OLT is disabled, then cancel
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700216 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700217 case <-time.After(dhcpWaitTime):
218 if service.DHCPState.Current() != "dhcp_ack_received" {
219 serviceLogger.WithFields(log.Fields{
220 "OnuId": service.Onu.ID,
221 "IntfId": service.Onu.PonPortID,
222 "OnuSn": service.Onu.Sn(),
223 "Name": service.Name,
224 "DHCPState": service.DHCPState.Current(),
225 }).Warn("DHCP failed, resetting DHCP State")
226 _ = service.DHCPState.Event("dhcp_failed")
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700227 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700228 }
229 }
230
231 }
232 }()
233 },
Matteo Scandolo4a036262020-08-17 15:56:13 -0700234 },
235 )
236
Matteo Scandolo618a6582020-09-09 12:21:29 -0700237 service.IGMPState = fsm.NewFSM(
238 "created",
239 fsm.Events{
240 {Name: "igmp_join_start", Src: []string{"created", "igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
241 {Name: "igmp_join_startv3", Src: []string{"igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
242 {Name: "igmp_join_error", Src: []string{"igmp_join_started"}, Dst: "igmp_join_error"},
243 {Name: "igmp_leave", Src: []string{"igmp_join_started"}, Dst: "igmp_left"},
244 },
245 fsm.Callbacks{
246 "igmp_join_start": func(e *fsm.Event) {
247 msg := Message{
248 Type: IGMPMembershipReportV2,
249 }
250 service.Channel <- msg
251 },
252 "igmp_leave": func(e *fsm.Event) {
253 msg := Message{
254 Type: IGMPLeaveGroup}
255 service.Channel <- msg
256 },
257 "igmp_join_startv3": func(e *fsm.Event) {
258 msg := Message{
259 Type: IGMPMembershipReportV3,
260 }
261 service.Channel <- msg
262 },
263 },
264 )
265
Matteo Scandolo4a036262020-08-17 15:56:13 -0700266 return &service, nil
267}
268
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700269// HandleAuth is used to start EAPOL for a particular Service when the corresponding flow is received
270func (s *Service) HandleAuth() {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700271
272 if !s.NeedsEapol {
273 serviceLogger.WithFields(log.Fields{
274 "OnuId": s.Onu.ID,
275 "IntfId": s.Onu.PonPortID,
276 "OnuSn": s.Onu.Sn(),
277 "Name": s.Name,
278 "NeedsEapol": s.NeedsEapol,
279 }).Debug("Won't start authentication as EAPOL is not required")
280 return
281 }
282
Matteo Scandolo4a036262020-08-17 15:56:13 -0700283 if err := s.EapolState.Event("start_auth"); err != nil {
284 serviceLogger.WithFields(log.Fields{
285 "OnuId": s.Onu.ID,
286 "IntfId": s.Onu.PonPortID,
287 "OnuSn": s.Onu.Sn(),
288 "Name": s.Name,
289 "err": err.Error(),
290 }).Error("Can't start auth for this Service")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700291 }
292}
293
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700294// HandleDhcp is used to start DHCP for a particular Service when the corresponding flow is received
Matteo Scandolobd875b32020-09-18 17:46:31 -0700295func (s *Service) HandleDhcp(pbit uint8, cTag int) {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700296
Matteo Scandolobd875b32020-09-18 17:46:31 -0700297 if s.CTag != cTag || (s.UsPonCTagPriority != pbit && pbit != 255) {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700298 serviceLogger.WithFields(log.Fields{
299 "OnuId": s.Onu.ID,
300 "IntfId": s.Onu.PonPortID,
301 "OnuSn": s.Onu.Sn(),
302 "Name": s.Name,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700303 }).Trace("DHCP flow is not for this service, ignoring")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700304 return
305 }
306
Matteo Scandolo4a036262020-08-17 15:56:13 -0700307 if !s.NeedsDhcp {
308 serviceLogger.WithFields(log.Fields{
309 "OnuId": s.Onu.ID,
310 "IntfId": s.Onu.PonPortID,
311 "OnuSn": s.Onu.Sn(),
312 "Name": s.Name,
313 "NeedsDhcp": s.NeedsDhcp,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700314 }).Trace("Won't start DHCP as it is not required")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700315 return
316 }
317
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700318 // TODO check if the DHCP flow was received before starting auth
Matteo Scandolo4a036262020-08-17 15:56:13 -0700319
320 if err := s.DHCPState.Event("start_dhcp"); err != nil {
321 serviceLogger.WithFields(log.Fields{
322 "OnuId": s.Onu.ID,
323 "IntfId": s.Onu.PonPortID,
324 "OnuSn": s.Onu.Sn(),
325 "Name": s.Name,
326 "err": err.Error(),
327 }).Error("Can't start DHCP for this Service")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700328 }
329}
330
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700331func (s *Service) HandlePackets() {
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700332 serviceLogger.WithFields(log.Fields{
333 "OnuId": s.Onu.ID,
334 "IntfId": s.Onu.PonPortID,
335 "OnuSn": s.Onu.Sn(),
336 "GemPortId": s.GemPort,
337 "Name": s.Name,
338 }).Debug("Listening on Service Packet Channel")
339
340 defer func() {
341 serviceLogger.WithFields(log.Fields{
342 "OnuId": s.Onu.ID,
343 "IntfId": s.Onu.PonPortID,
344 "OnuSn": s.Onu.Sn(),
345 "GemPortId": s.GemPort,
346 "Name": s.Name,
347 }).Debug("Done Listening on Service Packet Channel")
348 }()
349
350 for msg := range s.PacketCh {
351 serviceLogger.WithFields(log.Fields{
352 "OnuId": s.Onu.ID,
353 "IntfId": s.Onu.PonPortID,
354 "OnuSn": s.Onu.Sn(),
355 "Name": s.Name,
356 "messageType": msg.Type,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700357 }).Trace("Received message on Service Packet Channel")
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700358
359 if msg.Type == packetHandlers.EAPOL {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700360 eapol.HandleNextPacket(msg.OnuId, msg.IntfId, s.GemPort, s.Onu.Sn(), s.Onu.PortNo, s.EapolState, msg.Packet, s.Stream, nil)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700361 } else if msg.Type == packetHandlers.DHCP {
Matteo Scandolo24a88c42020-09-17 14:55:28 -0700362 _ = dhcp.HandleNextPacket(s.Onu.ID, s.Onu.PonPortID, s.Name, s.Onu.Sn(), s.Onu.PortNo, s.CTag, s.GemPort, s.HwAddress, s.DHCPState, msg.Packet, s.UsPonCTagPriority, s.Stream)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700363 } else if msg.Type == packetHandlers.IGMP {
364 log.Warn(hex.EncodeToString(msg.Packet.Data()))
365 _ = igmp.HandleNextPacket(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, msg.Packet, s.CTag, s.UsPonCTagPriority, s.Stream)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700366 }
367 }
368}
369
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700370func (s *Service) HandleChannel() {
371 serviceLogger.WithFields(log.Fields{
372 "OnuId": s.Onu.ID,
373 "IntfId": s.Onu.PonPortID,
374 "OnuSn": s.Onu.Sn(),
375 "GemPortId": s.GemPort,
376 "Name": s.Name,
377 }).Debug("Listening on Service Channel")
378
379 defer func() {
380 serviceLogger.WithFields(log.Fields{
381 "OnuId": s.Onu.ID,
382 "IntfId": s.Onu.PonPortID,
383 "OnuSn": s.Onu.Sn(),
384 "GemPortId": s.GemPort,
385 "Name": s.Name,
386 }).Debug("Done Listening on Service Channel")
387 }()
388 for msg := range s.Channel {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700389 switch msg.Type {
390 case StartEAPOL:
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700391 if err := s.handleEapolStart(s.Stream); err != nil {
392 serviceLogger.WithFields(log.Fields{
393 "OnuId": s.Onu.ID,
394 "IntfId": s.Onu.PonPortID,
395 "OnuSn": s.Onu.Sn(),
396 "Name": s.Name,
397 "err": err,
398 }).Error("Error while sending EapolStart packet")
399 _ = s.EapolState.Event("auth_failed")
400 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700401 case StartDHCP:
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700402 if err := s.handleDHCPStart(s.Stream); err != nil {
403 serviceLogger.WithFields(log.Fields{
404 "OnuId": s.Onu.ID,
405 "IntfId": s.Onu.PonPortID,
406 "OnuSn": s.Onu.Sn(),
407 "Name": s.Name,
408 "err": err,
409 }).Error("Error while sending DHCPDiscovery packet")
410 _ = s.DHCPState.Event("dhcp_failed")
Matteo Scandolo618a6582020-09-09 12:21:29 -0700411
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700412 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700413 case IGMPMembershipReportV2:
414 serviceLogger.WithFields(log.Fields{
415 "OnuId": s.Onu.ID,
416 "IntfId": s.Onu.PonPortID,
417 "OnuSn": s.Onu.Sn(),
418 "Name": s.Name,
419 }).Debug("Recieved IGMPMembershipReportV2 message on ONU channel")
420 _ = igmp.SendIGMPMembershipReportV2(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream)
421 case IGMPLeaveGroup:
422 serviceLogger.WithFields(log.Fields{
423 "OnuId": s.Onu.ID,
424 "IntfId": s.Onu.PonPortID,
425 "OnuSn": s.Onu.Sn(),
426 "Name": s.Name,
427 }).Debug("Recieved IGMPLeaveGroupV2 message on ONU channel")
428 _ = igmp.SendIGMPLeaveGroupV2(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream)
429 case IGMPMembershipReportV3:
430 serviceLogger.WithFields(log.Fields{
431 "OnuId": s.Onu.ID,
432 "IntfId": s.Onu.PonPortID,
433 "OnuSn": s.Onu.Sn(),
434 "Name": s.Name,
435 }).Debug("Recieved IGMPMembershipReportV3 message on ONU channel")
436 _ = igmp.SendIGMPMembershipReportV3(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream)
437
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700438 }
439 }
440}
441
442func (s *Service) Initialize(stream bbsimTypes.Stream) {
443 if err := s.InternalState.Event("initialized", stream); err != nil {
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700444 serviceLogger.WithFields(log.Fields{
445 "OnuId": s.Onu.ID,
446 "IntfId": s.Onu.PonPortID,
447 "OnuSn": s.Onu.Sn(),
448 "Name": s.Name,
449 "Err": err,
450 }).Error("Cannot initialize service")
451 }
452}
453
454func (s *Service) Disable() {
455 if err := s.InternalState.Event("disabled"); err != nil {
456 serviceLogger.WithFields(log.Fields{
457 "OnuId": s.Onu.ID,
458 "IntfId": s.Onu.PonPortID,
459 "OnuSn": s.Onu.Sn(),
460 "Name": s.Name,
461 "Err": err,
462 }).Error("Cannot disable service")
463 }
464}
465
Matteo Scandolo4a036262020-08-17 15:56:13 -0700466func (s *Service) handleEapolStart(stream bbsimTypes.Stream) error {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700467 // TODO fail Auth if it does not succeed in 30 seconds
Matteo Scandolo4a036262020-08-17 15:56:13 -0700468 serviceLogger.WithFields(log.Fields{
469 "OnuId": s.Onu.ID,
470 "IntfId": s.Onu.PonPortID,
471 "OnuSn": s.Onu.Sn(),
472 "GemPort": s.GemPort,
473 "Name": s.Name,
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700474 }).Trace("handleEapolStart")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700475
476 if err := eapol.SendEapStart(s.Onu.ID, s.Onu.PonPortID, s.Onu.Sn(), s.Onu.PortNo,
477 s.HwAddress, s.GemPort, s.EapolState, stream); err != nil {
478 serviceLogger.WithFields(log.Fields{
479 "OnuId": s.Onu.ID,
480 "IntfId": s.Onu.PonPortID,
481 "OnuSn": s.Onu.Sn(),
482 "GemPort": s.GemPort,
483 "Name": s.Name,
484 }).Error("handleEapolStart")
485 return err
486 }
487 return nil
488}
489
490func (s *Service) handleDHCPStart(stream bbsimTypes.Stream) error {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700491 // TODO fail DHCP if it does not succeed in 30 seconds
Matteo Scandolo4a036262020-08-17 15:56:13 -0700492 serviceLogger.WithFields(log.Fields{
493 "OnuId": s.Onu.ID,
494 "IntfId": s.Onu.PonPortID,
495 "OnuSn": s.Onu.Sn(),
496 "Name": s.Name,
497 "GemPortId": s.GemPort,
498 }).Debugf("HandleDHCPStart")
499
Matteo Scandolo24a88c42020-09-17 14:55:28 -0700500 if err := dhcp.SendDHCPDiscovery(s.Onu.PonPortID, s.Onu.ID, s.Name, int(s.CTag), s.GemPort,
Matteo Scandolo8d281372020-09-03 16:23:37 -0700501 s.Onu.Sn(), s.Onu.PortNo, s.DHCPState, s.HwAddress, s.UsPonCTagPriority, stream); err != nil {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700502 serviceLogger.WithFields(log.Fields{
503 "OnuId": s.Onu.ID,
504 "IntfId": s.Onu.PonPortID,
505 "OnuSn": s.Onu.Sn(),
506 "Name": s.Name,
507 "GemPortId": s.GemPort,
508 }).Error("HandleDHCPStart")
509 return err
510 }
511 return nil
512}
513
Matteo Scandolo4a036262020-08-17 15:56:13 -0700514func (s *Service) logStateChange(stateMachine string, src string, dst string) {
515 serviceLogger.WithFields(log.Fields{
516 "OnuId": s.Onu.ID,
517 "IntfId": s.Onu.PonPortID,
518 "OnuSn": s.Onu.Sn(),
519 "Name": s.Name,
520 }).Debugf("Changing Service.%s InternalState from %s to %s", stateMachine, src, dst)
521}