nisargjhaveri / WirelessAndroidAutoDongle

Use Wireless Android Auto with a car that supports only wired Android Auto using a Raspberry Pi.
MIT License
331 stars 43 forks source link

Bluetooth still connected after "handshake" #17

Closed hkfuertes closed 7 months ago

hkfuertes commented 8 months ago

Hello again, maybe this is not an issue, but I have been playing with the android project of this, and found there that just after Wifi credentials are exchanged, bluetooth connections are closed.

Is it possible to do this here? As the way it pairs is as an audio sink I don't know if the pi is an actual audio sink, or just pretends it in order for Android Auto to start the wifi credential transaction. Anyway, it keeps connected, and therefore I have 2 connections, one with the pi and other with the car at all times, and some times it gets a little bit confused, specially with phone calls...

If I go into the bluetooth settings, and untoggle the "phone calls" profile, then the handshake does not happens...

I don´t know that much C++ to propose a PR, sorry, but I can test whatever needed.

nisargjhaveri commented 8 months ago

Right. We should be able to disconnect bluetooth once the handshake is done. I had tried earlier, but ran into some issues. I can try again.

Till now, I was under the assumption that this is not causing any issue and all audio is anyway redirected to the headunit bluetooth once connected. But we should really look into it if that is not the case.

nisargjhaveri commented 8 months ago

I've pushed one change in #18, seems to work for me. You can try it out once if it makes things better.

I'm just thinking if this can have any adverse effect on reliability of the connection itself?

gamelaster commented 8 months ago

@nisargjhaveri I have weird issues with Bluetooth calls on my Kia, so I guess this disconnects might help. I will try artifact from #18

hkfuertes commented 8 months ago

Maybe this is another solution: https://github.com/nisargjhaveri/AAWirelessDongle/issues/21

Anyway, on my side, I tried the other day the #18 artifacts, but it did not work, as I already had it paired, and my phone went crazy, It worked the first time, but after restart the car and the PI, the Bluetooth was no where to be found. I will flash another card today and start over blank, and let you know...

Demon000 commented 8 months ago

@nisargjhaveri I have weird issues with Bluetooth calls on my Kia, so I guess this disconnects might help. I will try artifact from #18

Bluetooth calls are supposed to use HSP / HFP. I'm 90% sure the current profiles setup causes conflicts, but even after the fixes mentioned in #21, I don't think they would work. A (very complex) solution would be translating the HSP / HFP protocol to AA (so that HSP/HFP audio sent to the Raspberry PI gets forwarded as standard AA audio streams). This would require message parsing and it's not viable for the scope of this project (afaict).

hkfuertes commented 8 months ago

That's true. I tried manually disconnecting the Bluetooth connection (NOT turning off the Bluetooth, just the connection with the PI), and everything kept working as all the communication with the PI is done via WIFI. We just need the Bluetooth to start android auto. The thing is that for what I understand, Android Auto App will (only) react if the Bluetooth device that connects to it is an audio sink... is that true? So, if there is another way to make it react (via a custom service as @Demon000 suggests) that could be another solution, so that our phone does not think it is connected to a real Audio sink... do you know what I mean?

Demon000 commented 8 months ago

The Android Auto App reacts when only the Android Auto service (as long as properly configured) is exposed on the device (Raspberry Pi in this case). I have it working in my own project without creating any HFP/HSP service. I combined the implementation in this project (Bluez and DBus side) with the one from openauto (SDP records) to get something that works for my usecase.

Bluetooth is used by the phone to connect to the "headunit", grab the IP address and port of the TCP server accepting AA connections, and network credentials. It's not used after that for anything EXCEPT calls.

hkfuertes commented 8 months ago

Thank you for the explanation :)

Demon000 commented 8 months ago

No problem. Even though I don't use this project I thought I could share some knowledge. Working on this stuff has been very frustrating to me as there's no documentation of the protocol besides some outdated document and other implementations that are based on experimentation and the aforementioned outdated document.

