Brain-dump of the Replay XD PrimeX wireless protocol

I never got around to writing up this post, so instead this is just a brain-dump of what I found.

SSHing into the camera

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

buildroot login: root
~ # id
uid=0(root) gid=0(root) groups=0(root),10(wheel)

Well, that was easy.

~ # ps aux
PID   USER     TIME   COMMAND
    1 root       0:04 init
    2 root       0:00 [kthreadd]

  ... ...         ... ...

  671 root       0:00 ombra
  676 root       0:00 amba_mq_handler
  678 root       0:00 /usr/bin/AmbaStreamSVC
  681 root       0:00 /usr/bin/lu_lnxfio_stream
  684 root       0:00 /usr/bin/amba_qrconfig
  705 root       0:00 telnetd
  742 root       0:00 network_message_daemon
  752 root       0:00 cherokee-worker -a -C /etc/cherokee.conf -j -s -d
  769 root       0:00 AmbaOnDemandRTSPServer
  834 nobody     0:00 dnsmasq --nodns -5 -K -R -n --dhcp-range=192.168.42.2,192.168.42.6,infinite
  877 root       0:00 wpa_supplicant -Dnl80211 -iwlan0 -c/tmp/wpa_supplicant.conf -B
~ # network_message_daemon --help
        -f      --foreground    do not fork to allow stdin
        -m      --disc-port     discovery port (default=7877)
        -n      --no-libnet     do not forward to network message library
        -p      --port  portnumber (default=7878)
        -s      --disc  discovery string (default=amba discovery)
~ # netstat -nlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:7878            0.0.0.0:*               LISTEN      742/network_message
tcp        0      0 0.0.0.0:554             0.0.0.0:*               LISTEN      769/AmbaOnDemandRTS
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      752/cherokee-worker
tcp        0      0 0.0.0.0:8787            0.0.0.0:*               LISTEN      742/network_message
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      834/dnsmasq
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN      705/telnetd
netstat: /proc/net/tcp6: No such file or directory
udp        0      0 0.0.0.0:53              0.0.0.0:*                           834/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           834/dnsmasq
udp        0      0 0.0.0.0:7877            0.0.0.0:*                           742/network_message
netstat: /proc/net/udp6: No such file or directory
netstat: /proc/net/raw6: No such file or directory
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
~ # ls -la /proc/742/fd/1
lrwx------    1 root     root            64 Jan  1 00:02 /proc/742/fd/1 -> /dev/ttyS1

Capturing the message daemon’s output

~ # network_message_daemon -f
[amba_message_process_init]Message Process v2 is selected.
main(1333): skip challenge process

tcp_listen(228): binding port 7878
tcp_listen(228): binding port 8787
command_server(967): type 'q' to leave
command_server(1023): client7 online (192.168.42.6:56354)
command_server(1133): 7|{"msg_id":257,"token":0}|
amba_message_process : in_string is {"msg_id":257,"token":0}
[amba_json_default_parse_param]:Can't find param in json string, skip it
[token]: create a token is 1
amba_message_handle_block_send: will NOT wait for lu msg from uitron
amba_message_set_response: out_string is  { "rval": 0, "msg_id": 257, "param": 1 }
amba_message_set_response runtime = 19150 us
{"msg_id":257,"token":0}
{"rval": 0, "msg_id": 257, "param": 1 }

{"token":1,"msg_id":11}
{"rval":0,"msg_id":11,"brand":"Replay XD", "model":"Prime X", "api_ver":"2.8.00","fw_ver":"1.061","device_sn":"D21506009873","wifi_mac":"FC:E1:D9:00:98:73","wifi_ssid":"PrimeX","app_type":"sport", "logo":"/tmp/fuse_z/app_logo.jpg", "chip":"A7LS","http":"disable"}

{"token":1,"msg_id":13}
{"rval":0,"msg_id":13,"type":"battery","param":"100"}

