Sunday, November 23, 2014

Reverse engineering SJCAM4000 WiFi... well... kind of...



I got a so called Action Camera. Not enought interest on the whole video recording thing to spend a fortune on a GoPro, so I went for the Chinese option and bought a SJCAM 4000 wifi. I will not get into the whole review and unboxing discussion... that is not the purpose of this blog, you have plenty of pages already discussing that... google that...

Anyway, so the camera comes with a wifi option. How does that work? the camera opens an access point, you connect with an iOS or android app and you can configure and control the camera, see live video or download recordings (videos or pictured). That is great feature, I think, it saves you from having to extract the microSD card from the camera, which makes things easier, but I prefer using my laptop for downloading the pictures and videos than my handset, but no ubuntu app... grrrr.... had to figure out the protocol used in wifi mode...

I connected my laptop to the camera access point. I had to figure out the ip address of the camera:

arp -a

? (192.168.1.254) at 18:83:bf:XX:XX:XX [ether] on wlan0

Then I tried connecting to that IP with telnet and ssh without luck. Lastly I tried opening the webpage in that IP: http://192.168.1.254

Bingo!!! It opened a web page that allowed browsing the microSD card contents and even upload files, but no sight of configuration options or live video feed. That was really all I was looking for, but hell... I want the whole enchilada.

I installed an app in my android phone that allows capturing tcpdumps. I used tPacketCapture, which does not require having a rooted phone. If your phone is rooted, you can just use tcpdump from busybox. I captured a connection with my android app while I was doing some changes in the settings to inspect it later in the PC with wireshark. So here is what I found:

  1. The live video feed is just an RTSP connection, pretty standard and no encryption... cool... So connected the laptop back to the camera, opened VLC, Media->Open Network Stream and typed the URL I saw in my tcpdump pcap file: rtsp://192.168.1.254/sjcam.mov voila... live video from the camera
  2. The pcap file also had some http get requests. I could distinguish 2 types of requests, those with a parameter and those with out it. I assume the ones with no parameter are requests for info and the ones with a parameter are request for changing a setting. See the examples bellow (red is from laptop to camera, blue is from camera to laptop)
with no parameter:


GET /?custom=1&cmd=3016 HTTP/1.1
accept: */*
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; -------------------)
Host: 192.168.1.254
Connection: Keep-Alive
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: eCos/1.0
Cache-Control:no-store, no-cache, must-revalidate
Pragma: no-cache
Accept-Ranges: bytes
Content-length: 97
Content-type: text/xml
Connection: close

<?xml version="1.0" encoding="UTF-8" ?>
<Function>
<Cmd>3016</Cmd>
<Status>1</Status>
</Function>


with no parameter:


GET /?custom=1&cmd=2002&par=2 HTTP/1.1
accept: */*
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; -------------------)
Host: 192.168.1.254
Connection: Keep-Alive
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: eCos/1.0
Cache-Control:no-store, no-cache, must-revalidate
Pragma: no-cache
Accept-Ranges: bytes
Content-length: 97
Content-type: text/xml
Connection: close

<?xml version="1.0" encoding="UTF-8" ?>
<Function>
<Cmd>2002</Cmd>
<Status>0</Status>
</Function>

I did not dig further in this, but assume that each of those cmd numbers corresponds to a camera setting, and the parameter (par) is the value to set, but still need more research to figure out cmd and settings. I hope to make a python library to control the camera at some point, but will need some time to reverse engineer all the commands and parameters.

The last thing I did on my first weekend with the camera was try to watch the videos in my laptop and mobile phone, well, turns out the format of the recorded videos is ".MOV" and both mobile and laptop had issues with that format, even VLC which seems to play everything had issues: video was stopping and audio was out of sync. I converted the ".MOV" file to ".mp4" using avconv:

avconv -i input_file.MOV -vcodec copy -acodec mp2 output_file.mp4

What this does is generate an mp4 file in which the video is unaltered (no reencoding done, the video from the mov, h.264 compressed, is extracted and muxed again in the mp4 file without alteration). I have never been too keen on recompressing the video if it is already good from the source, unless there is a real need for it (reduce the file size). The audio gets compressed in mpeg layer 2 (audio codec in the ".MOV" is lpcm, no compression). Mp4 file format does not seem to support lpcm audio and I don't mind that much compressing the audio.

8 comments:

  1. Can this work also on non-wifi version of the sj4000? maybe thru usb?

    ReplyDelete
  2. Is there a way to access 192.168.1.254/DCIM with Total Commander rather than having to download videos as links via Chrome (or whatever browser) Thank for the guide, anyway

    ReplyDelete
  3. where actually did you find the link for the stream, i have the pcap file but i cant seem to find the "rtsp://192.168.1.254/sjcam.mov" link. btw i have an SJ5000+. i did find this: "rtsp://192.168.42.1/live/" but that still has no file to open

    ReplyDelete
    Replies
    1. it is probably very late... sorry, I did not see your post until now.
      There is no need to be a file in the end of the rtsp url, just try rtsp://192.168.42.1/live/ in VLC if that is what you are seeing

      Delete
  4. Hello desordenado,

    Please confirm if the same works even now. When I tried the same with VLC media player, it failed.

    Please revert back.

    Thanks

    ReplyDelete
  5. Well, I recently got a SJ4000 WiFi to play with and I did a similar research, though with different tools; I used plain dhclient for finding IP, Nmap for finding RTSP, followed by over-the-air snooping directly on Wireshark.

    My findings are published here, in case anyone is interested in reading:
    http://sj4000programming.sourceforge.net/

    Result of research agrees with you so far (except the problem in MOV files, which mine seemed to play fine; might depends on the firmware version). And about camera commands: 3016 returns current camera mode (1=video), and 2002 sets recording resolution (2=720p30); my experiment also cover these details.

    Happy tinkering,
    Nutchanon

    ReplyDelete
    Replies
    1. Glad to see we converged to similar results.
      Good work, by the way!!! will go into you page if I have to mess around with the camera anymore

      Delete
  6. After a whole day of research, installing and checking dozen of apps out there I still haven't found an exact solution

    The objective is following:
    1. Have a wi-fi camera paired to an iOS or android app
    2. Have camera stream live video to it
    3. Access/genarate RTSP broadcast data online from/to a mobile or desktop browser

    Out there there are many surveillance cams apps, but they use LAN or home wifi, not mobile

    There are platforms like Periscope with paired GoPro, but these are public accessible broadcasts with inability to intercept/extract just a video signal data and use it for custom web pages (or maybe there is a way?)

    If camera connected not to a PC but paired with a mobile app - is it possible to obtain the video data via RTSP from a browser?

    Thank you!

    ReplyDelete