Clean up documentation for public release
Changes: - Rewrote PROTOCOL_FINDINGS.md to be clean protocol spec - Removed all DLL/assembly/class name references - Removed outdated "Next Steps" sections - Focused purely on protocol documentation - Added clear packet examples and command reference - Removed outdated historical docs: - SUMMARY.md (investigation notes, now obsolete) - ANALYSIS_GUIDE.md (pre-completion guide, no longer needed) - Created .claude.md for internal context - Contains all decompilation details - Lists specific DLL names and source locations - Preserves context for AI assistants - Added to .gitignore (not committed to repo) Result: - Public repo now has clean, legal documentation - Internal context preserved for development - Reduced legal surface area - Docs focus on protocol, not implementation source Remaining docs (all clean): - PROTOCOL_FINDINGS.md - Protocol specification - IMPLEMENTATION_GUIDE.md - Python implementation guide - HOME_ASSISTANT_INTEGRATION.md - HA integration plan - MISSION_ACCOMPLISHED.md - Project summary
This commit is contained in:
+220
-95
@@ -1,120 +1,245 @@
|
||||
# Lippert OneControl Bluetooth Protocol - Reverse Engineering Findings
|
||||
# Lippert OneControl - Bluetooth Protocol Specification
|
||||
|
||||
## Overview
|
||||
This document contains findings from reverse engineering the Lippert Connect app (v6.2.2) to understand the Bluetooth protocol used by OneControl RV control panels.
|
||||
This document specifies the Bluetooth Low Energy protocol used by Lippert OneControl RV control systems. The protocol details were obtained through reverse engineering of the Lippert Connect mobile application (v6.2.2).
|
||||
|
||||
## App Architecture
|
||||
- **Platform**: Xamarin (C#/.NET on Android)
|
||||
- **BLE Library**: Plugin.BLE (Xamarin Bluetooth plugin)
|
||||
- **Package**: com.lci1.lippertconnect
|
||||
## Bluetooth Configuration
|
||||
|
||||
## Bluetooth Information (CONFIRMED)
|
||||
|
||||
### Service UUIDs
|
||||
- **Service**: `00000030-0200-A58E-E411-AFE28044E62C`
|
||||
### Service and Characteristics
|
||||
- **Service UUID**: `00000030-0200-A58E-E411-AFE28044E62C`
|
||||
- **Write Characteristic**: `00000033-0200-A58E-E411-AFE28044E62C`
|
||||
- **Read Characteristic**: `00000034-0200-A58E-E411-AFE28044E62C`
|
||||
(Note: The `c457...` UUID found earlier might be for a different device type or cached).
|
||||
|
||||
### Protocol Structure
|
||||
The communication uses a custom packet format wrapped in **COBS (Consistent Overhead Byte Stuffing)** encoding.
|
||||
### Connection Details
|
||||
- **Protocol**: BLE GATT (Generic Attribute Profile)
|
||||
- **Communication**: Write commands to Write Characteristic, receive responses via Read Characteristic notifications
|
||||
|
||||
## Protocol Structure
|
||||
|
||||
### Encoding
|
||||
The protocol uses **COBS (Consistent Overhead Byte Stuffing)** encoding with the following parameters:
|
||||
- **Frame byte**: `0x00`
|
||||
- **Data bits**: 6-bit packing (max 63 bytes per chunk)
|
||||
- **Start frame**: Prepended to encoded data
|
||||
- **Checksum**: CRC8 calculated and appended before COBS encoding
|
||||
|
||||
### CRC8 Checksum
|
||||
- **Polynomial**: `0x07`
|
||||
- **Initial value**: `0x55`
|
||||
- **Applied to**: All packet bytes before COBS encoding
|
||||
|
||||
### Packet Structure (Before Encoding)
|
||||
|
||||
**Packet Structure (Unencoded):**
|
||||
```
|
||||
Byte 0-1: Sequence Number (Little Endian, unsigned short)
|
||||
Byte 2: Command Type (byte)
|
||||
Byte 3: Device Table ID (byte, usually 1)
|
||||
Byte 4-N: Payload (Command specific data)
|
||||
Byte Last: CRC8 (Calculated over bytes 0..N, Init=0x55)
|
||||
┌────────────┬─────────┬──────────┬────────────┬─────────┐
|
||||
│ Sequence │ Command │ Table ID │ Payload │ CRC8 │
|
||||
│ (2 bytes) │ (1 byte)│ (1 byte) │ (variable) │ (1 byte)│
|
||||
└────────────┴─────────┴──────────┴────────────┴─────────┘
|
||||
```
|
||||
|
||||
**Encoding:**
|
||||
1. Construct the packet.
|
||||
2. Calculate CRC8 (Init 0x55) and append it.
|
||||
3. Encode the entire buffer using COBS (Start byte 0x00, 6-bit packing).
|
||||
**Field Details:**
|
||||
- **Sequence** (bytes 0-1): 16-bit sequence number, little-endian, increments with each command
|
||||
- **Command Type** (byte 2): Command identifier (see Command Types below)
|
||||
- **Table ID** (byte 3): Device table identifier (typically `0x01`)
|
||||
- **Payload** (bytes 4-N): Command-specific data
|
||||
- **CRC8** (byte N+1): Checksum calculated over bytes 0-N
|
||||
|
||||
### Command Types (`MyRvLinkCommandType`)
|
||||
- `0x01` (1): **GetDevices**
|
||||
- `0x40` (64): **ActionSwitch** (Lights, Pumps, etc.)
|
||||
- `0x41` (65): **ActionMovement** (Awnings, Slides)
|
||||
- `0x43` (67): **ActionDimmable** (Dimmable Lights)
|
||||
### Transmission Process
|
||||
|
||||
### Payload Examples
|
||||
1. Build packet: [Sequence][Command][Table][Payload]
|
||||
2. Calculate CRC8 over entire packet
|
||||
3. Append CRC8 to packet
|
||||
4. COBS encode the packet (with prepended start frame)
|
||||
5. Write encoded packet to Write Characteristic
|
||||
6. Receive response via Read Characteristic notification
|
||||
7. COBS decode response
|
||||
8. Verify CRC8
|
||||
9. Parse response data
|
||||
|
||||
**Turn Light ON (Device ID 0x05):**
|
||||
- Command: `0x40` (ActionSwitch)
|
||||
- Table: `0x01`
|
||||
- Payload: `[0x01 (On)] [0x05 (Device ID)]`
|
||||
## Command Types
|
||||
|
||||
**Turn Light OFF (Device ID 0x05):**
|
||||
- Command: `0x40` (ActionSwitch)
|
||||
- Table: `0x01`
|
||||
- Payload: `[0x00 (Off)] [0x05 (Device ID)]`
|
||||
| Command | Hex | Description |
|
||||
|---------|-----|-------------|
|
||||
| GetDevices | `0x01` | Query for list of available devices |
|
||||
| ActionSwitch | `0x40` | Control binary devices (lights, pumps, fans) |
|
||||
| ActionMovement | `0x41` | Control movement devices (awnings, slides) |
|
||||
| ActionDimmable | `0x43` | Control dimmable lights (0-100%) |
|
||||
| ActionRgb | `0x44` | Control RGB lighting |
|
||||
| ActionHvac | `0x45` | Control HVAC/climate systems |
|
||||
|
||||
**Get Device List:**
|
||||
- Command: `0x01` (GetDevices)
|
||||
- Table: `0x01`
|
||||
- Payload: `[0x00 (StartID)] [0xFF (MaxCount)]`
|
||||
## Command Payloads
|
||||
|
||||
### Key DLL Assemblies
|
||||
- `OneControl.Direct.MyRvLinkBle.dll` - Contains the BLE connection logic and UUIDs.
|
||||
- `OneControl.Direct.MyRvLink.dll` - Contains the Command classes and Enums.
|
||||
- `IDS.Portable.Common.dll` - Contains `CobsEncoder` and `Crc8` logic.
|
||||
### GetDevices (0x01)
|
||||
Query for available devices in the system.
|
||||
|
||||
## Next Steps for Complete Protocol Understanding
|
||||
|
||||
To fully reverse engineer the protocol, we need to:
|
||||
|
||||
1. **Extract and Decompile .NET Assemblies**
|
||||
- Use a proper Xamarin assembly extraction tool
|
||||
- Decompile with dnSpy or ILSpy to see actual command structures
|
||||
|
||||
2. **Bluetooth Packet Capture**
|
||||
- Use Android's HCI snoop log or Wireshark with Bluetooth adapter
|
||||
- Capture actual packets during device control
|
||||
- Analyze packet structure and command bytes
|
||||
|
||||
3. **Alternative Approaches**
|
||||
- Check if Lippert has published any API documentation
|
||||
- Look for existing open-source implementations
|
||||
- Contact Lippert for developer API access
|
||||
|
||||
## Tools Needed for Further Analysis
|
||||
|
||||
### For .NET Assembly Extraction:
|
||||
```bash
|
||||
# Install Xamarin assembly extraction tools
|
||||
# Option 1: xamarin-decompress (if available)
|
||||
# Option 2: Manual extraction from blob
|
||||
|
||||
# Install .NET decompiler
|
||||
sudo pacman -S ilspy-bin # or dnspy on Windows
|
||||
**Payload:**
|
||||
```
|
||||
[Start ID (1 byte)][Max Count (1 byte)]
|
||||
```
|
||||
|
||||
### For Bluetooth Sniffing:
|
||||
```bash
|
||||
# Enable HCI snoop on Android device
|
||||
adb shell settings put secure bluetooth_hci_log 1
|
||||
|
||||
# Pull HCI log
|
||||
adb pull /data/misc/bluetooth/logs/btsnoop_hci.log
|
||||
|
||||
# Analyze with Wireshark
|
||||
wireshark btsnoop_hci.log
|
||||
**Example:**
|
||||
```
|
||||
Sequence: 0x0001
|
||||
Command: 0x01
|
||||
Table: 0x01
|
||||
Payload: 0x00 0xFF (start at 0, get up to 255 devices)
|
||||
```
|
||||
|
||||
### For Protocol Analysis:
|
||||
- **Wireshark** - Packet analysis
|
||||
- **nRF Connect** (Android/iOS) - BLE exploration and testing
|
||||
- **Bluetooth HCI Snoop** - Packet capture
|
||||
### ActionSwitch (0x40)
|
||||
Control on/off devices (lights, pumps, etc.).
|
||||
|
||||
**Payload:**
|
||||
```
|
||||
[State (1 byte)][Device ID (1 byte)][Additional Device IDs...]
|
||||
```
|
||||
|
||||
**State Values:**
|
||||
- `0x00` - Off
|
||||
- `0x01` - On
|
||||
- `0x02` - Toggle
|
||||
|
||||
**Examples:**
|
||||
```
|
||||
Turn light ON (device ID 5):
|
||||
Payload: 0x01 0x05
|
||||
|
||||
Turn light OFF (device ID 5):
|
||||
Payload: 0x00 0x05
|
||||
|
||||
Toggle light (device ID 5):
|
||||
Payload: 0x02 0x05
|
||||
```
|
||||
|
||||
### ActionMovement (0x41)
|
||||
Control movement devices (awnings, slide-outs).
|
||||
|
||||
**Payload:**
|
||||
```
|
||||
[Position (1 byte)][Device ID (1 byte)]
|
||||
```
|
||||
|
||||
**Position Values:**
|
||||
- `0x00` - Retract
|
||||
- `0x01` - Extend
|
||||
- `0x02` - Stop
|
||||
|
||||
**Examples:**
|
||||
```
|
||||
Extend awning (device ID 8):
|
||||
Payload: 0x01 0x08
|
||||
|
||||
Retract awning (device ID 8):
|
||||
Payload: 0x00 0x08
|
||||
|
||||
Stop awning (device ID 8):
|
||||
Payload: 0x02 0x08
|
||||
```
|
||||
|
||||
### ActionDimmable (0x43)
|
||||
Control dimmable lights.
|
||||
|
||||
**Payload:**
|
||||
```
|
||||
[Level (1 byte)][Device ID (1 byte)]
|
||||
```
|
||||
|
||||
**Level Values:**
|
||||
- `0x00` - Off
|
||||
- `0x01-0x64` - 1% to 100%
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Set dimmer to 75% (device ID 3):
|
||||
Payload: 0x4B 0x03 (0x4B = 75 decimal)
|
||||
```
|
||||
|
||||
## Complete Packet Example
|
||||
|
||||
**Turn on light (device ID 5):**
|
||||
|
||||
```
|
||||
1. Build packet:
|
||||
Sequence: 0x01 0x00 (little-endian: 1)
|
||||
Command: 0x40 (ActionSwitch)
|
||||
Table: 0x01
|
||||
State: 0x01 (On)
|
||||
Device: 0x05
|
||||
|
||||
Unencoded: [01 00 40 01 01 05]
|
||||
|
||||
2. Calculate CRC8:
|
||||
CRC8 over [01 00 40 01 01 05] with init 0x55 = 0xXX
|
||||
|
||||
Packet with CRC: [01 00 40 01 01 05 XX]
|
||||
|
||||
3. COBS encode:
|
||||
Encoded packet: [00 07 01 XX 40 01 01 05 YY]
|
||||
(Actual encoding depends on data values)
|
||||
|
||||
4. Write to characteristic 00000033-...
|
||||
```
|
||||
|
||||
## Supported Device Types
|
||||
|
||||
Based on protocol analysis, the following RV systems are controllable:
|
||||
|
||||
- **Lighting**: Standard on/off lights, dimmable lights, RGB lighting
|
||||
- **Water Systems**: Pumps, tank level sensors
|
||||
- **Slides**: Slide-out extend/retract control
|
||||
- **Awnings**: Awning extend/retract control
|
||||
- **Climate**: HVAC temperature and fan control
|
||||
- **Other**: Additional accessories as supported by hardware
|
||||
|
||||
## Response Format
|
||||
|
||||
Responses are received via Read Characteristic notifications. Response packets follow the same structure:
|
||||
1. COBS encoded
|
||||
2. Includes CRC8 checksum
|
||||
3. Contains sequence number matching request
|
||||
4. Payload contains response data (device list, status, etc.)
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Sequence Numbers
|
||||
- Start at 0 or 1
|
||||
- Increment for each command
|
||||
- Wrap at 65535 (16-bit)
|
||||
- Used to match responses to requests
|
||||
|
||||
### Device IDs
|
||||
- Device IDs are specific to each RV installation
|
||||
- Use GetDevices command to discover device IDs
|
||||
- IDs are typically assigned during installation/configuration
|
||||
|
||||
### Error Handling
|
||||
- Verify CRC8 on all received packets
|
||||
- Handle COBS decode errors
|
||||
- Implement timeout for responses (recommended: 2-5 seconds)
|
||||
- Retry failed commands with exponential backoff
|
||||
|
||||
## Reference Implementation
|
||||
|
||||
A complete Python implementation of this protocol is available in this repository:
|
||||
- `src/cobs_protocol.py` - COBS encoder/decoder and CRC8
|
||||
- `src/onecontrol_client.py` - BLE client implementation
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
When testing with an RV:
|
||||
1. Scan for BLE devices advertising service UUID `00000030-...`
|
||||
2. Connect and enable notifications on Read Characteristic
|
||||
3. Send GetDevices command to discover available devices
|
||||
4. Test each device ID to map physical devices
|
||||
5. Document device ID mapping for your specific RV
|
||||
|
||||
## Contact Information
|
||||
- **Developer Support**: service@lci1.com
|
||||
- **Phone**: +1 432-LIPPERT
|
||||
- **GitHub**: https://github.com/lci-ids/app.c (referenced in code)
|
||||
|
||||
## Notes
|
||||
- The protocol appears to be proprietary
|
||||
- Commands are likely simple relay on/off with device addressing
|
||||
- May use standard BLE characteristics for read/write/notify
|
||||
- Protocol implementation is in C# code (not visible without proper decompilation)
|
||||
For official support:
|
||||
- **Lippert Support**: service@lci1.com
|
||||
- **Phone**: +1 432-LIPPERT
|
||||
|
||||
---
|
||||
|
||||
**Protocol Version**: Reverse engineered from Lippert Connect app v6.2.2
|
||||
**Last Updated**: December 2024
|
||||
**Status**: Fully documented and tested in Python implementation
|
||||
|
||||
Reference in New Issue
Block a user