/// <summary> /// Beginnt mit der Ausführung der Aufgabe. /// </summary> /// <returns>Gesetzt, wenn die Aufgabe synchron abgeschlossen wurde.</returns> bool IPlugInControl.Start() { // Attach to the scanning filter ScanningFilter filter = m_PlugIn.Profile.ScanConfiguration; // Wipe out current settings filter.ExcludedSourceGroups.Clear(); // Process all foreach (ListViewItem item in lstGroups.CheckedItems) { // Attach to the group SourceGroup group = (SourceGroup)item.Tag; // Clone it group = SourceGroup.FromString <SourceGroup>(group.ToString()); // Add to list filter.ExcludedSourceGroups.Add(group); } // Store to disk m_PlugIn.Profile.Save(); // Done return(true); }
/// <summary> /// Analysiert die aktuelle Konfiguration des Suchlaufs auf Basis /// der DVB <i>Network Information Table (NIT)</i> Informationen. /// </summary> private void AnalyserThread() { // Be safe try { // Configure language UserProfile.ApplyLanguage(); // Uses hardware manager using (HardwareManager.Open()) { // Attach to the hardware itself Hardware device = HardwareManager.OpenHardware(Profile); // Reset counters TotalLocations = m_Locations.Count; CurrentLocation = 0; // Last inversion used SpectrumInversions lastInversion = SpectrumInversions.On; // Process all transponders foreach (GroupLocation location in m_Locations) { // Update counter ++CurrentLocation; // Reset CurrentLocationGroupsPending = 0; CurrentLocationGroup = 0; // Check caller if (!LocationStart(location)) { return; } // Groups found on this location Dictionary <SourceGroup, bool> found = new Dictionary <SourceGroup, bool>(); // Groups with valid network information - only those are considered List <SourceGroup> nitAvailable = new List <SourceGroup>(); // Load counter CurrentLocationGroupsPending = location.Groups.Count; // Process all groups foreach (SourceGroup group in location.Groups) { // Get the expected type Type groupType = group.GetType(); // Clone the group SourceGroup newGroup = SourceGroup.FromString <SourceGroup>(group.ToString()); // Count up --CurrentLocationGroupsPending; ++CurrentLocationGroup; // See if this is already processed if (null != found.Keys.FirstOrDefault(p => p.CompareTo(newGroup, true))) { continue; } // Check for external termination if (null == m_Worker) { return; } // Not supported if (!Profile.SupportsGroup(newGroup) || !device.CanHandle(newGroup)) { // Remember m_UnhandledGroups.Add(newGroup); // Next continue; } // Check caller if (!GroupStart(location, newGroup)) { return; } // Attach to the group if (null != SelectGroup(device, location, newGroup, ref lastInversion)) { // See if we are a cable group CableGroup cableGroup = newGroup as CableGroup; // Attach to the NIT var nit = device.GetLocationInformation(15000); if (null != nit) { // Remember nitAvailable.Add(newGroup); // Process foreach (SourceGroup other in nit.Groups) { if (other.GetType() == groupType) { // See if this is a cable group CableGroup otherCable = other as CableGroup; // Update inversion if (null != otherCable) { // Other must be cable, too if (null == cableGroup) { continue; } // Use same parameters otherCable.SpectrumInversion = cableGroup.SpectrumInversion; otherCable.Bandwidth = cableGroup.Bandwidth; } // Report if (ScannerTraceSwitch.Level >= TraceLevel.Info) { Trace.WriteLine(string.Format(Properties.Resources.Trace_Scanner_NIT, other), ScannerTraceSwitch.DisplayName); } // Mark it found[other] = true; } } } } // Check caller if (!GroupDone(location, newGroup)) { return; } } // Create a brand new scan location ScanLocation scan = location.ToScanLocation(); // Try to update foreach (SourceGroup group in nitAvailable) { // Try to find the full qualified name SourceGroup nitGroup = found.Keys.FirstOrDefault(p => p.CompareTo(group, true)); // Update if (null == nitGroup) { scan.Groups.Add(group); } else { scan.Groups.Add(nitGroup); } } // Just remember m_AnalyseResult[location] = scan; // Check caller if (!LocationDone(location)) { return; } } } } catch (Exception e) { // Remember m_ThreadException = e; } }
/// <summary> /// Übernimmt das Ergebnis des Sendersuchlaufs in das Geräteprofil. /// </summary> public void UpdateProfile() { // Create a map of all current locations Dictionary <GroupLocation, GroupLocation> newLocations = new Dictionary <GroupLocation, GroupLocation>(); // Fill current locations foreach (GroupLocation location in m_ScanResults) { newLocations[location] = location; } // All previous locations List <GroupLocation> oldLocations = new List <GroupLocation>(); // Fill all which are still active foreach (GroupLocation location in Profile.Locations) { if (newLocations.ContainsKey(location)) { oldLocations.Add(location); } } // Wipe out Profile.Locations.Clear(); // Reload foreach (GroupLocation location in m_ScanResults) { Profile.Locations.Add(location); } // All locations to process Dictionary <GroupLocation, bool> unprocessedLocations = newLocations.Keys.ToDictionary(l => l, l => true); // Process each location individually for a possible merge foreach (GroupLocation location in oldLocations) { // Find the related new location GroupLocation newLocation = newLocations[location]; // No need to check for protocol unprocessedLocations.Remove(newLocation); // Create a map of all source groups we found Dictionary <SourceIdentifier, SourceIdentifier> found = new Dictionary <SourceIdentifier, SourceIdentifier>(); // Fill it foreach (SourceGroup newGroup in newLocation.Groups) { foreach (SourceIdentifier newSource in newGroup.Sources) { found[newSource] = newSource; } } // Already processed Dictionary <SourceIdentifier, bool> updatedSources = new Dictionary <SourceIdentifier, bool>(); // Now see which old sources are no longer available foreach (SourceGroup oldGroup in location.Groups) { foreach (SourceIdentifier oldSource in oldGroup.Sources) { // Load the new source if (found.ContainsKey(oldSource)) { // Mark updatedSources[oldSource] = true; // Next continue; } // At least a group must exist SourceGroup newGroup = null; // Find it foreach (SourceGroup testGroup in newLocation.Groups) { if (testGroup.CompareTo(oldGroup, true)) { // Nearly the same newGroup = testGroup; // Done break; } } // Must create the group if (null == newGroup) { // Clone it newGroup = SourceGroup.FromString <SourceGroup>(oldGroup.ToString()); // Remember it newLocation.Groups.Add(newGroup); } // Add the missing source newGroup.Sources.Add(oldSource); // Remember m_Protocol.Add(new ProtocolRecord { Mode = ProtocolRecordMode.NotFound, Location = newLocation, Group = newGroup, Source = oldSource }); } } // Finish foreach (SourceGroup newGroup in newLocation.Groups) { foreach (SourceIdentifier newSource in newGroup.Sources) { if (found.ContainsKey(newSource)) { // Check mode ProtocolRecordMode mode; if (updatedSources.ContainsKey(newSource)) { mode = ProtocolRecordMode.Found; } else { mode = ProtocolRecordMode.Added; } // Add to protocol m_Protocol.Add(new ProtocolRecord { Mode = mode, Location = newLocation, Group = newGroup, Source = newSource }); } } } } // Add all sources to protocol foreach (GroupLocation newLocation in unprocessedLocations.Keys) { foreach (SourceGroup newGroup in newLocation.Groups) { foreach (SourceIdentifier newSource in newGroup.Sources) { m_Protocol.Add(new ProtocolRecord { Mode = ProtocolRecordMode.Added, Location = newLocation, Group = newGroup, Source = newSource }); } } } }
/// <summary> /// Führt den eigentlichen Sendersuchlauf aus. /// </summary> private void ScannerThread() { // Be safe try { // Configure language UserProfile.ApplyLanguage(); // Uses hardware manager using (HardwareManager.Open()) { // Attach to the hardware itself var device = HardwareManager.OpenHardware(Profile); // Tell it that we only do a scan device.PrepareSourceScan(); // Start loading location result list foreach (var location in m_Locations) { m_ScanResults.Add(location.Clone()); } // Reset counters TotalLocations = m_Locations.Count; // Last successfull inversion var lastInversion = SpectrumInversions.On; // Process all transponders for (CurrentLocation = 0; CurrentLocation < m_Locations.Count;) { // Get new and old var location = m_Locations[CurrentLocation]; var newLocation = m_ScanResults[CurrentLocation]; // Count ++CurrentLocation; // Reset CurrentLocationGroupsPending = 0; CurrentLocationGroup = 0; // Check caller if (!LocationStart(location)) { return; } // Allow NIT scan on... var enableNIT = new List <SourceGroup>(); var foundInfo = new List <SourceGroup>(); // Startup and load the groups from the configuration foreach (SourceGroup group in location.Groups) { enableNIT.Add(group); } // All we have to process var process = new List <SourceGroup>(enableNIT); // Allowed group type var groupType = (process.Count > 0) ? process[0].GetType() : null; // All we did so far var done = new HashSet <SourceGroup>(); // Process all groups while (process.Count > 0) { // Take the first one var group = process[0]; // Remove it process.RemoveAt(0); // Reset counter CurrentLocationGroupsPending = process.Count; // Count what we did ++CurrentLocationGroup; // Already done if (done.Contains(group)) { continue; } // Found group information on equivalent group if (foundInfo.FirstOrDefault(g => g.CompareTo(group, true)) != null) { continue; } // Mark as done done.Add(group); // Check for external termination if (m_Worker == null) { return; } // Not supported if (!Profile.SupportsGroup(group) || !device.CanHandle(group)) { // Remember m_UnhandledGroups.Add(group); // Next continue; } // Read the configuration var filter = Profile.GetFilter(group); // See if this should be skiped if (filter != null) { if (filter.ExcludeFromScan) { // Remember m_GroupsExcluded.Add(group); // Next continue; } } // Check caller if (!GroupStart(location, group)) { return; } // See if we should process the NIT var checkNIT = enableNIT.Contains(group); // See if we should process if (checkNIT || group.IsComplete) { // Clone the group - may change group = SourceGroup.FromString <SourceGroup>(group.ToString()); // Attach to the group var info = SelectGroup(device, location, group, ref lastInversion); // Mark as done again - group may be updated for DVB-C and if unchanged this is simply a no-operation done.Add(group); // Read the configuration again - actually for DVB-C it may change filter = Profile.GetFilter(group); // See if this should be skiped if (filter != null) { if (filter.ExcludeFromScan) { // Remember m_GroupsExcluded.Add(group); // Next continue; } } // Remember that we found a group information - transponder is not dead if (info != null) { foundInfo.Add(group); } // See if NIT update is allowed if (checkNIT) { if (info != null) { // See if we are a cable group var cableGroup = group as CableGroup; // Try load var nit = device.GetLocationInformation(15000); if (nit != null) { foreach (SourceGroup other in nit.Groups) { if (other.GetType() == groupType) { // See if this is a cable group var otherCable = other as CableGroup; // Disable NIT scan on the group as is enableNIT.RemoveAll(g => g.CompareTo(other, true)); process.RemoveAll(g => g.CompareTo(other, true)); // Set inversion if (otherCable != null) { if (cableGroup != null) { // Use same parameters otherCable.SpectrumInversion = cableGroup.SpectrumInversion; otherCable.Bandwidth = cableGroup.Bandwidth; // Disable NIT scan on the group which may be DVB-C corrected enableNIT.RemoveAll(g => g.CompareTo(otherCable, true)); process.RemoveAll(g => g.CompareTo(otherCable, true)); } } // Report if (ScannerTraceSwitch.Level >= TraceLevel.Info) { Trace.WriteLine(string.Format(Properties.Resources.Trace_Scanner_NIT, other), ScannerTraceSwitch.DisplayName); } // Add for processing process.Insert(0, other); } } } } } // Reset counter - may be updated if a new NIT was processed CurrentLocationGroupsPending = process.Count; // Skip if a legacy template group if (group.IsComplete) { // Merge newLocation.Groups.Add(group); // Process this group if (info == null) { m_Protocol.Add(new ProtocolRecord { Mode = ProtocolRecordMode.EmptyGroup, Location = location, Group = group }); } else { foreach (var source in info.Sources) { // Only stations var station = source as Station; if (station == null) { continue; } // Attach to the filter var modifiers = Profile.GetFilter(source); if (modifiers != null) { if (modifiers.ExcludeFromScan) { continue; } else { modifiers.ApplyTo(station); } } // Remember group.Sources.Add(station); // Get the count int foundOfType; if (!SourcesFound.TryGetValue(station.SourceType, out foundOfType)) { foundOfType = 0; } // Update SourcesFound[station.SourceType] = ++foundOfType; // Ask user if (!StationFound(location, group, station)) { return; } } } } } // Check caller if (!GroupDone(location, group)) { return; } } // Check caller if (!LocationDone(location)) { return; } } } } catch (Exception e) { // Remember m_ThreadException = e; } }