示例#1
0
 private void AnalysisMessage(string cacheResult)
 {
     dbcMessage            = new DBCMessage();
     cacheResult           = cacheResult.Substring(cacheResult.IndexOf('_') + 1).TrimStart();
     dbcMessage.FrameID    = int.Parse(cacheResult.Substring(0, cacheResult.IndexOf(' ')));
     cacheResult           = cacheResult.Substring(cacheResult.IndexOf(' ') + 1).TrimStart();
     dbcMessage.FrameName  = cacheResult.Substring(0, cacheResult.IndexOf(':'));
     cacheResult           = cacheResult.Substring(cacheResult.IndexOf(':') + 1).TrimStart();
     dbcMessage.MessageLen = int.Parse(cacheResult.Substring(0, cacheResult.IndexOf(' ')));
     cacheResult           = cacheResult.Substring(cacheResult.IndexOf(' ') + 1).TrimStart();
     dbcMessage.Sender     = cacheResult.Substring(0).TrimEnd();
     dbcMessageList.Add(dbcMessage);
 }
示例#2
0
        /// <summary>
        /// Parse the given DBCFile string into the librarys.
        /// </summary>
        /// <param name="s">The string to parse.</param>
        private void Parse(string s)
        {
            NS_Lib       = new Dictionary <string, int>();
            BS_Lib       = new Dictionary <string, int>();
            MsgSendTypes = new Dictionary <int, string>();
            ecus         = new Dictionary <string, DBCECU>();
            messages     = new Dictionary <string, DBCMessage>();
            attributes   = new Dictionary <string, Dictionary <string, List <string> > >();
            signalGroups = new Dictionary <string, List <IDBCSignal> >();

            #region --- Strings for matches ---
            string NS         = @"NS_[\t ]*:[\r\t ]*\n(\t[\w]+[\r\t ]*\n)*";
            string BU         = @"BU_\s *:(\s +.*)*";
            string BOline     = @"BO_\s+\d+\s+\w+:\s*\d+\s+\w+";
            string SGline     = @"SG_\s+\w+\s*\w*\s*:\s*\d+\|\d+@[01][+-]\s+\([\d.-]*,[\d.-]*\)\s+\[.*\|.*\]\s+"".*""(\s+\w+,*\s*)+";
            string BO         = BOline + @"\s+(" + SGline + @")*";
            string CM         = @"CM_\s+\w+\s+\w+(\s+\w+)*\s+""([^""]*)*""";
            string BA_DEF     = @"BA_DEF_\s+.*;";
            string BA_DEF_DEF = @"BA_DEF_DEF_\s+.*;";
            string BA         = @"BA_\s+.*;";
            string VAL        = @"VAL_\s+.*;";
            //string SIG_GROUP = @"";
            #endregion

            // init some values
            string[] tmp = new string[0];
            int      i = -1, DataLength = 0;
            string   ECU_Name = "", Msg_Name = "", Snl_name = "", MsgIDHex = "";
            string   AttributeName = "", AttributeValue = "";
            try
            {
                #region --- New Symbols ---
                foreach (Match m in Regex.Matches(s, NS))
                {
                    // Remove NS_ and split by whitespace
                    string[] keys = m.Value.Split('\n');

                    // Add to NS lib if not already there
                    for (int ki = 1; ki < keys.Length; ki++)
                    {
                        if (!NS_Lib.ContainsKey(keys[ki]) && !string.IsNullOrEmpty(keys[ki]))
                        {
                            NS_Lib.Add(keys[ki], NS_Lib.Count);
                        }
                    }
                }
                #endregion

                #region --- ECUs ---
                foreach (Match m in Regex.Matches(s, BU))
                {
                    // Remove BU_ and split by whitespace
                    tmp = Regex.Split(m.Value.Replace("BU_", ""), @"\s+");

                    // Add to ECU libs
                    foreach (string str in tmp)
                    {
                        if (!ecus.ContainsKey(str))
                        {
                            //ECU_Lib.Add(str, ECU_Lib.Count);
                            ecus.Add(str, new DBCECU(tmp[i]));
                        }
                    }
                }
                #endregion

                #region --- Messages & Signals ---
                foreach (Match m in Regex.Matches(s, BO))
                {
                    // Deal with Message line: BO_ Tag | Message ID | Message Name | Message Length (bytes) | ECU
                    string messageLine = Regex.Match(m.Value, BOline).Value;

                    //split by whitespace
                    tmp = Regex.Split(messageLine.Replace(":", ""), @"\s+");

                    // Message Attributes
                    ECU_Name = tmp[4];
                    Msg_Name = tmp[2];
                    int midLen = tmp[1].Length > 4 ? 4 : 2;
                    MsgIDHex   = "0x" + Convert.ToInt64(tmp[1]).ToString("X3");
                    DataLength = Convert.ToInt32(tmp[3]);


                    //If ECU doesn't exist, create it
                    if (!ecus.ContainsKey(ECU_Name))
                    {
                        ecus.Add(ECU_Name, new DBCECU(ECU_Name));
                    }

                    // Add a new message
                    var newMessage = new DBCMessage(midLen + DataLength, ecus[ECU_Name], MsgIDHex, Msg_Name);
                    messages.Add(MsgIDHex, newMessage);

                    // Add message to Messages dictionary in current ECU
                    if (!ecus[ECU_Name].Messages.ContainsKey(MsgIDHex))
                    {
                        ecus[ECU_Name].Messages[MsgIDHex] = (IDBCMessage)newMessage;
                    }

                    // Deal with signal line:
                    // SG_ Tag | Signal ID | Optional Multiplexer | Start Bit + Length (bits) + Byte Direction | (Factor, Offset) | Physical Range [min,max] | Physical Units | Response ECU
                    foreach (Match sig in Regex.Matches(m.Value, SGline))
                    {
                        int multiplexer = 0; // 1 if there is a multiplexer, 0 if not
                        if (Regex.IsMatch(sig.Value, @"\w+\s+\w+\s+\w+\s*:"))
                        {
                            multiplexer = 1;
                        }

                        tmp = Regex.Split(Regex.Replace(sig.Value, @"[\(\)\[\]\|""@,:]", " "), @"\s+");

                        Snl_name = tmp[1];

                        // Signal Attributes
                        int           startBit   = Convert.ToInt32(tmp[2 + multiplexer]);
                        int           length     = Convert.ToInt32(tmp[3 + multiplexer]);
                        IntDescriptor descriptor = (tmp[4 + multiplexer][1] == '+') ? IntDescriptor.Unsigned : IntDescriptor.Signed;
                        ByteOrder     byteOrder;
                        if (tmp[4 + multiplexer][0] == '1')
                        {
                            byteOrder = ByteOrder.Intel;
                        }
                        else
                        {
                            byteOrder = ByteOrder.Motorola;
                        }
                        double factor    = Convert.ToDouble(tmp[5 + multiplexer], System.Globalization.CultureInfo.InvariantCulture);
                        double offset    = Convert.ToDouble(tmp[6 + multiplexer], System.Globalization.CultureInfo.InvariantCulture);
                        double physMin   = Convert.ToDouble(tmp[7 + multiplexer], System.Globalization.CultureInfo.InvariantCulture);
                        double physMax   = Convert.ToDouble(tmp[8 + multiplexer], System.Globalization.CultureInfo.InvariantCulture);
                        string physUnits = tmp[9 + multiplexer];

                        //If physMin and physMax are both 0, then physMax is as high as the largest bitvalue
                        physMax = (physMin == 0 && physMax == 0) ? (1 << length) : physMax;

                        // These values should be 0 and (2 << length - 1)
                        ulong  normMin = (ulong)((physMin - offset) / factor);
                        ulong  normMax = (ulong)((physMax - offset) / factor);
                        double res     = (physMax - physMin) / (normMax - normMin);
                        if (double.IsInfinity(res) || double.IsNaN(res))
                        {
                            res = 1;
                        }

                        // Responce ECUs
                        for (i = 10 + multiplexer; i < tmp.Length; i++)
                        {
                            if (!ecus.ContainsKey(tmp[i]))
                            {
                                ecus.Add(tmp[i], new DBCECU(tmp[i]));
                            }
                            if (!ecus[tmp[i]].RxMessages.ContainsKey(MsgIDHex))
                            {
                                ecus[tmp[i]].RxMessages.Add(MsgIDHex, messages[MsgIDHex]);
                            }
                        }

                        int old = startBit;

                        // TODO: verify this is needed.
                        // account for motorola being inverse
                        if (byteOrder == ByteOrder.Motorola)
                        {
                            int newStartBit = startBit;
                            for (i = 1; i < length; i++)
                            {
                                if (newStartBit % 8 == 0)
                                {
                                    newStartBit += 15;
                                }
                                else
                                {
                                    newStartBit -= 1;
                                }
                            }
                            startBit = newStartBit;
                        }

                        // Add a new signal
                        messages[MsgIDHex].Signals.Add(Snl_name, new DBCSignal(ecus[ECU_Name],
                                                                               messages[MsgIDHex], (uint)startBit, Snl_name, (uint)length, 0, 0,
                                                                               physMax, physMin, normMax, normMin, res, physUnits, descriptor,
                                                                               byteOrder, offset, sig.Value));
                    }
                }



                #endregion

                #region --- Functionality Description (comments) ---
                foreach (Match m in Regex.Matches(s, CM))
                {
                    /*  Note:
                     *  Only existing signals can have comments parsed for them,
                     *  there is no way to generate a new signal or message from
                     *  a comment statement. */

                    if (Regex.IsMatch(m.Value, @"SG_ "))
                    {
                        tmp      = Regex.Split(m.Value, @"\s+");
                        MsgIDHex = "0x" + Convert.ToInt64(tmp[2]).ToString("X3");
                        if (messages.ContainsKey(MsgIDHex))
                        {
                            Snl_name = tmp[3];
                            if (messages[MsgIDHex].Signals.ContainsKey(Snl_name))
                            {
                                string function = "";
                                for (i = 4; i < tmp.Length; i++)
                                {
                                    function += (tmp[i] + " ").Replace("\"", "");
                                }
                                ((DBCSignal)messages[MsgIDHex].Signals[Snl_name]).Function = function;
                            }
                        }
                    }
                }
                #endregion

                #region --- Base Attribute Definitions ---
                foreach (Match m in Regex.Matches(s, BA_DEF))
                {
                    string        attributeName;
                    string        attributeType;
                    string        tag = "Definition";
                    List <string> attributeSettings = new List <string>();
                    tmp = Regex.Split(m.Value, @"\s+");

                    if (Regex.IsMatch(m.Value, @"BU_"))
                    {
                        attributeName = tmp[2].Replace("\"", "");
                        attributeType = tmp[3];
                        for (int j = 4; j < tmp.Length; j++)
                        {
                            attributeSettings.Add(tmp[j].Replace(";", ""));
                        }
                    }
                    else if (Regex.IsMatch(m.Value, @"BO_"))
                    {
                        attributeName = tmp[2].Replace("\"", "");
                        attributeType = tmp[3];
                        for (int j = 4; j < tmp.Length; j++)
                        {
                            attributeSettings.Add(tmp[j].Replace(";", ""));
                        }

                        // OG code... fix in future
                        switch (attributeName)
                        {
                        case "GenMsgSendType":      //Message send type(cyclic, spontaneous, etc..)
                            string[] values = tmp[tmp.Length - 1].Split(',');
                            for (int k = 0; k < values.Length; k++)
                            {
                                //k is Enum int value, values[k] is string it represents
                                MsgSendTypes.Add(k, values[k].Replace("\"", "").Replace(";", ""));
                            }
                            break;

                        case "GenMsgCycleTime":
                            break;

                        case "GenMsgStartDelayTime":
                            break;

                        case "GenMsgDelayTime":
                            break;

                        default:
                            break;
                        }
                    }
                    else if (Regex.IsMatch(m.Value, @"SG_ "))
                    {
                        attributeName = tmp[2].Replace("\"", "");
                        attributeType = tmp[3];
                        for (int j = 4; j < tmp.Length; j++)
                        {
                            attributeSettings.Add(tmp[j].Replace(";", ""));
                        }
                    }
                    else
                    {
                        // extract info
                        attributeName = tmp[1].Replace("\"", "");
                        attributeType = tmp[2];
                        for (int j = 3; j < tmp.Length; j++)
                        {
                            attributeSettings.Add(tmp[j].Replace(";", ""));
                        }

                        // add to dict
                        if (attributes.ContainsKey(attributeName))
                        {
                            if (attributes[attributeName].ContainsKey(tag))
                            {
                                attributes[attributeName][tag].Concat(attributeSettings);
                            }
                            else
                            {
                                attributes[attributeName].Add(tag, attributeSettings);
                            }
                        }
                        else
                        {
                            attributes.Add(attributeName, new Dictionary <string, List <string> >());
                            attributes[attributeName].Add(tag, attributeSettings);
                        }
                    }
                }
                #endregion

                #region --- Base Attribute Definitions Defaults ---
                foreach (Match m in Regex.Matches(s, BA_DEF_DEF))
                {
                    string tag = "Default";
                    tmp = Regex.Split(Regex.Replace(m.Value, @"[;""]", ""), @"\s+");
                    if (tmp.Length < 3)
                    {
                        continue;
                    }
                    string attr = tmp[1];
                    string val  = tmp[2];

                    if (attributes.ContainsKey(attr))
                    {
                        if (attributes[attr].ContainsKey(tag))
                        {
                            attributes[attr][tag].Add(val);
                        }
                        else
                        {
                            attributes[attr].Add(tag, new List <string>()
                            {
                                val
                            });
                        }
                    }
                    else
                    {
                        attributes.Add(attr, new Dictionary <string, List <string> >()
                        {
                            { tag, new List <string>()
                              {
                                  val
                              } }
                        });
                    }
                }
                #endregion

                #region --- Base Attributes ---
                foreach (Match m in Regex.Matches(s, BA))
                {
                    string        tag = "Setting";
                    string        attributeName;
                    string        attributeValue;
                    List <string> attributeSettings = new List <string>();

                    //modified regex check to ignore spaces inside of quotes
                    tmp = Regex.Split(m.Value, "(?<=^[^\"]*(?:\"[^\"]*\"[^\"]*)*) (?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

                    if (Regex.IsMatch(tmp[2], @"BO_"))
                    {
                        MsgIDHex = "0x" + Convert.ToInt64(tmp[3]).ToString("X3");

                        //Handle attributes if MsgID exists
                        if (messages.ContainsKey(MsgIDHex))
                        {
                            attributeName  = tmp[1].Replace("\"", "");
                            attributeValue = tmp[4].Replace(";", "");
                            switch (attributeName)
                            {
                            case "GenMsgCycleTime":     //Cycle time
                                messages[MsgIDHex].CycleTime = uint.Parse(attributeValue);
                                break;

                            case "GenMsgSendType":     //Launch type(cyclic, spontaneous, etc.)
                                messages[MsgIDHex].LaunchType = MsgSendTypes[int.Parse(attributeValue)];
                                break;

                            case "GenMsgDelayTime":
                                messages[MsgIDHex].DelayTime = int.Parse(attributeValue);
                                break;
                            }
                        }
                    }
                    else if (Regex.IsMatch(m.Value, @"SG_ "))
                    {
                        MsgIDHex = "0x" + Convert.ToInt64(tmp[3]).ToString("X3");
                        Snl_name = tmp[4];

                        AttributeName  = tmp[1].Replace("\"", "");
                        AttributeValue = "";
                        for (i = 5; i < tmp.Length; i++)
                        {
                            AttributeValue += (tmp[i] + " ").Replace("\"", "").Replace(";", "");
                        }

                        // Check and add
                        if (messages.ContainsKey(MsgIDHex) &&
                            messages[MsgIDHex].Signals.ContainsKey(Snl_name))
                        {
                            ((DBCSignal)messages[MsgIDHex].Signals[Snl_name]).Attributes.Add(AttributeName, AttributeValue);
                        }
                    }
                    else
                    {
                        if (attributes.ContainsKey(tmp[1]))
                        {
                            if (attributes[tmp[1]].ContainsKey(tag))
                            {
                                attributes[tmp[1]][tag].Add(tmp[2]);
                            }
                            else
                            {
                                attributes[tmp[1]].Add(tag, new List <string>()
                                {
                                    tmp[2]
                                });
                            }
                        }
                        else
                        {
                            attributes.Add(tmp[1], new Dictionary <string, List <string> >()
                            {
                                { tag, new List <string>()
                                  {
                                      tmp[2]
                                  } }
                            });
                        }
                        //break;
                    }
                }
                #endregion

                #region --- Specified Signal Values ---

                foreach (Match m in Regex.Matches(s, VAL))
                {
                    tmp      = Regex.Split(m.Value, @"\s+");
                    MsgIDHex = "0x" + Convert.ToInt64(tmp[1]).ToString("X3");
                    Snl_name = tmp[2];

                    foreach (Match val in Regex.Matches(m.Value, "\\d+\\s+\".*?\""))
                    {
                        tmp = Regex.Split(val.Value.Replace("\"", " "), @"\s+");

                        long key = long.Parse(tmp[0]);
                        tmp[0] = "";
                        string specifiedValue = string.Join <string>(" ", tmp).Trim();

                        // Check and add
                        if (messages.ContainsKey(MsgIDHex) &&
                            messages[MsgIDHex].Signals.ContainsKey(Snl_name))
                        {
                            if (messages[MsgIDHex].Signals[Snl_name].SpecifiedValues.ContainsKey(key))
                            {
                                ((DBCSignal)messages[MsgIDHex].Signals[Snl_name]).SpecifiedValues[key] = specifiedValue;
                            }
                            else
                            {
                                ((DBCSignal)messages[MsgIDHex].Signals[Snl_name]).SpecifiedValues.Add(key, specifiedValue);
                            }
                        }
                    }
                }

                #endregion
            }
            catch (DatabaseLoadingException)
            {
                throw;
            }

            /*catch (Exception e)
             * {
             *  throw new DatabaseLoadingException("Parsing of the given DBC file failed.", e, this, "");
             * }*/

            #region old code section for Signal Groups

            /*
             *  OG SIG_GROUP_ parsing below
             *
             #region SIG_GROUP_ (Signal Groupings)
             *          case "SIG_GROUP_":
             *
             *              // Remove the tag and use space as a delimiter
             *              tmp = AcquireValues(str);
             *
             *              MsgIDHex = "0x" + Convert.ToInt64(tmp[1]).ToString("X3");
             *              ECU_name = MsgID_to_ECUname[MsgIDHex];
             *              string Group_name = tmp[2];
             *
             *              for (int itm = 5; itm < tmp.Length; itm++)
             *              {
             *                  Snl_name = tmp[itm];
             *                  if (SignalGroups.ContainsKey(Group_name))
             *                      SignalGroups[Group_name].Add(Messages[MsgIDHex].Signals[Snl_name]);
             *                  else
             *                      SignalGroups.Add(Group_name, new List<IDBCSignal>() { Messages[MsgIDHex].Signals[Snl_name] });
             *              }
             *
             *              break;
             #endregion
             * }
             */
            #endregion
        }
示例#3
0
        /// <summary>
        /// 加载DBC Signal
        /// </summary>
        /// <param name="content">当前行内容</param>
        /// <param name="message">当前消息</param>
        private void LoadSignal(String content, ref DBCMessage message)
        {
            var match = Regex.Match(content.Trim(), ConstDefine.SignalRegexPattern);

            if (!match.Success)
            {
                //TODO 应该添加Log
                return;
            }
            UInt16    tempUInt16;
            Double    tempDouble;
            DBCSignal signal = new DBCSignal();
            ByteOrder byteOrder;

            if (!Enum.TryParse <ByteOrder>(match.Groups[9].Value, out byteOrder))
            {
                byteOrder = ByteOrder.None;
            }
            signal.ByteOrder = byteOrder;
            if (!Double.TryParse(match.Groups[11].Value, out tempDouble))
            {
                tempDouble = 0D;
            }
            signal.Factor = tempDouble;
            if (!Double.TryParse(match.Groups[17].Value, out tempDouble))
            {
                tempDouble = 0D;
            }
            signal.Maximum     = tempDouble;
            signal.Message     = message;
            signal.MessageID   = message.MessageID;
            signal.MessageName = message.MessageName;
            if (!Double.TryParse(match.Groups[15].Value, out tempDouble))
            {
                tempDouble = 0D;
            }
            signal.Minimum = tempDouble;
            if (String.IsNullOrEmpty(match.Groups[2].Value))
            {
                signal.MultiplexerIndicator = MultiplexerIndicator.NormalSignal;
            }
            else if (match.Groups[6].Value == "M ")
            {
                signal.MultiplexerIndicator = MultiplexerIndicator.MultiplexedSignal;
            }
            else if (match.Groups[4].Value == "m")
            {
                signal.MultiplexerIndicator = MultiplexerIndicator.MultiplexedSignals;
                if (!UInt16.TryParse(match.Groups[5].Value, out tempUInt16))
                {
                    tempUInt16 = 0;
                }
                signal.MultiplexerSwitchValue = tempUInt16;
            }
            else
            {
                signal.MultiplexerIndicator = MultiplexerIndicator.NormalSignal;
            }
            if (!Double.TryParse(match.Groups[13].Value, out tempDouble))
            {
                tempDouble = 0D;
            }
            signal.Offset     = tempDouble;
            signal.SignalName = match.Groups[1].Value;
            if (!UInt16.TryParse(match.Groups[8].Value, out tempUInt16))
            {
                tempUInt16 = 0;
            }
            signal.SignalSize = tempUInt16;
            if (!UInt16.TryParse(match.Groups[7].Value, out tempUInt16))
            {
                tempUInt16 = 0;
            }
            signal.StartPosition = tempUInt16;
            signal.Unit          = match.Groups[19].Value;
            if (match.Groups[10].Value == "+")
            {
                signal.ValueType = Infrastructure.ValueType.Unsigned;
            }
            else if (match.Groups[10].Value == "-")
            {
                signal.ValueType = Infrastructure.ValueType.Signed;
            }
            else
            {
                signal.ValueType = Infrastructure.ValueType.Unsigned;
            }
            message.Signals.Add(signal);
        }
示例#4
0
        /// <summary>
        /// 加载DBC Message
        /// </summary>
        /// <param name="content">当前行内容</param>
        /// <param name="reader">当前文件流</param>
        private void LoadMessage(String content, StreamReader reader)
        {
            DBCMessage message = new DBCMessage();

            //起始索引
            Int32 preIndex = 0;

            //终止索引

            //获取分隔符位置,开始解析
            preIndex = content.IndexOf(" ", preIndex) + 1;
            var index = content.IndexOf(" ", preIndex);

            #region 获取Message ID

            String id = content.Substring(preIndex, index - preIndex);
            UInt32 messageId;
            if (!UInt32.TryParse(id, out messageId))
            {
                messageId = 0;
            }
            messageId        &= 0x9FFFFFFF;
            message.MessageID = messageId;

            #endregion

            #region 判断消息帧类型

            UInt32 frameType = messageId >> 31;
            if (frameType == 0)
            {
                message.FrameType = FrameType.StandardFrame;
            }
            else
            {
                message.FrameType = FrameType.ExtendFrame;
            }
            #endregion

            #region 获取消息Name

            preIndex            = index + 1;
            index               = content.IndexOf(":", preIndex);
            message.MessageName = content.Substring(preIndex, index - preIndex);

            #endregion

            #region 获取消息 Size (dlc)

            preIndex = index + 2;
            index    = content.IndexOf(" ", preIndex);
            UInt32 size;
            if (!UInt32.TryParse(content.Substring(preIndex, index - preIndex), out size))
            {
                size = 0;
            }
            message.MessageSize = size;

            #endregion

            #region 获取发送节点Name

            preIndex            = index + 1;
            index               = content.IndexOf("", preIndex);
            message.Transmitter = content.Substring(index, content.Length - index);

            #endregion

            #region 将消息添加至节点

            foreach (var node in this.DBCChannel.Nodes)
            {
                if (message.Transmitter == node.NodeName)
                {
                    var nextContent = reader.ReadLine();
                    while (nextContent != null)
                    {
                        if (String.IsNullOrEmpty(nextContent))
                        {
                            break;
                        }
                        LoadSignal(nextContent, ref message);
                        nextContent = reader.ReadLine();
                    }
                    node.Messages.Add(message);
                    break;
                }
            }

            #endregion
        }