{"token":1,"msg_id":3}
{"rval": 0, "msg_id": 3, "param": [ { "camera_clock": "2015-11-16 22:54:38" }, { "video_standard": "NTSC" }, { "app_status": "idle" }, { "stream_out_type": "none" }, { "video_resolution": "1920x1080 60P 16:9" }, { "video_fps": "30\/60\/120\/240fps NTSC" }, { "video_aspect_ratio": "16:9" }, { "video_quality": "S.Fine" }, { "video_fov": "140 Super Wide" }, { "video_slow_motion": "Off" }, { "photo_size": "14M (4608x3072 3:2)" }, { "photo_quality": "S.Fine" }, { "timelapse_photo": "off" }, { "exposure": "EV 0 (Default)" }, { "ae_metering": "Center (Default)" }, { "white_balance": "Auto (Default)" }, { "sharpness": "3 Standard (Default)" }, { "contrast": "64 (Default)" }, { "saturation": "64 (Default)" }, { "auto_set_date_time": "On" }, { "one_touch_recording": "Off" }, { "repower_auto_start_stop": "Off" }, { "power_down_delay": "1 Min (Default)" }, { "file_trim_function": "Off" }, { "thumbnail_video": "On" }, { "no_card_shutdown": "On" }, { "no_activity_shutdown": "On" }, { "SD_card_full": "Power Camera Off (Default)" }, { "liveview_resolution": "1080i60" }, { "liveview_signal": "NTSC" }, { "liveview_audio_output": "On" }, { "general_custom_filename": "RPXD" }, { "general_photo_stamp": "Off" }, { "general_video_stamp": "Off" }, { "serial_number": "D21506009873" }, { "wifi_mac": "FC:E1:D9:00:98:73" }, { "wifi_ssid": "PrimeX" }, { "wifi_password": "replayxd" }, { "status_remaining_time": "00:20:26" }, { "status_remaining_photo": "1820" } ] }

{"token":1,"msg_id":1,"type":"app_status"}
{"rval":0,"msg_id":1,"type":"app_status","param":"idle"}

{"token":1,"msg_id":1,"type":"stream_out_type"}
{"rval":0,"msg_id":1,"type":"stream_out_type","param":"none"}

{"type":"camera_clock","param":"2015-11-16 22:54:40","msg_id":2,"token":1}
{"rval": 0, "msg_id": 2 ,"type":"camera_clock"}

{"type":"stream_out_type","param":"rtsp","msg_id":2,"token":1}
{"rval": 0, "msg_id": 2 ,"type":"stream_out_type"}

{"token":1,"msg_id":259}
{"rval":0,"msg_id":259}

Pressed settings in the iOS app.

{"token":1,"msg_id":260}
{"rval":0,"msg_id":260}
{"token":1,"msg_id":3}
{"rval": 0, "msg_id": 3, "param": [ { "camera_clock": "2015-11-16 22:56:13" }, { "video_standard": "NTSC" }, { "app_status": "idle" }, { "stream_out_type": "rtsp" }, { "video_resolution": "1920x1080 60P 16:9" }, { "video_fps": "30\/60\/120\/240fps NTSC" }, { "video_aspect_ratio": "16:9" }, { "video_quality": "S.Fine" }, { "video_fov": "140 Super Wide" }, { "video_slow_motion": "Off" }, { "photo_size": "14M (4608x3072 3:2)" }, { "photo_quality": "S.Fine" }, { "timelapse_photo": "off" }, { "exposure": "EV 0 (Default)" }, { "ae_metering": "Center (Default)" }, { "white_balance": "Auto (Default)" }, { "sharpness": "3 Standard (Default)" }, { "contrast": "64 (Default)" }, { "saturation": "64 (Default)" }, { "auto_set_date_time": "On" }, { "one_touch_recording": "Off" }, { "repower_auto_start_stop": "Off" }, { "power_down_delay": "1 Min (Default)" }, { "file_trim_function": "Off" }, { "thumbnail_video": "On" }, { "no_card_shutdown": "On" }, { "no_activity_shutdown": "On" }, { "SD_card_full": "Power Camera Off (Default)" }, { "liveview_resolution": "1080i60" }, { "liveview_signal": "NTSC" }, { "liveview_audio_output": "On" }, { "general_custom_filename": "RPXD" }, { "general_photo_stamp": "Off" }, { "general_video_stamp": "Off" }, { "serial_number": "D21506009873" }, { "wifi_mac": "FC:E1:D9:00:98:73" }, { "wifi_ssid": "PrimeX" }, { "wifi_password": "replayxd" }, { "status_remaining_time": "00:20:26" }, { "status_remaining_photo": "1820" } ] }
{"token":1,"msg_id":9,"param":"video_resolution"}
{"rval": 0, "msg_id": 9, "param": "video_resolution", "permission": "settable", "options": [ "1920x1080 60P 16:9", "1920x1080 30P 16:9", "1280x720 120P 16:9", "1280x720 60P 16:9", "1280x720 30P 16:9", "848x480 240P 16:9", "848x480 120P 16:9", "848x480 60P 16:9", "848x480 30P 16:9" ] }

