# 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