source: trunk/CrypPlugins/PeerToPeerManager_NEW/P2PManager_KeyPattern.cs @ 1166

Last change on this file since 1166 was 1166, checked in by arnold, 12 years ago

P2PManager: Design embellished and added an "estimated end time" information.
Samples: Output Boxes for KeySearcher Outputs

File size: 20.9 KB
Line 
1/* Copyright 2010 Team CrypTool (Christian Arnold), Uni Duisburg-Essen
2
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6
7       http://www.apache.org/licenses/LICENSE-2.0
8
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14*/
15
16using System;
17using System.Collections.Generic;
18using System.Linq;
19using System.Text;
20using System.Threading;
21using Cryptool.PluginBase;
22using Cryptool.PluginBase.IO;
23using Cryptool.PluginBase.Control;
24using Cryptool.PluginBase.Miscellaneous;
25using System.ComponentModel;
26using KeySearcher;
27using System.Windows.Controls;
28using System.Windows.Threading;
29using Cryptool.Plugins.PeerToPeer.Jobs;
30
31namespace Cryptool.Plugins.PeerToPeer
32{
33    /// <summary>
34    /// This PlugIn only works, when its connected with a P2P_Peer object.
35    /// </summary>
36    [Author("Christian Arnold", "arnold@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
37    [PluginInfo(false, "P2P_Manager_KeyPattern", "Creates a new Manager-Peer for distributable KeyPattern-Jobs", "", "PeerToPeerManager_NEW/manager_medium_neutral.png", "PeerToPeerManager_NEW/manager_medium_working.png", "PeerToPeerManager_NEW/manager_medium_finished.png")]
38    public class P2PManager_KeyPattern : IInput
39    {
40        private P2PManagerBase_NEW p2pManager;
41        private P2PManager_KeyPatternSettings settings;
42        // IInput
43        private CryptoolStream decryptedData;
44        private byte[] initVector;
45        // IControls       
46        private IControlEncryption encryptionControl;
47        private IP2PControl p2pControl;
48
49        private KeyPattern pattern = null;
50        public KeyPattern Pattern
51        {
52            get
53            {
54                return pattern;
55            }
56            set
57            {
58                pattern = value;
59                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
60                    settings.Key = pattern.giveInputPattern();
61            }
62        }
63
64        /// <summary>
65        /// after starting the execution, set this value, so after receiving
66        /// a Job result, the WPF UpdateQuickWatch can use this value, without
67        /// accessing the Settings every time.
68        /// </summary>
69        private int bytesToUseForDecryption = 0;
70
71        #region In and Output
72
73        [PropertyInfo(Direction.InputData, "Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
74        public CryptoolStream DecryptedData
75        {
76            get { return this.decryptedData; }
77            set
78            {
79                if (value != this.decryptedData)
80                {
81                    this.decryptedData = value;
82                }
83            }
84        }
85
86        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
87        public byte[] InitVector
88        {
89            get { return this.initVector; }
90            set
91            {
92                if (value != this.initVector)
93                    this.initVector = value;
94            }
95        }
96
97        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
98        public IControlEncryption EncryptionControl
99        {
100            get { return this.encryptionControl; }
101            set
102            {
103                if (this.encryptionControl != null)
104                {
105                    this.encryptionControl.keyPatternChanged -= encryptionControl_keyPatternChanged;
106                    this.encryptionControl.OnStatusChanged -= encryptionControl_onStatusChanged;
107                }
108                if (value != null)
109                {
110                    Pattern = new KeyPattern(value.getKeyPattern());
111                    value.keyPatternChanged += encryptionControl_keyPatternChanged;
112                    value.OnStatusChanged += encryptionControl_onStatusChanged;
113                    this.encryptionControl = value;
114                    OnPropertyChanged("ControlMaster");
115
116                }
117                else
118                    this.encryptionControl = null;
119            }
120        }
121
122        private void encryptionControl_keyPatternChanged()
123        {
124            Pattern = new KeyPattern(this.encryptionControl.getKeyPattern());
125        }
126        private void encryptionControl_onStatusChanged(IControl sender, bool readyForExecution)
127        {
128            // obsolete stuff
129            if (readyForExecution)
130            {
131                this.process((IControlEncryption)sender);
132            }
133        }
134
135        /// <summary>
136        /// Catches the completely configurated, initialized and joined P2P object from the P2PPeer-Slave-PlugIn.
137        /// </summary>
138        [PropertyInfo(Direction.ControlMaster, "P2P Slave", "Input the P2P-Peer-PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
139        public IP2PControl P2PControl
140        {
141            get
142            {
143                return this.p2pControl;
144            }
145            set
146            {
147                if (this.p2pControl != null)
148                {
149                    this.p2pControl.OnStatusChanged -= P2PControl_OnStatusChanged;
150                }
151                if (value != null)
152                {
153                    this.p2pControl = (P2PPeerMaster)value;
154                    this.p2pControl.OnStatusChanged += new IControlStatusChangedEventHandler(P2PControl_OnStatusChanged);
155                    OnPropertyChanged("P2PMaster");
156                }
157                else
158                {
159                    this.p2pControl = null;
160                }
161            }
162        }
163
164        private void P2PControl_OnStatusChanged(IControl sender, bool readyForExecution)
165        {
166            //throw new NotImplementedException();
167        }
168
169        #endregion
170
171        #region Events
172
173        public event StatusChangedEventHandler OnPluginStatusChanged;
174
175        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
176
177        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
178
179        #endregion
180
181        #region Standard PlugIn-Functionality
182
183        public P2PManager_KeyPattern()
184        {
185            this.settings = new P2PManager_KeyPatternSettings();
186            this.settings.PropertyChanged += new PropertyChangedEventHandler(settings_PropertyChanged);
187            this.settings.TaskPaneAttributeChanged += new TaskPaneAttributeChangedHandler(settings_TaskPaneAttributeChanged);
188            this.settings.OnPluginStatusChanged += new StatusChangedEventHandler(settings_OnPluginStatusChanged);
189
190            QuickWatchPresentation = new P2PManagerPresentation();
191        }
192
193        #region QuickWatchPresentation Stuff
194
195        public UserControl QuickWatchPresentation
196        {
197            get;
198            private set;
199        }
200
201        public UserControl Presentation
202        {
203            get { return QuickWatchPresentation; }
204        }
205
206        private void UpdateQuickWatch(double progressInPercent)
207        {
208            UpdateQuickWatch(this.distributableKeyPatternJob.GlobalResultList, this.distributableKeyPatternJob.TotalAmount,
209                this.distributableKeyPatternJob.AllocatedAmount, this.distributableKeyPatternJob.FinishedAmount, 
210                progressInPercent, this.p2pManager.FreeWorkers(), this.p2pManager.BusyWorkers());
211        }
212
213        private void UpdateQuickWatch(LinkedList<KeySearcher.KeySearcher.ValueKey> globalTop10List,
214            BigInteger jobsTotalAmount, BigInteger jobsInProgress, BigInteger jobsFinished, double progressInPercent,
215            int freeWorkers, int busyWorkers)
216        {
217            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
218            LinkedListNode<KeySearcher.KeySearcher.ValueKey> listNode;
219
220            if (QuickWatchPresentation.IsVisible)
221            {
222                ((P2PManagerPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
223                {
224                    ((P2PManagerPresentation)QuickWatchPresentation).txtProgressInPercent.Text = "" + Math.Round(progressInPercent, 2) + "%";
225                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotal.Text = "" + jobsTotalAmount.ToString();
226                    ((P2PManagerPresentation)QuickWatchPresentation).txtInProgress.Text = "" + jobsInProgress.ToString();
227                    ((P2PManagerPresentation)QuickWatchPresentation).txtLeft.Text = "" + new BigInteger((jobsTotalAmount - jobsInProgress - jobsFinished)).ToString();
228                    ((P2PManagerPresentation)QuickWatchPresentation).txtFinished.Text = "" + jobsFinished.ToString();
229
230                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotalWorker.Text = "" + (freeWorkers + busyWorkers);
231                    ((P2PManagerPresentation)QuickWatchPresentation).txtFreeWorker.Text = "" + freeWorkers;
232                    ((P2PManagerPresentation)QuickWatchPresentation).txtBusyWorker.Text = "" + busyWorkers;
233
234                    /* START approximation of end time */
235                    // this value is MinValue until the first job is allocated to a worker
236                    DateTime estimateDateTime = this.p2pManager.EstimatedEndTime();
237                    if(estimateDateTime != DateTime.MaxValue)
238                    {
239                        ((P2PManagerPresentation)QuickWatchPresentation).txtEstimatedEndTime.Text = estimateDateTime.ToString();
240                    }
241                    /* END approximation of end time */
242
243                    ((P2PManagerPresentation)QuickWatchPresentation).entries.Clear();
244                    listNode = globalTop10List.First;
245
246                    int i = 0;
247                    while (listNode != null)
248                    {
249                        i++;
250
251                        ResultEntry entry = new ResultEntry();
252                        entry.Ranking = "" + i;
253                        entry.Value = "" + Math.Round(listNode.Value.value, 3);
254                        entry.Key = listNode.Value.key;
255                        entry.Text = enc.GetString(listNode.Value.decryption, 0, this.bytesToUseForDecryption);
256
257                        ((P2PManagerPresentation)QuickWatchPresentation).entries.Add(entry);
258                        listNode = listNode.Next;
259                    }
260                    // to resize the WPF Presentation, so it will fit in the PlugIn-Borders
261                    ((P2PManagerPresentation)QuickWatchPresentation).P2PManagerPresentation_SizeChanged(null, null);
262                }, null);
263            }
264        }
265
266        #endregion
267
268        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
269        {
270            if (OnPluginStatusChanged != null)
271                OnPluginStatusChanged(this, args);
272        }
273
274        void settings_TaskPaneAttributeChanged(ISettings settings, TaskPaneAttributeChangedEventArgs args)
275        {
276            //throw new NotImplementedException();
277        }
278
279        void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
280        {
281            if (e.PropertyName == "Key")
282            {
283                if (this.EncryptionControl != null)
284                {
285                    KeyPattern checkPattern = new KeyPattern(this.EncryptionControl.getKeyPattern());
286                    if (!checkPattern.testWildcardKey(this.settings.Key))
287                    {
288                        GuiLogMessage("The set Pattern doesn't fit to the encryption plugin connected with this manager!", NotificationLevel.Warning);
289                    }
290                    else
291                        GuiLogMessage("Successfully changed the KeyPattern in the settings.", NotificationLevel.Info);
292                }
293            }
294
295            if (this.p2pControl == null)
296                return;
297            if (e.PropertyName == "BtnUnregister")
298            {
299                if (this.p2pManager != null && this.p2pManager.Started)
300                {
301                    Stop();
302                    //this.p2pManager.Stop(PubSubMessageType.Unregister);
303                    GuiLogMessage("Unregister button pressed, Publisher has stopped!", NotificationLevel.Info);
304                }
305            }
306            if (e.PropertyName == "BtnRegister")
307            {
308                if (this.p2pManager == null || !this.p2pManager.Started)
309                {
310                    this.process(this.EncryptionControl);
311                    GuiLogMessage("Register button pressed, Publisher has been started!", NotificationLevel.Info);
312                }
313            }
314            if (e.PropertyName == "BtnSolutionFound")
315            {
316                if (this.p2pManager != null && this.p2pManager.Started)
317                {
318                    Stop();
319                    //this.p2pManager.Stop(PubSubMessageType.Solution);
320                    GuiLogMessage("TEST: Emulate Solution-Found-message", NotificationLevel.Info);
321                }
322            }
323        }
324
325        public ISettings Settings
326        {
327            set { this.settings = (P2PManager_KeyPatternSettings)value; }
328            get { return this.settings; }
329        }
330
331        // Pre-Execute Method is below this region
332
333        // Execute-Method is below this region
334
335        public void PostExecution()
336        {
337            //throw new NotImplementedException();
338        }
339
340        public void Pause()
341        {
342            //throw new NotImplementedException();
343        }
344
345        public void Stop()
346        {
347
348            if (this.p2pManager != null && this.p2pManager.Started)
349            {
350                this.p2pManager.Stop(PubSubMessageType.Unregister);
351                this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Neutral);
352                this.p2pManager.OnGuiMessage -= p2pManager_OnGuiMessage;
353                this.p2pManager.OnProcessProgress -= p2pManager_OnProcessProgress;
354                this.p2pManager.OnNewJobAllocated -= p2pManager_OnNewJobAllocated;
355                this.p2pManager.OnNoMoreJobsLeft -= p2pManager_OnNoMoreJobsLeft;
356                this.p2pManager.OnResultReceived -= p2pManager_OnResultReceived;
357                // set Manager to null, so after restarting the Workspace,
358                // a new Distributable stop will be initialized with (maybe)
359                // changed settings
360                this.p2pManager = null;
361            }
362        }
363
364        public void Initialize()
365        {
366        }
367
368        public void Dispose()
369        {
370        }
371
372        #endregion
373
374        public void PreExecution()
375        {
376            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
377            if (P2PControl == null)
378            {
379                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
380                return;
381            }
382        }
383
384        void p2pManager_OnProcessProgress(double progressInPercent)
385        {
386            ProgressChanged(progressInPercent, 100.0);
387            UpdateQuickWatch(progressInPercent);
388        }
389
390        void p2pManager_OnGuiMessage(string sData, NotificationLevel notificationLevel)
391        {
392            GuiLogMessage(sData, notificationLevel);
393        }
394
395        DistributableKeyPatternJob distributableKeyPatternJob;
396        public void Execute()
397        {
398            if (this.InitVector != null && this.DecryptedData != null)
399                this.process(this.EncryptionControl);
400        }
401
402        private void process(IControlEncryption iControlEncryption)
403        {
404            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
405            if (P2PControl == null)
406            {
407                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
408                return;
409            }
410            if (iControlEncryption == null)
411            {
412                GuiLogMessage("No Encryption Control connected with this PlugIn", NotificationLevel.Error);
413                return;
414            }
415
416            if (this.p2pManager == null)
417            {
418                byte[] byteEncryptedData = null;
419                CryptoolStream newEncryptedData = new CryptoolStream();
420                try
421                {
422                    newEncryptedData.OpenRead(this.DecryptedData.FileName);
423                    // Convert CryptoolStream to an byte Array and store it in the DHT
424                    if (newEncryptedData.Length > Int32.MaxValue)
425                        throw (new Exception("Encrypted Data are too long for this PlugIn. The maximum size of Data is " + Int32.MaxValue + "!"));
426                    byteEncryptedData = new byte[newEncryptedData.Length];
427                    int k = newEncryptedData.Read(byteEncryptedData, 0, byteEncryptedData.Length);
428                    if (k < byteEncryptedData.Length)
429                        throw (new Exception("Read Data are shorter than byteArrayLen"));
430                }
431                catch (Exception ex)
432                {
433                    throw (new Exception("Fatal error while reading the CryptoolStream. Exception: " + ex.ToString()));
434                }
435                finally
436                {
437                    newEncryptedData.Close();
438                    newEncryptedData.Dispose();
439                }
440                             
441                string pattern = this.encryptionControl.getKeyPattern();
442                KeyPattern kp = new KeyPattern(pattern);
443                if (kp.testWildcardKey(this.settings.Key))
444                {
445                    kp.WildcardKey = this.settings.Key;
446                }
447                else
448                {
449                    GuiLogMessage("The Key Pattern in the settings isn't valid for the given Encryption!", NotificationLevel.Error);
450                    return;
451                }
452
453                // create a new DistributableJob instance
454                distributableKeyPatternJob = new DistributableKeyPatternJob
455                    (kp, this.settings.KeyPatternSize * 10000, byteEncryptedData, this.InitVector);
456
457                this.p2pManager = new P2PManagerBase_NEW(this.P2PControl, distributableKeyPatternJob);
458                this.p2pManager.OnGuiMessage += new P2PPublisherBase.GuiMessage(p2pManager_OnGuiMessage);
459                this.p2pManager.OnProcessProgress += new P2PManagerBase_NEW.ProcessProgress(p2pManager_OnProcessProgress);
460                this.p2pManager.OnNewJobAllocated += new P2PManagerBase_NEW.NewJobAllocated(p2pManager_OnNewJobAllocated);
461                this.p2pManager.OnNoMoreJobsLeft += new P2PManagerBase_NEW.NoMoreJobsLeft(p2pManager_OnNoMoreJobsLeft);
462                this.p2pManager.OnResultReceived += new P2PManagerBase_NEW.ResultReceived(p2pManager_OnResultReceived);
463            }
464
465            this.bytesToUseForDecryption = this.settings.BytesToUse;
466
467            this.p2pManager.StartManager(this.settings.TopicName, this.settings.SendAliveMessageInterval * 1000);
468
469            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
470        }
471
472        void p2pManager_OnResultReceived(BigInteger jobId)
473        {
474            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
475        }
476
477        void p2pManager_OnNoMoreJobsLeft()
478        {
479            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
480        }
481
482        void p2pManager_OnNewJobAllocated(BigInteger jobId)
483        {
484            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
485        }
486
487
488        #region INotifyPropertyChanged Members
489
490        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
491
492        public void OnPropertyChanged(string name)
493        {
494            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
495        }
496
497        public event PluginProgressChangedEventHandler OnPluginProcessChanged;
498
499        private void ProgressChanged(double value, double max)
500        {
501            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
502        }
503
504        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
505        {
506            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
507        }
508
509        #endregion
510    }
511
512}
Note: See TracBrowser for help on using the repository browser.