github.com/blueinnovationsgroup/can-go@v0.0.0-20230518195432-d0567cda0028/pkg/dbc/def.go (about) 1 package dbc 2 3 import ( 4 "strconv" 5 "text/scanner" 6 ) 7 8 // Def represents a single definition within a DBC file. 9 type Def interface { 10 // Position of the definition. 11 Position() scanner.Position 12 13 // parseFrom parses the definition from a parser. 14 parseFrom(*Parser) 15 } 16 17 // VersionDef defines the version of a DBC file. 18 type VersionDef struct { 19 Pos scanner.Position 20 Version string 21 } 22 23 var _ Def = &VersionDef{} 24 25 func (d *VersionDef) parseFrom(p *Parser) { 26 d.Pos = p.keyword(KeywordVersion).pos 27 d.Version = p.string() 28 } 29 30 // Position returns the position of the definition. 31 func (d *VersionDef) Position() scanner.Position { 32 return d.Pos 33 } 34 35 // NewSymbolsDef defines new symbol entries in a DBC file. 36 type NewSymbolsDef struct { 37 Pos scanner.Position 38 Symbols []Keyword 39 } 40 41 var _ Def = &NewSymbolsDef{} 42 43 func (d *NewSymbolsDef) parseFrom(p *Parser) { 44 p.useWhitespace(significantTab) 45 defer p.useWhitespace(defaultWhitespace) 46 d.Pos = p.keyword(KeywordNewSymbols).pos 47 p.token(':') 48 for p.peekToken().typ == '\t' { 49 p.token('\t') 50 d.Symbols = append(d.Symbols, Keyword(p.identifier())) 51 } 52 } 53 54 // Position returns the position of the definition. 55 func (d *NewSymbolsDef) Position() scanner.Position { 56 return d.Pos 57 } 58 59 // BitTimingDef defines the baud rate and the settings of the BTR registers of a CAN network. 60 // 61 // This definition is obsolete and not used anymore. 62 type BitTimingDef struct { 63 Pos scanner.Position 64 BaudRate uint64 65 BTR1 uint64 66 BTR2 uint64 67 } 68 69 var _ Def = &BitTimingDef{} 70 71 func (d *BitTimingDef) parseFrom(p *Parser) { 72 d.Pos = p.keyword(KeywordBitTiming).pos 73 p.token(':') 74 d.BaudRate = p.optionalUint() 75 if p.peekToken().typ == ':' { 76 d.BTR1 = p.optionalUint() 77 } 78 if p.peekToken().typ == ',' { 79 d.BTR2 = p.optionalUint() 80 } 81 } 82 83 // Position returns the position of the definition. 84 func (d *BitTimingDef) Position() scanner.Position { 85 return d.Pos 86 } 87 88 // NodesDef defines the names of all nodes participating in the network. 89 // 90 // This definition is required in every DBC file. 91 // 92 // All node names must be unique. 93 type NodesDef struct { 94 Pos scanner.Position 95 NodeNames []Identifier 96 } 97 98 var _ Def = &NodesDef{} 99 100 func (d *NodesDef) parseFrom(p *Parser) { 101 p.useWhitespace(significantNewline) 102 defer p.useWhitespace(defaultWhitespace) 103 d.Pos = p.keyword(KeywordNodes).pos 104 p.token(':') 105 for p.peekToken().typ == scanner.Ident { 106 d.NodeNames = append(d.NodeNames, p.identifier()) 107 } 108 if p.peekToken().typ != scanner.EOF { 109 p.token('\n') 110 } 111 } 112 113 // Position returns the position of the definition. 114 func (d *NodesDef) Position() scanner.Position { 115 return d.Pos 116 } 117 118 // ValueDescriptionDef defines a textual description for a single signal value. 119 // 120 // The value may either be a signal raw value transferred on the bus or the value of an environment variable in a 121 // remaining bus simulation. 122 type ValueDescriptionDef struct { 123 Pos scanner.Position 124 Value float64 125 Description string 126 } 127 128 var _ Def = &ValueDescriptionDef{} 129 130 func (d *ValueDescriptionDef) parseFrom(p *Parser) { 131 d.Pos = p.peekToken().pos 132 d.Value = p.float() 133 d.Description = p.string() 134 } 135 136 // Position returns the position of the definition. 137 func (d *ValueDescriptionDef) Position() scanner.Position { 138 return d.Pos 139 } 140 141 // ValueTableDef defines a global value table. 142 // 143 // The value descriptions in value tables define value encodings for signal raw values. 144 // 145 // In commonly used DBC files, the global value tables aren't used, but the value descriptions are defined for each 146 // signal independently. 147 type ValueTableDef struct { 148 Pos scanner.Position 149 TableName Identifier 150 ValueDescriptions []ValueDescriptionDef 151 } 152 153 var _ Def = &ValueTableDef{} 154 155 func (d *ValueTableDef) parseFrom(p *Parser) { 156 d.Pos = p.keyword(KeywordValueTable).pos 157 d.TableName = p.identifier() 158 for p.peekToken().typ != ';' { 159 valueDescriptionDef := ValueDescriptionDef{} 160 valueDescriptionDef.parseFrom(p) 161 d.ValueDescriptions = append(d.ValueDescriptions, valueDescriptionDef) 162 } 163 p.token(';') 164 } 165 166 // Position returns the position of the definition. 167 func (d *ValueTableDef) Position() scanner.Position { 168 return d.Pos 169 } 170 171 // MessageDef defines a frame in the network. 172 // 173 // The definition includes the name of a frame as well as its properties and the signals transferred. 174 type MessageDef struct { 175 // Pos is the position of the message definition. 176 Pos scanner.Position 177 178 // MessageID contains the message CAN ID. 179 // 180 // The CAN ID has to be unique within the DBC file. 181 // 182 // If the most significant bit of the message ID is set, the ID is an extended CAN ID. The extended CAN ID can be 183 // determined by masking out the most significant bit with the mask 0xCFFFFFFF. 184 MessageID MessageID 185 186 // Name is the name of the message. 187 // 188 // The message name has to be unique within the DBC file. 189 Name Identifier 190 191 // Size specifies the size of the message in bytes. 192 Size uint64 193 194 // Transmitter specifies the name of the node transmitting the message. 195 // 196 // The transmitter has to be defined in the set of node names in the nodes definition. 197 // 198 // If the message has no transmitter, the string 'Vector__XXX' has to be given here. 199 Transmitter Identifier 200 201 // Signals specifies the signals of the message. 202 Signals []SignalDef 203 } 204 205 var _ Def = &MessageDef{} 206 207 func (d *MessageDef) parseFrom(p *Parser) { 208 d.Pos = p.keyword(KeywordMessage).pos 209 d.MessageID = p.messageID() 210 d.Name = p.identifier() 211 p.token(':') 212 d.Size = p.uint() 213 d.Transmitter = p.identifier() 214 for p.peekToken().typ != scanner.EOF && p.peekKeyword() == KeywordSignal { 215 signalDef := SignalDef{} 216 signalDef.parseFrom(p) 217 d.Signals = append(d.Signals, signalDef) 218 } 219 } 220 221 // Position returns the position of the definition. 222 func (d *MessageDef) Position() scanner.Position { 223 return d.Pos 224 } 225 226 // SignalDef defines a signal within a message. 227 type SignalDef struct { 228 // Pos is the position of the definition. 229 Pos scanner.Position 230 231 // Name of the signal. 232 // 233 // Has to be unique for all signals within the same message. 234 Name Identifier 235 236 // StartBit specifies the position of the signal within the data field of the frame. 237 // 238 // For signals with byte order Intel (little-endian) the position of the least-significant bit is given. 239 // 240 // For signals with byte order Motorola (big-endian) the position of the most significant bit is given. 241 // 242 // The bits are counted in a saw-tooth manner. 243 // 244 // The start bit has to be in the range of [0 ,8*message_size-1]. 245 StartBit uint64 246 247 // Size specifies the size of the signal in bits. 248 Size uint64 249 250 // IsBigEndian is true if the signal's byte order is Motorola (big-endian). 251 IsBigEndian bool 252 253 // IsSigned is true if the signal is signed. 254 IsSigned bool 255 256 // IsMultiplexerSwitch is true if the signal is a multiplexer switch. 257 // 258 // A multiplexer indicator of 'M' defines the signal as the multiplexer switch. 259 // Only one signal within a single message can be the multiplexer switch. 260 IsMultiplexerSwitch bool 261 262 // IsMultiplexed is true if the signal is multiplexed by the message's multiplexer switch. 263 IsMultiplexed bool 264 265 // MultiplexerSwitch is the multiplexer switch value of the signal. 266 // 267 // The multiplexed signal is transferred in the message if the switch value of the multiplexer signal is equal to 268 // its multiplexer switch value. 269 MultiplexerSwitch uint64 270 271 // Offset is the signals physical value offset. 272 // 273 // Together with the factor, the offset defines the linear conversion rule to convert the signal's raw value into 274 // the signal's physical value and vice versa. 275 // 276 // physical_value = raw_value * factor + offset 277 // raw_value = (physical_value - offset) / factor 278 Offset float64 279 280 // Factor is the signal's physical value factor. 281 // 282 // See: Offset. 283 Factor float64 284 285 // Minimum defines the signal's minimum physical value. 286 Minimum float64 287 288 // Maximum defines the signal's maximum physical value. 289 Maximum float64 290 291 // Unit defines the unit of the signal's physical value. 292 Unit string 293 294 // Receivers specifies the nodes receiving the signal. 295 // 296 // If the signal has no receiver, the string 'Vector__XXX' has to be given here. 297 Receivers []Identifier 298 } 299 300 var _ Def = &SignalDef{} 301 302 func (d *SignalDef) parseFrom(p *Parser) { 303 d.Pos = p.keyword(KeywordSignal).pos 304 d.Name = p.identifier() 305 // Parse: Multiplexing 306 if p.peekToken().typ != ':' { 307 tok := p.nextToken() 308 if tok.typ != scanner.Ident { 309 p.failf(tok.pos, "expected ident") 310 } 311 switch { 312 case tok.txt == "M": 313 d.IsMultiplexerSwitch = true 314 case tok.txt[0] == 'm' && len(tok.txt) > 1: 315 d.IsMultiplexed = true 316 i, err := strconv.Atoi(tok.txt[1:]) 317 if err != nil || i < 0 { 318 p.failf(tok.pos, "invalid multiplexer value") 319 } 320 d.MultiplexerSwitch = uint64(i) 321 default: 322 p.failf(tok.pos, "expected multiplexer") 323 } 324 } 325 p.token(':') 326 d.StartBit = p.uint() 327 p.token('|') 328 d.Size = p.uint() 329 p.token('@') 330 d.IsBigEndian = p.intInRange(0, 1) == 0 331 d.IsSigned = p.anyOf('-', '+') == '-' 332 p.token('(') 333 d.Factor = p.float() 334 p.token(',') 335 d.Offset = p.float() 336 p.token(')') 337 p.token('[') 338 d.Minimum = p.float() 339 p.token('|') 340 d.Maximum = p.float() 341 p.token(']') 342 d.Unit = p.string() 343 // Parse: Receivers 344 d.Receivers = append(d.Receivers, p.identifier()) 345 for p.peekToken().typ == ',' { 346 p.token(',') 347 d.Receivers = append(d.Receivers, p.identifier()) 348 } 349 } 350 351 // Position returns the position of the definition. 352 func (d *SignalDef) Position() scanner.Position { 353 return d.Pos 354 } 355 356 // SignalValueTypeDef defines an extended type definition for a signal. 357 type SignalValueTypeDef struct { 358 Pos scanner.Position 359 MessageID MessageID 360 SignalName Identifier 361 SignalValueType SignalValueType 362 } 363 364 var _ Def = &SignalValueTypeDef{} 365 366 func (d *SignalValueTypeDef) parseFrom(p *Parser) { 367 d.Pos = p.keyword(KeywordSignalValueType).pos 368 d.MessageID = p.messageID() 369 d.SignalName = p.identifier() 370 p.optionalToken(':') // SPECIAL-CASE: colon not part of spec, but encountered in the wild 371 d.SignalValueType = p.signalValueType() 372 p.token(';') 373 } 374 375 // Position returns the position of the definition. 376 func (d *SignalValueTypeDef) Position() scanner.Position { 377 return d.Pos 378 } 379 380 // MessageTransmittersDef defines multiple transmitter nodes of a single message. 381 // 382 // This definition is used to describe communication data for higher layer protocols. 383 // 384 // This is not used to define CAN layer-2 communication. 385 type MessageTransmittersDef struct { 386 Pos scanner.Position 387 MessageID MessageID 388 Transmitters []Identifier 389 } 390 391 var _ Def = &MessageTransmittersDef{} 392 393 func (d *MessageTransmittersDef) parseFrom(p *Parser) { 394 d.Pos = p.keyword(KeywordMessageTransmitters).pos 395 d.MessageID = p.messageID() 396 p.token(':') 397 for p.peekToken().typ != ';' { 398 d.Transmitters = append(d.Transmitters, p.identifier()) 399 // SPECIAL-CASE: Comma not included in spec, but encountered in the wild 400 p.optionalToken(',') 401 } 402 p.token(';') 403 } 404 405 // Position returns the position of the definition. 406 func (d *MessageTransmittersDef) Position() scanner.Position { 407 return d.Pos 408 } 409 410 // ValueDescriptionsDef defines inline descriptions for specific raw signal values. 411 type ValueDescriptionsDef struct { 412 Pos scanner.Position 413 ObjectType ObjectType 414 MessageID MessageID 415 SignalName Identifier 416 EnvironmentVariableName Identifier 417 ValueDescriptions []ValueDescriptionDef 418 } 419 420 var _ Def = &ValueDescriptionsDef{} 421 422 func (d *ValueDescriptionsDef) parseFrom(p *Parser) { 423 d.Pos = p.keyword(KeywordValueDescriptions).pos 424 if p.peekToken().typ == scanner.Ident { 425 d.ObjectType = ObjectTypeEnvironmentVariable 426 d.EnvironmentVariableName = p.identifier() 427 } else { 428 d.ObjectType = ObjectTypeSignal 429 d.MessageID = p.messageID() 430 d.SignalName = p.identifier() 431 } 432 for p.peekToken().typ != ';' { 433 valueDescriptionDef := ValueDescriptionDef{} 434 valueDescriptionDef.parseFrom(p) 435 d.ValueDescriptions = append(d.ValueDescriptions, valueDescriptionDef) 436 } 437 p.token(';') 438 } 439 440 // Position returns the position of the definition. 441 func (d *ValueDescriptionsDef) Position() scanner.Position { 442 return d.Pos 443 } 444 445 // EnvironmentVariableDef defines an environment variable. 446 // 447 // DBC files that describe the CAN communication and don't define any additional data for system or remaining bus 448 // simulations don't include environment variables. 449 type EnvironmentVariableDef struct { 450 Pos scanner.Position 451 Name Identifier 452 Type EnvironmentVariableType 453 Minimum float64 454 Maximum float64 455 Unit string 456 InitialValue float64 457 ID uint64 458 AccessType AccessType 459 AccessNodes []Identifier 460 } 461 462 var _ Def = &EnvironmentVariableDef{} 463 464 func (d *EnvironmentVariableDef) parseFrom(p *Parser) { 465 d.Pos = p.keyword(KeywordEnvironmentVariable).pos 466 d.Name = p.identifier() 467 p.token(':') 468 d.Type = p.environmentVariableType() 469 p.token('[') 470 d.Minimum = p.float() 471 p.token('|') 472 d.Maximum = p.float() 473 p.token(']') 474 d.Unit = p.string() 475 d.InitialValue = p.float() 476 d.ID = p.uint() 477 d.AccessType = p.accessType() 478 d.AccessNodes = append(d.AccessNodes, p.identifier()) 479 for p.peekToken().typ == ',' { 480 p.token(',') 481 d.AccessNodes = append(d.AccessNodes, p.identifier()) 482 } 483 p.token(';') 484 } 485 486 // Position returns the position of the definition. 487 func (d *EnvironmentVariableDef) Position() scanner.Position { 488 return d.Pos 489 } 490 491 // EnvironmentVariableDataDef defines an environment variable as being of type "data". 492 // 493 // Environment variables of this type can store an arbitrary binary data of the given length. 494 // The length is given in bytes. 495 type EnvironmentVariableDataDef struct { 496 Pos scanner.Position 497 // EnvironmentVariableName is the name of the environment variable. 498 EnvironmentVariableName Identifier 499 // DataSize is the size of the environment variable data in bytes. 500 DataSize uint64 501 } 502 503 var _ Def = &EnvironmentVariableDataDef{} 504 505 func (d *EnvironmentVariableDataDef) parseFrom(p *Parser) { 506 d.Pos = p.keyword(KeywordEnvironmentVariableData).pos 507 d.EnvironmentVariableName = p.identifier() 508 p.token(':') 509 d.DataSize = p.uint() 510 p.token(';') 511 } 512 513 // Position returns the position of the definition. 514 func (d *EnvironmentVariableDataDef) Position() scanner.Position { 515 return d.Pos 516 } 517 518 // CommentDef defines a comment. 519 type CommentDef struct { 520 Pos scanner.Position 521 ObjectType ObjectType 522 NodeName Identifier 523 MessageID MessageID 524 SignalName Identifier 525 EnvironmentVariableName Identifier 526 Comment string 527 } 528 529 var _ Def = &CommentDef{} 530 531 func (d *CommentDef) parseFrom(p *Parser) { 532 d.Pos = p.keyword(KeywordComment).pos 533 d.ObjectType = p.optionalObjectType() 534 switch d.ObjectType { 535 case ObjectTypeNetworkNode: 536 d.NodeName = p.identifier() 537 case ObjectTypeMessage: 538 d.MessageID = p.messageID() 539 case ObjectTypeSignal: 540 d.MessageID = p.messageID() 541 d.SignalName = p.identifier() 542 case ObjectTypeEnvironmentVariable: 543 d.EnvironmentVariableName = p.identifier() 544 } 545 d.Comment = p.string() 546 p.token(';') 547 } 548 549 // Position returns the position of the definition. 550 func (d *CommentDef) Position() scanner.Position { 551 return d.Pos 552 } 553 554 // AttributeDef defines a user-defined attribute. 555 // 556 // User-defined attributes are a means to extend the object properties of the DBC file. 557 // 558 // These additional attributes have to be defined using an attribute definition with an attribute default value. 559 // 560 // For each object having a value defined for the attribute, an attribute value entry has to be defined. 561 // 562 // If no attribute value entry is defined for an object, the value of the object's attribute is the attribute's default. 563 type AttributeDef struct { 564 Pos scanner.Position 565 ObjectType ObjectType 566 Name Identifier 567 Type AttributeValueType 568 MinimumInt int64 569 MaximumInt int64 570 MinimumFloat float64 571 MaximumFloat float64 572 EnumValues []string 573 } 574 575 var _ Def = &AttributeDef{} 576 577 func (d *AttributeDef) parseFrom(p *Parser) { 578 d.Pos = p.keyword(KeywordAttribute).pos 579 d.ObjectType = p.optionalObjectType() 580 d.Name = p.stringIdentifier() 581 d.Type = p.attributeValueType() 582 switch d.Type { 583 case AttributeValueTypeInt, AttributeValueTypeHex: 584 if p.peekToken().typ != ';' { 585 d.MinimumInt = p.int() 586 d.MaximumInt = p.int() 587 } 588 case AttributeValueTypeFloat: 589 if p.peekToken().typ != ';' { 590 // SPECIAL CASE: Support attributes without min/max 591 d.MinimumFloat = p.float() 592 d.MaximumFloat = p.float() 593 } 594 case AttributeValueTypeEnum: 595 d.EnumValues = append(d.EnumValues, p.string()) 596 for p.peekToken().typ == ',' { 597 p.token(',') 598 d.EnumValues = append(d.EnumValues, p.string()) 599 } 600 } 601 p.token(';') 602 } 603 604 // Position returns the position of the definition. 605 func (d *AttributeDef) Position() scanner.Position { 606 return d.Pos 607 } 608 609 // AttributeDefaultValueDef defines the default value for an attribute. 610 type AttributeDefaultValueDef struct { 611 Pos scanner.Position 612 AttributeName Identifier 613 DefaultIntValue int64 614 DefaultFloatValue float64 615 DefaultStringValue string 616 } 617 618 var _ Def = &AttributeDefaultValueDef{} 619 620 func (d *AttributeDefaultValueDef) parseFrom(p *Parser) { 621 d.Pos = p.keyword(KeywordAttributeDefault).pos 622 d.AttributeName = Identifier(p.string()) 623 // look up attribute type 624 for _, prevDef := range p.defs { 625 if attributeDef, ok := prevDef.(*AttributeDef); ok && attributeDef.Name == d.AttributeName { 626 switch attributeDef.Type { 627 case AttributeValueTypeInt, AttributeValueTypeHex: 628 d.DefaultIntValue = p.int() 629 case AttributeValueTypeFloat: 630 d.DefaultFloatValue = p.float() 631 case AttributeValueTypeString: 632 d.DefaultStringValue = p.string() 633 case AttributeValueTypeEnum: 634 d.DefaultStringValue = p.enumValue(attributeDef.EnumValues) 635 } 636 break 637 } 638 } 639 p.token(';') 640 } 641 642 // Position returns the position of the definition. 643 func (d *AttributeDefaultValueDef) Position() scanner.Position { 644 return d.Pos 645 } 646 647 // AttributeValueForObjectDef defines a value for an attribute and an object. 648 type AttributeValueForObjectDef struct { 649 Pos scanner.Position 650 AttributeName Identifier 651 ObjectType ObjectType 652 MessageID MessageID 653 SignalName Identifier 654 NodeName Identifier 655 EnvironmentVariableName Identifier 656 IntValue int64 657 FloatValue float64 658 StringValue string 659 } 660 661 var _ Def = &AttributeValueForObjectDef{} 662 663 func (d *AttributeValueForObjectDef) parseFrom(p *Parser) { 664 d.Pos = p.keyword(KeywordAttributeValue).pos 665 d.AttributeName = Identifier(p.string()) 666 d.ObjectType = p.optionalObjectType() 667 switch d.ObjectType { 668 case ObjectTypeMessage: 669 d.MessageID = p.messageID() 670 case ObjectTypeSignal: 671 d.MessageID = p.messageID() 672 d.SignalName = p.identifier() 673 case ObjectTypeNetworkNode: 674 d.NodeName = p.identifier() 675 case ObjectTypeEnvironmentVariable: 676 d.EnvironmentVariableName = p.identifier() 677 } 678 // look up attribute type 679 for _, prevDef := range p.defs { 680 if attributeDef, ok := prevDef.(*AttributeDef); ok && attributeDef.Name == d.AttributeName { 681 switch attributeDef.Type { 682 case AttributeValueTypeInt, AttributeValueTypeHex: 683 d.IntValue = p.int() 684 case AttributeValueTypeFloat: 685 d.FloatValue = p.float() 686 case AttributeValueTypeString: 687 d.StringValue = p.string() 688 case AttributeValueTypeEnum: 689 d.StringValue = p.enumValue(attributeDef.EnumValues) 690 } 691 break 692 } 693 } 694 p.token(';') 695 } 696 697 // Position returns the position of the definition. 698 func (d *AttributeValueForObjectDef) Position() scanner.Position { 699 return d.Pos 700 } 701 702 // UnknownDef represents an unknown or unsupported DBC definition. 703 type UnknownDef struct { 704 Pos scanner.Position 705 Keyword Keyword 706 } 707 708 var _ Def = &UnknownDef{} 709 710 func (d *UnknownDef) parseFrom(p *Parser) { 711 tok := p.peekToken() 712 d.Pos = tok.pos 713 d.Keyword = Keyword(tok.txt) 714 p.discardLine() 715 } 716 717 // Position returns the position of the definition. 718 func (d *UnknownDef) Position() scanner.Position { 719 return d.Pos 720 }