public void PreAction(GXActionArgs arg)
        {
            GXDLMSImageTransfer it = Target as GXDLMSImageTransfer;

            if (arg.Action == ActionType.Action)
            {
                if (arg.Index == 1)
                {
                    if (arg.Tag is GXImageUpdateStatus status)
                    {
                        //Initiate the Image transfer process.
                        arg.Value = it.ImageTransferInitiate(arg.Client, status.ImageIdentifier, status.Image.Length);
                    }
                    else
                    {
                        //Check that delay is correct and save it.
                        GetDelay(arg);
                        if (arg.Exception != null)
                        {
                            return;
                        }
                        GXManufacturerCollection manufacturers = new GXManufacturerCollection();
                        GXManufacturerCollection.ReadManufacturerSettings(manufacturers);
                        GXManufacturer man = manufacturers.FindByIdentification(arg.Client.ManufacturerId);
                        Properties.Settings.Default.ImageDelay = (int)arg.Value / 1000;
                        GXImageDlg dlg = new GXImageDlg(man.ManucatureSettings, arg.Client);
                        OnImageDialog(dlg, arg);
                        if (arg.Action == ActionType.None)
                        {
                            return;
                        }
                        arg.Index  = 5;
                        arg.Action = ActionType.Read;
                        return;
                    }
                }
                else if (arg.Index == 2)
                {
                    //Start image block transfer.
                    GXImageUpdateStatus status = (GXImageUpdateStatus)arg.Tag;
                    int imageBlockCount;
                    arg.Value = it.ImageBlockTransfer(arg.Client, status.Image, status.ImageStartIndex, out imageBlockCount);
                    OnDescription("Sending " + imageBlockCount + " blocks.");
                }
                else if (arg.Index == 3)
                {
                    arg.Value = it.ImageVerify(arg.Client);
                    OnDescription("Verifying image.");
                }
                else if (arg.Index == 4)
                {
                    arg.Value = it.ImageActivate(arg.Client);
                    OnDescription("Activating image.");
                }
            }
        }
 void OnImageDialog(GXImageDlg dlg, GXActionArgs arg)
 {
     if (InvokeRequired)
     {
         BeginInvoke(new ImageDialogEventHandler(OnImageDialog), dlg, arg).AsyncWaitHandle.WaitOne();
     }
     else
     {
         DescriptionList.Items.Clear();
         if (dlg.ShowDialog(this) != DialogResult.OK)
         {
             arg.Action = ActionType.None;
             return;
         }
         GXImageUpdateStatus status = new GXImageUpdateStatus();
         arg.Tag = status;
         status.ImageIdentifier = dlg.GetImageIdentifier();
         arg.Text = "Updating image " + Path.GetFileNameWithoutExtension(dlg.FileNameTb.Text) + "...";
         OnDescription("Updating image " + dlg.FileNameTb.Text);
         status.Image = dlg.Image;
     }
 }
        public void PostAction(GXActionArgs arg)
        {
            GXDLMSImageTransfer it     = Target as GXDLMSImageTransfer;
            GXImageUpdateStatus status = (GXImageUpdateStatus)arg.Tag;

            if (arg.Action == ActionType.Read)
            {
                if (arg.Index == 5)
                {
                    if (!it.ImageTransferEnabled)
                    {
                        GXHelpers.ShowMessageBox(this, Properties.Resources.ImageTransferDisabled, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        arg.Action = ActionType.None;
                        return;
                    }
                    OnDescription(Properties.Resources.ImageTransferEnabled);
                    //Get ImageBlockSize.
                    arg.Index = 2;
                }
                else if (arg.Index == 2)
                {
                    OnDescription(Properties.Resources.ImageBlockSize + it.ImageBlockSize);
                    //Read image_transferred_blocks_status.
                    arg.Index = 3;
                }
                else if (arg.Index == 3)
                {
                    int index = 0;
                    foreach (char b in it.ImageTransferredBlocksStatus)
                    {
                        if (b == '0')
                        {
                            DialogResult ret = GXHelpers.ShowMessageBox(this, index + " Image blocks already exists. Do you want to overwrite image? " + Environment.NewLine
                                                                        + "Answering No will update missing blocks.", "GXDLMSDirector",
                                                                        MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                            if (ret == DialogResult.Cancel)
                            {
                                arg.Action = ActionType.None;
                                return;
                            }
                            if (ret == DialogResult.No)
                            {
                                status.ImageStartIndex = index;
                                arg.Index  = 2;
                                arg.Action = ActionType.Action;
                                return;
                            }
                            break;
                        }
                        ++index;
                    }
                    OnDescription(Properties.Resources.ImageBlockSize + it.ImageBlockSize);
                    //Invoke Initiates image transfer.
                    arg.Index  = 1;
                    arg.Action = ActionType.Action;
                }
                else if (arg.Index == 6)
                {
                    OnImageTransferStatus(it.ImageTransferStatus);
                    GetDelay(arg);
                    if (arg.Exception != null)
                    {
                        return;
                    }
                    int delay = (int)arg.Value;
                    arg.Value = null;
                    switch (it.ImageTransferStatus)
                    {
                    case ImageTransferStatus.NotInitiated:
                        if (++status.StatusReadCount > 10)
                        {
                            OnDescription("Failed to read Image transfer status after image transfer initiate.");
                            GXHelpers.ShowMessageBox(this, "Failed to read Image transfer status after image transfer initiate.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            arg.Action = ActionType.None;
                            return;
                        }
                        Thread.Sleep(delay);
                        arg.Index = 6;
                        break;

                    case ImageTransferStatus.TransferInitiated:
                        if (!status.TransformingImage)
                        {
                            arg.Action = ActionType.Action;
                            arg.Index  = 2;
                            status.TransformingImage = true;
                        }
                        else
                        {
                            if (!Properties.Settings.Default.ImageManualUpdate)
                            {
                                arg.Action = ActionType.Action;
                                if (arg.Client.CanInvoke(arg.Target, 3))
                                {
                                    arg.Index = 3;
                                }
                                else if (arg.Client.CanInvoke(arg.Target, 4))
                                {
                                    arg.Index = 4;
                                }
                                else
                                {
                                    GXHelpers.ShowMessageBox(this, Properties.Resources.ImageTransferedNotActivatedTxt, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                    arg.Action = ActionType.None;
                                }
                            }
                            else
                            {
                                arg.Action = ActionType.None;
                                ManualBtn_CheckedChanged(null, null);
                            }
                        }
                        break;

                    case ImageTransferStatus.VerificationInitiated:
                        Thread.Sleep(delay);
                        OnDescription(Properties.Resources.VerificationInitiated);
                        arg.Text  = Properties.Resources.VerificationInitiated;
                        arg.Index = 6;
                        break;

                    case ImageTransferStatus.VerificationSuccessful:
                        arg.Index  = 4;
                        arg.Action = ActionType.Action;
                        break;

                    case ImageTransferStatus.VerificationFailed:
                        OnDescription(Properties.Resources.VerificationFailed);
                        arg.Text   = Properties.Resources.VerificationFailed;
                        arg.Action = ActionType.None;
                        break;

                    case ImageTransferStatus.ActivationInitiated:
                        Thread.Sleep(delay);
                        OnDescription(Properties.Resources.ActivationInitiated);
                        arg.Text = Properties.Resources.ActivationInitiated;
                        break;

                    case ImageTransferStatus.ActivationSuccessful:
                        OnDescription(Properties.Resources.ActivationSuccessful);
                        GXHelpers.ShowMessageBox(this, Properties.Resources.ImageActivatedTxt, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        arg.Action = ActionType.None;
                        break;

                    case ImageTransferStatus.ActivationFailed:
                        OnDescription(Properties.Resources.ActivationFailed);
                        arg.Text   = Properties.Resources.ActivationFailed;
                        arg.Action = ActionType.None;
                        break;
                    }
                }
            }
            else if (arg.Action == ActionType.Action)
            {
                if (arg.Index == 1)
                {
                    OnDescription("Image transfer initiated.");
                    arg.Action = ActionType.Read;
                    arg.Index  = 6;
                }
                else if (arg.Index == 2)
                {
                    OnDescription("Image transfered.");
                    arg.Index  = 6;
                    arg.Action = ActionType.Read;
                }
                else if (arg.Index == 3)
                {
                    if (arg.Exception is GXDLMSException)
                    {
                        //If meter is verifying the image.
                        if ((arg.Exception as GXDLMSException).ErrorCode == (int)ErrorCode.TemporaryFailure)
                        {
                            if (!Properties.Settings.Default.ImageManualUpdate)
                            {
                                arg.Exception = null;
                                GetDelay(arg);
                                if (arg.Exception != null)
                                {
                                    return;
                                }
                                int delay = (int)arg.Value;
                                Thread.Sleep(delay);
                                arg.Value = null;
                            }
                        }
                        else
                        {
                            OnDescription("Image verifying failed.");
                        }
                        return;
                    }
                    if (!Properties.Settings.Default.ImageManualUpdate)
                    {
                        arg.Index  = 6;
                        arg.Action = ActionType.Read;
                    }
                    else
                    {
                        arg.Action = ActionType.None;
                    }
                }
                else if (arg.Index == 4)
                {
                    if (arg.Exception is GXDLMSException)
                    {
                        //If meter is activating image.
                        if ((arg.Exception as GXDLMSException).ErrorCode == (int)ErrorCode.TemporaryFailure)
                        {
                            if (!Properties.Settings.Default.ImageManualUpdate)
                            {
                                arg.Exception = null;
                                GetDelay(arg);
                                if (arg.Exception != null)
                                {
                                    return;
                                }
                                int delay = (int)arg.Value;
                                Thread.Sleep(delay);
                                arg.Value = null;
                            }
                        }
                        else
                        {
                            OnDescription("Image activation failed.");
                        }
                        return;
                    }
                    OnDescription(Properties.Resources.ImageActivatedTxt);
                    arg.Action    = ActionType.None;
                    arg.Rebooting = true;
                    GXHelpers.ShowMessageBox(this, Properties.Resources.ActionImplemented, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }