Control your GoPro Hero Camera anywhere with HTTP protocol.
- GoPro Hero Camera can be controlled with standard http protocol.
- Reverse engineering the network protocol is easier than you think.
- Always Google your subjects before spending 2 hours researching yourself ☺.
I had my GoPro Hero 3 since 2013 and it remains one of the best toys I’ve ever had of all times — I’ve brought my GoPro to racetracks, snowboarding, white water rafting to capture all the unforgettable adventures. I love it wholeheartedly but the biggest complaint I had is it’s hard to know when the camera is operating — This information can only be seen on the camera display or with the standalone GoPro phone application or with a wrist remote. In most cases the wrist remote will be your best option - it is very accessible and it does not interfere with your activities. (I dare you to pull out your phone, control your GoPro while going down mountain runs in 40 mph on a snowboard.) A GoPro wrist remote will set you back a cool 90 bucks but I am a frugal computer science engineer by trade and I prefer to do things myself☺. Since the GoPro phone application talks to the GoPro camera through wifi, there is a good possibility we can re-use the same API and port the functionality on to an Android watch/Apple watch, hence the idea, but first we need to figure out the API specification.
GoPro Hero 3 Silver Edition x 1.
Android Phone x 1.
GoPro Application for Android x 1.
Computer x 1.
A copy of Wireshark on computer x 1.
The problem space.
As an avid Android engineer, my optimistic approach is to fire an Intent from my custom application and call the hooks in the GoPro android application which allows me to fire events on the go. To confirm that is not possible, we need to decompile the GoPro Android application with apk-tool to see what is declared in the application AndroidManifest.xml.
We’re not seeing any provider that supports Intent Action, which means we cannot use the GoPro app as a proxy and control from our own app, tough luck. Another approach is to figure out where the call-path is for the camera communication, and then recompile the application with necessary hooks to make it to work, which seems like a good approach on paper but it’s not easy and straightforward.
A Change of Plan.
In normal setup, the phone connects to the Wifi network that is broadcasted directly from the camera. After the connection has been established, the GoPro phone application will issue commands over the wire to “communicate” with the camera itself.
Since we know the GoPro app talks directly with the GoPro camera through wifi, there is a good chance that we can capture the network traffic and work our way backwards to see the interaction between them.
In english this is what we want to do —
- GoPro phone application talks to the camera directly over wifi.
- If we’re able to intercept all connections between the phone application and the camera, there’s a good chance we can re-use the same API and talk to the camera with a different client.
- In order to do that, we need to intercept the network connections on the phone level.
Ok, Chris this is cool, how do we do that?
tcpdump + wireshark = your friend.
In short, tcpdump is an unix program that analyzes all TCP/IP packets going through over the network pipeline. With this, we will be able to analyze the traffic between the phone and the camera from the phone itself. To make our lives easier, wireshark visualizes these requests and make our analysis work easier to comprehend.
To start, we need to ensure tcpdump is available on your rooted Android device. In this example, I used Shark For Root application to call the tcpdump program on my Nexus 5 to begin the logging process. To install and configure the tcpdump program, follow this guide. In case you’re using Android Lollipop, you might run into the following PIE issue
error: only position independent executables (PIE) are supported .
click here for workarounds.
Cool, now we have all the tools we need, let’s go ahead and launch the Shark Native app and get some logs.
The standard foolproof procedure is as follows:
- Press the start button in Shark4Root to start logging the network traffic.
- Play with the GoPro phone application, one functionality at a time. (Power ON/OFF, Shutter, Camera modes)
- Stop the logging in Shark4Root
- Dump the pcap file from phone to computer and read the file from wireshark.
- Analysis time, baby!
- Indeed, the GoPro camera is running some sort of http server instance on the camera itself. The client has an assigned IP address 10.5.5.109 while the camera itself is always 10.5.5.9, given majority of the traffic is being sent and received from these IPs.
- For every http request that is sent to the camera, the parameter “t” represents the wifi password as indicated with the camera config. e.g.
HTTP GET /bacpac/set?t=<wifi_password>
- To turn the camera on…
HTTP GET /bacpac/PW?t=<wifi_password>&p=%01
- To turn the camera off….
HTTP GET /bacpac/PW?t=<wifi_password>&p=%00
- To press the shutter..
HTTP GET /bacpac/SH?t=<wifi_password>&p=%01
Cool story bro, how do we validate the protocol calls?
The easiest way to do it is to fire that request directly from a client connected to the GoPro. On Mac I love using Cocoa Rest Client. You can also get the Advanced Rest Client Chrome extension which basically does the same thing. Issuing a HTTP 200 GET request to http://10.5.5.9/bacpac/PW?t=<wifi_password>&p=%01 validates our observation and indeed turns on the GoPro camera. Now we have all the tools to control the camera wireless from another computer.
Google is your friend.
Turns out someone else has already done all the research for all available protocols supported by GoPro. KonradIT @ github has done some research on it and here’s a list of available commands for GoPro Hero 4 Black edition. Lesson learned — always Google before getting your hands dirty :).
Found this piece interesting? Follow me here!