private void NrDictAdd(byte deviceAddr, bool enableLogging) { int retries; if (NrDict.TryGetValue(deviceAddr, out retries)) { NrDict.Remove(deviceAddr); retries++; if (retries <= ParRetryNr) { if (enableLogging) { EdiabasProtected.LogFormat(EdiabasNet.EdLogLevel.Ifh, "NR({0:X02}) count={1}", deviceAddr, retries); } NrDict.Add(deviceAddr, retries); } else { if (enableLogging) { EdiabasProtected.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** NR({0:X02}) exceeded", deviceAddr); } } } else { if (enableLogging) { EdiabasProtected.LogFormat(EdiabasNet.EdLogLevel.Ifh, "NR({0:X02}) added", deviceAddr); } NrDict.Add(deviceAddr, 0); } }
protected EdiabasNet.ErrorCodes ObdTrans(byte[] sendData, int sendDataLength, ref byte[] receiveData, out int receiveLength) { receiveLength = 0; if (TcpDiagStream == null) { return(EdiabasNet.ErrorCodes.EDIABAS_IFH_0019); } EdiabasNet.ErrorCodes errorCode = EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE; UInt32 retries = CommRepeatsProtected; string retryComm = EdiabasProtected.GetConfigProperty("RetryComm"); if (retryComm != null) { if (EdiabasNet.StringToValue(retryComm) == 0) { retries = 0; } } for (int i = 0; i < retries + 1; i++) { errorCode = ParTransmitFunc(sendData, sendDataLength, ref receiveData, out receiveLength); if (errorCode == EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE) { return(errorCode); } if (errorCode == EdiabasNet.ErrorCodes.EDIABAS_IFH_0003) { // interface error break; } } return(errorCode); }
public override bool ReceiveFrequent(out byte[] receiveData) { receiveData = null; if (CommParameterProtected == null) { EdiabasProtected.SetError(EdiabasNet.ErrorCodes.EDIABAS_IFH_0006); return(false); } receiveData = ByteArray0; return(true); }
private void NrDictRemove(byte deviceAddr, bool enableLogging) { if (NrDict.ContainsKey(deviceAddr)) { if (enableLogging) { EdiabasProtected.LogFormat(EdiabasNet.EdLogLevel.Ifh, "NR({0:X02}) removed", deviceAddr); } NrDict.Remove(deviceAddr); } }
public override bool InterfaceDisconnect() { EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, "Disconnect"); bool result = true; try { if (TcpDiagStream != null) { TcpDiagStream.Close(); TcpDiagStream = null; } } catch (Exception) { result = false; } try { if (TcpDiagClient != null) { TcpDiagClient.Close(); TcpDiagClient = null; } } catch (Exception) { result = false; } if (!TcpControlDisconnect()) { result = false; } try { if (UdpSocket != null) { UdpSocket.Close(); UdpSocket = null; } } catch (Exception) { result = false; } TcpHostIp = null; ReconnectRequired = false; return(result); }
public override bool TransmitData(byte[] sendData, out byte[] receiveData) { receiveData = null; if (CommParameterProtected == null) { EdiabasProtected.SetError(EdiabasNet.ErrorCodes.EDIABAS_IFH_0006); return(false); } EdiabasNet.ErrorCodes cachedErrorCode; byte[] cachedResponse; if (ReadCachedTransmission(sendData, out cachedResponse, out cachedErrorCode)) { if (cachedErrorCode != EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE) { EdiabasProtected.SetError(cachedErrorCode); return(false); } receiveData = cachedResponse; return(true); } if (ReconnectRequired) { InterfaceDisconnect(); if (!InterfaceConnect()) { ReconnectRequired = true; EdiabasProtected.SetError(EdiabasNet.ErrorCodes.EDIABAS_IFH_0003); return(false); } } int recLength; EdiabasNet.ErrorCodes errorCode = ObdTrans(sendData, sendData.Length, ref RecBuffer, out recLength); if (errorCode != EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE) { if (errorCode == EdiabasNet.ErrorCodes.EDIABAS_IFH_0003) { ReconnectRequired = true; } CacheTransmission(sendData, null, errorCode); EdiabasProtected.SetError(errorCode); return(false); } receiveData = new byte[recLength]; Array.Copy(RecBuffer, receiveData, recLength); CacheTransmission(sendData, receiveData, EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE); return(true); }
public override bool InterfaceConnect() { if (TcpDiagClient != null) { return(true); } try { EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "Connect"); TcpHostIp = null; if (RemoteHostProtected.StartsWith(AutoIp, StringComparison.OrdinalIgnoreCase)) { List <IPAddress> detectedVehicles = DetectedVehicles(RemoteHostProtected, 1); if ((detectedVehicles == null) || (detectedVehicles.Count < 1)) { return(false); } TcpHostIp = detectedVehicles[0]; UdpSocket.Close(); EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, string.Format("Received: IP={0}", TcpHostIp)); } else { TcpHostIp = IPAddress.Parse(RemoteHostProtected); } TcpDiagClient = new TcpClientWithTimeout(TcpHostIp, DiagnosticPort, ConnectTimeout).Connect(); TcpDiagStream = TcpDiagClient.GetStream(); TcpDiagRecLen = 0; LastTcpDiagRecTime = DateTime.MinValue.Ticks; TcpDiagRecQueue.Clear(); StartReadTcpDiag(6); EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "Connected"); ReconnectRequired = false; } catch (Exception ex) { EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "InterfaceConnect exception: " + EdiabasNet.GetExceptionText(ex)); InterfaceDisconnect(); return(false); } return(true); }
protected bool SendData(byte[] sendData, int length, bool enableLogging) { if (TcpDiagStream == null) { return(false); } try { lock (TcpDiagStreamRecLock) { TcpDiagStreamRecEvent.Reset(); TcpDiagRecQueue.Clear(); } byte targetAddr = sendData[1]; byte sourceAddr = sendData[2]; if (sourceAddr == 0xF1) { sourceAddr = (byte)TesterAddress; } int dataOffset = 3; int dataLength = sendData[0] & 0x3F; if (dataLength == 0) { // with length byte if (sendData[3] == 0) { dataLength = (sendData[4] << 8) | sendData[5]; dataOffset = 6; } else { dataLength = sendData[3]; dataOffset = 4; } } int payloadLength = dataLength + 2; DataBuffer[0] = (byte)((payloadLength >> 24) & 0xFF); DataBuffer[1] = (byte)((payloadLength >> 16) & 0xFF); DataBuffer[2] = (byte)((payloadLength >> 8) & 0xFF); DataBuffer[3] = (byte)(payloadLength & 0xFF); DataBuffer[4] = 0x00; // Payoad type: Diag message DataBuffer[5] = 0x01; DataBuffer[6] = sourceAddr; DataBuffer[7] = targetAddr; Array.Copy(sendData, dataOffset, DataBuffer, 8, dataLength); int sendLength = dataLength + 8; lock (TcpDiagStreamSendLock) { TcpDiagStream.Write(DataBuffer, 0, sendLength); } // wait for ack int recLen = ReceiveTelegram(AckBuffer, 5000); if (recLen < 0) { if (enableLogging) { EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "*** No ack received"); } return(false); } if ((recLen < 6) || (recLen > sendLength) || (AckBuffer[5] != 0x02)) { if (enableLogging) { EdiabasProtected.LogData(EdiabasNet.EdLogLevel.Ifh, AckBuffer, 0, recLen, "*** Ack frame invalid"); } return(false); } AckBuffer[4] = DataBuffer[4]; AckBuffer[5] = DataBuffer[5]; for (int i = 4; i < recLen; i++) { if (AckBuffer[i] != DataBuffer[i]) { if (enableLogging) { EdiabasProtected.LogData(EdiabasNet.EdLogLevel.Ifh, AckBuffer, 0, recLen, "*** Ack data invalid"); } return(false); } } } catch (Exception) { return(false); } return(true); }
public List <IPAddress> DetectedVehicles(string remoteHostConfig, int maxVehicles = -1) { if (!remoteHostConfig.StartsWith(AutoIp, StringComparison.OrdinalIgnoreCase)) { return(null); } // ReSharper disable once UseObjectOrCollectionInitializer UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); #if !WindowsCE UdpSocket.EnableBroadcast = true; #endif IPEndPoint ipUdp = new IPEndPoint(IPAddress.Any, 0); UdpSocket.Bind(ipUdp); lock (UdpRecListLock) { UdpRecIpListList = new List <IPAddress>(); } UdpMaxResponses = maxVehicles; StartUdpListen(); bool broadcastSend = false; #if !WindowsCE string configData = remoteHostConfig.Remove(0, AutoIp.Length); if ((configData.Length > 0) && (configData[0] == ':')) { string adapterName = configData.StartsWith(":all", StringComparison.OrdinalIgnoreCase) ? string.Empty : configData.Remove(0, 1); System.Net.NetworkInformation.NetworkInterface[] adapters = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); foreach (System.Net.NetworkInformation.NetworkInterface adapter in adapters) { if (adapter.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up) { System.Net.NetworkInformation.IPInterfaceProperties properties = adapter.GetIPProperties(); if (properties.UnicastAddresses != null) { foreach (System.Net.NetworkInformation.UnicastIPAddressInformation ipAddressInfo in properties.UnicastAddresses) { if (ipAddressInfo.Address.AddressFamily == AddressFamily.InterNetwork) { if ((adapterName.Length == 0) || (adapter.Name.StartsWith(adapterName, StringComparison.OrdinalIgnoreCase))) { try { byte[] ipBytes = ipAddressInfo.Address.GetAddressBytes(); byte[] maskBytes = ipAddressInfo.IPv4Mask.GetAddressBytes(); for (int i = 0; i < ipBytes.Length; i++) { ipBytes[i] |= (byte)(~maskBytes[i]); } IPAddress broadcastAddress = new IPAddress(ipBytes); EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, string.Format("Sending: '{0}': Ip={1} Mask={2} Broadcast={3}", adapter.Name, ipAddressInfo.Address, ipAddressInfo.IPv4Mask, broadcastAddress)); IPEndPoint ipUdpIdent = new IPEndPoint(broadcastAddress, ControlPort); UdpSocket.SendTo(UdpIdentReq, ipUdpIdent); broadcastSend = true; } catch (Exception) { EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, "Broadcast failed"); } } } } } } } } else #endif { try { #if Android || WindowsCE IPEndPoint ipUdpIdent = new IPEndPoint(IPAddress.Broadcast, ControlPort); #else IPEndPoint ipUdpIdent = new IPEndPoint(IPAddress.Parse("169.254.255.255"), ControlPort); #endif EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, string.Format("Sending to: {0}", ipUdpIdent.Address)); UdpSocket.SendTo(UdpIdentReq, ipUdpIdent); broadcastSend = true; } catch (Exception) { EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, "Broadcast failed"); } } if (!broadcastSend) { EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, "No broadcast send"); InterfaceDisconnect(); return(null); } UdpEvent.WaitOne(1000, false); if (UdpRecIpListList.Count == 0) { EdiabasProtected?.LogString(EdiabasNet.EdLogLevel.Ifh, "No answer received"); InterfaceDisconnect(); return(null); } UdpSocket.Close(); List <IPAddress> ipList; lock (UdpRecListLock) { ipList = UdpRecIpListList; UdpRecIpListList = null; } return(ipList); }
private EdiabasNet.ErrorCodes TransKwp2000(byte[] sendData, int sendDataLength, ref byte[] receiveData, out int receiveLength, bool enableLogging) { receiveLength = 0; if (sendDataLength > 0) { NrDict.Clear(); int sendLength = TelLengthBmwFast(sendData); if (enableLogging) { EdiabasProtected.LogData(EdiabasNet.EdLogLevel.Ifh, sendData, 0, sendLength, "Send"); } if (!SendData(sendData, sendLength, enableLogging)) { if (enableLogging) { EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Sending failed"); } return(EdiabasNet.ErrorCodes.EDIABAS_IFH_0003); } } for (; ;) { int timeout = (NrDict.Count > 0) ? ParTimeoutNr : ParTimeoutStd; //if (enableLogging) EdiabasProtected.LogFormat(EdiabasNet.EdLogLevel.Ifh, "Timeout: {0}", timeout); if (!ReceiveData(receiveData, timeout)) { if (enableLogging) { EdiabasProtected.LogString(EdiabasNet.EdLogLevel.Ifh, "*** No data received"); } return(EdiabasNet.ErrorCodes.EDIABAS_IFH_0009); } int recLength = TelLengthBmwFast(receiveData); EdiabasProtected.LogData(EdiabasNet.EdLogLevel.Ifh, receiveData, 0, recLength + 1, "Resp"); int dataLen = receiveData[0] & 0x3F; int dataStart = 3; if (dataLen == 0) { // with length byte if (receiveData[3] == 0) { dataLen = (receiveData[4] << 8) | receiveData[5]; dataStart += 3; } else { dataLen = receiveData[3]; dataStart++; } } if ((dataLen == 3) && (receiveData[dataStart] == 0x7F) && (receiveData[dataStart + 2] == 0x78)) { // negative response 0x78 NrDictAdd(receiveData[2], enableLogging); } else { NrDictRemove(receiveData[2], enableLogging); break; } if (NrDict.Count == 0) { break; } } receiveLength = TelLengthBmwFast(receiveData) + 1; return(EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE); }