Esempio n. 1
0
        protected virtual byte?ResolveMode <T>()
            where T : class, IOBDData
        {
            if (!ModeCache.TryGetValue(typeof(T), out byte?mode))
            {
                mode = AddToModeCache <T>();
            }

            return(mode);
        }
Esempio n. 2
0
        protected override object ProcessMessage(string message)
        {
            if (message == null)
            {
                return(null);
            }

            DateTime timestamp = DateTime.Now;

            RawDataReceived?.Invoke(this, new RawDataReceivedEventArgs(message, timestamp));

            if (message.ToUpper() == "CAN ERROR")
            {
                CanError?.Invoke(this, new CanErrorEventArgs {
                    Message = message
                });
            }
            else if (message.Length > 4)
            {
                // DarthAffe 15.08.2020: Splitted messages are prefixed with 0: (first chunk) and 1: (second chunk)
                // DarthAffe 15.08.2020: They also seem to be always preceded by a '009'-message, but since that's to short to be processed it should be safe to ignore.
                // DarthAffe 15.08.2020: Since that behavior isn't really documented (at least I wasn't able to find it) that's all trial and error and might not work for all pids with long results.
                if (message[1] == ':')
                {
                    if (message[0] == '0')
                    {
                        MessageChunk = message.Substring(2, message.Length - 2);
                    }
                    else if (message[0] == '1')
                    {
                        string fullMessage = MessageChunk + message.Substring(2, message.Length - 2);
                        MessageChunk = null;
                        return(ProcessMessage(fullMessage));
                    }
                }
                else
                {
                    string resModeStr = message.Substring(0, 2);
                    try
                    {
                        byte resMode = Convert.ToByte(resModeStr, 16);

                        if (resMode == GetModeByte() + 0x40 || ModeCache.ContainsValue((byte)(resMode - 0x40)))
                        {
                            byte pid     = (byte)message.Substring(2, 2).GetHexVal();
                            int  longPid = message.Substring(2, 4).GetHexVal();
                            if (DataTypeCache.TryGetValue(longPid, out Type dataType) || DataTypeCache.TryGetValue(pid, out dataType))
                            {
                                if (ModeCache.TryGetValue(dataType, out var modeByte) && (modeByte ?? GetModeByte()) != resMode - 0x40)
                                {
                                    // Mode didn't match PID
                                    return(null);
                                }

                                IOBDData obdData = (IOBDData)Activator.CreateInstance(dataType);
                                bool     isLong  = obdData.PID == longPid;
                                int      start   = isLong ? 6 : 4;
                                obdData.Load(message.Substring(start, message.Length - start));

                                if (DataReceivedEventHandlers.TryGetValue(dataType, out IDataEventManager dataEventManager))
                                {
                                    dataEventManager.RaiseEvent(this, obdData, timestamp);
                                }

                                if (DataReceivedEventHandlers.TryGetValue(typeof(IOBDData), out IDataEventManager genericDataEventManager))
                                {
                                    genericDataEventManager.RaiseEvent(this, obdData, timestamp);
                                }

                                return(obdData);
                            }
                        }
                    }
                    catch (FormatException)
                    {
                        // Ignore format exceptions from convert
                    }
                }
            }

            return(null);
        }