Giter Club home page Giter Club logo

spotify-car-thing-reverse-engineering's People

Contributors

deadman96385 avatar err4o4 avatar risograph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spotify-car-thing-reverse-engineering's Issues

Custom HTML using the stock, out-of-the-box firmware

It seemed like extra hassle to have to update the firmware just to run a custom webapp, so here's the minimum amount of JavaScript to initialize the stock, OOTB Superbird so you can see your own HTML on it.

Unlike the Chromium in later firmware, the stock Superbird is running QtWebEngine 5.12.7, equivalent to Chromium 69.0.3497.113 (although its User-Agent reports 69.0.3497.128). The webapp is built into the qt-superbird-app, embedded as Qt resources. It can be extracted from the binary using Ghidra and the scripts described in @gipi's article, Reversing C++, Qt based applications using Ghidra, available in their repo at https://github.com/gipi/ghidra_scripts.

There's no "Control WebSocket" in the stock app when it first launches, it instead initially uses a QWebChannel, and there appear to be a few initialization commands sent back from the webapp to qt-superbird-app before it will start rendering HTML and provide messages over the QWebChannel. Not all the initialization commands are necessary to start rendering HTML, and the status messages that come in regularly over the QWebChannel can be ignored.

QtWebEngine heavily caches all the files it accesses, and manually emptying the cache(s) between runs will spare a lot of headaches when testing.

Assuming you've followed in the instructions in @frederic's https://github.com/frederic/superbird-bulkcmd repo to enable ADB (or equivalent), you can do something like this to stop the existing processes, upload an example.html, clear the caches, and launch qt-superbird-app manually using the same configuration as specified for supervisord plus a Chrome remote debugging port:

$ adb shell supervisorctl stop swupdate
swupdate: stopped
$ adb shell supervisorctl stop superbird
superbird: stopped
$ adb shell mkdir /tmp/webapp
$ adb push example.html /tmp/webapp/
example.html: 1 file pushed, 0 skipped. 0.8 MB/s (1188 bytes in 0.001s)
$ adb forward tcp:9222 tcp:9222
9222
$ adb shell rm -rf /var/cache/QtWebEngineCache/*
$ adb shell rm -rf /var/cache/qt-superbird-app/*
$ adb shell 'QT_LOGGING_RULES="" QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox --ignore-gpu-blacklist --touch-events=enabled" QT_QPA_EGLFS_INTEGRATION="eglfs_mali" QMLSCENE_DEVICE="" QT_QUICK_BACKEND="" QT_QPA_EGLFS_PHYSICAL_WIDTH="51" QT_QPA_EGLFS_PHYSICAL_HEIGHT="86" QT_QPA_EGLFS_ROTATION="-90" QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS="/dev/input/event3:rotate=270" QT_QPA_EGLFS_NO_LIBINPUT="1" HOME="/home/superbird" XDG_CACHE_HOME="/var/cache" XDG_RUNTIME_DIR="/var/cache/qt-superbird-app" QTWEBENGINE_REMOTE_DEBUGGING=9222 qt-superbird-app --config=/etc/qt-superbird-app/superbird_target.ini --url file:///tmp/webapp/example.html'
2015-01-01T03:44:04.870Z [D] main.cpp:66 BOOTMARK: main(): 0ms
2015-01-01T03:44:04.872Z [D] main.cpp:73 BOOTMARK: Config Parsed: 3ms
...

You can also run your webapp on your local machine and reverse the port to the Superbird using ADB, replacing --url file:///tmp/webapp/example.html above with --url http://localhost:8000/example.html:

$ adb reverse tcp:8000 tcp:8000
$ python3 -m http.server
Serving HTTP on port 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
...

Here's the contents of example.html, the meta elements are from the stock webapp, qwebchannel.js is built-in, the handleResponse function overloads the stock one to not delete the callbacks once they're executed to avoid some JS warnings, and the signalEmitted function is where you'd go to see the status messages coming in over the channel:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=800,height=480,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="HandheldFriendly" content="true"/>
<title>Superbird</title>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script>
var _superbirdchannel = new QWebChannel(qt.webChannelTransport, function(channel){});
_superbirdchannel.handleResponse = function(message) {
  if (!message.hasOwnProperty("id")) {
    console.error("Invalid response message received: ", JSON.stringify(message));
    return;
  };
  this.execCallbacks[message.id](message.data);
};
_superbirdchannel.execCallbacks[0] = function(data){};
_superbirdchannel.execCallbacks[1] = function(data){};
_superbirdchannel.objects = {};
_superbirdchannel.objects.superbird = {};
_superbirdchannel.objects.superbird.signalEmitted = function(signal, args){};
_superbirdchannel.send({type: 3, id: 0});
_superbirdchannel.send({type: 7, object: 'superbird', signal: 5});
_superbirdchannel.send({type: 6, object: 'superbird', method: 9, args: [], id: 1});
</script>
</head>
<body style="background-color:#0f0;">
<h1>superbird OOTB</h1>
</body>
</html>

When run, it looks like this:

superbirdootb

Discussion of Car Thing annoyances and possible future project goals

In another issue @chewitt posed the question, what are the goals of this work?

I figured that the best place to start is with the things that annoy us so I'd love to hear from folks what they wish the Car Thing did differently. Here's my initial list:

  1. Interaction with the Car Thing often returns audio playback to the phone. I'm currently using the car thing on my desk and with the current behavior I can't really do much more than use the previous/next buttons. Pressing "play" will cause audio to revert to being played out from my phone rather than my desktop Spotify player.
  2. Reliance on a phone at all. Right now I have an old iPhone 6 acting as the base station for the car thing, but it feels silly. It would be great to be able to pair this with my computer and not have to rely on a dummy phone at all.
  3. Volume control over Spotify connect works...sometimes. Sometimes it will change the desktop player's volume, sometimes it just doesn't.
  4. Turning the display off after N minutes of no playback. Right now the car thing stays on forever as long as it has power. Fortunately I can plug it into a power strip I use that has a master/slave setup with my main desktop. When the desktop goes to sleep or is off, the rest of my audio gear shuts off too. However it would be nice if the car thing could "go to sleep" if there's no activity for a while.

Reconstructed webapp source code (with working builds!)

Thanks to the sourcemaps Spotify left on the device, I've put together a complete reconstruction of the TypeScript/React source code of the superbird webapp with working builds (using Vite, so you also get hot reload) and a script to easily push changes to the device. Hopefully this should let us do things like add more menus and features or remove software restrictions!

I've put all the code in this repo along with some documentation, feel free to file issues and give feedback: https://github.com/Merlin04/superbird-webapp

Feature request feasibility

Hello!

As we go forward experimenting with the newly unlocked hardware, Woot Woot! (I'm very excited to see what comes of it), I was wondering if the following features were even possible:

-Google Maps navigation displayed on car thing

-Ability to accept calls with an android device

I've created a Discord Community Server

Hey guys I've created a simple community server for us to chat and share projects.

It's pretty simple and new but I'll be improving as we go on, and if there anyone who wishes to help let me know.

Here's the invite link: https://discord.gg/Nksa7SQc
Any questions just hit me up.

#Update 1 - Invite Link is fixed

Able to open dev menu (but it's useless)

By patching the Spotify APK I was able to open the developer menu on the device.

It's not very useful though, basically just contains a couple extra settings:

2ea2fdb8-378f-4251-a914-3038d1f0732a

5110e940-105b-4c44-8a05-ad75be26f534

f760620d-cb99-434f-9d05-5eda583fb2c8

Getting more OEM/ODM info

I dont know if anyone else has research this yet but I found something interesting by searching for FCC applications by Spotify. Below is the link.
https://fccid.io/2AP3D
It seems as though there was an earlier style of Car Thing without a screen which I did not know about. Might be useful for anyone out there looking into this device though.

10%

Oops, accidentally pressed enter - ignore this

Button combinations

I just wanted to share that I came across the fact that if you hold the top 4 left buttons (excluding the recessed button) and then boot it, it seems to go into a different mode that shows up under lsusb. I am not well versed in the hardware side of things, so the info you have on here already might mean that you know this already, but just wanted to let you know.

Thanks,
-MH

CarPlay & Android Auto functionality

According to this twitter post by Zhuowei Zhang from July linking this Car Thing support article, it seems as if you can cast the display of your Car Thing to any CarPlay/Android Auto compatible on-board computer*.

This probably means that, if ever made possible, a CFW'd Car Thing could display whatever it wants to an on-board computer.
If anyone has any more info about this, please reply. And I ask of anyone with a supported device & a Car Thing to test this out for me.

Linked in the post's replies is proof that the CarPlay has MFi compatibility. Link (see lines 1033 thru 1043)

*Information from https://support.spotify.com/us/article/setting-up-car-thing/:

"Apple CarPlay and Android Auto
If Apple CarPlay or Android Auto is available in your car, you can use it with Car Thing. Just connect Car Thing to the sound system with the USB cable.
Car Thing’s screen will then also show on the head unit’s screen, but you can still use Car Thing to control what is playing.
For more information go to Android Auto Help Center or Apple CarPlay support site."

MITM Processing of Car Thing Requests

I've found that there is a lot of interesting information that gets streamed through the host device from the Car Thing using MITM.
A popular endpoint seems to be "https://spclient.wg.spotify.com/gabo-receiver-service/v3/events"

There is also a request to this domain "https://spclient.wg.spotify.com/carthing-proxy/network/v2/logevents/8550R786Q81O" that transmits vitals from the device.

[
  {
    "swap_cached": 0,
    "cached": 129628,
    "mem_total": 501172,
    "swap_total": 0,
    "type": "memory_v2",
    "buffers": 1244,
    "mem_free": 126880,
    "swap_free": 0,
    "timestamp": 1665943898032,
    "mem_available": 254092,
    "processes": {
      "QtWebEngineProcess --type:zygote": {
        "vm_hwm": 30132,
        "vm_rss": 17512
      },
      "supervisord": {
        "vm_rss": 11868,
        "vm_hwm": 11948
      },
      "swupdate": {
        "vm_rss": 1528,
        "vm_hwm": 3260
      },
      "QtWebEngineProcess --type=renderer": {
        "vm_rss": 125904,
        "vm_hwm": 131756
      },
      "sp-als-backlight": {
        "vm_hwm": 208,
        "vm_rss": 172
      },
      "bluetoothd": {
        "vm_rss": 2168,
        "vm_hwm": 3004
      },
      "qt-superbird-app": {
        "vm_rss": 139220,
        "vm_hwm": 177360
      }
    }
  },
  {
    "uptime": "12 12",
    "mounts": {
      "/var": {
        "available_MB": 1882,
        "used_MB": 35
      },
      "/var/lib": {
        "available_MB": 221,
        "used_MB": 2
      },
      "/": {
        "used_MB": 392,
        "available_MB": 76
      },
      "/home": {
        "available_MB": 1882,
        "used_MB": 35
      }
    },
    "timestamp": 1665943898199,
    "type": "storage"
  },
  {
    "type": "temperature",
    "timestamp": 1665943898200,
    "temperatures": {
      "dram_thermal": "34.72",
      "soc_thermal": "42.10",
      "ddr_thermal": "42.30",
      "bluetooth_thermal": "34.56",
      "pcb_thermal": "34.35"
    }
  }
]

Fixing a rattly knob?

My car thing has a particularly rattly knob (compared it to a friend's) - has anyone taken apart the device to the point where the internals of the knob are exposed? I think that could help with diagnosing the problem (in addition to satisfying my curiosity about how the mechanism works)

Similar to Radxa Zero ?

The Radxa Zero uses an Amlogic S905Y2, and I wonder if some of the development information is applicable?
For example, check out this page about maskrom, which mentions the same 1b8e:c003 Amlogic, Inc. GX-CHIP device just like the Car Thing does when you hold the 4 buttons.

I wonder if this is a way we could sideload our own binaries, kind of like using fastboot to boot a recovery image on an android device.

10% off coupon code

To anyone who hasn't purchased the car thing yet - there's a 10% off coupon code you can use, EXTRA10

Random car thing findings

I'll just be logging random stuff I figure out here lol

Older firmware versions seem to use a very stripped down chromium thing for it's UI but newer versions (not sure when they made the switch) use a much more fully featured copy of chromium that has a new tab page and everything. Easiest way to access it is to edit /etc/supervisord.conf and remove the kiosk and webapp flags from the chrome command.

If you dump the fw from a brand new car thing you can essentially treat that dump like a factory image. A bit more info and a script to flash it are here: frederic/superbird-bulkcmd#12

Key Codes from buttons

You can use the command showkey to dump the key codes.

Back Button = ESC ( 0x1 KEY_ESC )
Rotary Button -RETRUN (0x1c KEY_ENTER)

Starting from Top left, the preset buttons
1 - Number key 1 - (0x2 KEY_1)
2 - Number key 2 - (0x3 KEY_2)
3 - Number key 3 - (0x4 KEY_3)
4 - Number key 4 - (0x5 KEY_4)
5 - Power Button - Letter Key M - (0x32 KEY_M)

Cross-platform alternative to amlogic usb tool binary

I found this repo which appears to be source for an earlier version of the amlogic usb tool. Specifically, it appears to be:
Amlogic update USB tool(Ver 1.5) 2017/05
as opposed to the one provided by Frederic, which is:
Amlogic update USB tool(Ver 1.7.2) 2018/04

I had no trouble building it on Ubuntu x86_64, but it doesn't work with superbird, which isn't terribly surprising.

There is another repo, forked from the first one, with some changes made to support p230. Probably not much use for us.

I also found that the khadas repo has the same update tool for Windows, x86_64 Linux, and armhf Linux. The versions here match the one provided by frederic. I got excited at the armhf one, but I'm getting an exec format error when i try to use it, so I think I'm missing some detail. I haven't tried the Windows one. There are some additional tools in that repo that may be useful as well.

So, my point is: If someone understands what's going on better than I, they could tweak that old source so that it works with superbird, and then we would have a tool that could potentially be ported to other platforms.

I am particularly interested in this, because my main dev machine is aarch64, and I had to haul out an old Intel machine to work on superbird; It

Source code request

Hi! Has anyone tried asking for the source code for whatever form of Linux they're running from Spotify themselves?

Might be some good pointers in there for how the hardware is wired up internally.

Method to switch between boot slots

The car thing seems to have a way to fallback to the previous version of the OS if something fails on the latest one, similar to newer android phones and their A/B partition layout.

Switching method:

  1. Plug in car thing
  2. Wait for Spotify logo to appear then wait an additional second
  3. Unplug it, never actually letting it load the OS
  4. Repeat the above steps 8 times
  5. Leave car thing plugged in on the 8th time

This should force it to go back to the previous OS version then if you do the same thing again it'll go to the latest one.

Car thing as a macropad!

Thanks to u/Jaba_Haba on reddit for bringing Macro Deck (the software making this possible) to my attention!
https://www.reddit.com/r/carthinghax/comments/yq5p77/macro_deck_for_car_thing/

  1. Flash the ADB image from here: #22
    There's instructions on how to do it in the folder with the firmware images.
  2. Make sure adb is installed and working on your PC. XDA has a decent walkthrough
  3. Install and set up Macro Deck https://macrodeck.org/
  4. Download these files:
    https://github.com/Macro-Deck-org/Macro-Deck-Web-Client (Click Code then Download zip)
    https://gist.github.com/lmore377/4c944a97407e34e10d998ee6a3e33f6a (For both files right click Raw then Save link as...) Currently not up to date, will fix soon ™️
  5. Extract the zip file to any folder then run these commands:
adb shell mount -o remount,rw /
adb push supervisord.conf /etc
adb shell cp -r /usr/share/qt-superbird-app/webapp/ /usr/share/qt-superbird-app/webapp.bak/
adb shell rm -rf /usr/share/qt-superbird-app/webapp/*
adb push Macro-Deck-Web-Client-main/* /usr/share/qt-superbird-app/webapp/
adb push index-edited.html /usr/share/qt-superbird-app/webapp/index.html
adb reboot
  1. After the car thing reboots you should see the macro deck web ui load up. At this point just run adb reverse tcp:8191 tcp:8191 (change 8191 if you use a different port) then press connect on the car thing. You'll need to do this every time you reboot your pc or unplug/plug in car thing

The only caveat is that none of the physical buttons work. I think this is just a limitation of macro deck but if you manage to figure out how to get keyboard keys working here's the mapping:
Preset 1-4: Numbers 1-4 on a keyboard
Menu: M
Back: ESC
Wheel Button: Either space or enter. I can't remember which
Wheel: Mouse scroll wheel

The only edit on the index-edited.html file is at line 104 to autofill the IP address since there's no form of keyboard input on the car thing. supervisord.conf was just edited to disable swupdate and the process that handles phone communication to free up some resources.

Edit: one more thing, if you ever want to update the web client for whatever reason you just need to edit line 104 in index.html to match what I edited and push the updated files over ADB to /usr/share/qt-superbird-app/webapp/

Opening the Car Thing

At a temperature of roughly 180F (80C) I was able to melt the glue at remove the screen. I do not recommend holding the Car Thing while melting the glue.

image

image

Announce: Wall Thing - Debian Chromium Kiosk on Spotify Car Thing (superbird)

Since a lot of people are still lurking here, thought you might be interested in the progress I have made toward using the Car Thing as a kiosk for Home Assistant.

What I have now is Debian 13 in the data partition, using the stock kernel (on boot_a), with Chromium browser fullscreen showing a Home Assistant Lovelace page, and buttons controlling lighting and presets via Home Assistant API.

Here is the repo, :
superbird-debian-kiosk

You can download a pre-made image here: Releases
Latest Release

Please see the Readme for flashing instructions

Requirements:

  • Spotify Car Thing
  • another device to act as host, such as Radxa Zero, Rockpi S, Raspberry Pi 4, etc
  • a USB cable to connect the two
  • power supply for the host device
  • a desktop/laptop for flashing the image to the Car Thing

Features

Working:

  • Debian 13 (Trixie) aarch64
  • Framebuffer display working with X11, in portrait or landscape, with touch input
  • Networking via USB RNDIS (requires a host device)
  • Automatic blacklight on/off with display wake/sleep
  • VNC and SSH (forwarded through host device)
  • Chromium browser, fullscreen kiosk mode
  • Buttons and dial used to control a light and recall scenes/automations/scripts on Home Assistant
  • 256MB settings partition used for Chromium user profile

Available, but not used in this image:

  • Bluetooth
  • Backlight brightness control (currently fixed at 100)
  • Audio (mic array, DSP)

Not working:

  • Wifi
  • GPU acceleration

WiFi is technically possible on this hardware, but the stock bootloaders and kernel disable it.
It might be possible to cherry-pick the wifi information from the Radxa Zero device tree (practically the same SoC), but I think you would need to rebuild one or more of the bootloader stages to make it work.

GPU: the hardware has a Mali GPU, but the stock OS uses it via DirectFB QT library, and does not include necessary libraries to make it work with X11. It may be possible to grab the needed files from Radxa Zero.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.