初探酷走Android行车记录仪

in kubo •  6 years ago  (edited)

酷走记录仪

博客有段时间没有更新了,提前说好这不是一般的行车记录仪评测文章,我现在开的 SUV 上并没有装记录仪,只是同事刚好送了一个厂商已倒闭的记录仪,看到这款采用 Intel Atom 处理器的行车记录仪有点兴趣,准备初步研究下。

酷走行车记录仪由深圳汉普云联科技生产,具体型号为 KZV201,网上关于此行车记录仪的评测文章还是有一些的,之前 京东众筹 上的链接应该还在,想了解的朋友们可以看看。

这里我就不做具体介绍了,外观图也就不上了。初步了解此记录仪使用 Intel SOFIA Atom x3 处理器,因此集成了 3G 上网功能(带 SIM 卡插槽),支持 2.4 GHz Wi-Fi 网络、蓝牙 4.0、GPS 及 FM 发射功能。酷走记录仪虽然号称支持 1080p 全高清视频录制,然而实际测试录像效果也是比较一般,另外采用 Android 5.0 系统也挺少见。

由于机身没有任何物理按键,所有功能都要通过手机 App 连接行车记录仪 Wi-Fi 热点来完成,这也是相当坑的地方:由于厂家已经不提供支持更新了,目前手机 App 里不少功能缺失,最基本的 SIM 卡(专用物联网卡)数据流量充值功能都不能使用;手机 App 连修改记录仪系统时间的功能都没有提供(可能厂家考虑的是自动通过 SIM 卡数据流量进行时间同步),导致目前记录仪的时间都不正确。

Web 接口使用

为了摆脱随时可能会完全崩掉的手机 App,我就需要知道基本的管理接口和视频调阅接口。

记录仪自带的 Wi-Fi 热点使用固定的 192.168.43.1 IP 地址(别指望能修改了),手机或者电脑连接酷走的 Wi-Fi 热点之后就可以 ping 通记录仪地址了,下面我贴出来的例子都是在 Chromebook 上测试的,首先我用 Linux 自带的 nc 命令来扫一下记录仪开放的端口:

