//-----------------------------------------------------------------------
//
// Copyright © 2012 Nils Hammar. All rights reserved.
//
//-----------------------------------------------------------------------
/*
* Software to access vehicle information via the OBD-II connector.
*
* Copyright © 2012 Nils Hammar
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Alternative licensing is possible, see the licensing document.
*
* The above text may not be removed or modified.
*/
namespace UserInterface.GUI
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using global::DataSource;
using global::DataSource.FileAccess;
using global::DeviceApi.J2534;
using global::Protocol;
using global::SharedObjects;
using global::SharedObjects.Api;
using global::SharedObjects.DataMgmt;
using global::SharedObjects.GUI;
using global::SharedObjects.GUI.Popup;
using global::SharedObjects.Misc;
using global::SharedObjects.Protocol;
using global::SharedObjects.Protocol.OBD;
using global::UserInterface.GUI.Objects;
///
/// Protocols panel declaration.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Reviewed.")]
public partial class ProtocolSelectPanel : UserControl, IProtocolCallback, IEnableButtons, IModeParser
{
///
/// Number of ECUs in chunk to probe.
///
private const int ECU_CHUNK = 8;
///
/// Image for yellow cog icon.
///
private static Image cogYellow = null;
///
/// Image for red cog icon.
///
private static Image cogRed = null;
///
/// Image for green cog icon.
///
private static Image cogGreen = null;
///
/// Image for used cog icon.
///
private static Image cogNeutral = null;
///
/// Image for used cog icon.
///
private static Image cogError = null;
///
/// Image for used cog icon.
///
private static Image cogUsed = null;
///
/// List of currently used protocol families. Used to reduce list of protocols in the UI to only the protocols that can be used.
///
private List usedProtocolFamilyList = new List();
///
/// List of available protocols.
///
private List availableProtocols = new List();
///
/// Indicate if all protocols shall be presented even though the device isn't listed to support them.
///
private bool allProtocols = false;
///
/// Last selected protocol.
///
/// Notice that multiple protocols can be handled, and that this is a scratch area used when creating a new protocol tab.
///
///
private ProtocolItemWrapper currentProtocolItemWrapper;
///
/// Current device instance.
///
private IPassThruDevice passThruDevice;
///
/// Current PassThru interface instance.
///
private IPassThru iPassThru;
///
/// Current vehicle instance.
///
private XmlClass.vehicle vehicle;
///
/// Current node in the tree which this instance is under.
///
private PanelTreeNode panelTreeNode;
///
/// Current serial port handler.
///
private SerialPortHandler serialPortHandler;
///
/// Composite OBD code file access, this is an union of the general and vehicle specific codes.
///
private ObdCodeFileAccess compositeObd;
///
/// Current logging instance.
///
private ILogging iLogging;
///
/// Current preferences instance.
///
private IPreferences iPreferences;
///
/// Misc functions interface instance.
///
private IMiscFunc iMiscFunc;
///
/// Application tree instance.
///
private IApplicationTree applicationTree;
///
/// Data Source instance.
///
private IDataSource iDataSource;
///
/// Rows in the data grid view.
///
private DataGridViewRowCollection rows;
///
/// Boolean indicating that a response arrived.
///
private bool gotResponse = false;
///
/// Object to synchronize threads with.
///
private object lockObject = new object();
///
/// Detected usable source address for tester.
///
private string detectedSrcAddress;
///
/// Detected source address.
///
private uint srcAddr = 0;
///
/// List of detected ECU addresses during a probe.
///
private List detectedEcus = new List();
///
/// If extended scan of ECUs shall be done.
///
/// Only applicable for 29 bit address.
///
///
private bool extendedScan = false;
///
/// Hint activator instance.
///
private IHintActivator hintActivator;
///
/// Data file directory path.
///
private string dataFileDir;
///
/// Initializes a new instance of the class.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "CanApp.CustomToolTip", Justification = "Reviewed.")]
public ProtocolSelectPanel()
{
this.InitializeComponent();
this.rows = this.protocolsDgv.Rows;
this.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.setAcceptedSrcAddrTextbox(string.Empty);
this.detectedSrcAddress = string.Empty;
this.toolTip1.SetToolTip(this.extendedScanCB, "Scans through all ECU address alternatives on ISO15765 29bit addressing.");
}
///
/// Initialize the instance.
///
/// Misc functions interface instance.
/// Current logging instance.
/// Current preferences instance.
/// Data source instance.
/// Current PassThru device instance.
/// Current PassThru interface instance.
/// Current vehicle instance.
/// Current serial port handler.
/// Composite OBD code file access, this is an union of the general and vehicle specific codes.
/// Hint activator instance.
/// Data file directory path.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "iDataSource", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "iPreferences", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "iMiscFunc", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "iLogging", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "compositeObd", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "vehicle", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "passThruDevice", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "iPassThru", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "serialPortHandler", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "hintActivator", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "dataFileDir", Justification = "Reviewed, intentional.")]
public void init(
IMiscFunc iMiscFunc,
ILogging iLogging,
IPreferences iPreferences,
IDataSource iDataSource,
IPassThruDevice passThruDevice,
IPassThru iPassThru,
XmlClass.vehicle vehicle,
SerialPortHandler serialPortHandler,
ObdCodeFileAccess compositeObd,
IHintActivator hintActivator,
string dataFileDir)
{
this.iMiscFunc = iMiscFunc;
this.iLogging = iLogging;
this.iPreferences = iPreferences;
this.iDataSource = iDataSource;
this.passThruDevice = passThruDevice;
this.iPassThru = iPassThru;
this.vehicle = vehicle;
this.serialPortHandler = serialPortHandler;
this.compositeObd = compositeObd;
this.hintActivator = hintActivator;
this.dataFileDir = dataFileDir;
ProtocolSelectPanel.fixImage(ref cogYellow, this.dataFileDir, "Icons\\cog_yellow.png");
ProtocolSelectPanel.fixImage(ref cogRed, this.dataFileDir, "Icons\\cog_red.png");
ProtocolSelectPanel.fixImage(ref cogGreen, this.dataFileDir, "Icons\\cog_green.png");
ProtocolSelectPanel.fixImage(ref cogNeutral, this.dataFileDir, "Icons\\cog.png");
ProtocolSelectPanel.fixImage(ref cogError, this.dataFileDir, "Icons\\cog_error.png");
ProtocolSelectPanel.fixImage(ref cogUsed, this.dataFileDir, "Icons\\cog_delete.png");
// Refresh the Protocols drop-down list.
this.updateProtocols();
}
///
/// Set the mapping of tree node to this instance.
///
/// Application tree instance.
/// Current node in the tree which this instance is under.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "panelTreeNode", Justification = "Reviewed, intentional.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "applicationTree", Justification = "Reviewed, intentional.")]
public void setPanelTreeNode(IApplicationTree applicationTree, PanelTreeNode panelTreeNode)
{
this.applicationTree = applicationTree;
this.panelTreeNode = panelTreeNode;
}
///
/// Close tab for connection.
///
/// Panel to close.
/// Protocol to release.
/// Node in application tree that was closed.
public void closeTab(ConnectionPanel panel, Protocols freeProtocol, PanelTreeNode protocolNode)
{
if (this.panelTreeNode.Nodes.Contains(protocolNode))
{
this.panelTreeNode.Nodes.Remove(protocolNode);
}
this.applicationTree.selectNode(this.panelTreeNode);
// TabPage tabPage = this.connectionList[panel];
// tabPage.Controls.Remove(panel);
//// this.mainTabControl.Controls.Remove(tabPage);
if (freeProtocol != null)
{
// Free the protocol family.
foreach (int family in freeProtocol.families)
{
this.usedProtocolFamilyList.Remove(family);
}
}
// Refresh the Protocols drop-down list.
this.updateProtocols();
}
///
/// Set the protocol text.
///
/// Protocol text.
public void setProtocol(string protocolText)
{
int i = 0;
foreach (DataGridViewRow row in this.rows)
{
DataGridViewCellCollection cells = row.Cells;
ProtocolItemWrapper protocolItemWrapper = (ProtocolItemWrapper)cells["col_item"].Value;
if (protocolItemWrapper.protocol.name == protocolText)
{
this.selectRow(i);
break;
}
i++;
}
}
///
/// Enable fields on the control.
///
/// 'true' to enable, 'false' to disable.
public void enableFields(bool enable)
{
this.protocolsDgv.Enabled = enable;
this.allProtocolsCB.Enabled = enable;
this.detectButton.Enabled = enable && !this.iPassThru.isSerial();
this.extendedScanCB.Enabled = this.detectButton.Enabled;
this.allProtocolsCB.Enabled = this.detectButton.Enabled;
this.newConnectionBT.Enabled = enable && (this.passThruDevice != null) && (this.availableProtocols.Count > 0);
}
///
/// Clean up at a disconnection.
///
public void disconnect()
{
foreach (PanelTreeNode protocolNode in this.panelTreeNode.Nodes)
{
if (protocolNode.userControl is ConnectionPanel)
{
ConnectionPanel connectionPanel = (ConnectionPanel)protocolNode.userControl;
connectionPanel.close();
}
}
this.panelTreeNode.Nodes.Clear();
this.usedProtocolFamilyList.Clear();
// Refresh the Protocols drop-down list.
this.updateProtocols();
}
///
/// Prepare connection.
///
/// Connection panel instance.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed, intentional.")]
public ConnectionPanel prepareConnection()
{
ConnectionPanel connectionPanel = null;
if (this.InvokeRequired)
{
try
{
connectionPanel = (ConnectionPanel)this.Invoke(new prepareConnectionFunc(this.prepareConnection), new object[] { });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
IPassThruConnection passThruConnection = new PassThruConnection(this.passThruDevice);
connectionPanel = new ConnectionPanel(
this.iLogging,
this.vehicle,
this.applicationTree,
this.iMiscFunc,
this.iPreferences,
this.iDataSource,
this,
passThruConnection,
this.currentProtocolItemWrapper,
this.compositeObd.obdcodes,
this.serialPortHandler,
this.detectedSrcAddress,
this.hintActivator,
this.dataFileDir);
PanelTreeNode protocolNode = new PanelTreeNode(this.currentProtocolItemWrapper.protocol.name, "cog.png", "cog_edit.png", connectionPanel);
connectionPanel.setOwningNode(protocolNode);
this.panelTreeNode.Nodes.Add(protocolNode);
this.panelTreeNode.Expand();
this.applicationTree.selectNode(protocolNode);
// Mark protocol family as used.
foreach (int family in this.currentProtocolItemWrapper.protocol.families)
{
this.usedProtocolFamilyList.Add(family);
}
// Refresh the Protocols drop-down list.
this.updateProtocols();
}
return connectionPanel;
}
///
/// Indicate that the buttons shall be enabled.
///
public void enableButtons()
{
if (this.InvokeRequired)
{
try
{
this.Invoke(new enableButtonsFunc(this.enableButtons), new object[] { });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
this.detectButton.Enabled = !this.iPassThru.isSerial();
this.extendedScanCB.Enabled = this.detectButton.Enabled;
this.allProtocolsCB.Enabled = this.detectButton.Enabled;
}
}
///
/// Signal that initialization failed when starting connection.
///
public void initFail()
{
}
///
/// Update the progress bar with the initialization progress.
///
/// Step processed.
/// Total steps.
public void updateProgress(int progressStep, int total)
{
}
///
/// Provide information about detected protocol.
///
/// Name of protocol.
public void setProtocolInfo(string protocolName)
{
}
#region IModeParser
///
/// Gets Current PID parser instance.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations", Justification = "Reviewed, intentional.")]
public IPidParser pidParser
{
get
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
}
///
/// Receive data to be parsed and presented.
///
/// Data to be presented.
/// Source address of message.
/// Detected protocol by ELM/AGV adapter.
public void receiveMessageData(byte[] payload, uint srcAddress, uint detectedProtocol)
{
if (payload != null)
{
if (!this.detectedEcus.Contains(srcAddress))
{
this.detectedEcus.Add(srcAddress);
}
#if TRACE
string txt = string.Empty;
for (int i = 0; i < payload.Length; i++)
{
if (i > 0)
{
txt += ", ";
}
txt += "0x" + payload[i].ToString("x2");
}
this.iLogging.appendText("0x" + srcAddress.ToString("x2") + "====> " + txt + "\r\n");
#endif
lock (this.lockObject)
{
if (payload.Length >= 2 && payload[0] == 0x41 && payload[1] == 0x00)
{
this.gotResponse = true;
Monitor.PulseAll(this.lockObject);
}
}
#if TRACE
this.iLogging.appendText("PULSED!!!\r\n");
#endif
}
}
///
/// Close the service.
///
public void close()
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
///
/// Set up a dictionary of the known Mode/PID combinations.
/// Notice that the list we use is the list that is filtered depending on preferred units. (Metric or Imperial)
///
public void configureModePidDictionary()
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
///
/// Register a panel able to receive data.
///
/// Panel to register.
public void registerPanel(IDataPanel panel)
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
///
/// Set the pending requests that can be performed after the current request has had an answer.
///
/// List of pending requests.
public void setPendingRequests(System.Collections.Generic.IList pendingModeRequests)
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
///
/// Remove registered panel.
///
/// Panel to unregister.
public void unregisterPanel(IDataPanel panel)
{
throw new NotImplementedException("Not implemented, only here to conform to interface IModeParser.");
}
#endregion
///
/// Detect protocol.
///
/// 'true' if successful.
public bool detectProtocol()
{
bool success = false;
if (this.serialPortHandler == null)
{
ProtocolItemWrapper matchedProtocol = null;
this.detectedEcus.Clear();
try
{
this.setImageRows(cogNeutral);
this.setAcceptedSrcAddrTextbox(string.Empty);
this.srcAddr = 0;
bool failure = false;
for (int i = 0; i < this.rows.Count && !success && !failure; i++)
{
this.setRowImage(i, cogYellow);
DataGridViewCellCollection cells = this.getRowCells(i);
ProtocolItemWrapper protocolItemWrapper = this.getProtocolItemWrapper(cells);
this.logInfo(cells, protocolItemWrapper);
bool is29bit;
uint currentSourceAddress;
getProtocolBaseInfo(protocolItemWrapper, out is29bit, out currentSourceAddress);
List ecus = this.getProbeEcus(protocolItemWrapper, is29bit);
IPassThruConnection passThruConnection = new PassThruConnection(this.passThruDevice);
PassThruConstants.resultCode status = performConnect(protocolItemWrapper, passThruConnection);
try
{
if (status == PassThruConstants.resultCode.ERR_SUCCESS)
{
int timeout = protocolItemWrapper.protocol.timeout;
MessageHandler messageHandler = new MessageHandler(this.iLogging, timeout, passThruConnection, protocolItemWrapper.protocol);
if (is29bit)
{
this.try29bitProtocol(ref success, ref matchedProtocol, ref failure, i, protocolItemWrapper, is29bit, ecus, passThruConnection, messageHandler);
}
else
{
this.tryOtherProtocol(ref success, ref matchedProtocol, ref failure, i, protocolItemWrapper, is29bit, currentSourceAddress, ecus, passThruConnection, messageHandler);
}
}
else
{
this.setRowImage(i, cogUsed);
}
}
catch (Exception ex)
{
this.iLogging.appendText(ex.GetType().ToString() + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n");
this.setRowImage(i, cogError);
}
finally
{
PassThruConstants.resultCode closeStatus = passThruConnection.Gl_PassThruDisconnect();
this.iLogging.errTestConnection(passThruConnection, closeStatus);
}
if (success)
{
this.setRowImage(i, cogGreen);
}
else
{
if (failure)
{
this.setRowImage(i, cogError);
}
else
{
this.setRowImage(i, cogRed);
}
}
}
}
catch (Exception ex)
{
this.iLogging.appendText(ex.Message + "\r\n" + ex.StackTrace + "\r\n");
}
finally
{
this.enableButtons();
}
this.iLogging.appendText("detectedEcus = " + this.detectedEcus.Count + "\r\n");
}
else
{
// Serial port dongles shall handle the handshake themselves, so we just accept them.
success = true;
}
return success;
}
///
/// Get some base info for the protocol.
///
/// Protocol data wrapper.
/// set to 'true' if ISO15765 29-bit.
/// Source address to try (for some protocols).
private static void getProtocolBaseInfo(ProtocolItemWrapper protocolItemWrapper, out bool is29bit, out uint currentSourceAddress)
{
is29bit = false;
currentSourceAddress = 0x00;
if (protocolItemWrapper.addressData != null && protocolItemWrapper.addressData.baseSourceAddress != null)
{
currentSourceAddress = Utils.hexParse(protocolItemWrapper.addressData.baseSourceAddress);
is29bit = (protocolItemWrapper.addressData.bits == 29);
}
}
///
/// Perform connection.
///
/// Protocol item wrapper.
/// Passthru connection instance.
/// Status code.
private static PassThruConstants.resultCode performConnect(ProtocolItemWrapper protocolItemWrapper, IPassThruConnection passThruConnection)
{
PassThruConstants.resultCode status;
if (protocolItemWrapper.addressData != null)
{
status = passThruConnection.Gl_PassThruConnect((int)protocolItemWrapper.protocol.id, protocolItemWrapper.addressData.connFlags, protocolItemWrapper.commspeed.bps);
}
else
{
if (protocolItemWrapper.protocol.id == Protocols.ISO9141 || protocolItemWrapper.protocol.id == Protocols.ISO14230)
{
status = passThruConnection.Gl_PassThruConnect(
(int)protocolItemWrapper.protocol.id,
PassThruConstants.connflags.ISO9141_K_LINE_ONLY | PassThruConstants.connflags.ISO9141_NO_CHECKSUM,
protocolItemWrapper.commspeed.bps);
}
else
{
status = passThruConnection.Gl_PassThruConnect(
(int)protocolItemWrapper.protocol.id,
0x00,
protocolItemWrapper.commspeed.bps);
}
}
return status;
}
///
/// A little workaround to resolve the problem of not knowing the path
/// in the designer mode.
///
/// Image instance.
/// Data file directory path.
/// Sub-path to specific image. E.g. "Icons\cog_yellow.png"
private static void fixImage(ref Image img, string dataFileDir, string imgPath)
{
if (img == null)
{
string basePath;
if (dataFileDir == null)
{
DataSourceImplementation.locateDataFiles();
}
if (dataFileDir == null)
{
// Ugly hard-coding.
basePath = @"E:\VsProjects\CanApp2\CanApp\AppData\";
}
else
{
basePath = dataFileDir;
}
img = Image.FromFile(basePath + imgPath);
}
}
///
/// Prepare connection.
///
/// Connection panel instance.
private delegate ConnectionPanel prepareConnectionFunc();
///
/// Create a new connection.
/// This doesn't open the connection, just creates a new tab with the values
/// applicable for connection.
///
/// Sending object.
/// Event data.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed, intentional.")]
private void newConnectionBT_Click(object sender, EventArgs e)
{
this.prepareConnection();
}
///
/// Update protocols drop-down.
///
private void updateProtocols()
{
this.availableProtocols.Clear();
this.rows.Clear();
if (this.iPassThru != null)
{
Protocols[] deviceSupportedProtocols = this.iPassThru.getProtocols();
for (int i1 = 0; i1 < Protocols.protocolScanOrder.Length; i1++)
{
Protocols currentProtocol = Protocols.getProtocolById(Protocols.protocolScanOrder[i1]);
#if TRACE
this.iLogging.appendText("currentProtocol=" + currentProtocol.name + ", currentProtocol.canDetect=" + currentProtocol.canDetect + "\r\n");
#endif
bool supportedProtocol = this.allProtocols;
if (!supportedProtocol)
{
foreach (Protocols deviceSupportedProtocol in deviceSupportedProtocols)
{
if (deviceSupportedProtocol.id == Protocols.protocolScanOrder[i1])
{
supportedProtocol = true;
break;
}
}
}
if (supportedProtocol)
{
bool usedFamily = false;
foreach (int family in currentProtocol.families)
{
if (this.usedProtocolFamilyList.Contains(family))
{
usedFamily = true;
break;
}
}
if (!usedFamily)
{
this.availableProtocols.Add(currentProtocol);
}
List speeds = this.getSpeedsForProtocol(currentProtocol);
if (speeds != null && speeds.Count > 0)
{
speeds.Reverse();
foreach (XmlClass.commspeed speed in speeds)
{
if (currentProtocol.addressDataList != null && currentProtocol.addressDataList.Count > 0)
{
foreach (Protocols.AddressData addr in currentProtocol.addressDataList)
{
string nameData = currentProtocol.name + " / " + speed.name + " / " + addr.bits + " bits";
this.addRow(currentProtocol, usedFamily, speed, addr, nameData);
}
}
else
{
string nameData = currentProtocol.name + " / " + speed.name;
this.addRow(currentProtocol, usedFamily, speed, null, nameData);
}
}
}
else
{
string nameData = currentProtocol.name;
this.addRow(currentProtocol, usedFamily, null, null, nameData);
}
}
}
}
this.newConnectionBT.Enabled = (this.passThruDevice != null) && (this.availableProtocols.Count > 0);
this.detectButton.Enabled = (this.rows.Count > 1) && !this.iPassThru.isSerial();
this.extendedScanCB.Enabled = this.detectButton.Enabled;
this.allProtocolsCB.Enabled = this.detectButton.Enabled;
if (this.rows.Count > 0)
{
this.updateProtocolFromRow(0);
}
}
///
/// Add one row to the protocols table.
///
/// Protocol to add.
/// Protocol family.
/// Interface speed.
/// Address data information.
/// Text description of row data.
private void addRow(Protocols currentProtocol, bool usedFamily, XmlClass.commspeed speed, Protocols.AddressData addr, string nameData)
{
int rowNum = this.rows.Add();
DataGridViewRow row = this.rows[rowNum];
DataGridViewCellCollection cells = row.Cells;
cells["col_protocol"].Value = nameData;
cells["col_item"].Value = new ProtocolItemWrapper(currentProtocol, speed, addr);
if (!usedFamily)
{
cells["col_status"].Value = cogNeutral;
}
else
{
cells["col_status"].Value = cogUsed;
}
}
///
/// Handle change of check state in checkbox for All Protocols.
///
/// Sending object.
/// Event data.
private void allProtocolsCB_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
if (cb.Focused)
{
this.allProtocols = cb.Checked;
// Refresh Protocol list.
this.updateProtocols();
}
}
///
/// Try to detect protocol.
///
/// Sending object.
/// Event data.
private void detectButton_Click(object sender, EventArgs e)
{
if (this.rows.Count > 1)
{
this.detectButton.Enabled = false;
this.extendedScanCB.Enabled = this.detectButton.Enabled;
this.allProtocolsCB.Enabled = this.detectButton.Enabled;
Thread thr = new Thread(this.detectThread);
thr.Start();
}
}
///
/// Thread performing the detection in the background to avoid locking up the UI.
///
private void detectThread()
{
this.detectProtocol();
}
///
/// Try ISO15765 29-bit.
///
/// Set to 'true' if successful match.
/// Instance of matched protocol.
/// Set to 'true' if failure.
/// Index value.
/// Probed protocol.
/// 'true' if 29 bit. (shall always be true here)
/// Array of ECUs to probe.
/// Current device connection.
/// Current message handler instance.
private void try29bitProtocol(
ref bool success,
ref ProtocolItemWrapper matchedProtocol,
ref bool failure,
int i,
ProtocolItemWrapper protocolItemWrapper,
bool is29bit,
List ecus,
IPassThruConnection passThruConnection,
MessageHandler messageHandler)
{
#if TRACE
int i0 = 0;
#endif
if (this.srcAddr != 0)
{
int start = 0;
int count = ecus.Count - start;
while (count > 0 && !failure)
{
if (count > ECU_CHUNK)
{
count = ECU_CHUNK;
}
XmlClass.vehicle.ecuData[] ecuArr = ecus.GetRange(start, count).ToArray();
this.iLogging.appendText("ECUS:");
foreach (XmlClass.vehicle.ecuData ecuItem in ecuArr)
{
this.iLogging.appendText(" " + ecuItem.id);
}
this.iLogging.appendText("\r\n");
start += count;
count = ecus.Count - start;
if (ecuArr.Length > 0)
{
this.tryProtocol(
ref success,
ref matchedProtocol,
ecuArr,
ref failure,
i,
protocolItemWrapper,
passThruConnection,
this.srcAddr,
is29bit,
messageHandler);
}
}
}
else
{
foreach (uint addrPart in protocolItemWrapper.addressData.srcAddr)
{
#if TRACE
this.iLogging.appendText("srcAddr[" + i0 + "]='0x" + addrPart.ToString("x2") + "'\r\n");
i0++;
#endif
int start = 0;
int count = ecus.Count - start;
while (count > 0 && !failure)
{
if (count > ECU_CHUNK)
{
count = ECU_CHUNK;
}
XmlClass.vehicle.ecuData[] ecuArr = ecus.GetRange(start, count).ToArray();
this.iLogging.appendText("ECUS:");
foreach (XmlClass.vehicle.ecuData ecuItem in ecuArr)
{
this.iLogging.appendText(" " + ecuItem.id);
}
this.iLogging.appendText("\r\n");
start += count;
count = ecus.Count - start;
if (ecuArr.Length > 0)
{
this.tryProtocol(
ref success,
ref matchedProtocol,
ecuArr,
ref failure,
i,
protocolItemWrapper,
passThruConnection,
addrPart,
is29bit,
messageHandler);
if (success && this.srcAddr == 0)
{
this.srcAddr = addrPart;
this.detectedSrcAddress = "0x" + addrPart.ToString("x2");
this.setAcceptedSrcAddrTextbox(this.detectedSrcAddress);
}
}
}
if (success)
{
break;
}
}
}
}
///
/// Try any other protocol but ISO15765 29-bit.
///
/// Set to 'true' if successful match.
/// Instance of matched protocol.
/// Set to 'true' if failure.
/// Index value.
/// Probed protocol.
/// 'true' if 29 bit. (shall always be false here)
/// Current source address to use.
/// Array of ECUs to probe.
/// Passthru connection instance.
/// Current message handler instance.
private void tryOtherProtocol(
ref bool success,
ref ProtocolItemWrapper matchedProtocol,
ref bool failure,
int i,
ProtocolItemWrapper protocolItemWrapper,
bool is29bit,
uint currentSourceAddress,
List ecus,
IPassThruConnection passThruConnection,
MessageHandler messageHandler)
{
#if TRACE
this.iLogging.appendText("srcAddr='0x" + currentSourceAddress.ToString("x2") + "'\r\n");
#endif
int start = 0;
int count = ecus.Count - start;
while (count > 0 && !failure)
{
if (count > ECU_CHUNK)
{
count = ECU_CHUNK;
}
XmlClass.vehicle.ecuData[] ecuArr = ecus.GetRange(start, count).ToArray();
this.iLogging.appendText("ECUS:");
foreach (XmlClass.vehicle.ecuData ecuItem in ecuArr)
{
this.iLogging.appendText(" " + ecuItem.id);
}
this.iLogging.appendText("\r\n");
start += count;
count = ecus.Count - start;
if (ecuArr.Length > 0)
{
this.tryProtocol(
ref success,
ref matchedProtocol,
ecuArr,
ref failure,
i,
protocolItemWrapper,
passThruConnection,
currentSourceAddress,
is29bit,
messageHandler);
}
}
}
///
/// Get list of ECUs to probe.
///
/// Wrapper for current protocol data.
/// 'true' if 29 bit addressing.
/// List of ECUs
private List getProbeEcus(ProtocolItemWrapper protocolItemWrapper, bool is29bit)
{
List ecus;
if (is29bit && this.extendedScan)
{
ecus = new List();
for (int j = 0; j < 256; j++)
{
XmlClass.vehicle.ecuData ecuData = new XmlClass.vehicle.ecuData();
ecuData.id = "0x" + j.ToString("x2");
ecuData.name = string.Empty;
ecus.Add(ecuData);
}
}
else
{
ecus = this.getProbeEcus(protocolItemWrapper);
}
return ecus;
}
///
/// Get list of ECUs to probe.
///
/// Wrapper for current protocol data.
/// List of ECUs
private List getProbeEcus(ProtocolItemWrapper protocolItemWrapper)
{
List ecus = new List();
if (protocolItemWrapper.protocol.id == Protocols.ISO15765 && protocolItemWrapper.addressData.bits == 11)
{
for (int j = 0; j < 8; j++)
{
XmlClass.vehicle.ecuData ecuItem = new XmlClass.vehicle.ecuData();
ecuItem.id = "0x" + j.ToString("x2");
ecuItem.name = string.Empty;
ecus.Add(ecuItem);
}
}
else
{
if (this.vehicle.ecus != null && this.vehicle.ecus.Count > 0)
{
ecus = new List(this.vehicle.ecus);
}
foreach (uint ecuAddr in Protocols.genericAddressList)
{
XmlClass.vehicle.ecuData ecuItem = new XmlClass.vehicle.ecuData();
ecuItem.id = "0x" + ecuAddr.ToString("x2");
ecuItem.name = string.Empty;
ecus.Add(ecuItem);
}
}
return ecus;
}
///
/// Set text to source address text box.
///
/// Detected source address text string.
private delegate void setAcceptedSrcAddrTextboxFunc(string detectedSrcAddress);
///
/// Set text to source address text box.
///
/// Detected source address text string.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "detectedSrcAddress", Justification = "Reviewed, intentional.")]
private void setAcceptedSrcAddrTextbox(string detectedSrcAddress)
{
if (this.acceptedSrcAddrTB.InvokeRequired)
{
try
{
this.Invoke(new setAcceptedSrcAddrTextboxFunc(this.setAcceptedSrcAddrTextbox), new object[] { detectedSrcAddress });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
this.acceptedSrcAddrTB.Text = detectedSrcAddress;
}
}
///
/// Try one protocol.
///
/// Set to 'true' if successful.
/// Wrapper for detected protocol.
/// Array of ECUs to probe.
/// 'true' if probe failed.
/// Index value.
/// Wrapper for probed protocol.
/// Current device connection.
/// Source address (tester address).
/// 'true' if 29 bit addressing.
/// Message handler instance.
private void tryProtocol(
ref bool success,
ref ProtocolItemWrapper matchedProtocol,
XmlClass.vehicle.ecuData[] ecuArr,
ref bool failure,
int i,
ProtocolItemWrapper protocolItemWrapper,
IPassThruConnection passThruConnection,
uint currentSourceAddress,
bool is29bit,
MessageHandler messageHandler)
{
IProtocolHandler protocolHandler = this.getProtocolHandler(protocolItemWrapper, currentSourceAddress, is29bit, messageHandler);
if (protocolHandler != null)
{
protocolHandler.addModeParser(this);
try
{
if (protocolItemWrapper.protocol.id > 0)
{
uint messageFlags;
if (is29bit)
{
messageFlags = PassThruConstants.txflags.CAN_29BIT_ID | PassThruConstants.txflags.ISO15765_FRAME_PAD;
}
else
{
messageFlags = PassThruConstants.txflags.ISO15765_FRAME_PAD;
}
FilterHandler filterHandler = null;
try
{
filterHandler = new FilterHandler(
this.iLogging,
passThruConnection,
protocolHandler,
ecuArr,
messageFlags,
protocolItemWrapper);
messageHandler.startThread();
protocolHandler.init(0x00);
this.gotResponse = false;
this.sendProbeMessage(protocolHandler.srcAddr, is29bit, protocolHandler);
lock (this.lockObject)
{
if (!this.gotResponse)
{
if (!Monitor.Wait(this.lockObject, protocolHandler.protocol.timeout * 2))
{
if (this.gotResponse)
{
this.iLogging.appendTextLn("ProtocolSelectPanel.tryProtocol(): Timeout with data present.");
}
}
}
}
matchedProtocol = this.handlePossibleResponse(protocolItemWrapper);
#if TRACE
this.iLogging.appendText("this.gotResponse='" + this.gotResponse + "'\r\n");
#endif
if (matchedProtocol != null && matchedProtocol.protocol != null)
{
this.iLogging.appendText("Matched Protocol = '" + matchedProtocol.protocol.name + "'\r\n");
this.selectRow(i);
success = true;
}
}
catch (ProtocolInitException ex)
{
#if TRACE
this.iLogging.appendText(ex.Message + "\r\n" + ex.StackTrace + "\r\n");
#endif
this.iLogging.appendText(ex.Message + "\r\n");
}
catch (Exception ex)
{
#if TRACE
this.iLogging.appendText(ex.Message + "\r\n" + ex.StackTrace + "\r\n");
#endif
this.iLogging.appendText(ex.Message + "\r\n");
failure = true;
}
finally
{
#if TRACE
this.iLogging.appendText("Stopping messageHandler Thread.\r\n");
#endif
messageHandler.stopThread();
if (filterHandler != null)
{
filterHandler.removeAllFilters();
}
}
}
}
finally
{
protocolHandler.removeModeParser(this);
protocolHandler.stopProtocol();
}
}
}
///
/// Select the given row in the table.
///
/// Number of row to select.
private delegate void selectRowFunc(int i);
///
/// Select the given row in the table.
///
/// Number of row to select.
private void selectRow(int i)
{
if (this.InvokeRequired)
{
try
{
this.Invoke(new selectRowFunc(this.selectRow), new object[] { i });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
this.protocolsDgv.ClearSelection();
this.protocolsDgv.Rows[i].Selected = true;
this.protocolsDgv.CurrentCell = this.protocolsDgv[0, i];
}
}
///
/// Handle and act on possible response from vehicle.
///
/// Protocol item wrapper.
/// Wrapper containing information about detected protocol.
private ProtocolItemWrapper handlePossibleResponse(ProtocolItemWrapper protocolItemWrapper)
{
ProtocolItemWrapper matchedProtocol = null;
if (this.gotResponse)
{
matchedProtocol = protocolItemWrapper;
}
return matchedProtocol;
}
///
/// Send a probe message that shall provide a response.
///
/// Source address (address of tester).
/// 'true' if 29 bit addressing.
/// Protocol handler instance.
private void sendProbeMessage(uint currentSourceAddress, bool is29bit, IProtocolHandler protocolHandler)
{
this.iLogging.appendText("is29bit=" + is29bit + "\r\n");
if (is29bit)
{
protocolHandler.sendProbeMessage(currentSourceAddress, PassThruConstants.txflags.CAN_29BIT_ID | PassThruConstants.txflags.ISO15765_FRAME_PAD, TxMsg.GET_SUPPORTED_PIDS);
}
else
{
protocolHandler.sendProbeMessage(0x00, PassThruConstants.txflags.ISO15765_FRAME_PAD, TxMsg.GET_SUPPORTED_PIDS);
}
}
///
/// Get the protocol handler instance for the protocol.
///
/// Protocol item wrapper instance.
/// Source Address.
/// 'true' if 29 bit addressing.
/// Message Handler instance.
/// Protocol handler instance.
private IProtocolHandler getProtocolHandler(ProtocolItemWrapper protocolItemWrapper, uint currentSourceAddress, bool is29bit, MessageHandler messageHandler)
{
IProtocolHandler protocolHandler;
switch (protocolItemWrapper.protocol.id)
{
case Protocols.J1850VPW:
case Protocols.J1850PWM:
protocolHandler = new Protocol_J1850(
this.iLogging,
protocolItemWrapper.protocol,
messageHandler,
currentSourceAddress,
true,
this);
break;
case Protocols.ISO9141:
case Protocols.ISO14230:
protocolHandler = new Protocol_ISO14230(
this.iLogging,
protocolItemWrapper.protocol,
messageHandler,
currentSourceAddress,
false,
this);
break;
case Protocols.ISO15765:
protocolHandler = new Protocol_ISO15765(
this.iLogging,
protocolItemWrapper.protocol,
messageHandler,
currentSourceAddress,
false,
is29bit,
this);
break;
default:
protocolHandler = null;
break;
}
return protocolHandler;
}
///
/// Write some info to the event log.
///
/// Cells from the current row.
/// Protocol item wrapper instance.
private delegate void logInfoFunc(DataGridViewCellCollection cells, ProtocolItemWrapper protocolItemWrapper);
///
/// Write some info to the event log.
///
/// Cells from the current row.
/// Protocol item wrapper instance.
private void logInfo(DataGridViewCellCollection cells, ProtocolItemWrapper protocolItemWrapper)
{
if (this.InvokeRequired)
{
try
{
this.Invoke(new logInfoFunc(this.logInfo), new object[] { cells, protocolItemWrapper });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
#if TRACE
this.iLogging.appendText("===================================================\r\n");
this.iLogging.appendText(cells["col_protocol"].Value + "\r\n");
this.iLogging.appendText("protocolItemWrapper.protocol.canDetect = " + protocolItemWrapper.protocol.canDetect + ", cells[\"col_status\"].Value=" + cells["col_status"].Value + "\r\n");
#endif
}
}
///
/// Get the protocol item wrapper instance from the cell collection.
///
/// Cell collection to get the item wrapper from.
/// Item wrapper instance.
private delegate ProtocolItemWrapper getProtocolItemWrapperFunc(DataGridViewCellCollection cells);
///
/// Get the protocol item wrapper instance from the cell collection.
///
/// Cell collection to get the item wrapper from.
/// Item wrapper instance.
private ProtocolItemWrapper getProtocolItemWrapper(DataGridViewCellCollection cells)
{
ProtocolItemWrapper protocolItemWrapper = null;
if (this.InvokeRequired)
{
try
{
protocolItemWrapper = (ProtocolItemWrapper)this.Invoke(new getProtocolItemWrapperFunc(this.getProtocolItemWrapper), new object[] { cells });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
protocolItemWrapper = (ProtocolItemWrapper)cells["col_item"].Value;
}
return protocolItemWrapper;
}
///
/// Get the cells for a table row.
///
/// Row number.
/// Collection of cells for the row.
private delegate DataGridViewCellCollection getRowCellsFunc(int i);
///
/// Get the cells for a table row.
///
/// Row number.
/// Collection of cells for the row.
private DataGridViewCellCollection getRowCells(int i)
{
DataGridViewCellCollection cells = null;
if (this.InvokeRequired)
{
try
{
cells = (DataGridViewCellCollection)this.Invoke(new getRowCellsFunc(this.getRowCells), new object[] { i });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
cells = this.rows[i].Cells;
}
return cells;
}
///
/// Set the status image of the status cell on all rows.
///
/// Image to place in cell.
private void setImageRows(Image img)
{
for (int i = 0; i < this.rows.Count; i++)
{
this.setRowImage(i, img);
}
}
///
/// Set the status image of the status cell on the given row.
///
/// Row number to update.
/// Image to place in cell.
private delegate void setRowImageFunc(int i, Image img);
///
/// Set the status image of the status cell on the given row.
///
/// Row number to update.
/// Image to place in cell.
private void setRowImage(int i, Image img)
{
if (this.InvokeRequired)
{
try
{
this.Invoke(new setRowImageFunc(this.setRowImage), new object[] { i, img });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
DataGridViewRow row = this.rows[i];
DataGridViewCellCollection cells = row.Cells;
ProtocolItemWrapper protocolItemWrapper = (ProtocolItemWrapper)cells["col_item"].Value;
if (protocolItemWrapper.protocol.canDetect)
{
this.setStatusImage(cells, img);
}
}
}
///
/// Set the status image of the status cell.
///
/// Cell collection for the row to be updated.
/// Image to place in cell.
private delegate void setStatusImageFunc(DataGridViewCellCollection cells, Image img);
///
/// Set the status image of the status cell.
///
/// Cell collection for the row to be updated.
/// Image to place in cell.
private void setStatusImage(DataGridViewCellCollection cells, Image img)
{
if (this.InvokeRequired)
{
try
{
this.Invoke(new setStatusImageFunc(this.setStatusImage), new object[] { cells, img });
}
catch (ThreadAbortException)
{
throw;
}
catch (System.Reflection.TargetParameterCountException ex)
{
MessageBox.Show(
"Exception: " + ex.Message + "\r\n",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
}
catch (System.ObjectDisposedException)
{
// Ignore.
}
}
else
{
cells["col_status"].Value = img;
}
}
///
/// Get the speeds supporting the giving protocol.
///
/// Protocol to get speed list for.
/// Speed list.
private List getSpeedsForProtocol(Protocols probeProtocol)
{
List speeds = new List();
foreach (XmlClass.commspeed speedItem in this.iDataSource.commspeeds)
{
if (probeProtocol.id == Protocols.ISO15765 && speedItem.validISO15765)
{
speeds.Add(speedItem);
}
if ((probeProtocol.id == Protocols.ISO9141 || probeProtocol.id == Protocols.ISO14230) && speedItem.validISO9141)
{
speeds.Add(speedItem);
}
if ((probeProtocol.id == Protocols.J1850PWM || probeProtocol.id == Protocols.J1850VPW) && speedItem.validJ1850)
{
speeds.Add(speedItem);
}
}
return speeds;
}
///
/// Handle changed row in table.
///
/// Sending object.
/// Event data.
private void protocolsDgv_RowEnter(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
this.updateProtocolFromRow(rowIndex);
}
///
/// Update the protocol from the given row.
///
/// Row number.
private void updateProtocolFromRow(int rowIndex)
{
DataGridViewRow row = this.rows[rowIndex];
DataGridViewCellCollection cells = row.Cells;
this.newConnectionBT.Enabled = (this.passThruDevice != null) && (cells["col_status"].Value != cogUsed);
ProtocolItemWrapper protocolItemWrapper = (ProtocolItemWrapper)cells["col_item"].Value;
if (protocolItemWrapper != null)
{
this.currentProtocolItemWrapper = protocolItemWrapper;
if (protocolItemWrapper.addressData != null
&& protocolItemWrapper.addressData.srcAddr != null
&& protocolItemWrapper.addressData.srcAddr.Length > 0)
{
this.detectedSrcAddress = "0x" + protocolItemWrapper.addressData.srcAddr[0].ToString("x2");
}
else
{
this.detectedSrcAddress = "0xf1"; // Best guess.
}
}
else
{
this.currentProtocolItemWrapper = null;
this.detectedSrcAddress = null;
}
}
///
/// Indicate that the buttons shall be enabled.
///
private delegate void enableButtonsFunc();
///
/// Toggle the extended scan flag.
///
/// Sending object.
/// Event data.
private void extendedScanCB_CheckedChanged(object sender, EventArgs e)
{
this.extendedScan = this.extendedScanCB.Checked;
}
}
}