[SEBA-885] Ability to restart EAPOL and DHCP if the state machine doesn't complete

Change-Id: I2f0c7be787ab9ca2ddf59deadaa6c789456cd3d4
diff --git a/.gitignore b/.gitignore
index 77dd818..6c768c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
+.idea
 /bbr
 /bbsim
 /bbsimctl
 logs/*
 release
-.DS_Store
\ No newline at end of file
+.DS_Store
+*.logs
+*.trace
\ No newline at end of file
diff --git a/api/.gitignore b/api/.gitignore
index 5a7fb48..8a058c3 100644
--- a/api/.gitignore
+++ b/api/.gitignore
@@ -1 +1,2 @@
-**/*.pb.go
\ No newline at end of file
+**/*.pb.go
+**/*.pb.gw.go
\ No newline at end of file
diff --git a/cmd/bbr/bbr.go b/cmd/bbr/bbr.go
index 4a4ec91..4f9eb03 100644
--- a/cmd/bbr/bbr.go
+++ b/cmd/bbr/bbr.go
@@ -81,7 +81,7 @@
 		&apiDoneChannel,
 		true, // this parameter is not important in the BBR Case
 		true, // this parameter is not important in the BBR Case
-		0, // this parameter does not matter in the BBR case
+		0,    // this parameter does not matter in the BBR case
 		true,
 	)
 	oltMock := bbrdevices.OltMock{
diff --git a/cmd/bbsim/bbsim.go b/cmd/bbsim/bbsim.go
index eea4b95..74bda32 100644
--- a/cmd/bbsim/bbsim.go
+++ b/cmd/bbsim/bbsim.go
@@ -153,7 +153,7 @@
 		"TotalOnus":    options.NumPonPerOlt * options.NumOnuPerPon,
 		"Auth":         options.Auth,
 		"Dhcp":         options.Dhcp,
-		"Delay":    options.Delay,
+		"Delay":        options.Delay,
 	}).Info("BroadBand Simulator is on")
 
 	// control channels, they are only closed when the goroutine needs to be terminated
@@ -171,7 +171,6 @@
 		close(oltDoneChannel)
 	}()
 
-
 	wg := sync.WaitGroup{}
 	wg.Add(5)
 
diff --git a/docs/source/onu-state-machine.rst b/docs/source/onu-state-machine.rst
index f66dd22..a53dfec 100644
--- a/docs/source/onu-state-machine.rst
+++ b/docs/source/onu-state-machine.rst
@@ -8,49 +8,102 @@
 
 Here is a list of possible state transitions in BBSim:
 
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| Transition                     | Starting States                                                                                                   | End State                      | Notes                                                                                         |
-+================================+===================================================================================================================+================================+===============================================================================================+
-|                                |                                                                                                                   | created                        |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| discover                       | created                                                                                                           | discovered                     |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| enable                         | discovered, disabled                                                                                              | enabled                        |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| receive_eapol_flow             | enabled, gem_port_added                                                                                           | eapol_flow_received            |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| add_gem_port                   | enabled, eapol_flow_received                                                                                      | gem_port_added                 | We need to wait for both the flow and the gem port to come before moving to ``auth_started``  |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| start_auth                     | eapol_flow_received, gem_port_added, eap_response_success_received, auth_failed, dhcp_ack_received, dhcp_failed   | auth_started                   |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| eap_start_sent                 | auth_started                                                                                                      | eap_start_sent                 |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| eap_response_identity_sent     | eap_start_sent                                                                                                    | eap_response_identity_sent     |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| eap_response_challenge_sent    | eap_response_identity_sent                                                                                        | eap_response_challenge_sent    |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| eap_response_success_received  | eap_response_challenge_sent                                                                                       | eap_response_success_received  |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| auth_failed                    | auth_started, eap_start_sent, eap_response_identity_sent, eap_response_challenge_sent                             | auth_failed                    |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| start_dhcp                     | eap_response_success_received, dhcp_ack_received, dhcp_failed                                                     | dhcp_started                   |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| dhcp_discovery_sent            | dhcp_started                                                                                                      | dhcp_discovery_sent            |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| dhcp_request_sent              | dhcp_discovery_sent                                                                                               | dhcp_request_sent              |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| dhcp_ack_received              | dhcp_request_sent                                                                                                 | dhcp_ack_received              |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
-| dhcp_failed                    | dhcp_started, dhcp_discovery_sent, dhcp_request_sent                                                              | dhcp_failed                    |                                                                                               |
-+--------------------------------+-------------------------------------------------------------------------------------------------------------------+--------------------------------+-----------------------------------------------------------------------------------------------+
+.. list-table:: ONU States
+    :widths: 10 35 10 45
+    :header-rows: 1
 
