
The Integration Workflow
Integrating a new device involves two main phases:1. Reverse Engineering
Understanding how the device communicates. This typically means capturing and analyzing its Bluetooth Low Energy (BLE) traffic to decode its protocol for commands and data streaming.
2. Software Integration
Writing code within the Omi mobile app to manage the connection, communication, and data processing for the new device.
This guide focuses on devices that stream audio data, but the principles apply to other data types as well.
Prerequisites
Before you begin, ensure you have the following:The Hardware
The third-party device you want to integrate
Android Phone
Highly recommended for superior BLE traffic capturing capabilities
Wireshark
Essential tool for analyzing captured network traffic
Omi App Codebase
A local development setup of the Omi app
Technical Knowledge Required
| Skill | Level | Description |
|---|---|---|
| BLE Concepts | Basic | Services, Characteristics, UUIDs |
| Dart/Flutter | Intermediate | For app integration |
| Python | Optional | For writing verification scripts |
Part 1: Reverse Engineering the Device Protocol
Your first goal is to become a detective. You need to learn the device’s language, which for most wearables is spoken over Bluetooth Low Energy (BLE).Step 1.1: Capture BLE Traffic
The most effective way to learn the protocol is to capture the communication between the device and its official app.- Android (Recommended)
- iOS
1
Enable Developer Options
Go to Settings → About phone and tap Build number seven times.
2
Enable ADB & Snoop Log
Go to Settings → System → Developer options. Enable:
- USB debugging
- Enable Bluetooth HCI snoop log
3
Restart Bluetooth
Turn Bluetooth off and on again for the change to take effect.
4
Generate Traffic
Use the official vendor app to connect to your device. Perform key operations like starting and stopping a recording, changing settings, etc.
5
Retrieve the Log
After capturing, disable the snoop log.Non-Rooted Devices: Generate a bug report from Developer options. The log file
btsnoop_hci.log will be in the ZIP archive under FS/data/misc/bluetooth/logs/.Rooted Devices: Pull directly using ADB:6
Analyze in Wireshark
Open the
btsnoop_hci.log file in Wireshark.To find your device’s address:
adb shell dumpsys bluetooth_managerStep 1.2: Analyze Traffic in Wireshark
With your log file open, it’s time to find the important packets.Filter by Device
Find your device’s address and apply a display filter to isolate its traffic
Look for Patterns
For audio streaming, look for large numbers of similar-sized packets sent rapidly
Inspect Packet Details
Look for GATT Service UUID, Characteristic UUID, and raw data payload
Map the Services
Create a “map” of Service UUIDs, Characteristic UUIDs, and Data Formats
Key Information to Find:
- Service UUIDs: High-level containers (e.g., “Audio Service”, “Device Information Service”)
- Characteristic UUIDs: Specific data endpoints (e.g., “Audio Stream Data”, “Battery Level”)
- Data Format: Encoding of the payload (e.g., Opus, PCM, µ-law, AAC)
Step 1.3: Decode the Data Payload
The data payload is a hexadecimal string. Your task is to figure out its structure.Example: Identifying Opus Frames
Example: Identifying Opus Frames
Let’s say you capture several 240-byte data packets. You notice the first byte is always
b8, and this byte reappears every 40 bytes within the same packet.This is a strong clue! The Opus audio codec uses a Table of Contents (TOC) byte at the start of each frame. The repeating b8 byte suggests the packet contains six 40-byte Opus frames.Common Audio Codecs
Common Audio Codecs
| Codec | Description |
|---|---|
| Opus | High-quality, low-latency (most common in modern devices) |
| PCM | Uncompressed audio (16-bit typical) |
| µ-law | Compressed 8-bit audio (telephony standard) |
| AAC | Advanced Audio Coding (Apple devices) |
Step 1.4: Verify Your Findings
Before integrating, write a small standalone script to confirm your assumptions.Part 2: Integrating with the Omi App
Now, let’s integrate your device into the Omi app’s modular architecture.Understanding Omi’s Device Architecture
| Component | Location | Purpose |
|---|---|---|
DeviceConnection | .../device_connection.dart | Abstract class defining the standard interface for all devices |
DeviceTransport | .../transports/ble_transport.dart | Low-level BLE communication handler |
DeviceConnectionFactory | .../device_connection.dart | Constructs the correct connection object based on DeviceType |
Implementation Steps
Add a New DeviceType
Open Also update
app/lib/backend/schema/bt_device/bt_device.dart and add your device:getTypeOfBluetoothDevice function and create a helper (e.g., isXyzDevice) to identify your device during Bluetooth scans.Create Your Device Connection Class
Create
app/lib/services/devices/xyz_connection.dart:Register Your Device in the Factory
Open
app/lib/services/devices/device_connection.dart and add a new case:Refer to
app/lib/services/devices/omi_connection.dart for a complete example of a complex device implementation.Part 3: Testing and Contribution
Testing Your Integration
Test your integration thoroughly within the Omi app:| Test | Description |
|---|---|
| Discovery & Connection | Can you successfully discover and connect to the device? |
| Live Transcription | Does real-time transcription work as expected? |
| Battery Level | Is the battery level displayed correctly? |
| Stability | Is the connection stable? Does it handle reconnection gracefully? |
Troubleshooting Common Issues
Connection Fails
Connection Fails
- Double-check your Service and Characteristic UUIDs
- Ensure the device is not connected to its official app or another phone
- Verify BLE permissions are granted in the app
Audio is Garbled
Audio is Garbled
- Your
BleAudioCodecinperformGetAudioCodecis likely incorrect - Verify the codec and its parameters (sample rate, bit depth)
- Check if there’s a header to strip from audio packets
No Data Received
No Data Received
- Confirm you are subscribing to the correct characteristic for notifications
- Check in Wireshark if the device is actually sending data after connection
- Verify the characteristic supports notifications (check properties)
Contributing Your Work
Omi is built by the community. If you’ve integrated a new device, we strongly encourage you to contribute it back!1
Check the Contribution Guide
Review our Contribution Guide for code standards and PR process.
2
Open a Pull Request
Submit your integration to the Omi GitHub repository.
3
Join the Community
Discuss your integration with the team and community on Discord.