(xenial)zzm@localhost:~$ nc -znv 192.168.43.1 20-20000 2>&1 | grep 'succeeded'
Connection to 192.168.43.1 53 port [tcp/*] succeeded!
Connection to 192.168.43.1 5556 port [tcp/*] succeeded!
Connection to 192.168.43.1 8080 port [tcp/*] succeeded!
Connection to 192.168.43.1 8886 port [tcp/*] succeeded!

显然 53 是 Wi-Fi 热点自带的 DNS 服务器端口,看起来 8080 就是 Web 接口的端口了,我在安装了酷走 App 的手机上运行 tcpdump 程序进行抓包就可以分析 8080 端口的请求了。

用户登录

首先是用户登录请求:

chronos@localhost ~/Downloads $ curl -v "http://192.168.43.1:8080/term?act=user_login&user=\{%22email%22:null,%22emailVerifyCode%22:null,%22emailVerifyCodeValidtime%22:nu
ll,%22emailVerifyStatus%22:0,%22iconUuid%22:null,%22id%22:0,%22lastLoginTime%22:null,%22name%22:null,%22nickname%22:null,%22password%22:null,%22phone%22:null,%22phoneLoginCode%22:null,%22phoneLoginCodeValidtime%22:null,%22realName%22:null,%22regTime%22:null,%22uuid%22:%222F06A8D7CA314388B58DC46719702844%22\}&password=8888&termtype=3&force=false"
*   Trying 192.168.43.1...
* TCP_NODELAY set
* Connected to 192.168.43.1 (192.168.43.1) port 8080 (#0)
> GET /term?act=user_login&user={%22email%22:null,%22emailVerifyCode%22:null,%22emailVerifyCodeValidtime%22:null,%22emailVerifyStatus%22:0,%22iconUuid%22:null,%22id%22:0,%22lastLoginTime%22:null,%22name%22:null,%22nickname%22:null,%22password%22:null,%22phone%22:null,%22phoneLoginCode%22:null,%22phoneLoginCodeValidtime%22:null,%22realName%22:null,%22regTime%22:null,%22uuid%22:%222F06A8D7CA314388B58DC46719702844%22}&password=8888&termtype=3&force=false HTTP/1.1
> Host: 192.168.43.1:8080
> User-Agent: curl/7.60.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Set-Cookie: JSESSIONID=1lqydpb54hnunwlfbfj8eqkzi;Path=/
< Set-Cookie: TONG_TOKEN_ID=a2664fc77f2d4c2abf90bea58e3bb6bf;Path=/;Expires=Tue, 29-Feb-2000 00:26:30 GMT
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Content-Type: text/plain;charset=UTF-8
< Access-Control-Allow-Methods: GET, POST
< Access-Control-Allow-Credentials: true
< Transfer-Encoding: chunked
< Server: Jetty(i-jetty 1.0.27)
< 
* Connection #0 to host 192.168.43.1 left intact
{"data":"a2664fc77f2d4c2abf90bea58e3bb6bf","elapsedTime":94,"message":"鉴权通过!","responseCode":100}

注意

上面 curl 命令中的括号做了转义防止 curl 请求错误,实际请求地址中并没有反斜杠,另外请求地址中的 %22 就是双引号,如果在浏览器中访问也可以直接把 %22 换成双引号。

可以看到记录仪 Web 服务器是基于 Jetty 写的,GET 请求地址中的 userpassword 参数不能缺少,password 就是记录仪的管理密码(默认:8888),user 参数是个 JSON 对象,基本所有参数都可以使用 null,除了 uuid 参数表示登录用户(可以随机生成一串 UUID),重复发送登录请求将会报错。

最值得关注的是返回 Cookie 数据中的 JSESSIONID=1lqydpb54hnunwlfbfj8eqkzi 值,后面所有 Web 请求都会用到这个会话 ID。

查看设备信息

基础设备信息也可以使用 curl 附带 JSESSIONID Cookie 值进行查询,下面其它的请求就不详细列出来了:

curl -v -b "JSESSIONID=1lqydpb54hnunwlfbfj8eqkzi" "http://192.168.43.1:8080/term?act=device_info&appID=null"

设备信息输出如下:

GET /term?act=device_info&appID=null HTTP/1.1
Host: 192.168.43.1:8080
Cookie: JSESSIONID=73jb4a4t1urf1un1krkwn6drr

HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Credentials: true
Transfer-Encoding: chunked
Server: Jetty(i-jetty 1.0.27)

{"data":{"hotName":null,"hotPassword":null,"hwVerion":"4","imei":"XXXXXXX","osVersion":"2.2.3","password":null,"productCode":null,"randomCode":null,"sn":"KXXXXXX","swVersion":"1.0.27","videoPassword":null},"elapsedTime":9,"message":null,"responseCode":100}

查看记录仪配置请求:

GET /term?act=query_termconfiginfo HTTP/1.1

{"data":{"hotName":"KUZO_KXXXXXX","hotPassword":"password","hwVerion":"4","imei":"XXXXXXX","osVersion":"2.2.3","password":"8888","productCode":null,"randomCode":null,"sn":"KXXXXXX","swVersion":"1.0.27","videoPassword":""},"elapsedTime":14,"message":"Success!","responseCode":100}

查看 SIM 卡 ICCID(返回值在 data 中):

GET /term?act=query_sim_iccid HTTP/1.1

{"data":"XXXXXXX","elapsedTime":14,"message":null,"responseCode":100}

查看 FM 发射状态(这个 POST 请求没有附带任何参数):

POST /term?act=query_fm_open_status HTTP/1.1
Content-Length: 0

{"data":false,"elapsedTime":35,"message":null,"responseCode":100}

查看 GPS 状态:

GET /term?act=query_gps_status HTTP/1.1

{"data":{"position":{"accuracy":14.33,"altitude":15.030368,"angle":337.0591,"crs":1,"gpsTime":"20181023180046","latitude":31.907135402870722,"longitude":118.77761111400555,"speed":0.0},"positionFix":true,"positionType":1,"satellitesInUse":5,"satellitesInView":6},"elapsedTime":3,"message":null,"responseCode":100}

可以看到这里能直接查询到 GPS 的当前经纬度以及精确度,还能看到卫星的使用情况,比较讽刺的是这边 GPS 时间都得到了,记录仪系统在网络不可用的情况下却没考虑使用 GPS 时间。

查询存储状态(装了 TF 卡之后就能看到存储卡容量状态了):

GET /term?act=query_storage_info HTTP/1.1

{"data":{"TFExist":true,"TFTotalCapacity":63847890944,"TFUsedCapacity":6595575808,"internalTotalCapacity":3918114816,"internalUsedCapacity":2259316736},"elapsedTime":3,"message":null,"responseCode":100}

查询 3G 移动网络状态:

GET /term?act=query_3g_status HTTP/1.1

{"data":{"dialUpSuccess":false,"intensity":0,"mnc":"01","type":"3G"},"elapsedTime":19,"message":null,"responseCode":100}

音乐管理

此记录仪支持通过手机 App 上传音乐到记录仪的存储卡,然后通过蓝牙进行播放控制,列举音乐接口:

GET /term?act=list_music HTTP/1.1

{"data":[{"fileSize":4008624,"id":0,"length":0,"md5":"e8b1a4e5-0a4d-4c1f-b6bf-44052507fc37","name":null,"path":"/mnt/media_rw/sdcard1/Kuzo/Music/2F06A8D7CA314388B58DC46719702844/2/13/e8b1a4e5-0a4d-4c1f-b6bf-44052507fc37.mp3","singer":null,"userUuid":"2F06A8D7CA314388B58DC46719702844","uuid":"e8b1a4e5-0a4d-4c1f-b6bf-44052507fc37"}],"elapsedTime":7,"message":"Success!","responseCode":100}

查询最大音量(最大级别为 15):

GET /term?act=query_max_volume HTTP/1.1

{"data":15,"elapsedTime":5,"message":null,"responseCode":100}

查看当前音量:

GET /term?act=query_volume HTTP/1.1

{"data":10,"elapsedTime":9,"message":"15 15","responseCode":100}

视频管理

首先按小时段列举视频,请忽略不正确的系统时间:

GET /term?act=list_video_hour HTTP/1.1

{"data":["20000115230000","20000116000000","20000116010000","20000116020000","20000116030000"],"elapsedTime":171,"message":null,"responseCode":100}

指定开始和结束的小时时间段列举视频:

GET /term?act=list_poi&start_time=20000116030000&end_time=20000116040000 HTTP/1.1

{"data":[],"elapsedTime":9,"message":null,"responseCode":100}

列举某个小时的所有视频,可以看到存储卡里视频的完整路径:

GET /term?act=list_video_db&hour_time=20000116030000 HTTP/1.1

{"data":[{"createTime":"20000116030127","id":42,"length":120009,"lockType":0,"name":"2000-01-16_03-01-27.mp4","path":"/mnt/media_rw/sdcard1/Kuzo/Video/2000/1/16/3/2000-01-16_03-01-27.mp4","sn":null,"uuid":"a6035028ded14482936c1580aba8e298","videoType":0},{"createTime":"20000116030327","id":43,"length":119940,"lockType":0,"name":"2000-01-16_03-03-27.mp4","path":"/mnt/media_rw/sdcard1/Kuzo/Video/2000/1/16/3/2000-01-16_03-03-27.mp4","sn":null,"uuid":"291a4796c1274dfea99a978c84ca33d0","videoType":0}],"elapsedTime":986,"message":null,"responseCode":100}

获取某个视频文件的封面截图,此请求直接返回 jpg 图像数据:

GET /term?act=snapshot&name=2000-01-16_03-21-26.mp4&time=0 HTTP/1.1

HTTP/1.1 200 OK
Content-Type: image/jpeg
Accept-Ranges: bytes
Content-Length: 42351
Content-Disposition: attachment;filename=2000-01-16_03-19-26_0.jpg
Server: Jetty(i-jetty 1.0.27)

指定开始和结束时间段获取历史轨迹,由于记录仪的 GPS 是一直开启的,还好轨迹还算比较准确,这里轨迹数据比较长我就不详细贴出来了:

GET /term?act=query_history_track&start_time=20181013180104&end_time=20181013180304&len=121 HTTP/1.1

最后是最关键的下载录像接口,通过 name 参数指定视频文件名即可:

GET /term?act=get_video&name=2000-01-16_03-19-26.mp4 HTTP/1.1
User-Agent: Lavf/57.56.100
Accept: */*
Range: bytes=0-
Connection: close
Host: 192.168.43.1:8080
Icy-MetaData: 1

HTTP/1.1 206 Partial Content
Content-Type: application/octet-stream
Accept-Ranges: bytes
Content-Length: 61722040
Content-Disposition: attachment;filename=2000-01-16_03-19-26.mp4
Content-Range: bytes 3104-61722039/61722040
Connection: close
Server: Jetty(i-jetty 1.0.27)

有点奇葩的就是这个下载录像的请求却并没有验证用户会话 ID,因此你也可以通过任何一款播放器指定地址直接远程回放录像:

http://192.168.43.1:8080/term?act=get_video&name=2000-01-16_03-19-26.mp4

实时视频接口

通过 tcpdump 抓包就会发现记录仪的实时视频预览是通过上面扫描出来的 8886 端口,记录仪提供 RTSP 形式的实时预览接口:

rtsp://192.168.43.1:8886?videoapi=mc2&transport=tcp

需要注意的是记录仪自带的 RTSP 服务器似乎只支持 TCP 流传输,如果使用 VLC 播放器,则需要将 Live555 流传输选项改为:RTP over RTSP (TCP) 才能正常播放。

厂家可能出于预览流畅性考虑 RTSP 并没有直接提供 1080p 的视频,然而我通过 VLC 播放器进行 RTSP 实时预览还是存在两至三秒的延时,在 Chromebook 下切换使用 VXG Media Player 插件进行实时预览则不存在延时问题。

总结

目前该行车记录仪使用下来还存在几个主要问题:

  • SIM 卡无法联网的情况下系统时间没办法修改;
  • 手机 App 提供的记录仪通过扫码连接外部 Wi-Fi 或者手机热点的功能无法工作,如果可以的话系统时间同步应该就不是问题;
  • 记录仪硬件上有降噪麦克风,而且支持通过蓝牙的语音对讲功能(只用于目前手机 App 里基本不可用的结伴出行组队),但是视频录像却不支持音频录制,同样 RTSP 实时视频中也没有带音频流。

这些问题只能后面有空的话再抽时间看看能否进入记录仪的 Android 系统进行修改了,祝大家玩的开心。

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:
https://zohead.com/archives/kuzo-recorder/

Congratulations @zohead! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!