hkfuertes commented 8 months ago

The Android Auto App reacts when only the Android Auto service (as long as properly configured) is exposed on the device (Raspberry Pi in this case). I have it working in my own project without creating any HFP/HSP service. I combined the implementation in this project (Bluez and DBus side) with the one from openauto (SDP records) to get something that works for my usecase.

Bluetooth is used by the phone to connect to the "headunit", grab the IP address and port of the TCP server accepting AA connections, and network credentials. It's not used after that for anything EXCEPT calls.

In this case... we don't want the calls to be routed to the PI, right? We are not emulating a whole headunit, just a bridge, most of us we will also have a Bluetooth connection with the car for Audio/Phone calls... I guess that we only want the PI to receive the projection (which I believe includes Audio (not calls)) right?

Demon000 commented 8 months ago

The Android Auto App reacts when only the Android Auto service (as long as properly configured) is exposed on the device (Raspberry Pi in this case). I have it working in my own project without creating any HFP/HSP service. I combined the implementation in this project (Bluez and DBus side) with the one from openauto (SDP records) to get something that works for my usecase. Bluetooth is used by the phone to connect to the "headunit", grab the IP address and port of the TCP server accepting AA connections, and network credentials. It's not used after that for anything EXCEPT calls.

In this case... we don't want the calls to be routed to the PI, right? We are not emulating a whole headunit, just a bridge, most of us we will also have a Bluetooth connection with the car for Audio/Phone calls... I guess that we only want the PI to receive the projection (which I believe includes Audio (not calls)) right?

The projection audio is sent via TCP (via the Wi-Fi to which the phone connects using the credentials provided using Bluetooth).

In short terms, getting rid of the HFP service so that calls are not routed to the PI should make calls be available to be routed somewhere else (the actual headunit).

hkfuertes commented 8 months ago

Also, related question (but not so quite), if you know... is there any toggle buried inside the Android Auto App that prevents it to send the Audio through the TCP? With the 2.4ghz WiFi, sometimes the audio breaks, we could offload the TCP connection somehow and route the audio via Bluetooth to the car 🤷‍♂️

Demon000 commented 8 months ago

Also, related question (but not so quite), if you know... is there any toggle buried inside the Android Auto App that prevents it to send the Audio through the TCP? With the 2.4ghz WiFi, sometimes the audio breaks, we could offload the TCP connection somehow and route the audio via Bluetooth to the car 🤷‍♂️

