/// <summary>
        /// Get data for pid
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        public OdbQueryResponse RequestFor(OdbPid pid)
        {
            //add new query to databaze
            if (!queryResponses.ContainsKey(pid))
            {
                OdbQuery newQuery = new OdbQuery();
                newQuery.Pid = pid;
                newQuery.Status = this.checkSupported(newQuery);
                queryResponses.Add(pid, newQuery);

                reporter.ReportNewQuery(newQuery);
            }

            //read data from query
            OdbQuery query = queryResponses[pid];
            OdbQueryResponse response = new OdbQueryResponse();
            if (query.Status == QueryStatus.Complete)
            {
                response.Data = query.Data;
                response.Unit = query.Pid.Units;
                response.MinValue = query.Pid.MinValue;
                response.MaxValue = query.Pid.MaxValue;

                return response;
            }
            return null;
        }
        /// <summary>
        /// Report deleted query
        /// </summary>
        /// <param name="pid"></param>
        public void ReportDeleteQuery(OdbPid pid)
        {
            if (!OdbClient.OBD_REPORTER_ENABLED)
            {
                return;
            }

            Debug.WriteLine(InfoPrefix + "Query for '{0} ({1})' has been removed from register queries.", pid.Description, pid.Pid);
        }
 /// <summary>
 /// Get supp
 /// </summary>
 /// <param name="what"></param>
 /// <returns></returns>
 private async Task registerSupportedPid(OdbPid what)
 {
     OdbResponse response = await this.socket.SendAndCheck(what);
     OdbData data = this.socket.ResolveData(response, what);
     if (data != null)
     {
         this.decodeSupportedPidsAndRegisterIt(what, data);
     }
 }
