Address crashes when the ONU ID is not found and when IGMP state change fails.

Also allow re-joining from the igmp_started state.

Change-Id: I1e8690c8a2d1f4f5968ecd5339ee931044ff4700
diff --git a/internal/bbsim/api/onus_handler.go b/internal/bbsim/api/onus_handler.go
index 116199a..3c62f48 100644
--- a/internal/bbsim/api/onus_handler.go
+++ b/internal/bbsim/api/onus_handler.go
@@ -261,7 +261,7 @@
 				"OnuSn":  onu.Sn(),
 			}).Errorf("IGMP request failed: %s", igmpErr.Error())
 			res.StatusCode = int32(codes.FailedPrecondition)
-			res.Message = err.Error()
+			res.Message = igmpErr.Error()
 			return res, igmpErr
 		}
 	}
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 572507e..d08d934 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -1061,8 +1061,26 @@
 }
 
 func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
-	pon, _ := o.GetPonById(omci_msg.IntfId)
-	onu, _ := pon.GetOnuById(omci_msg.OnuId)
+	pon, err := o.GetPonById(omci_msg.IntfId)
+	if err != nil {
+		oltLogger.WithFields(log.Fields{
+			"error": err,
+			"onu_id": omci_msg.OnuId,
+			"pon_id": omci_msg.IntfId,
+		}).Error("pon ID not found")
+		return nil, err
+	}
+
+	onu, err := pon.GetOnuById(omci_msg.OnuId)
+	if err != nil {
+		oltLogger.WithFields(log.Fields{
+			"error": err,
+			"onu_id": omci_msg.OnuId,
+			"pon_id": omci_msg.IntfId,
+		}).Error("onu ID not found")
+		return nil, err
+	}
+
 	oltLogger.WithFields(log.Fields{
 		"IntfId": onu.PonPortID,
 		"OnuId":  onu.ID,
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index d355472..3763429 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -151,8 +151,8 @@
 			{Name: "send_eapol_flow", Src: []string{"initialized"}, Dst: "eapol_flow_sent"},
 			{Name: "send_dhcp_flow", Src: []string{"eapol_flow_sent"}, Dst: "dhcp_flow_sent"},
 			// IGMP
-			{Name: "igmp_join_start", Src: []string{"eap_response_success_received", "gem_port_added", "eapol_flow_received", "dhcp_ack_received", "igmp_left", "igmp_join_error"}, Dst: "igmp_join_started"},
-			{Name: "igmp_join_startv3", Src: []string{"eap_response_success_received", "gem_port_added", "eapol_flow_received", "dhcp_ack_received", "igmp_left", "igmp_join_error"}, Dst: "igmp_join_started"},
+			{Name: "igmp_join_start", Src: []string{"eap_response_success_received", "gem_port_added", "eapol_flow_received", "dhcp_ack_received", "igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
+			{Name: "igmp_join_startv3", Src: []string{"eap_response_success_received", "gem_port_added", "eapol_flow_received", "dhcp_ack_received", "igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
 			{Name: "igmp_join_error", Src: []string{"igmp_join_started"}, Dst: "igmp_join_error"},
 			{Name: "igmp_leave", Src: []string{"igmp_join_started", "gem_port_added", "eapol_flow_received", "eap_response_success_received", "dhcp_ack_received"}, Dst: "igmp_left"},
 		},