I'm not sure... You'd probably have to patch the data coming from the headunit, (which requires messing with SSL and Message reconstruction / deconstruction, to confuse the phone into thinking the headunit doesn't support any audio channels, in which case the phone will send the audio via other means (Bluetooth / 3.5mm jack / its own speakers). If the headunit still acts as an audio sink while in AA mode, this should work.

Does the PI not support 5GHz hotspot?

hkfuertes commented 8 months ago

Raspberry PI 3A+ and 4 yes, but Pi02W does not. I personally use the 3A+, but I have to admit that the Zero2W is smaller and easier on the eye to have it in my car dashboard. I was testing a Zero2W and when saw this behavior (I plan to gift it to my parents)...

nisargjhaveri commented 8 months ago

Anyway, on my side, I tried the other day the https://github.com/nisargjhaveri/AAWirelessDongle/pull/18 artifacts, but it did not work, as I already had it paired, and my phone went crazy, It worked the first time, but after restart the car and the PI, the Bluetooth was no where to be found. I will flash another card today and start over blank, and let you know...

@hkfuertes, that's unfortunate. Disconnecting/powering off bluetooth just after the connection was working flawlessly for me, I thought this might be the way to go. Let me know if the things are better in a fresh card, though I don't know why it would be any different.

nisargjhaveri commented 8 months ago

No problem. Even though I don't use this project I thought I could share some knowledge. Working on this stuff has been very frustrating to me as there's no documentation of the protocol besides some outdated document and other implementations that are based on experimentation and the aforementioned outdated document.

Thanks a lot @Demon000 for sharing! I agree that it is frustrating and most things are trial and error or going to random fragments of information to make sense out of it!

If we can make it work without HFP service, it would be the best. I had tried a couple of things, but could not eliminate the service. Let's me what you shared in #21, though I need to read up some more on SDP records to understand it better.

gamelaster commented 8 months ago

 A (very complex) solution would be translating the HSP / HFP protocol to AA (so that HSP/HFP audio sent to the Raspberry PI gets forwarded as standard AA audio streams)

Yeah, too complex, and not worth. Although, my phone is connected (BT) only to headunit, not to RPi, so I think this is really bug in Kia, because when I accept the call from car infotainment, it all works, but hard to say.

 is there any toggle buried inside the Android Auto App that prevents it to send the Audio through the TCP?

From Android Auto documentation, the audio streams are mandatory, and it depends on Android Auto APK how it will deal with it. Best way is to tamper with protobuf sent by headunit about streams, and remove them, to see if it will work at all. Maybe latest versions supports this, but from what I know, audio streams are mandatory.

Demon000 commented 8 months ago

A (very complex) solution would be translating the HSP / HFP protocol to AA (so that HSP/HFP audio sent to the Raspberry PI gets forwarded as standard AA audio streams)

Yeah, too complex, and not worth. Although, my phone is connected (BT) only to headunit, not to RPi, so I think this is really bug in Kia, because when I accept the call from car infotainment, it all works, but hard to say.

is there any toggle buried inside the Android Auto App that prevents it to send the Audio through the TCP?

From Android Auto documentation, the audio streams are mandatory, and it depends on Android Auto APK how it will deal with it. Best way is to tamper with protobuf sent by headunit about streams, and remove them, to see if it will work at all. Maybe latest versions supports this, but from what I know, audio streams are mandatory.

They are mandatory, but the implementation allows it. I can test it later with my own AA server implementation.

gamelaster commented 8 months ago

They are mandatory, but the implementation allows it. I can test it later with my own AA server implementation.

Yeah, of course, it is not required by protobuf, but it depends how much Android Auto projector app will like it. If you don't mind, on what are you working on?

Demon000 commented 8 months ago

They are mandatory, but the implementation allows it. I can test it later with my own AA server implementation.

Yeah, of course, it is not required by protobuf, but it depends how much Android Auto projector app will like it. If you don't mind, on what are you working on?

Android Auto implementation in node.js / electron.

hkfuertes commented 8 months ago

Anyway, on my side, I tried the other day the #18 artifacts, but it did not work, as I already had it paired, and my phone went crazy, It worked the first time, but after restart the car and the PI, the Bluetooth was no where to be found. I will flash another card today and start over blank, and let you know...

@hkfuertes, that's unfortunate. Disconnecting/powering off bluetooth just after the connection was working flawlessly for me, I thought this might be the way to go. Let me know if the things are better in a fresh card, though I don't know why it would be any different.

I tested this yesterday and it worked! :) But anyway, I guess I could wait for the NON-HSP implementation, as the original issue happens about 5% of the times only... On my part, this issue can be closed :)

nisargjhaveri commented 7 months ago

@gamelaster, were you also able try out the artefacts from #18? It seems to work well for @hkfuertes and me, though I'm still skeptical of the change to have adverse effect on connection reliability in case the phone detects the bluetooth is gone and does not connect/disconnects from the wireless AA. If it is working well for you as well, I can merge it since the non-HSP solution doesn't seem to be feasible.

gamelaster commented 7 months ago

@nisargjhaveri Sorry, I didn't tried this, I always forgot to take SD card with me. I will try to flash it tomorrow and try for few days. Would it be OK if I will get back to you during weekend, so I can test it properly? About non-HSP, I agree that it's not good idea to use.

nisargjhaveri commented 7 months ago

@gamelaster Should be completely fine, just wanted to know if you already tried. I guess the bluetooth calls issue you reported above might not be related as you mentioned in the other comment anyway.