User Tools

Site Tools


doc:appunti:hardware:insta360_one_rs_wifi_reverse_engineering

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
doc:appunti:hardware:insta360_one_rs_wifi_reverse_engineering [2023/07/03 16:25] – [Connecting to the WiFi] niccolodoc:appunti:hardware:insta360_one_rs_wifi_reverse_engineering [2023/09/08 10:45] – [Insta360: WiFi protocol reverse engineering] niccolo
Line 1: Line 1:
 ====== Insta360: WiFi protocol reverse engineering ====== ====== Insta360: WiFi protocol reverse engineering ======
  
-I purchased an **Insta360 ONE RS** action camera in June 2023, I'm rather satisfied by its performances, but I'm really disappointed by the accompanying Android app. The app (version 1.40.1) is a monster download of **676 Mb**, once installed it requires more than 1 Gb of storage. It is rather invasive about permissions request because it wants access to the camera (the phone's camera!), contacts, microphone and phone. Once started it is totally **social oriented**, presenting me **blatantly useless info** about what other people does with their cameras.+I purchased an **[[insta360_one_rs|Insta360 ONE RS]]** action camera in June 2023, I'm rather satisfied by its performances, but I'm really disappointed by the accompanying Android app. The app (version 1.40.1) is a monster download of **676 Mb**, once installed it requires more than 1 Gb of storage. It is rather invasive about permissions request because it wants access to the camera (the phone's camera!), contacts, microphone and phone. Once started it is totally **social oriented**, presenting me **blatantly useless info** about what other people does with their cameras.
  
 **What I need is a simple remote control** for my action camera, not another invasive and useless social network. Beside that, the app doesn't work on my phone; maybe because the hardware specs are not at the cutting edge of techonolgy (but neverthless my phone has 4 Gb of RAM and a 4 cores MediaTek Helio A22 SoC), whenever I tap the icon to start the live view the app crashes. So the basic function of remote controlo does not work. **What I need is a simple remote control** for my action camera, not another invasive and useless social network. Beside that, the app doesn't work on my phone; maybe because the hardware specs are not at the cutting edge of techonolgy (but neverthless my phone has 4 Gb of RAM and a 4 cores MediaTek Helio A22 SoC), whenever I tap the icon to start the live view the app crashes. So the basic function of remote controlo does not work.
