| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
This project is a DIY proxy tool that bridges a wireless Android phone with a USB-connected car head unit to enable the use of Android Auto. Originally derived from the WirelessAndroidAutoDongle project (specifically as a replacement for its aawgd component), it has since evolved into an independent and self-contained solution with its own development direction.
The project initially focused on supporting the Raspberry Pi, but has since grown to include other platforms as well.
Sample Connection Diagram – Raspberry Pi Zero 2 W
After extensive stress testing and continuous development, the project has reached a level of stability that meets its original goals.
I now use it almost daily in my own car and continue to fix any issues that come up to ensure a smooth and reliable experience.
There's also a great and supportive community on Discord built around this project. If you'd like to join, ask questions, or get help,
feel free to connect with us on the aa-proxy Discord server.
This project is currently tested and built for the following boards that support USB OTG:
More details: https://aa-proxy.github.io/docs/supported-hardware
Note
Raspberry Pi 3 B+ is not supported due to the lack of USB OTG support.
Warning
2.4GHz Wi-Fi is being deprecated by Google and is no longer a reliable long-term solution.
Newer head units with higher resolutions (e.g. Full HD displays in some Kia/Hyundai models) require 5GHz Wi-Fi
to function with full resolution support.
Only boards with 5GHz-capable Wi-Fi chips will be able to utilize the full display resolution.
Simply changing the DPI will not solve this limitation.
Additionally, 2.4GHz Wi-Fi can interfere with Bluetooth, since both operate on the same frequency band.
This can occasionally cause connection issues — especially during the initial pairing phase when both Wi-Fi and Bluetooth are active.
The problem is particularly noticeable on devices like the Raspberry Pi Zero 2 W.
In theory, support can be extended to other hardware platforms in the future, as long as the following basic requirements are met:
Some work is already underway to bring support to more hardware platforms. For the latest updates or specific questions, feel free to ask on Discord.
The latest stable SD card images are available on the Releases page.
From the next time onward, the system should automatically connect to your phone and start Android Auto without additional steps.
Warning
For convenience during the initial setup, SSH access is enabled by default and the device uses a predefined Wi-Fi password. It is strongly recommended to change these defaults and/or disable SSH access for security reasons.
Note
📶 Default Wi-Fi credentials:
SSID: aa-proxy
WPA password: aa-proxy
🔐 Default SSH credentials:
User: root
Password: password
See below for instructions on how to connect to the device's Wi-Fi network.
If the board has a status LED, aa-proxy-rs uses it to show the connection status. At startup it looks for /sys/class/leds/aa-proxy: when it exists the LED is driven, otherwise nothing happens, so boards without a LED work as usual.
| Status | LED | When |
|---|---|---|
| Waiting | heartbeat (double pulse) | Bluetooth/Wi-Fi handshake in progress |
| Connecting | slow blink (500/500 ms) | handshake done, USB being set up |
| Connected | steady on | session running |
| Error | fast blink (100/100 ms) | last attempt failed, until the next connection |
AAWireless boards (RGB LEDs) keep their own behavior: green heartbeat while waiting, steady blue when connected.
To enable it on another board, give the LED the label aa-proxy in the device tree (the kernel needs CONFIG_LEDS_GPIO and the heartbeat, timer and default-on triggers):
leds {
compatible = "gpio-leds";
led-0 {
label = "aa-proxy";
gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
};
};
On boot the log tells whether the LED was found (single LED detected or no /sys/class/leds/aa-proxy LED found).
When you connect to the device's WiFi network, you can access the web interface, which is available by default at: http://10.0.0.1.
Warning
If you want to connect to the device (e.g. via the web interface or SSH) while Android Auto is running, it won't be accessible from your phone. In that case, you have two options:
If you're still having trouble connecting, try disabling MAC address randomization. This guide provides clear instructions on how to do it on Android.
Using the web interface, you can configure all settings that are also available in /etc/aa-proxy-rs/config.toml:
You can also download logs with a single click.
Man-in-the-middle mode support has been added recently. This is the mode which allows to change the data passed between the HU and the phone.
Separate encrypted connections are made to each device to be able to see or modify the data passed between HU and MD.
This is opening new possibilities like, e.g., forcing HU to specific DPI, adding EV capabilities to HU/cars which doesn't support this Google Maps feature.
All the above is not currently supported but should be possible and easier with this mode now implemented.
To have this mode working you need enable mitm option in configuration and provide certificate and private key for communication for both ends/devices.
Default directory where the keys are search for is: /etc/aa-proxy-rs/, and the following file set needs to be there:
I will not add these files into this repository to avoid potential problems. You can find it in other places, or even other git repos, like:
Special thanks to @gamelaster for the help, support and his OpenGAL Proxy project.
Thanks to above MITM mode a DPI setting of the car HU can be forced/replaced. This way we can change the hardcoded value to our own. This is allowing to view more data (at cost of readability/font size).
Example with Google Maps, where a Report button is available after changing this value:
| 160 DPI (default) | 130 DPI |
|---|---|
![]() |
![]() |
Google introduced EV routing features at CES24. The first cars to support this via Android Auto are the Ford Mustang Mach-E and F-150 Lightning.
This clip shows how it works in the car:
The idea of using this feature with other cars started here: #19 in February 2025. After a long journey searching for someone with the knowledge and hardware that could help us obtain the logs, we finally, at the end of June 2025, thanks to @SquidBytes, got the sample data to analyze.
Thanks to many hours of work by @Deadknight and @gamelaster, we were finally able to make some use of that data. Unfortunately, the work is still in progress, but I am currently at a stage where, by customizing some parameters, I can provide real-time battery level data to aa-proxy-rs, and overall it makes correct estimates for my car.
aa-proxy-rs has an embedded REST server for obtaining battery data from any source (I am using a slightly modified version of the canze-rs app for this purpose). It reads the data on the same Raspberry Pi (connecting wirelessly to the Bluetooth OBD dongle).
aa-proxy-rs can be configured to execute a specific data collection script when Android Auto starts and needs the battery level data, and also when it stops. The script can be configured in config.toml and is executed with the arguments start and stop accordingly.
Thanks to the power of open source, even older EVs can now enjoy modern features and a much better navigation experience!
Sometimes deleting the system Bluetooth cache at /var/lib/bluetooth and restarting bluetoothd fixes persistent issues with device connectivity. Consider also using "Forget" of bluetooth device in the Android phone.
By default, the application logs to the file: /var/log/aa-proxy-rs.log
This log can be useful for troubleshooting and diagnosing issues.
You can easily download the log file via the embedded web interface.
You can test and use aa-proxy-rs with Google's Desktop Head Unit (DHU) in two ways:
This method allows you to test with actual hardware and aa-proxy-rs running directly on the device. The flow then looks like this:
[📱 Android Phone] ⇄ [📶 BT+WiFi] ⇄ [📟 RPi with aa-proxy-rs] ⇄ [🔌 USB] ⇄ [🖥️ PC with DHU]
Steps:
[Mon Aug 25 15:24:43 2025] usb 3-1: new high-speed USB device number 84 using xhci_hcd [Mon Aug 25 15:24:43 2025] usb 3-1: New USB device found, idVendor=18d1, idProduct=2d00, bcdDevice= 6.12 [Mon Aug 25 15:24:43 2025] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [Mon Aug 25 15:24:43 2025] usb 3-1: Product: aa-proxy-rs (Raspberry Pi Zero 2 W Rev 1.0) [Mon Aug 25 15:24:43 2025] usb 3-1: Manufacturer: aa-proxy [Mon Aug 25 15:24:43 2025] usb 3-1: SerialNumber: 00000000a3f7d2c9
If you want to run the aa-proxy-rs application itself for development or functional testing — without using a physical Raspberry Pi — you can build and run it natively on the same platform where DHU is running (Linux/macOS).
In this setup, we recommend using the wired option in the config, which enables a USB-based connection between your phone and host machine. The flow then looks like this:
[📱 Android Phone] ⇄ [🔌 USB] ⇄ [💻 PC with aa-proxy-rs] ⇄ [🖥️ DHU]
To make this work, follow these steps:
There are many commercial solutions available for wireless Android Auto, such as AAWireless or Motorola MA1. I even bought a clone from AliExpress — but unfortunately, it didn’t work in my car (I ended up giving it to a friend who had a compatible vehicle).
Thanks to Nicnl on Reddit, who commented under this post, I discovered a great open-source project based on Raspberry Pi hardware: WirelessAndroidAutoDongle by Nisarg Jhaveri.
The author did some excellent research and created a working DIY solution — and most importantly, he shared it openly with the community. That’s something I truly admire and appreciate!
Because the project is open source, I was even able to run additional LoRa hardware on the same Raspberry Pi for a completely different purpose.
The original project uses a daemon called aawgd, which handles proxying data between the phone and the USB-connected head unit. Unfortunately (or fortunately!), the original implementation wasn’t always reliable in my case — I experienced crashes, failed reconnections, and the need to restart the service manually.
After submitting this pull request, I decided to create a Rust-based alternative to aawgd. That’s how this project started — by reimplementing the C++ code into a new, standalone application written in Rust.
From the beginning, I aimed to simplify parts of the original code wherever possible. This project also became a great opportunity (and a lot of fun!) to dive deeper into how the system was designed and how everything works under the hood.
One of the biggest challenges I faced was implementing reliable bidirectional I/O forwarding. Since the entire application is asynchronous and uses Tokio, my first instinct was to use copy_bidirectional. However, this approach didn’t work as expected — likely due to how the USB socket for the usb-gadget kernel module interacts with polling/epoll mechanisms.
I also experimented with running separate read/write operations inside Tokio tasks, but ultimately found a better solution: using the modern io_uring interface via the tokio_uring library.
This approach turned out to be both highly efficient and completely stable — solving the problem in a clean and performant way.
The project depends on the kernel-level io_uring API for its core data transfer functionality. As a result, Linux kernel version 5.10 or newer is required.
Please note: I work on this project in my free time as a hobby. While I do my best to respond and fix issues, I can't always guarantee quick replies or provide ETAs for requested features.
The connection process is quite complex and involves several carefully timed steps to establish a stable link between the phone and the car head unit. Below is an overview of what the app does from start to finish:
The USB side is the active initiator of data transmission, starting with sending a 10-byte first frame. Because of this, timing is critical:
Proper synchronization between these steps ensures a stable and reliable connection.
Default startup config file is /etc/aa-proxy-rs/config.toml.
Configuration options are documented in comments, but these needs some more attention:
legacy
Original aawgd is using two USB gadgets: default and accessory. When connecting to car headunit, it switches first to default then to accessory.
During my development I found out that my car headunit doesn't need this switching. It is working fine connecting directly to accessory gadget.
Moreover with this approach it is much faster and doesn't need to wait for USB events in dedicated UEvent thread. As the result I decided to leave the old (legacy)
code under this switch for compatibility with some headunits.
In short: if you have problems with USB connection try to enable the legacy mode.
connect
By default without this option the aa-proxy-rs is starting but it is only visible as a bluetooth dongle, to which you have to connect manually from your phone to
initiate AndroidAuto connection. If I am correct this was called dongle mode in aawgd.
If you provide connect option with default 00:00:00:00:00:00 wildcard address, then the daemon is trying to connect to known (paired?) bluetooth devices (phones) in a loop
(the bluetoothd have a cached list of recently connected devices in /var/lib/bluetooth).
If you set this option to specific MAC_ADDRESS where MAC_ADDRESS is the MAC of your phone (bluetooth), then the aa-proxy-rs will try to connect only to this specified device
in a loop (ignoring all bluetoothd cached devices).
If you'd like to build the SD card images yourself, head over to our Buildroot repository:
https://github.com/aa-proxy/buildroot
There you’ll find all the necessary tools and instructions to generate custom images tailored to your hardware or specific needs.
While the aa-proxy-rs binary is typically used as part of the prebuilt system image, it can also be run manually:
Usage: aa-proxy-rs [OPTIONS] Options: -c, --config <CONFIG> Config file path [default: /etc/aa-proxy-rs/config.toml] -g, --generate-system-config Generate system config and exit -h, --help Print help -V, --version Print version
Warning
Kernel Requirements for Stand-alone Usage
If you plan to run aa-proxy-rs on your own system (outside of the provided system images), be aware that additional custom kernel modules are required for full functionality. These modules are not upstreamed and must be built separately.
You can find the necessary patches here:
👉 https://github.com/aa-proxy/buildroot/tree/main/external/patches/linux
Please keep this in mind when creating your own custom solution with aa-proxy-rs.
To achieve full functionality similar to the official Buildroot-based images, make sure the following kernel options are enabled as well:
To ensure a consistent development environment, this project includes a setup script that configures Git hooks and other local tooling.
Run the following script after cloning the repository:
./setup-dev.sh
This will configure Git to use repository-managed hooks.
Git hooks are not shared automatically between developers. Without this setup, local hooks (such as formatting checks) will not run.
This script ensures that everyone working on the project uses the same development rules (e.g. cargo fmt checks before commits).
If you prefer to configure hooks manually, you can run:
git config core.hooksPath .githooks
However, using setup-dev.sh is the recommended approach.
| Back | FazBrowse Home | New Git URL |