[SEBA-819][SEBA-820] Adding commands to restart EAPOL and DHCP

Change-Id: I283dcae58bc5dbf0ef405c4ce6b5f2e8b818b993
diff --git a/internal/bbsim/api/onus_handler.go b/internal/bbsim/api/onus_handler.go
index 7f42f89..8feee21 100644
--- a/internal/bbsim/api/onus_handler.go
+++ b/internal/bbsim/api/onus_handler.go
@@ -158,3 +158,71 @@
 
 	return res, nil
 }
+
+func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
+	res := &bbsim.Response{}
+
+	logger.WithFields(log.Fields{
+		"OnuSn": req.SerialNumber,
+	}).Infof("Received request to restart authentication ONU")
+
+	olt := devices.GetOLT()
+
+	onu, err := olt.FindOnuBySn(req.SerialNumber)
+
+	if err != nil {
+		res.StatusCode = int32(codes.NotFound)
+		res.Message = err.Error()
+		return res, err
+	}
+
+	if err := onu.InternalState.Event("start_auth"); err != nil {
+		logger.WithFields(log.Fields{
+			"OnuId":  onu.ID,
+			"IntfId": onu.PonPortID,
+			"OnuSn":  onu.Sn(),
+		}).Errorf("Cannot restart authenticaton for ONU: %s", err.Error())
+		res.StatusCode = int32(codes.FailedPrecondition)
+		res.Message = err.Error()
+		return res, err
+	}
+
+	res.StatusCode = int32(codes.OK)
+	res.Message = fmt.Sprintf("Authentication restarted for ONU %s.", onu.Sn())
+
+	return res, nil
+}
+
+func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
+	res := &bbsim.Response{}
+
+	logger.WithFields(log.Fields{
+		"OnuSn": req.SerialNumber,
+	}).Infof("Received request to restart DHCP on ONU")
+
+	olt := devices.GetOLT()
+
+	onu, err := olt.FindOnuBySn(req.SerialNumber)
+
+	if err != nil {
+		res.StatusCode = int32(codes.NotFound)
+		res.Message = err.Error()
+		return res, err
+	}
+
+	if err := onu.InternalState.Event("start_dhcp"); err != nil {
+		logger.WithFields(log.Fields{
+			"OnuId":  onu.ID,
+			"IntfId": onu.PonPortID,
+			"OnuSn":  onu.Sn(),
+		}).Errorf("Cannot restart DHCP for ONU: %s", err.Error())
+		res.StatusCode = int32(codes.FailedPrecondition)
+		res.Message = err.Error()
+		return res, err
+	}
+
+	res.StatusCode = int32(codes.OK)
+	res.Message = fmt.Sprintf("DHCP restarted for ONU %s.", onu.Sn())
+
+	return res, nil
+}
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 69721df..a5aa208 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -106,14 +106,14 @@
 			// NOTE should disabled state be diffente for oper_disabled (emulating an error) and admin_disabled (received a disabled call via VOLTHA)?
 			{Name: "disable", Src: []string{"eap_response_success_received", "auth_failed", "dhcp_ack_received", "dhcp_failed"}, Dst: "disabled"},
 			// EAPOL
-			{Name: "start_auth", Src: []string{"eapol_flow_received", "gem_port_added"}, Dst: "auth_started"},
+			{Name: "start_auth", Src: []string{"eapol_flow_received", "gem_port_added", "eap_response_success_received", "auth_failed", "dhcp_ack_received", "dhcp_failed"}, Dst: "auth_started"},
 			{Name: "eap_start_sent", Src: []string{"auth_started"}, Dst: "eap_start_sent"},
 			{Name: "eap_response_identity_sent", Src: []string{"eap_start_sent"}, Dst: "eap_response_identity_sent"},
 			{Name: "eap_response_challenge_sent", Src: []string{"eap_response_identity_sent"}, Dst: "eap_response_challenge_sent"},
 			{Name: "eap_response_success_received", Src: []string{"eap_response_challenge_sent"}, Dst: "eap_response_success_received"},
 			{Name: "auth_failed", Src: []string{"auth_started", "eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent"}, Dst: "auth_failed"},
 			// DHCP
