# BAP Header and Multi-Frame Protocol This document details the BAP message structure, header format, and multi-frame handling for both PQ and MQB platforms. ## Message Structure Overview BAP messages consist of: 1. **Header** - Contains opcode, LSG ID, and function ID 2. **Payload** - Actual data being transmitted 3. **Multi-frame preamble** - For messages exceeding single frame capacity ## PQ Platform Message Architecture ### Single Frame Messages (≤6 bytes) ```plaintext ┌─────────────────┬─────────────────┬──────────────────────┐ │ Byte 0 │ Byte 1 │ Bytes 2-7 │ ├─────────────────┼─────────────────┼──────────────────────┤ │ Header High │ Header Low │ Payload Data │ │ [0|OP|LSG_H] │ [LSG_L|FCT] │ (0-6 bytes) │ └─────────────────┴─────────────────┴──────────────────────┘ Header Structure (16 bits): ┌─┬───┬────────┬──────────┐ │0│OP │ LSG │ FCT │ ├─┼───┼────────┼──────────┤ │1│3bt│ 6 bits │ 6 bits │ └─┴───┴────────┴──────────┘ ``` **Header Bit Breakdown:** ```plaintext Bit 15: Frame type (0 = Single frame) Bit 14-12: Opcode (0x0-0x7) Bit 11-6: LSG ID (0x00-0x3F) Bit 5-0: Function ID (0x00-0x3F) ``` ### Multi-Frame Messages (>6 bytes) PQ uses the first bit to determine frame type: #### Start Frame ```plaintext ┌─────────────┬─────────────┬─────────────┬─────────────┬──────────────┐ │ Byte 0 │ Byte 1 │ Byte 2 │ Byte 3 │ Bytes 4-7 │ ├─────────────┼─────────────┼─────────────┼─────────────┼──────────────┤ │ Preamble H │ Preamble L │ Header H │ Header L │ Payload │ │[1|0|Len_H] │ [Len_L] │ [OP|LSG_H] │ [LSG_L|FCT] │ (0-4 bytes) │ └─────────────┴─────────────┴─────────────┴─────────────┴──────────────┘ Preamble Structure (16 bits): ┌─┬─┬──────────────┐ │1│0│ Total Length │ ├─┼─┼──────────────┤ │ │ │ 12 bits │ └─┴─┴──────────────┘ ``` #### Continuation Frame ```plaintext ┌─────────────┬─────────────────────────────────┐ │ Byte 0 │ Bytes 1-7 │ ├─────────────┼─────────────────────────────────┤ │ Sequence │ Payload Data │ │[1|1|Index] │ (1-7 bytes) │ └─────────────┴─────────────────────────────────┘ Sequence Byte Structure: ┌─┬─┬──────────────┐ │1│1│ Frame Index │ ├─┼─┼──────────────┤ │ │ │ 6 bits │ └─┴─┴──────────────┘ ``` **Multi-Frame Sequence Values:** - Start frame: `0x80` (binary: 10000000) - First continuation: `0xC0` (binary: 11000000) - Second continuation: `0xC1` (binary: 11000001) - And so on... ### PQ Example: 14-byte Phone Status Message ```plaintext CAN ID: 0x123 Total payload: 14 bytes Header: 0x3B14 (Status opcode, LSG 0x2C, FCT 0x14) Frame 1 (Start): 80 0E 3B 14 01 02 03 04 │ │ │ │ └─ First 4 payload bytes │ │ └-─┴─ BAP Header └-─┴─ Length preamble (14 bytes) Frame 2 (Cont): C0 05 06 07 08 09 0A │ └─ Next 6 payload bytes └─ Sequence 0 Frame 3 (Cont): C1 0B 0C 0D 0E │ └─ Final 4 payload bytes └─ Sequence 1 ``` ## MQB Platform Message Architecture MQB uses 29-bit extended CAN IDs with LSG embedded in the identifier: ```plaintext 29-bit CAN ID Structure: ┌────────────────┬────────────┬──────────────┐ │ Base ID │ LSG ID │ ASG\FSG ID │ │ (16 bits) │ (8 bits) │ (4 bits) │ └────────────────┴────────────┴──────────────┘ Example: 0x17330B10 ├─ 0x1733: Base ID ├─ 0x0B: LSG (Rear View Camera) └─ 0x10: FSG direction ``` ### MQB Single Frame Messages ```plaintext ┌─────────────┬─────────────┬──────────────────────┐ │ Byte 0 │ Byte 1 │ Bytes 2-7 │ ├─────────────┼─────────────┼──────────────────────┤ │ Opcode │ Function ID │ Payload Data │ │ │ │ (0-6 bytes) │ └─────────────┴─────────────┴──────────────────────┘ ``` ### MQB Multi-Frame Messages #### Start Frame ```plaintext ┌─────────────┬─────────────┬─────────────┬──────────────────┐ │ Byte 0 │ Byte 1 │ Byte 2 │ Bytes 3-7 │ ├─────────────┼─────────────┼─────────────┼──────────────────┤ │ Segment Hdr │ Total Length│ Function? │ Payload Data │ │ 0x80 │ (bytes) │ │ (0-5 bytes) │ └─────────────┴─────────────┴─────────────┴──────────────────┘ ``` #### Continuation Frames ```plaintext ┌─────────────┬─────────────────────────────────┐ │ Byte 0 │ Bytes 1-7 │ ├─────────────┼─────────────────────────────────┤ │ Segment Hdr │ Payload Data │ │ 0xC0-0xCF │ (1-7 bytes) │ └─────────────┴─────────────────────────────────┘ ``` ### MQB Example: Large Data Transfer ```plaintext CAN ID: 0x17333310 (LSG 0x33 embedded) Total payload: 146 bytes Frame 1: 80 92 4C C1 03 01 33 00 │ │ └─ Start of payload │ └─ Total length (146 bytes) └─ Start marker Frame 2: C0 03 0B 08 00 38 07 EF Frame 3: C1 F8 00 00 00 00 0A 00 Frame 4: C2 00 00 00 00 05 00 08 ... Frame 19: C2 40 00 00 00 00 00 00 │ └─ Continuation data └─ Sequence wrapped (C2 reused) ``` ## Platform Comparison | Feature | PQ Platform | MQB Platform | |---------|-------------|--------------| | CAN ID Type | 11-bit standard | 29-bit extended | | LSG Location | In message header | In CAN ID | | Max Single Frame | 6 bytes | 6 bytes | | Multi-frame Overhead | 4 bytes (start), 1 byte (cont) | 3 bytes (start), 1 byte (cont) | | Sequence Range | 0xC0-0xFF (64 frames) | 0xC0-0xCF (16 frames, wraps) | | Hardware Filtering | No | Yes (by LSG in CAN ID) | ## Multi-Frame Implementation Details ### Frame Assembly Algorithm ```plaintext 1. Detect frame type: - Check first byte MSB - 0b0xxxxxxx = Single frame - 0b10xxxxxx = Multi-frame start - 0b11xxxxxx = Multi-frame continuation 2. For multi-frame start: - Extract total length - Initialize buffer - Store header (PQ) or function info (MQB) - Copy initial payload 3. For continuation frames: - Verify sequence number - Append payload to buffer - Check if complete 4. Handle edge cases: - Sequence number mismatch → reset - Timeout → discard partial message - Buffer overflow → error ``` ### Timing Requirements - **Frame spacing**: Max 20ms between frames - **Assembly timeout**: 100ms for complete message - **Retransmission**: After 3 failed attempts ### Error Recovery 1. **Missing continuation frame** - Wait for timeout - Request retransmission via Error opcode 2. **Sequence mismatch** - Discard partial message - Reset state machine - Log error for diagnostics 3. **Buffer overflow** - Reject message - Send Error response - Clear buffers ## Implementation Examples ### PQ Platform Frame Detection ```c bool is_multiframe_start(uint8_t first_byte) { return (first_byte & 0xC0) == 0x80; } bool is_multiframe_cont(uint8_t first_byte) { return (first_byte & 0xC0) == 0xC0; } uint8_t get_sequence_number(uint8_t seq_byte) { return seq_byte & 0x3F; // Lower 6 bits } ``` ### MQB Platform LSG Extraction ```c uint8_t extract_lsg_from_canid(uint32_t can_id) { return (can_id >> 8) & 0xFF; // Bits 15-8 } bool is_fsg_direction(uint32_t can_id) { return (can_id & 0x10) == 0x10; } ``` ## Best Practices 1. **Buffer Management** - Pre-allocate buffers for known max message sizes - Use circular buffers for high-traffic LSGs - Implement proper bounds checking 2. **State Machine Design** - Clear states: IDLE, RECEIVING, COMPLETE, ERROR - Timeout handling in each state - Graceful error recovery 3. **Performance Optimization** - Use hardware CAN filters on MQB - Implement zero-copy buffer handling - Batch process continuation frames ## Related Documentation - [[core/Opcodes and Function IDs|Opcode Reference]] - Message operation types - [[platforms/pq-implementation|PQ Platform Details]] - Platform-specific features - [[platforms/mqb-implementation|MQB Platform Details]] - Extended CAN implementation