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.

Sunday, November 9, 2014

cloudClock: Force an update of the time with ntpd

Whenever ntpd detects a huge different between the system time and the ntp server time, ntpd does not update the time. I should investigate further on why it behaves that way, but I think I know enough about ntpd already for now... so I investigated how to make ntpd to force the update and this is what I found:

To force a large NTP update, do the following:

Stop the NTPD service ("/etc/init.c/ntpd stop")
run ntpd -gnqd
Start the NTPD service again ("/etc/init.c/ntpd start")