初探酷走Android行车记录仪
酷走记录仪
博客有段时间没有更新了,提前说好这不是一般的行车记录仪评测文章,我现在开的 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: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" * 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 请求地址中的 user
和 password
参数不能缺少,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 系统进行修改了,祝大家玩的开心。
依云:
2018年11月02日 星期五 10:31上午
curl 有个参数禁用特殊字符的,好像是 -g。一个个地转义多累啊。
Uranus Zhou:
2018年11月02日 星期五 09:47下午
直接拷贝的抓包数据里的地址,嘿嘿;
不过之前测试 curl 的 -g 参数时才了解地址里的大括号在 bash 上还需要再加转义。
I BULI:
2023年10月23日 星期一 09:52上午
您好,请问这款设备如何重置呀?网上已经搜不到这个厂商提供的相关资料了,我尝试安装酷走APP1.5.3安卓版本提示SDK版本过低,无法正常运行。
Uranus Zhou:
2023年10月30日 星期一 10:26上午
按照 酷走Android行车记录仪研究 这篇文章里的介绍可以使用 adb 调试哦,
另外安装 Vysor 软件之后,就可以通过 adb 连接行车记录仪了。
连接之后,就可以进入 Android 界面,可以在设置里进行重置咯。