Micro Drone 3.0 Camera API

Reverse engineered API for the Micro Drone 3.0 Camera.

Micro Drone 3.0 logo

Micro Drone 3.0 is an affordable feature-packed mini quadcopter. It can be controlled either using the 2.4 GHz remote controller (receiver on main board) or an Android/iPhone app over WiFi (through the camera module). Although the project was crowdfunded on Indiegogo, the software is not open source and no API documentation is available. This is an attempt to reverse engineer the main parts of the Camera API, so anyone can experiment further.

Micro Drone 3.0 photo

General

The Micro Drone 3.0 Camera module takes around 20 seconds to boot when you attach it to the battery. It creates an WiFi access point (eg. MD3.0_ABCD) to which you need to connect your phone before starting the Micro Drone app.

Micro Drone 3.0 Android app screenshot

The Camera module is on 192.168.1.1 and provides the following services:

  • 67/udp: DHCP daemon (udhcpd from BusyBox v1.16.1)
  • 80/tcp: HTTP server and controller (/bin/camera using Boa/0.94.14rc21)
  • 2345/tcp: unknown (/bin/camera)
  • 10000/udp: unknown (/bin/camera)
  • 23/tcp: telnet daemon with root shell (telnetd) (needs to be activated)

The Android/iPhone app communicates for camera operations, video streaming and serial remote control only over port 80/tcp to the main daemon (/bin/camera). On the same port this daemon exposes an HTTP interface, but also a custom protocol for streaming video and serial remote control commands.

HTTP API

Over HTTP a Reecam CGI interface is available (user admin without any password), but it is easier to use the handy mdcam tool to work with the camera.

To download all photos and videos to your computer with the mdcam tool:

$ mdcam ls | cut -d' ' -f1 | xargs -n 1 mdcam download

The full HTTP API is:

  • /get_status.cgi
  • /get_params.cgi
  • /get_properties.cgi
  • /check_user.cgi
  • /get_badauth.cgi
  • /create_session.cgi
  • /close_session.cgi
  • /is_mjpeg_stream_exist.cgi
  • /request_av.cgi
  • /set_params.cgi
  • /snapshot.cgi
  • /videostream.cgi
  • /ptz_control.cgi
  • /get_log.cgi
  • /wifi_scan.cgi
  • /get_session_list.cgi
  • /search_record.cgi
  • /del_record.cgi
  • /get_record.cgi
  • /start_record.cgi
  • /stop_record.cgi
  • /format_sd.cgi
  • /backup.cgi
  • /restore.cgi
  • /restore_factory.cgi
  • /delete_factory.cgi
  • /upgrade.cgi
  • /write_comm.cgi
  • /read_comm.cgi
  • /test_wifi_connected.cgi
  • /alarm_snapshots.cgi
  • /search_snapshot.cgi
  • /del_snapshot.cgi
  • /get_snapshot.cgi
  • /set_stream.cgi
  • /get_cur_ir_adc_value.cgi
  • /wifi_ate_tx_start.cgi

To get a live video stream open the following network URL in VLC media player:

Telnet shell

To activate the Telnet interface enable it though the HTTP API by visiting:

After a reboot you can connect over telnet into a root shell with BusyBox v1.16.1:

$ telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.

# uname -a
Linux (none) 3.0.8 #1723 Wed Nov 25 16:49:38 CST 2015 armv5tejl GNU/Linux
# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00100000 00010000 "boot"
mtd1: 00500000 00010000 "kernel"
mtd2: 00080000 00010000 "user"
mtd3: 00180000 00010000 "manufacturer"
# df
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                    18056         4     18052   0% /dev
/dev/mtdblock2             512       252       260  49% /mnt/user
/dev/mtdblock3            1536       220      1316  14% /mnt/manufacturer
/dev/mmcblk0p1        15621208   1151032  14470176   7% /mnt/sd
# mount
rootfs on / type rootfs (rw)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
/dev/mtdblock2 on /mnt/user type jffs2 (rw,relatime)
/dev/mtdblock3 on /mnt/manufacturer type jffs2 (rw,relatime)
/dev/mmcblk0p1 on /mnt/sd type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

It is a little tricky to retrieve the /bin/camera binary, because it removes itself after starting. Nevertheless it is still loaded in the memory, so you can find it in /proc/*/exe. It seems that they expected someone to examine this binary, because it contains a string hello kitty and kgb/cia 2011 COPYRIGHT@REECAM 5460.

Serial interface

The Android/iPhone app also manages to send remote control commands the drone. This is done through a serial interface that seems to be directly exposed to the app through libcamlib.so on the client side and /bin/camera on the server side.

Disassembling the Android APK reveals that com.D_Lawliet.fly.FlyActivity contains the targets = new byte[7] property that encodes the serial commands that are being sent with each packet. Meaning of those bytes:

  • targets[0]: -6
  • targets[1]: throttle (0 is off)
  • targets[2]: rudder (min 1?)
  • targets[3]: elevation (1..127)
  • targets[4]: aileron (1..127)
  • targets[5]: 0 + settings (speed mode, inverted flying)
  • targets[6]: checksum ([1] xor [2] xor [3] xor [4] xor[5]`)

The target serial device for this commands is /dev/ttyAMA1. Proof of concept that triggers throttle for a few seconds:

# echo -e "\xfa\x40\x40\x40\x40\x00\x00" > /dev/ttyAMA1