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.
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.
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]
: -6targets[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