Exemple #4
0
        /// <summary>
        /// Report deleted query
        /// </summary>
        /// <param name="pid"></param>
        public void ReportDeleteQuery(OdbPid pid)
        {
            if (!OdbClient.OBD_REPORTER_ENABLED)
            {
                return;
            }

            Debug.WriteLine(InfoPrefix + "Query for '{0} ({1})' has been removed from register queries.", pid.Description, pid.Pid);
        }
        /// <summary>
        /// Decode supported pids and  register it
        /// </summary>
        /// <param name="what"></param>
        /// <param name="data"></param>
        private void decodeSupportedPidsAndRegisterIt(OdbPid what, OdbData data)
        {
            List<int> pids = new List<int>();

            int pid = Convert.ToInt32(what.Pid.Split(' ')[1], 16);
            for (int i = 0; i < data.Data.Length; i++)
            {
                char[] binary = Convert.ToString(Convert.ToInt32(data.Data[i], 16), 2).ToCharArray();
                for (int j = 0; j < binary.Length; j++)
                {
                    pid++;
                    if (binary[j] == '1')
                    {
                        pids.Add(pid);
                    }
                }
            }

            this.RegisterSupportedPids(data.EcuIdentifier(), data.Protocol, pids);
        }
        /// <summary>
        /// Clear response message
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private string clearResponse(string response, OdbPid what)
        {
            response = response.Replace("\r", " ");

            String[] lines = response.Split('\n');
            for (int i = lines.Length - 1; i >= 0; i--)
            {
                String line = lines[i];
                line = this.clearLine(what, line);

                if (line.Length > 0)
                {
                    return line;
                }
            }
            return this.clearLine(what, lines.Last());
        }
        /// <summary>
        /// Resolve incoming data and setup odb data
        /// </summary>
        /// <param name="response"></param>
        /// <param name="what"></param>
        /// <returns></returns>
        public OdbData ResolveData(String response, OdbPid what)
        {
            int counter = 0;

            String[] bytes = response.Split(' ');
            bytes = this.validateReponseBytes(bytes);
            OdbData data = OdbPids.GetResponseFormatForProtocolNumber(bytes.Length, what.ByteCount);

            if (bytes.Length < what.ByteCount)
            {
                return null;
            }

            try
            {
                data.Protocol = this.SelectedProtocol;
                for (int i = 0; i < data.Header.Length; i++)
                {
                    data.Header[i] = bytes[counter];
                    counter++;
                }
                for (int i = 0; i < data.Info.Length; i++)
                {
                    data.Info[i] = bytes[counter];
                    counter++;
                }
                for (int i = 0; i < data.Data.Length; i++)
                {
                    data.Data[i] = bytes[counter];
                    counter++;
                }
                for (int i = 0; i < data.Ender.Length; i++)
                {
                    data.Ender[i] = bytes[counter];
                    counter++;
                }
            }
            catch
            {
                return null;
            }
            return data;
        }
 /// <summary>
 /// resolve data
 /// </summary>
 /// <param name="response"></param>
 /// <param name="what"></param>
 /// <returns></returns>
 public OdbData ResolveData(OdbResponse response, OdbPid what)
 {
     return this.ResolveData(response.Response, what);
 }
        /// <summary>
        /// Is valid response from device
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private bool isValidResponse(String response, OdbPid what)
        {
            var lowerResponse = response.ToLowerInvariant();
            var rightLength = lowerResponse.Trim().Length > 0;
            var containsError = lowerResponse.Contains("error");
            var containsUnknownChars = lowerResponse.Trim() == ">";
            var containsNoData = lowerResponse.Contains("no data") || lowerResponse.Contains("?");

            //no data is valid response
            if (containsNoData)
            {
                return true;
            }

            //if is data command then validate data length
            if (what.IsDataCommand && this.ResolveData(response, what) == null)
            {
                return false;
            }

            //for normal command
            return rightLength && !containsError && !containsUnknownChars;
        }
        /// <summary>
        /// Receive data from device
        /// </summary>
        /// <param name="what"></param>
        /// <param name="start"></param>
        /// <returns></returns>
        private async Task<OdbResponse> receiveDataFromDevice(OdbPid what, DateTime start)
        {            
            //await for response
            await Task.Delay(this.getReponseByPid(what));

            //create response
            OdbResponse odbResponse = new OdbResponse();
            odbResponse.Pid = what;

            try
            {
                //reader
                uint loaded = await reader.LoadAsync(BUFFER_STEP);

                String response = reader.ReadString(reader.UnconsumedBufferLength);
                while (loaded == BUFFER_STEP)
                {
                    loaded = await reader.LoadAsync(BUFFER_STEP);
                    response += reader.ReadString(reader.UnconsumedBufferLength);
                }
                odbResponse.Response = this.clearResponse(response, what);
                odbResponse.IsValid = this.isValidResponse(response, what);
            }
            catch
            {
                odbResponse.Response = "";
                odbResponse.IsValid = false;
            }

            odbResponse.Time = DateTime.Now.Subtract(start);

            return odbResponse;
        }
 /// <summary>
 /// Send message and check response
 /// </summary>
 /// <param name="what"></param>
 /// <returns></returns>
 public async Task<OdbResponse> SendAndCheck(OdbPid what)
 {
     OdbResponse response = await this.Send(what);
     if (!response.Response.Contains(what.ExpectedResponse))
     {
         throw new OdbException(OdbError.WrongResponseFromDevice);
     }
     return response;
 }
 /// <summary>
 /// Check if pid is supported for ecu
 /// </summary>
 /// <param name="ecu"></param>
 /// <param name="pid"></param>
 /// <returns></returns>
 public Boolean IsPidSupportedForEcu(Ecu ecu, OdbPid pid)
 {
     if (supportedPids.ContainsKey(ecu.EcuId))
     {
         var modes = supportedPids[ecu.EcuId];
         if (modes.ContainsKey(pid.Mode))
         {
             var pids = modes[pid.Mode];
             return pids.Contains(pid.GetPidIdInDecimal());
         }
     }
     return false;
 }
Exemple #13
0
        /// <summary>
        /// Clear response message
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private string clearResponse(string response, OdbPid what)
        {
            response = response.Replace("\r", " ");

            String[] lines = response.Split('\n');
            for (int i = lines.Length - 1; i >= 0; i--)
            {
                String line = lines[i];
                line = line.Replace("\n", " ");
                line = line.Replace(">", "");
                line = line.Replace(what.Pid, "");
                line = line.Trim();

                if (line.Length > 0)
                {
                    return line;
                }
            }
            return lines.Last().Trim();
        }