{"type":"video_resolution","param":"1920x1080 30P 16:9","msg_id":2,"token":1}
{"rval": 0, "msg_id": 2 ,"type":"video_resolution"}

{"token":1,"msg_id":9,"param":"video_fps"}
{"rval": 0, "msg_id": 9, "param": "video_fps", "permission": "settable", "options": [ "30\/60\/120\/240fps NTSC", "25\/50\/100\/200fps PAL", "24\/48fps Cinema" ] }

{"type":"video_fps","param":"25/50/100/200fps PAL","msg_id":2,"token":1}
{"rval": 0, "msg_id": 2 ,"type":"video_fps"}

{"token":1,"msg_id":9,"param":"video_aspect_ratio"}
{"rval": 0, "msg_id": 9, "param": "video_aspect_ratio", "permission": "settable", "options": [ "16:9", "4:3" ] }

{"type":"video_aspect_ratio","param":"4:3","msg_id":2,"token":1}
{"rval": 0, "msg_id": 2 ,"type":"video_aspect_ratio"}

Capturing the web server’s output

/ # cherokee-worker -a -C /etc/cherokee.conf -j -s
{'type': "warning", 'time': "01/01/1970 00:07:39.386", 'title': "Could not open temporal file '/tmp/cherokee-spawner-885': No such file or directory", 'code': "spawner.c:91", 'error': "149", 'description': "It looks like the cherokee supervisor is not running, or it could not create the required temporal file.", 'version': "1.2.101b150320_", 'compilation_date': "Mar 20 2015 15:20:14", 'configure_args': " '--target=arm-linux' '--host=arm-linux' '--build=x86_64-unknown-linux-gnu' '--prefix=/usr' '--exec-prefix=/usr' '--sysconfdir=/etc' '--program-prefix=' '--disable-gtk-doc' '--enable-shared' '--enable-static-module=all' '--enable-static' '--disable-shared' '--enable-nls=no' '--disable-nls' '--disable-ipv6' '--enable-trace=no' '--enable-beta' '--without-python' '--without-php' '--with-sendfile-support=no' '--with-mysql=no' 'build_alias=x86_64-unknown-linux-gnu' 'host_alias=arm-linux' 'target_alias=arm-linux' 'CC=/cygdrive/y/hd100a/A7LSDK540_Boss_20140428_SVN153000_hd100a_v161/boss_sdk/buildroot/../host.oem/usr/bin/arm-none-linux-gnueabi-gcc' 'CFLAGS=-pipe -Os  -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' 'LDFLAGS=' 'CPP=/cygdrive/y/hd100a/A7LSDK540_Boss_20140428_SVN153000_hd100a_v161/boss_sdk/buildroot/../host.oem/usr/bin/arm-none-linux-gnueabi-cpp' '--target=arm-linux' '--host=arm-linux' '--build=x86_64-unknown-linux-gnu' '--prefix=/usr' '--exec-prefix=/usr' '--sysconfdir=/etc' '--program-prefix=' '--disable-gtk-doc' '--enable-shared' '--enable-static-module=all' '--enable-static' '--disable-shared' '--enable-nls=no' '--disable-nls' '--disable-ipv6' '--enable-trace=no' '--enable-beta' '--without-python' '--without-php' '--with-sendfile-support=no' '--with-mysql=no' 'build_alias=x86_64-unknown-linux-gnu' 'host_alias=arm-linux' 'target_alias=arm-linux' 'CC=/cygdrive/y/hd100a/A7LSDK540_Boss_20140428_SVN153000_hd100a_v161/boss_sdk/buildroot/../host.oem/usr/bin/arm-none-linux-gnueabi-gcc' 'CFLAGS=-pipe -Os  -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64' 'LDFLAGS=' 'CPP=/cygdrive/y/hd100a/A7LSDK540_Boss_20140428_SVN153000_hd100a_v161/boss_sdk/buildroot/../host.oem/usr/bin/arm-none-linux-gnueabi-cpp'"}
Cherokee Web Server 1.2.101b150320_ (Mar 20 2015): Listening on port ALL:80,
TLS disabled, IPv6 disabled, using epoll, 4096 fds system limit, max. 2041
connections, 5 threads, 408 connections per thread, standard scheduling policy
/ # AmbaOnDemandRTSPServer
Create AmbaStream_IpcScv_thread!!
mmap c1f3f000 to 0x20bcb000 with size=1cf1000 successfully!!
Enable Video stream
play the live stream rtsp://192.168.42.1/live