protected virtual byte?ResolveMode <T>() where T : class, IOBDData { if (!ModeCache.TryGetValue(typeof(T), out byte?mode)) { mode = AddToModeCache <T>(); } return(mode); }
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); }