Exemple #14
0
        /// <summary>
        /// Parse data for specified pid
        /// </summary>
        /// <param name="odbPid"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private Double parseDataForSpecifiedPid(OdbPid odbPid, OdbData data)
        {
            int A = -1, B = -1, C = -1, D = -1;
            int length = data.Data.Length;

            if (length > 4 || length == 0) 
            {
                throw new OdbException(OdbError.IncorrectDataLength);
            }

            if (length >= 4) 
            {
                D = Convert.ToInt32(data.Data[3], 16);
            }
            if (length >= 3) 
            {
                C = Convert.ToInt32(data.Data[2], 16);
            }
            if (length >= 2) 
            {
                B = Convert.ToInt32(data.Data[1], 16);
            }
            if (length >= 1) 
            {
                A = Convert.ToInt32(data.Data[0], 16);
            }

            return odbPid.Compute(A, B, C, D);
        }
 /// <summary>
 /// Get response for
 /// </summary>
 /// <param name="client"></param>
 /// <param name="odbPid"></param>
 /// <param name="action"></param>
 private void getResponseFor(OdbClient client, OdbPid odbPid, Action<Double> action)
 {
     var response = client.RequestFor(odbPid);
     if (response != null)
     {
         action(response.Data);
     }
 }
        /// <summary>
        /// Register supported pids
        /// </summary>
        /// <param name="ecuIdentifier"></param>
        /// <param name="odbPid"></param>
        /// <param name="pids"></param>
        private void RegisterSupportedPids(int ecuIdentifier, OdbPid odbPid, List<int> pids)
        {
            if (!supportedPids.ContainsKey(ecuIdentifier))
            {
                supportedPids.Add(ecuIdentifier, new Dictionary<OdbPid, List<int>>());
            }

            Dictionary<OdbPid, List<int>> supportedPidsForEcu = supportedPids[ecuIdentifier];
            if (supportedPidsForEcu.ContainsKey(odbPid))
            {
                var pidsSupported = supportedPidsForEcu[odbPid];
                supportedPidsForEcu[odbPid] = pidsSupported.Concat(pids).ToList();
            }
            else
            {
                supportedPidsForEcu.Add(odbPid, pids);
            }
        }
 /// <summary>
 /// Clear line
 /// </summary>
 /// <param name="what"></param>
 /// <param name="line"></param>
 /// <returns></returns>
 private string clearLine(OdbPid what, String line)
 {
     line = line.Replace("\n", " ");
     line = line.Replace(">", "");
     line = line.Replace(what.Pid, "");
     line = line.Trim();
     return line;
 }
        /// <summary>
        /// Send message, return bytes response
        /// </summary>
        /// <param name="what"></param>
        /// <returns></returns>
        public async Task<OdbResponse> Send(OdbPid what)
        {
            if (!this.IsConnected)
            {
                throw new OdbException(OdbError.DeviceIsNotConnected);
            }

            //timer
            DateTime start = DateTime.Now;

            //send
            try
            {
                writer.WriteString(what.Pid + "\r\r");
                await writer.StoreAsync();
                await writer.FlushAsync();
            }
            catch
            {
                this.IsConnected = false;
                throw new OdbException(OdbError.DeviceIsNotConnected);
            }

            //receive data from device
            OdbResponse odbResponse = await receiveDataFromDevice(what, start);

            //try again on error reponse
            while (!odbResponse.IsValid && this.tryCount > 0)
            {
                reporter.ReportInfo("Incorrect response '" + odbResponse.Response + "' from device. Try another request. Current try step is " + this.tryCount + ".");
                odbResponse = await receiveDataFromDevice(what, start);
                this.tryCount--;
            }
            this.tryCount = RESPONSE_TRY_COUNT;

            //report response to console
            reporter.ReportResponse(odbResponse);

            return odbResponse;
        }
 /// <summary>
 /// Get response time what for pid
 /// </summary>
 /// <param name="what"></param>
 /// <returns></returns>
 private int getReponseByPid(OdbPid what)
 {
     if (what.IsElmCommand)
     {
         return 500;
     }
     return 250;
 }
 /// <summary>
 /// Get data for pid
 /// </summary>
 /// <param name="pid"></param>
 /// <returns></returns>
 public void UnregisterQuery(OdbPid pid)
 {
     //remove query from databaze
     if (queryResponses.ContainsKey(pid))
     {
         queryResponses.Remove(pid);
         reporter.ReportDeleteQuery(pid);
     }
 }