//----------------------------------------------------------------------- // // 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 Protocol { using System.Collections.Generic; using global::SharedObjects.Misc; using global::SharedObjects.Protocol; /// /// Construct address depending on protocol. /// public class AddressBuilder { /// /// Gets compiled list of destination addresses. /// public IEnumerable destinationAddresses { get { return new List(this.destinationAddressList); } } /// /// Gets compiled list of ECUs. /// public IEnumerable ecus { get { return new List(this.ecuDataList); } } /// /// Gets default alternative in address list. /// public string defaultValue { get; private set; } /// /// Compiled list of destination addresses. /// private List destinationAddressList = new List(); /// /// Compiled list of ECU addresses. /// private List ecuDataList = new List(); /// /// If the 29 bit addressing is expected. /// private bool is29bit; /// /// Wrapper for current protocol data. /// private ProtocolItemWrapper currentProtocolItemWrapper; /// /// Current vehicle. /// private XmlClass.vehicle vehicle; /// /// Source address for tester. /// private uint sourceAddress; /// /// Initializes a new instance of the class. /// /// Wrapper for current protocol data. /// Current vehicle. /// Source address for tester. public AddressBuilder( ProtocolItemWrapper currentProtocolItemWrapper, XmlClass.vehicle vehicle, uint sourceAddress) { this.currentProtocolItemWrapper = currentProtocolItemWrapper; this.vehicle = vehicle; if (this.currentProtocolItemWrapper != null && this.currentProtocolItemWrapper.addressData != null) { this.is29bit = (this.currentProtocolItemWrapper.addressData.bits == 29); } else { this.is29bit = false; } this.sourceAddress = sourceAddress; this.buildAddressList(); } /// /// Load data into the destination address combobox. /// /// Way too complicated... :( /// /// private void buildAddressList() { this.destinationAddressList.Clear(); this.ecuDataList.Clear(); if (this.is29bit) { this.populate29bitDestAddress(); } else { this.populateOtherDestAddresses(); } if (this.destinationAddressList.Count > 0 && this.destinationAddressList[0] is string) { this.defaultValue = (string)this.destinationAddressList[0]; } } /// /// All addresses except 29-bit ISO15765. /// private void populateOtherDestAddresses() { if (this.currentProtocolItemWrapper != null && this.currentProtocolItemWrapper.addressData != null) { if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.broadcastAddress)) { this.destinationAddressList.Add(this.currentProtocolItemWrapper.addressData.broadcastAddress); } if (this.vehicle.ecus != null && this.vehicle.ecus.Count > 0) { if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.baseDestinationAddress)) { this.destinationAddressList.Add(this.currentProtocolItemWrapper.addressData.baseDestinationAddress); } } else { if (this.currentProtocolItemWrapper.addressData.bits == 11) { if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.baseDestinationAddress)) { uint baseAddr = Utils.hexParse(this.currentProtocolItemWrapper.addressData.baseDestinationAddress); for (uint i = 0; i < 7; i++) { uint newAddr = (baseAddr | i); this.destinationAddressList.Add("0x" + newAddr.ToString("x2") + " Raw"); this.addEcu("0x" + newAddr.ToString("x2")); } } } else { if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.baseDestinationAddress)) { foreach (uint addr in Protocols.genericAddressList) { this.destinationAddressList.Add("0x" + addr.ToString("x2") + " Generic"); this.addEcu("0x" + addr.ToString("x2")); } } } } } } /// /// 29-bit ISO15765. /// private void populate29bitDestAddress() { if (this.currentProtocolItemWrapper != null && this.currentProtocolItemWrapper.addressData != null && this.sourceAddress != 0) { this.default29bitDestAddress(); } else { this.fallback29bitDestAddress(); } } /// /// When there is address data available and a source address detected we /// can construct the default 29 bit addresses here. /// private void default29bitDestAddress() { if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.broadcastAddress)) { uint addr = Utils.hexParse(this.currentProtocolItemWrapper.addressData.broadcastAddress); addr |= this.sourceAddress; this.destinationAddressList.Add("0x" + addr.ToString("x8") + " Broadcast"); } if (!string.IsNullOrEmpty(this.currentProtocolItemWrapper.addressData.baseDestinationAddress)) { uint baseAddr = Utils.hexParse(this.currentProtocolItemWrapper.addressData.baseDestinationAddress); baseAddr |= this.sourceAddress; // If the vehicle has a list of ECUs declared we only need one address // entry and are set with that. if (this.vehicle.ecus != null && this.vehicle.ecus.Count > 0) { this.destinationAddressList.Add("0x" + baseAddr.ToString("x8") + " Template"); } else { // If the selected vehicle is 29 bits and has addresses declared we can use the address list from it. if (this.vehicle.addressbits == 29 && this.vehicle.txaddrlist.Count > 0) { foreach (XmlClass.vehicle.addrlist addr in this.vehicle.txaddrlist) { if (!addr.broadcast) { uint newAddr = baseAddr; uint ecuAddr = Utils.hexParse(addr.address) & 0x0000ff00; newAddr |= ecuAddr; this.destinationAddressList.Add("0x" + newAddr.ToString("x8") + " Raw"); this.addEcu("0x" + ((ecuAddr >> 8) & 0xff).ToString("x2")); } } } else { // As a last resort fall back to a list of generic ECU addresses. foreach (uint addr in Protocols.genericAddressList) { uint newAddr = baseAddr; newAddr |= (addr << 8); this.destinationAddressList.Add("0x" + newAddr.ToString("x8") + " Generic"); this.addEcu("0x" + addr.ToString("x2")); } } } } } /// /// Fallback handling for 29 bit addresses. /// private void fallback29bitDestAddress() { if (this.vehicle.addressbits == 29) { foreach (XmlClass.vehicle.addrlist addr in this.vehicle.txaddrlist) { if (addr.broadcast) { this.destinationAddressList.Add(addr.address + " Broadcast."); } } foreach (XmlClass.vehicle.addrlist addr in this.vehicle.txaddrlist) { if (!addr.broadcast) { this.destinationAddressList.Add(addr.address + " Raw."); uint ecuAddr = Utils.hexParse(addr.address) & 0x0000ff00; this.addEcu("0x" + ((ecuAddr >> 8) & 0xff).ToString("x2")); } } } else { if (this.currentProtocolItemWrapper != null && this.currentProtocolItemWrapper.addressData != null) { uint baseAddr = Utils.hexParse(this.currentProtocolItemWrapper.addressData.baseDestinationAddress); baseAddr |= this.sourceAddress; foreach (uint addr in Protocols.genericAddressList) { uint newAddr = baseAddr; newAddr |= (addr << 8); this.destinationAddressList.Add("0x" + newAddr.ToString("x8") + " Generic"); this.addEcu("0x" + addr.ToString("x2")); } } } } /// /// Add ECU address. /// /// ECU address string. private void addEcu(string ecuAddress) { XmlClass.vehicle.ecuData ecuItem = new XmlClass.vehicle.ecuData(); ecuItem.id = ecuAddress; ecuItem.name = string.Empty; this.ecuDataList.Add(ecuItem); } } }