-			{Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
+			{Name: "start_dhcp", Src: []string{"eap_response_success_received", "dhcp_ack_received", "dhcp_failed"}, Dst: "dhcp_started"},
 			{Name: "dhcp_discovery_sent", Src: []string{"dhcp_started"}, Dst: "dhcp_discovery_sent"},
 			{Name: "dhcp_request_sent", Src: []string{"dhcp_discovery_sent"}, Dst: "dhcp_request_sent"},
 			{Name: "dhcp_ack_received", Src: []string{"dhcp_request_sent"}, Dst: "dhcp_ack_received"},
diff --git a/internal/bbsimctl/commands/onu.go b/internal/bbsimctl/commands/onu.go
index 716c7d3..620e052 100644
--- a/internal/bbsimctl/commands/onu.go
+++ b/internal/bbsimctl/commands/onu.go
@@ -55,11 +55,25 @@
 	} `positional-args:"yes" required:"yes"`
 }
 
+type ONUEapolRestart struct {
+	Args struct {
+		OnuSn OnuSnString
+	} `positional-args:"yes" required:"yes"`
+}
+
+type ONUDhcpRestart struct {
+	Args struct {
+		OnuSn OnuSnString
+	} `positional-args:"yes" required:"yes"`
+}
+
 type ONUOptions struct {
-	List     ONUList     `command:"list"`
-	Get      ONUGet      `command:"get"`
-	ShutDown ONUShutDown `command:"shutdown"`
-	PowerOn  ONUPowerOn  `command:"poweron"`
+	List         ONUList         `command:"list"`
+	Get          ONUGet          `command:"get"`
+	ShutDown     ONUShutDown     `command:"shutdown"`
+	PowerOn      ONUPowerOn      `command:"poweron"`
+	RestartEapol ONUEapolRestart `command:"auth_restart"`
+	RestartDchp  ONUDhcpRestart  `command:"dhcp_restart"`
 }
 
 func RegisterONUCommands(parser *flags.Parser) {
@@ -142,7 +156,7 @@
 	res, err := client.ShutdownONU(ctx, &req)
 
 	if err != nil {
-		log.Fatalf("Cannot not shutdown ONU %s: %v", options.Args.OnuSn, err)
+		log.Fatalf("Cannot shutdown ONU %s: %v", options.Args.OnuSn, err)
 		return err
 	}
 
@@ -163,7 +177,49 @@
 	res, err := client.PoweronONU(ctx, &req)
 
 	if err != nil {
-		log.Fatalf("Cannot not power on ONU %s: %v", options.Args.OnuSn, err)
+		log.Fatalf("Cannot power on ONU %s: %v", options.Args.OnuSn, err)
+		return err
+	}
+
+	fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
+
+	return nil
+}
+
+func (options *ONUEapolRestart) Execute(args []string) error {
+	client, conn := connect()
+	defer conn.Close()
+
+	ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
+	defer cancel()
+	req := pb.ONURequest{
+		SerialNumber: string(options.Args.OnuSn),
+	}
+	res, err := client.RestartEapol(ctx, &req)
+
+	if err != nil {
+		log.Fatalf("Cannot restart EAPOL for ONU %s: %v", options.Args.OnuSn, err)
+		return err
+	}
+
+	fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
+
+	return nil
+}
+
+func (options *ONUDhcpRestart) Execute(args []string) error {
+	client, conn := connect()
+	defer conn.Close()
+
+	ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
+	defer cancel()
+	req := pb.ONURequest{
+		SerialNumber: string(options.Args.OnuSn),
+	}
+	res, err := client.RestartDhcp(ctx, &req)
+
+	if err != nil {
+		log.Fatalf("Cannot restart DHCP for ONU %s: %v", options.Args.OnuSn, err)
 		return err
 	}