-In addition some transition can be forced via the API:
+    * - Transition
+      - Starting States
+      - End State
+      - Notes
+    * -
+      -
+      - created
+      -
+    * - discover
+      - created
+      - discovered
+      -
+    * - enable
+      - discovered, disabled
+      - enabled
+      -
+    * - receive_eapol_flow
+      - enabled, gem_port_added
+      - eapol_flow_received
+      -
+    * - add_gem_port
+      - enabled, eapol_flow_received
+      - gem_port_added
+      - We need to wait for both the flow and the gem port to come before moving to ``auth_started``
+    * - start_auth
+      - eapol_flow_received, gem_port_added, eap_start_sent, eap_response_identity_sent, eap_response_challenge_sent, eap_response_success_received, auth_failed, dhcp_ack_received, dhcp_failed
+      - auth_started
+      -
+    * - eap_start_sent
+      - auth_started
+      - eap_start_sent
+      -
+    * - eap_response_identity_sent
+      - eap_start_sent
+      - eap_response_identity_sent
+      -
+    * - eap_response_challenge_sent
+      - eap_response_identity_sent
+      - eap_response_challenge_sent
+      -
+    * - eap_response_success_received
+      - eap_response_challenge_sent
+      - eap_response_success_received
+      -
+    * - auth_failed
+      - auth_started, eap_start_sent, eap_response_identity_sent, eap_response_challenge_sent
+      - auth_failed
+      -
+    * - start_dhcp
+      - eap_response_success_received, dhcp_discovery_sent, dhcp_request_sent, dhcp_ack_received, dhcp_failed
+      - dhcp_started
+      -
+    * - dhcp_discovery_sent
+      - dhcp_started
+      - dhcp_discovery_sent
+      -
+    * - dhcp_request_sent
+      - dhcp_discovery_sent
+      - dhcp_request_sent
+      -
+    * - dhcp_ack_received
+      - dhcp_request_sent
+      - dhcp_ack_received
+      -
+    * - dhcp_failed
+      - dhcp_started, dhcp_discovery_sent, dhcp_request_sent
+      - dhcp_failed
+      -
 
-+---------------------+----------------------------------------------------------------------------+-----------+---------------------------------------------------------------------------------------------------------+
-| End StateTransition | Starting States                                                            | End State | Notes                                                                                                   |
-+=====================+============================================================================+===========+=========================================================================================================+
-| disable             | eap_response_success_received, auth_failed, dhcp_ack_received, dhcp_failed | disabled  | Emulates a devide mulfunction. Sends a ``DyingGaspInd`` and then an ``OnuIndication{OperState: 'down'}``|
-+---------------------+----------------------------------------------------------------------------+-----------+---------------------------------------------------------------------------------------------------------+
+In addition some transition can be forced via the API,
+check the previous table to verify when you can trigger those actions and
+:ref:`BBSimCtl` for more informations about ``BBSimCtl``:
+
+.. list-table:: API State Transitions
+    :widths: 15 15 70
+    :header-rows: 1
+
+    * - BBSimCtl command
+      - Transitions To
+      - Notes
+    * - shutdown
+      - disable
+      - Emulates a devide shutdown. Sends a ``DyingGaspInd`` and then an ``OnuIndication{OperState: 'down'}``
+    * - poweron
+      - enable
+      - Emulates a devide power on. Sends a ``OnuDiscInd`` and then an ``OnuIndication{OperState: 'up'}``
+    * - auth_restart
+      - start_auth
+      - Forces the ONU to send a new ``EapStart`` packet.
+    * - dhcp_restart
+      - start_dhcp
+      - Forces the ONU to send a new ``DHCPDiscovery`` packet.
 
 Below is a diagram of the state machine:
 
@@ -98,6 +151,10 @@
         eap_response_identity_sent -> auth_failed
         eap_response_challenge_sent -> auth_failed
 
+        eap_start_sent -> auth_started
+        eap_response_identity_sent -> auth_started
+        eap_response_challenge_sent -> auth_started
+
         eap_response_success_received -> auth_started
         auth_failed -> auth_started
         dhcp_ack_received -> auth_started
@@ -116,6 +173,8 @@
         dhcp_failed -> disabled
         disabled -> enabled
 
+        dhcp_discovery_sent -> dhcp_started
+        dhcp_request_sent -> dhcp_started
         dhcp_ack_received -> dhcp_started
         dhcp_failed -> dhcp_started
     }
\ No newline at end of file
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 6182577..dbbeb2b 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -116,7 +116,7 @@
 			// 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", "eap_response_success_received", "auth_failed", "dhcp_ack_received", "dhcp_failed"}, Dst: "auth_started"},
+			{Name: "start_auth", Src: []string{"eapol_flow_received", "gem_port_added", "eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent", "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"},
diff --git a/internal/bbsim/devices/onu_state_machine_test.go b/internal/bbsim/devices/onu_state_machine_test.go
index c8ad84c..c169c12 100644
--- a/internal/bbsim/devices/onu_state_machine_test.go
+++ b/internal/bbsim/devices/onu_state_machine_test.go
@@ -81,6 +81,15 @@
 	assert.Equal(t, onu.InternalState.Current(), "eap_response_challenge_sent")
 	onu.InternalState.Event("eap_response_success_received")
 	assert.Equal(t, onu.InternalState.Current(), "eap_response_success_received")
+
+	// test that we can retrigger EAPOL
+	states := []string{"eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent", "eap_response_success_received", "auth_failed", "dhcp_ack_received", "dhcp_failed"}
+	for _, state := range states {
+		onu.InternalState.SetState(state)
+		err := onu.InternalState.Event("start_auth")
+		assert.Equal(t, err, nil)
+		assert.Equal(t, onu.InternalState.Current(), "auth_started")
+	}
 }
 
 func Test_Onu_StateMachine_dhcp_start(t *testing.T) {
@@ -121,4 +130,14 @@
 	assert.Equal(t, onu.InternalState.Current(), "dhcp_request_sent")
 	onu.InternalState.Event("dhcp_ack_received")
 	assert.Equal(t, onu.InternalState.Current(), "dhcp_ack_received")
+
+	// test that we can retrigger DHCP
+	onu.DhcpFlowReceived = true
+	states := []string{"eap_response_success_received", "dhcp_discovery_sent", "dhcp_request_sent", "dhcp_ack_received", "dhcp_failed"}
+	for _, state := range states {
+		onu.InternalState.SetState(state)
+		err := onu.InternalState.Event("start_dhcp")
+		assert.Equal(t, err, nil)
+		assert.Equal(t, onu.InternalState.Current(), "dhcp_started")
+	}
 }