Line 18: Line 18:
  
 So I installed the Insta360 app into a **rooted** Android smartphone. On the same phone I'm running the **Termux** app where I installed the **tcpdump** package. So I discovered that the app talks to the Insta360 camera through the port **6666/TCP**, where a server is expecting and returning messages. The messages are not in clear text: it turned out that they are serialized using the **[[https://protobuf.dev/|Protocol Buffers]]** mechanism (thanks to this **[[https://hackaday.io/project/188975-insta360-x3-ble-remote-control-with-esp32|Hackaday.io post]]** which gave me the enlightening hint). So I installed the Insta360 app into a **rooted** Android smartphone. On the same phone I'm running the **Termux** app where I installed the **tcpdump** package. So I discovered that the app talks to the Insta360 camera through the port **6666/TCP**, where a server is expecting and returning messages. The messages are not in clear text: it turned out that they are serialized using the **[[https://protobuf.dev/|Protocol Buffers]]** mechanism (thanks to this **[[https://hackaday.io/project/188975-insta360-x3-ble-remote-control-with-esp32|Hackaday.io post]]** which gave me the enlightening hint).
 +
 +===== Running tcpdump into the Insta360 =====
 +
 +If your Android device is not rooted, you can still capture the WiFi traffic between the Android app and the Insta360 camera by just executing **tpcudmp** directly on the GNU/Linux operating system of the camera. You have to download and install the required binaries, which are fortunately provided by the **[[http://entware.net/|Entware Projec]]**.
 +
 +Download from **[[http://bin.entware.net/|entware.net]]** the following packages (choose **aarch64** architecture, kernel **3.10**):
 +
 +  * libc_2.27-11_aarch64-3.10.ipk
 +  * libgcc_8.4.0-11_aarch64-3.10.ipk
 +  * libpcap_1.10.4-1_aarch64-3.10.ipk
 +  * librt_2.27-11_aarch64-3.10.ipk
 +  * libssp_8.4.0-11_aarch64-3.10.ipk
 +  * libthread-db_2.27-11_aarch64-3.10.ipk
 +  * tcpdump_4.99.4-1_aarch64-3.10.ipk
 +
 +Create a directory into the SD card **/tmp/SD0/opt/** and unpack the above archives, keeping the directory structure and dereferencing links into plain files (the SD filesystem does not support symbolic links).
 +
 +Suppose that the Android device running the Insta360 app has IP address 192.168.42.2, run the following script at the command line of the camera:
 +
 +<code bash>
 +#!/bin/sh
 +test -f /opt/bin/tcpdump || mount -o bind /tmp/SD0/opt /opt
 +/opt/bin/tcpdump -w /tmp/SD0/tcpdump-$(date +%m%d%H%M%S).log -s0 -n 'host 192.168.42.2'
 +</code>
 +
 +
 +===== Packets anatomy =====
 +
 +==== Sent Packets ====
 +
 +=== Sync Packet ===
 +
 +^ Offset  ^ Content  ^ Bytes  ^ Note  ^
 +|   0 | Packet Length     | 4   | Overall length of the packet, including this 4 bytes.  |
 +|   4 | 0x06 0x00 0x00    | 3   | Message Type: Sync Packet.  |
 +|   7 | syNceNdinS        | 10  | Magic String.  |
 +
 +=== Keep Alive Packet ===
 +
 +^ Offset  ^ Content  ^ Bytes  ^ Note  ^
 +|   0 | Packet Length     | 4   | Overall length of the packet, including this 4 bytes.  |
 +|   4 | 0x05 0x00 0x00    | 3   | Message Type: Keep Alive.  |
 +
 +=== Phone Commands ===
 +
 +^ Offset  ^ Content  ^ Bytes  ^ Note  ^
 +|   0 | Packet Length     | 4  | Overall length of the packet, including this 4 bytes.  |
 +|   4 | 0x04 0x00 0x00    | 3  | Message Type: Phone Command.  |
 +|   7 | Message Code      | 2  | Examples: PHONE_COMMAND_GET_OPTIONS, PHONE_COMMAND_SET_OPTIONS, PHONE_COMMAND_TAKE_PICTURE, PHONE_COMMAND_START_CAPTURE, etc.  |
 +|   9 | 0x02              | 1  |
 +|  10 | Sequence Number   | 3  | Each command sent to the camera have its increasing sequence number, the relative response contains the same sequence number.  |
 +|  13 | 0x80 0x00 0x00    | 3  |
 +|  16 | Protobuf Message  | Variable  | The message serialized using Protocol Buffers.  |
 +
 +
 +==== Received Packets ====
 +
 +=== Notifications or Response to Phone Commands ===
 +
 +^ Offset  ^ Content  ^ Bytes  ^ Note  ^
 +|   0 | Packet Length     | 4  | Overall length of the packet, including this 4 bytes.  |
 +|   4 | 0x04 0x00 0x00    | 3  | Response Type: Phone Command.  |
 +|   7 | Response Code     | 2  | Examples: 200: OK, 500: ERROR, CAMERA_NOTIFICATION_CURRENT_CAPTURE_STATUS, etc.  |
 +|   9 | 0x02              | 1  |
 +|  10 | Sequence Number   | 3  | Matches to the requesting message.  |
 +|  13 | 0x80              | 1  |
 +|  14 | Unknown           | 2  |  |
 +|  16 | Protobuf Message  | Variable  | The response message serialized using Protocol Buffers.  |
 +
  
 ===== Inspecting the raw Protobuf messages ===== ===== Inspecting the raw Protobuf messages =====
Line 31: Line 100:
 </code> </code>
  
-Then **extract some protobuf binary messages from the tcpdump output**; in the following example we try to decode a binary message received from the camera by the Android app. It seems that each message is prefixed by a 12 bytes header (more on that later), so in the Python code strip that header away and keep only the message body before calling the ''protobuf_to_json()'' function:+Then **extract some protobuf binary messages from the tcpdump output**; in the following example we try to decode a binary message received from the camera by the Android app. Each message is prefixed by a 12 bytes header (see packets anatomy, above), so in the Python code strip that header away and keep only the message body before calling the ''protobuf_to_json()'' function:
  
 <code python> <code python>
Line 94: Line 163:
 ===== Getting the .proto definitions ===== ===== Getting the .proto definitions =====
  
-:!: **WARNING**: In this paragraph you can read about my first attempt in getting the *.proto files from a demo executable. It turned out that **the files were not complete and not fully up-to-date**. It is advised to use the current Android app to get a more recent version of the *.proto files. See the next paragraph for the recipe.+:!: **WARNING**: In this paragraph you can read about my first attempt in getting the *.proto files from a demo executable. It turned out that **the files were not complete and not fully up-to-date**. It is advised to use the current Android app to get a more recent version of the *.proto files. See the **[[#getting_the_proto_files_from_the_android_apk|next paragraph for the full recipe]]**.
  
 To understand the messages structure of the messages exchanged betwwen the software and the camera **it is necessary to have the .proto files** that define the syntax, but how can you do it without having access to the non-free source codes of Insta360? To understand the messages structure of the messages exchanged betwwen the software and the camera **it is necessary to have the .proto files** that define the syntax, but how can you do it without having access to the non-free source codes of Insta360?
Line 163: Line 232:
  
 ===== Getting the .proto files from the Android APK ===== ===== Getting the .proto files from the Android APK =====
 +
 +Download the .proto file extractor tool from **[[https://github.com/RigacciOrg/insta360-wifi-api/tree/main/utils|this repository]]**. Download the Android app and extract the **libOne.so** file from it. Then run the following recipe:
  
 <code bash> <code bash>
Line 199: Line 270:
 echo "Python files were compiled into the pb2 directory." echo "Python files were compiled into the pb2 directory."
 </code> </code>
 +
 +===== The Insta360 Python remote program =====
 +
 +On the **[[https://github.com/RigacciOrg/insta360-wifi-api/|insta360-wifi-api GitHub repository]]** you can find a Python library which implements basic communication with the Insta360 camera over WiFi connection. There is also an example Python program with the basic functionality of **remote control**. You can easily run it from a PC with GNU/Linux, but you can also install the required Python language and libraries in MS-Windows and even on Android. I run that program on my smartphone, it just required to install the **[[https://f-droid.org/en/packages/com.termux/|Termux]]** app.
 +
 +
 +===== Unsolved Problems =====
 +
 +It seems **impossibile to change some settings via the WiFi API**; e.g. I was not able to change:
 +
 +  * Sharpness
 +  * Prompt Sound
 +  * Indicator Light (LEDs)
 +
 +When some settings are changed via the WiFi API, **the preview on the camera screen does not reflect that change**; nor in the live stream, nor into the on-screen-display labels. E.g. white balance, capture resolution, fielf of view. Fortunately if you start the video capture, the settings are effective.
 +
 +
 +===== White Balance Settings =====
 +
 +It is possible to change the white balance setting by changing the value of **white_balance** choosing from some enumerated presets or directly by changing the temperature value of **white_balance_value**. There seems to be some inconsistency between the labels assigned to the presets in the .proto files and the actual temperature values. I think that the best choice is to assign the white_balance_value, ignoring the enumerated presets.
 +
 +^ white_balance_value  ^ white_balance  ^ Protobuf Enum Label  ^
 +|   AUTO |   0 | WB_AUTO  |
 +|   2000 |   6 |  |
 +|   2200 |   7 |  |
 +|   2400 |   8 |  |
 +|   2600 |   9 |  |
 +|   2800 |   1 | WB_2700K  |
 +|   3000 |  10 |  |
 +|   3200 |  11 |  |
 +|   3400 |  12 |  |
 +|   3600 |  13 |  |
 +|   3800 |  14 |  |
 +|   4000 |   2 | WB_4000K  |
 +|   4500 |  15 |  |
 +|   5000 |   5 | WB_7500K  |
 +|   5500 |  16 |  |
 +|   6000 |  17 |  |
 +|   6500 |   3 | WB_5000K  |
 +|   7000 |  18 |  |
 +|   7500 |   4 | WB_6500K  |
 +|   8000 |  19 |  |
 +|   8500 |  20 |  |
 +|   9000 |  21 |  |
 +|   9500 |  22 |  |
 +|  10000 |  23 |  |
 +
  
 ===== Web References ===== ===== Web References =====
doc/appunti/hardware/insta360_one_rs_wifi_reverse_engineering.txt · Last modified: 2023/09/08 10:46 by niccolo