forked from flycodepl/mi-band-firmware-analyse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse_fw
executable file
·52 lines (45 loc) · 2.08 KB
/
parse_fw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env escript
%%! -noshell -noinput
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% ex: ft=erlang ts=4 sw=4 et
-define(MILI_HR, 16#78, 16#75, 16#63, 16#6B).
-define(MILI, 16#00, 16#98, 16#00, 16#20, 16#89).
-define(RUNNING, 16#00, 16#98, 16#00, 16#20, 16#A1).
-define(WEIGHT, 16#10, 16#00, 16#AC, 16#A4).
main([InputFilename]) ->
{ok, FW} = file:read_file(InputFilename),
{ok, Type} = guess_type(FW),
{ok, Version} = get_version(Type, FW),
IntCRC = erlang:crc32(FW),
Info = #{file_name => filename:basename(InputFilename),
type => Type,
version => Version,
crc32 => integer_to_list(IntCRC, 16)
},
io:format("~p~n", [Info]).
%% @doc mili_hr has additional 24b headers. Rest is like in Mili
get_version(mili_hr, <<_SkipMiliHRHeader:16#24/binary, Rest/binary>>) ->
get_version(mili, Rest);
get_version(mili, <<_Header:1056/binary, Version:4/binary, _Rest/binary>>) ->
<<Revision,Build,Minor,Major>> = Version,
ParsedVersion = {Major,Minor,Build,Revision},
{ok, ParsedVersion};
%% @doc running firmware has version in ASCII.
%% Firmwares below version 0.2.5 doesn't has 'version string'...
%% @end
get_version(running, <<_Header:1056/binary, Version:6/binary, _Rest/binary>>) ->
case Version of
<<255,255,255,255,255,255>> ->
{error, unknown_version};
<<$v, Major, $., Minor, $., Build>> ->
%% int nw = ((newVMajor & 0xff) << 16) | ((newVMinor & 0xff) << 8) | (newVRev & 0xff);
%% V = ((Major band 16#FF) bsl 16) bor ((Minor band 16#FF) bsl 8) bor (Build band 16#FF),
IntVersion = [ list_to_integer([X]) || X <- [Major, Minor, Build] ],
ParsedVersion = list_to_tuple(IntVersion),
{ok, ParsedVersion}
end.
guess_type(<<?MILI_HR, _Rest/binary>>) -> {ok, mili_hr};
guess_type(<<?MILI, _Rest/binary>>) -> {ok, mili};
guess_type(<<?RUNNING, _Rest/binary>>) -> {ok, running};
guess_type(<<?WEIGHT, _Rest/binary>>) -> {ok, weight};
guess_type(_) -> {error, unknown_type}.