-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor AA protocol code to use protocol buffers #16
Comments
Got farther in decoding more of the init message into proto code. Turns out the Linux Google desktop head unit binary is not stripped, so if you look at the symbols and know the structure of the code protoc generates you can get info:
|
This looks really really promising for less headaches in the source. (I'd archive the Linux binary before Google notices and removes it though :P ) |
Yes it does look good, the only problem is for the love of my life I was never able to understand the protobuf thing, I'm not saying that I know too much about programing or so, but with the original code I kind'a can understand what I'm doing, and how to manipulate / construct the message, all through still having some difficulties figuring out everything. Here is some more information I managed to figure out, if GPS sensor data can be fully decoded it means the phone can take advantage of the car's GPS rather than relying on the phone GPS.
data[3]=(byte)0x0a - Is indicating the Location sensor: This translates to velocity of 0.001 (aka we are NOT moving)
This on the other hand translates to a suspicious accuracy of 0.001 (i use to inject this so AA doesn't take the location received from the car in consideration, otherwise it will put you in the middle of the ocean at Lat: 0, Long: 0)
I figured out the the (byte)0x30 and (byte)0x20 are following a pattern, every time increment of 8. |
For aa version 1.6 drive status 0 was enough, since aa 2.0 it does check on the GPS data sent over by the car..... Grrrrrrr.... If no data sent over the speed is considered null which means car not parked, what a crazy logic. Yeah I know what's the concept of protobuf but somehow they are not designed for my brain.... You know when you just cannot make sense of something no matter what.... Or maybe my brain is to limited to understand them..... I fully get the concept but was never able to get the examples running form Google site so I gave up. Byte buffer it is then, trail and fail and more fail till I succeed, but that's the wrong way i know your approach is much better. Take a look on the byte buffer for the Bluetooth hands free as well, I think you will be able to work out the naming there as well, I have added it as comment to issue number 2, sorry typing from phone and lazy to insert links |
Yeah I could see it adds another layer of obfuscation, but basically what it's doing is you write a text file which describes the structs then protoc generates you source code to convert the structs to and from the bytestream (with Parse and Serialize methods on C++ version) Since the bytestreams you are writing are originally protobuf messages they have data in them for protoc to understand the format, but just no names of the fields. So you can use the decode_raw mode to print out the structure of a dump. So what I was doing was looking at that then adding the field names myself based on the existing code and/or guessing. You can test it by decoding the dump on the command line with protoc and the proto file. So like for example for the CarInfo struct, this writes the same data as the sd_buf:
I used SerializeToOstream since I'm lazy 😄 but there is Serialize and Parse to raw buffers too. For the GPS stuff, I'm not sure that's the right way to go it might cause problems with maps and other stuff. What about the SENSOR_TYPE_DRIVING_STATUS? It seems like it's a bool which sets this setting directly. EDIT: Reposting under right account |
Argh, that's super annoying. I would assume it would use the phone's GPS if the HU doesn't report a GPS sensor. Still can't mess with the map when driving but at least it would match a real HU. The car has a GPS so maybe we need to figure out how to get that data from the CMU dbus. Yeah I will take a look at the bluetooth stuff when I have some time. Some of the other stuff I would hope to add is hooking up more stuff to the real CMU parts. Like the Mazda OS has access to the hardware light sensor though a proc file, I want to hook that up to night/day mode instead of the time. It also seems like there is way to expose the XM radio as a AA music source based on the desktop headunit code. That would be awesome. |
It doesn't mess up the GPS, I'm using it like that for the last 2 days, initially it set you to 0,0 (near Africa) but than the phone GPS picks up and it all works fine. |
@lmagder it looks like you have way more knowledge than me, so maybe you have an idea on this. This is how the Sensor data should look (in Java):
Now, I know that the following bytearray is working:
I also know that data[13] in the input byte array is translated to d[5] in Java, if instead of
Now to my unknowing head this says that the first 4 bytes of the Any ideas? |
Can you paste |
Here is the whole class:
|
LocationData proto definiton, hope that will help you:
|
Thanks @anod the only problem is I wasn't yet able to construct the proper bytearray for this, I think I need to sit down and chew over those protobuf documentations till I finally able to master them. |
I think example will help you, Example of nightmode message:
Result: To recreate location data message:
|
@anod - You're a legend, inserted a location successfully, based on your protobuf now I need to fully implement it into the code, rather than converting it on the command line. This is huge (and great), it means we can offload all the GPS to the headunit (tablet) and rely on the external GPS antenna of the headunit rather than the small built in GPS of the phone, beside if we offload the GPS that should reduce power needed by phone, meaning it can charger slightly better when plugged in. |
Also, some additions about location data: latitude, longtitude seem to be multiplied by 1e7 and then converted to int. Accuracy is multiplied by 1e3, altitude 1e2, speed 1e3 and bearing 1e6. This is probably because all those payloads are ints in protocol, but have decimals in actual data. |
So, basically, if decimal latitude from GPS is |
Yes that's correct, I already got it working from Android.
P.s. set the bearing and speed to 0 ignoring the real value and you will
have access to unlimited browsing all the time.
Kind regards.
Emil Borconi-Szedressy
Sent from my mobile
…On 3 Dec 2016 3:16 p.m., "Jernej Virag" ***@***.***> wrote:
So, basically, if decimal latitude from GPS is 46.0552778, the actual
number encoded into message should be 460552778. If current speed is 112.12
km/h, the number sent should be 112120, etc. etc.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#16 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAo8PMkXl-mCDneVih3y5IIRA-IIb-y-ks5rEYe5gaJpZM4J6Irb>
.
|
Also, NanoPB http://koti.kapsi.fi/~jpa/nanopb/ seems to be a simpler more lightweight option for a C PB lib :) |
Ah too late though :) already converted it to use the standard one as a test: https://github.com/lmagder/headunit/tree/protobuf-refactor Haven't tried on my car yet, and too big a change to be a serious pull request but it's there if anyone's interested. The ubuntu version works at least and the mazda one compiles. |
Ahh, nice, the proto definitions make code significantly more bareable :D |
Yeah, hopefully it will be easy to integrate the other fixes you guys discovered while I was doing this. Just tried in my car and it runs! I was worried the C++ conversion would add runtime requirements, but it seems using static libc++ avoids this. Audio broke for some reason but not mic, everything else works. Time to start debugging... :) The audio issue was intermittent before on 0.94 and was usually fixed by rebooting the CMU, so maybe not related. |
Ok false alarm. The audio actually works. I just had the phone connected to the car through Bluetooth audio by accident so it was routing the audio through there. So I would say the code at https://github.com/lmagder/headunit/tree/protobuf-refactor has the same functionality as 0.94 currently. |
Thanks to @anod here is a quite complex protobuf with some additional info included. Going to post here when more is decoded.
|
@lmagder can you do a quick test on your branch? Set all input (audio) and the video channel property "available_in_call" to "false" and try if phone calls still get kicked back to the phone? |
It's not my merit, it's @anod who did 95% of the work, I just completed a
few more after he gave me a hint on how to get them, so the credit belongs
to him not to me.
Kind regards.
Emil Borconi-Szedressy
Sent from my mobile
…On 4 Dec 2016 8:55 p.m., "Lucas Magder" ***@***.***> wrote:
@izacus <https://github.com/izacus> sure, I will try and report back. If
you want to mess with it my branch should be self-contained to build too if
you get the submodules also.
@borconi <https://github.com/borconi> awesome! Thanks. Looks like we
picked different names for some the same fields. Was bound to happen, but
slight difficult to merge :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#16 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAo8PN_pCIFE1IKEc6b3kJfUWLZXXwgYks5rEyilgaJpZM4J6Irb>
.
|
@lmagder hmm, your build refuses to recognise my Pixel XL on USB, kinda just dies with "MISMATCH".
What were the changes there? (Also code doesn't compile without NDEBUG at all, which makes debugging now extremely hard.) (Whatever it is, it was broken in lmagder@adef161?diff=unified ) |
Argh, sorry, you might want to try this branch https://github.com/lmagder/headunit/tree/protobuf-refactor it's strictly 0.94 with the protobuf changes. My main branch has a bunch of refactoring I'm not done yet so might be kind broken. It works on my PC with a 6P, but on my laptop I get the same MISMATCH error as you so at least I can debug. |
Also you are right I broke NDEBUG, but I think you can turn on the logging ints in the hu_uti.cpp file and it will print. Sorry it's kind of rough. |
Yeah, no problem, just wanted to rebase my sensors stuff so we don't duplicate work :) The issue seems to be in bulk transfer code, for some reason the first RECV fails. I'll just grab the protobuf branch as the base. |
Ok, I have put some more of the protobuf data together, although most of it has no use at the moment because AA doesn't support it YET, but I'm confident it will eventually.
|
Great, this is useful. Unfortunately some of the stuff is renamed, probably the correct name according to the AA designers, but different than our current code, which makes it not a super clean merge. I guess we should eventually convert over to share the proto definitions more easily. I dunno about the Gear enum. That does seem crazy. Maybe there is a non-contiguous range of valid values? Are you sure your disassembly is correct? |
Yeah pretty positive it's correct. Thanks to @anod again. For sharing now I
have the answer to that as well, just need to work it all out.
Knock you self out with this:
https://android.googlesource.com/platform/packages/services/Car/+/nougat-release/
It will help a lot with understanding the whole AA protocol. I did saw all
the possible values for gear data in one of the files I just need to add
them to the protp
Kind regards.
Emil Borconi-Szedressy
Sent from my mobile
…On 19 Dec 2016 2:16 a.m., "Lucas Magder" ***@***.***> wrote:
Great, this is useful. Unfortunately some of the stuff is renamed,
probably the correct name according to the AA designers, but different than
our current code, which makes it not a super clean merge. I guess we should
eventually convert over to share the proto definitions more easily.
I dunno about the Gear enum. That does seem crazy. Maybe there is a
non-contiguous range of valid values? Are you sure your disassembly is
correct?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#16 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAo8PKut2IPH74tDhFPeXUGFwX0Fo6J3ks5rJejvgaJpZM4J6Irb>
.
|
Ok, update the gear enum as well with correct/possible values.... this project is getting really exciting... I'm very very intrigued now to figure out how can AA communicate with the car cluster, looks like nougat will be able to do that... assuming we have a class which can implement that on the car side.... Update: |
Alos one very interesting - @anod you might like this - (and possibly important thing I have discovered and it is fully undocumented at the moment) is an additional service. So where we have this as of definition:
We should have:
|
Ohh, the driving status enum now makes a lot more sense - and kinda explains what's going on with the keyboard. |
@borconi The driving status names don't make any sense for me, maybe only unrestricted :) But, what I can't understand is the values for sensor type, in the sources they are different that we use (SENSOR_TYPE_DRIVING_STATUS = 13; SENSOR_TYPE_NIGHT_DATA = 10) and in the source code their values are 11 and 9 (also in auto apk 1.0 they were referred like that) According to this driving status is actually driving restrictions |
@anod - Yeah the naming and coding it a total mind f!, have a look here: It is VERY confusing trying to puzzle it together I lost track so many times already and every time I have to sit down and start chewing from start what is what.... Basically when we define the connection, the driving status is the 13rd defined element, hence we use to think it is sensor 13, BUT actually in Android Auto that is sensor number 11 only.... so while we define it as 13 in the protobuf when we send data, we are sending data like 80036a020801 (message 8003, defined item 13, status 1 - this will be mapped in android auto to Sensor 11 satus 1) hope it makes sense, I know it is VERY VERY confusing.... |
Yes I understand that, cannot find the place where conversion is happening. should be where ServiceDiscoveryResponse is being processed |
I wasn't able to find that either, but here is a small conversion table to help keep track every time we get confused 😈
@anod - Oh and about the driving_status.... |
It also controls the type of keyboard displayed - there's a fullscreen keyboard (unusable with hardware keys), keyboard built for a rotary control (only usable with rotary input) and no keyboard display in the map. So the point is that you can switch depending on car state. |
That makes sense and paints the whole picture now...
Kind regards
Emil Borconi-Szedressy
Tel: +44-791-32-32-588
…On 20 December 2016 at 15:10, Jernej Virag ***@***.***> wrote:
It also controls the type of keyboard displayed - there's a fullscreen
keyboard (unusable with hardware keys), keyboard built for a rotary control
(only usable with rotary input) and no keyboard display in the map.
So the point is that you can switch depending on car state.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#16 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAo8PAbgTH05gRNkR-CktOKEOAG9KAf3ks5rJ-_PgaJpZM4J6Irb>
.
|
Hmm, so the question here still is - why do we have to send "13" in supported sensor type to get the keyboard on maps to show up? In all the Google source code, that number is just marked as "RESERVED". Is there anything else playing at that? |
@borconi Hey I am working on getting the phone_service to work correctly and I am just learning about protobuf so does this look correct? the numbers in the enum are the actual values of bthfstate returned by the signal handler CallStatus in BTHF: #79 #80
|
@Trevelopment yeap looks right from protobuf point of view. Where did you get the enum values? |
@Trevelopment I had a quick look in the Desktop Headunit binary and I think the ENUM you are looking is slightly different:
Also the CallAdapter (named Phone Status in AA world) has several other properties:
Also there are a few other things which are related to this, so to get this sorted in the very correct way there is quite some work to be done. I'm currently up to my eyeball working on some different projects (like this: https://www.youtube.com/watch?v=l62z3aFZePQ) However if you get stuck on it do give me a shout and I will try to help you on this at some point in a couple of weeks. EDIT: |
@borconi Thanks man. I got those values by running |
@Trevelopment my skills are almost 0, honestly most of the time I have no clue what I'm doing and I'm not bluffing. I do all my coding with StackOverflow, never learned anything anywhere... and I have HUGE gaps in my knowledge. You will need XDA Labs to purchase, more details about the app: https://forum.xda-developers.com/general/paid-software/app-obd2-plugin-android-auto-torque-t3657805 |
@borconi dude you skills are definitely way higher than 0. But I gotta go to work so |
@borconi DUDE that shiz is OFF the CHAIN. I had the idea to make something like this ever since I got my OBDII ELM327 but I hadn't even thought about integrating Torque with AA and it works GREAT. Of course there's always things to make better in the world of software but so far 👍 👍 👍 👍 kudos my friend! I didn't even have really any time to set it up so I jsut picked a quick 6 and I had this up and running in less than 2 minutes! |
Thanks |
@borconi I'm a professional software engineer, and, believe me, while there's skill and experience, a lot of it is "Can you Google / StackOverflow the answer to your problem?" Being able to achieve something is a big hurdle for most people to overcome. 👍 |
Thanks @mishan |
hey @borconi I turned this guy onto your app: https://youtu.be/cr7Onzl5jro its in Spanish with English subtitles but this guy has a decent following. I hope its been helping boost your app sales buddy |
Thank you. He already helped translate the app to Spanish
Kind regards.
Emil Borconi-Szedressy
Sent from my mobile
…On 4 Nov 2017 12:10 pm, "Trezdog44" ***@***.***> wrote:
hey @borconi <https://github.com/borconi> I turned this guy onto your
app: https://youtu.be/cr7Onzl5jro its in Spanish with English subtitles
but this guy has a decent following. I hope its been helping boost your app
sales buddy
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#16 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAo8PCbtOsQqVarzZn9InT5evQwi_xjPks5szFRLgaJpZM4J6Irb>
.
|
Sharing some more with you guys, in case you want to integrate it in your build. Below are MediaBrowserServices and NavigationServices protobuffers:
You will need to declare this services when you establish the connection between the car and phone. If you do you can get media info and navigation info while Android Auto is in the background, handy to display notification even when Android Auto is in the background. This is how then you re-construct the messages. (I know it's Java not C but hopefully you will be able to port it accordingly):
|
Thanks! this is good info. I have no idea how to display this info in the CMU without requiring massive edits to the JS but maybe someday we will find a way. |
I did some preliminary investigation into writing proto
files instead of manually constructing the wire protocol, but only with some messages sent by the headunit to the phone so far.
For example in the function I added to send a button message
I saved this out with timestamp = 15, button = 32, isPress = true as buttonMessage.bin. Running this through
protoc --decode_raw < buttonMessage.bin
yields
so actually you can see there are two messages concatenated here (since there can't be two field #1s).
Assuming all the fields are there the first field is pretty simple, something like
so I chopped it off to get
so just making up names assuming what the code does and inferring types from the wire format since unfortunately protoc does not print them, despite knowing them.
seems to work:
I did a few more like the touch event and the day/night sensor notification and you can start to see patterns. The first packet is always a single enum which is the type of second packet and then all the input events are one packet type with optional sub-structs, same with the sensor event. So it seems you can send all or any subset of the sensors at once. I attached the files.
This would definitely clean up code a lot (especially the sd_buf stuff in hu_app.c) and it shouldn't add runtime requirements since all the protoc stuff generates code you compile and link against. The only potential problem is that protoc generates C++ code by default, which is probably nicer and would work since input_filter uses modern C++, but would be a drastic change. There is a unofficial protoc-c project though
testFiles.zip
The text was updated successfully, but these errors were encountered: