Remove named groups and simplify raw data usage.
authorSiraaj Khandkar <siraaj@khandkar.net>
Sun, 4 Oct 2015 23:16:06 +0000 (19:16 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Sun, 4 Oct 2015 23:16:06 +0000 (19:16 -0400)
Makefile
README.md
include/x_plane_data.hrl [deleted file]
rebar.config
src/x_plane_data.app.src
src/x_plane_data.erl [deleted file]
src/x_plane_data_raw.erl [new file with mode: 0644]
src/x_plane_datum.erl [deleted file]
src/x_plane_datum_defaults.hrl [deleted file]
test/x_plane_data_SUITE.erl

index 3be17b7..92e43ad 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ deps-update:
        @rebar update-deps
 
 dialyze:
-       @dialyzer ebin deps/hope/ebin
+       @dialyzer ebin
 
 test:
        @rebar ct skip_deps=true --verbose=0
index 7cc34b8..027e94c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,67 +7,38 @@ Example
 -------
 
 ```erlang
--include_lib("include/x_plane_data.hrl").
-
 main(Port) ->
     {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
     {ok, {_, _, <<XPlaneDataPacket/binary>>}} = gen_udp:recv(Socket, 0),
-    {ok, XPlaneData} = x_plane_data:of_bin(XPlaneDataPacket),
-
-    % Currently there're 133 possible data types sent by X-Plane 10, of which
-    % I've identified and labeled only some of. See x_plane_datum:t() type for
-    % what is currently labeled.
-    % The types I've not yet labeled are in the format specified by
-    % x_plane_datum:anonymous() and can be looked-up by their index number.
-
-    % Find labeled data types
-    {some, #x_plane_datum_speeds
-        { vind_kias   = VindKias
-        , vind_keas   = VindKeas
-        , vtrue_ktas  = VtrueKtas
-        , vtrue_ktgs  = VtrueKtgs
-        , vind_mph    = VindMph
-        , vtrue_mphas = VtrueMphas
-        , vtrue_mphgs = VtrueMphgs
-        },
-    } = hope_kv_list:get(XPlaneData, speeds),
-
-    {some, #x_plane_datum_pitch_roll_heading
-        { pitch_deg  = PitchDeg
-        , roll_deg   = RollDeg
-        , hding_true = HdingTrue
-        , hding_mag  = HdingMag
-        },
-    } = hope_kv_list:get(XPlaneData, pitch_roll_heading),
-
-    {some, #x_plane_datum_lat_lon_alt
-        { lat_deg   = LatDeg
-        , lon_deg   = LonDeg
-        , alt_ftmsl = AltFtmsl
-        , alt_ftagl = AltFtagl
-        , on_runwy  = OnRunwy
-        , alt_ind   = AltInd
-        , lat_south = LatSouth
-        , lon_west  = LatWest
-        },
-    } = hope_kv_list:get(XPlaneData, lat_lon_alt),
-
-    % Find an unlabled data type
-    {some, {10, V1, V2, V3, V4, V5, V6, V7, V8}} = hope_kv_list:get(XPlaneData, 10),
-
-    % Attempt to find a data type that was not included in current packet
-    none = hope_kv_list:get(XPlaneData, 130),
-    none = hope_kv_list:get(XPlaneData, 67),
+    {ok, {Index, Groups}} = x_plane_data_raw:of_bin(XPlaneDataPacket),
+
+    % Speeds are in group 3
+    {3, Speeds} = lists:keyfind(3, 1, Groups),
+    { VindKias
+    , VindKeas
+    , VtrueKtas
+    , VtrueKtgs
+    , _
+    , VindMph
+    , VtrueMphas
+    , VtrueMphgs
+    } = Speeds,
+
+    % Pitch roll and headings values are in group 17
+    {17, PitchRollHeadings} = lists:keyfind(17, 1, Groups),
+    { PitchDeg
+    , RollDeg
+    , HdingTrue
+    , HdingMag
+    , _
+    , _
+    , _
+    , _
+    } = PitchRollHeadings,
 
     ...
 ```
 
-Note: you can, of course, use any other method to search a `[{K, V}]` list
-(which is how `x_plane_data:t()` is structured), such as:
-`proplists:get_value/2`, `lists:keyfind/3`, etc., but I prefer the API of
-`hope_kv_list`, so I used that.
-
-
 Data format references
 ----------------------
 
diff --git a/include/x_plane_data.hrl b/include/x_plane_data.hrl
deleted file mode 100644 (file)
index d93611d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
--record(x_plane_datum_speeds,
-    { vind_kias   :: float() % 1
-    , vind_keas   :: float() % 2
-    , vtrue_ktas  :: float() % 3
-    , vtrue_ktgs  :: float() % 4
-                             % 5
-    , vind_mph    :: float() % 6
-    , vtrue_mphas :: float() % 7
-    , vtrue_mphgs :: float() % 8
-    }).
-
--record(x_plane_datum_pitch_roll_heading,
-    { pitch_deg  :: float()  % 1
-    , roll_deg   :: float()  % 2
-    , hding_true :: float()  % 3
-    , hding_mag  :: float()  % 4
-                             % 5
-                             % 6
-                             % 7
-                             % 8
-    }).
-
--record(x_plane_datum_lat_lon_alt,
-    { lat_deg   :: float() % 1
-    , lon_deg   :: float() % 2
-    , alt_ftmsl :: float() % 3
-    , alt_ftagl :: float() % 4
-    , on_runwy  :: float() % 5
-    , alt_ind   :: float() % 6
-    , lat_south :: float() % 7
-    , lon_west  :: float() % 8
-    }).
index c394a6c..7ea2705 100644 (file)
@@ -1,6 +1,6 @@
 %%% vim: set filetype=erlang:
 { deps
-, [ {hope , ".*" , {git , "https://github.com/ibnfirnas/hope.git" , {tag , "3.8.1"}}}
+, [
   ]
 }.
 
index ccad1bb..2084322 100644 (file)
@@ -1,7 +1,7 @@
 {application, x_plane_data,
  [
   {description, "X-Plane UDP data packet parser."},
-  {vsn, "0.0.1"},
+  {vsn, "0.1.0"},
   {registered, []},
   {applications, [
                   kernel,
diff --git a/src/x_plane_data.erl b/src/x_plane_data.erl
deleted file mode 100644 (file)
index 0a31a42..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
--module(x_plane_data).
-
--include("x_plane_datum_defaults.hrl").
-
--export_type(
-    [ t/0
-    ]).
-
--export(
-    [ of_bin/1
-    ]).
-
--type parsing_error() ::
-      packet_unrecognized
-    | packet_length_invalid
-    | x_plane_datum:parsing_error()
-    .
-
--type t() ::
-    [x_plane_datum:t()].
-
--define(BYTE_SIZE_OF_EACH_BLOCK, 36).
-
--spec of_bin(binary()) ->
-    hope_result:t(t(), parsing_error()).
-of_bin(<<Packet/binary>>) ->
-    of_bin(Packet, ?DEFAULT_MAX_INDEX).
-
--spec of_bin(binary(), non_neg_integer()) ->
-    hope_result:t(t(), parsing_error()).
-of_bin(<<"DATA", _PacketIndexByte:1/bytes, ContiguousBlocks/binary>>, MaxIndex) ->
-    % Packet index byte seems to be changing from X-Plane version to version.
-    % What is it's meaning?
-    if byte_size(ContiguousBlocks) rem ?BYTE_SIZE_OF_EACH_BLOCK =:= 0 ->
-            Blocks = blocks_split(ContiguousBlocks),
-            ParseBlock = fun (B) -> x_plane_datum:of_bin(B, MaxIndex) end,
-            hope_list:map_result(Blocks, ParseBlock)
-    ;  true ->
-            {error, packet_length_invalid}
-    end;
-of_bin(<<_/binary>>, _) ->
-    {error, packet_unrecognized}.
-
--spec blocks_split(binary()) ->
-    [binary()].
-blocks_split(<<>>) ->
-    [];
-blocks_split(<<Block:?BYTE_SIZE_OF_EACH_BLOCK/bytes, Blocks/binary>>) ->
-    [Block | blocks_split(Blocks)].
diff --git a/src/x_plane_data_raw.erl b/src/x_plane_data_raw.erl
new file mode 100644 (file)
index 0000000..f419137
--- /dev/null
@@ -0,0 +1,86 @@
+-module(x_plane_data_raw).
+
+-export_type(
+    [ t/0
+    , index/0
+    , group_index/0
+    , group_values/0
+    , group/0
+    , groups/0
+    ]).
+
+-export(
+    [ of_bin/1
+    ]).
+
+-type parsing_error() ::
+      packet_bad_header
+    | packet_bad_length
+    .
+
+-type group_index() ::
+    non_neg_integer().
+
+-type group_values() ::
+    { float()
+    , float()
+    , float()
+    , float()
+    , float()
+    , float()
+    , float()
+    , float()
+    }.
+
+-type group() ::
+    {group_index(), group_values()}.
+
+% Packet index byte. Essentially a schema version.
+-type index() ::
+    integer().
+
+-type groups() ::
+    [group()].
+
+-type t() ::
+    {index(), groups()}.
+
+-define(BYTE_SIZE_OF_EACH_BLOCK, 36).
+-define(PACKET_HEADER, "DATA").
+
+-spec of_bin(binary()) ->
+      {ok, t()}
+    | {error, parsing_error()}
+    .
+of_bin(<<?PACKET_HEADER, _:8/integer, ContiguousBlocks/binary>>)
+    when byte_size(ContiguousBlocks) rem ?BYTE_SIZE_OF_EACH_BLOCK =/= 0 ->
+    {error, packet_bad_length};
+of_bin(<<?PACKET_HEADER, Index:8/integer, ContiguousBlocks/binary>>) ->
+    Groups = [group_of_bin(B) || B <- blocks_split(ContiguousBlocks)],
+    {ok, {Index, Groups}};
+of_bin(<<_/binary>>) ->
+    {error, packet_bad_header}.
+
+-spec blocks_split(binary()) ->
+    [binary()].
+blocks_split(<<>>) ->
+    [];
+blocks_split(<<Block:?BYTE_SIZE_OF_EACH_BLOCK/bytes, Blocks/binary>>) ->
+    [Block | blocks_split(Blocks)].
+
+-spec group_of_bin(binary()) ->
+    group().
+group_of_bin(
+    << Index:32/little-integer
+     ,    V1:32/little-float
+     ,    V2:32/little-float
+     ,    V3:32/little-float
+     ,    V4:32/little-float
+     ,    V5:32/little-float
+     ,    V6:32/little-float
+     ,    V7:32/little-float
+     ,    V8:32/little-float
+    >>
+) ->
+    Values = {V1, V2, V3, V4, V5, V6, V7, V8},
+    {Index, Values}.
diff --git a/src/x_plane_datum.erl b/src/x_plane_datum.erl
deleted file mode 100644 (file)
index 15b21aa..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
--module(x_plane_datum).
-
--include("x_plane_datum_defaults.hrl").
--include("include/x_plane_data.hrl").
-
--export_type(
-    [ t/0
-    , label/0
-    , anonymous/0
-    , identified/0
-    , parsing_error/0
-    ]).
-
--export(
-    [ of_bin/1  % Use default max index
-    , of_bin/2  % Specify max index
-    ]).
-
--type parsing_error() ::
-      {block_structure_invalid, binary()}
-    | {block_index_byte_out_of_range, anonymous()}
-    .
-
--type anonymous() ::
-    { non_neg_integer()
-    , float()
-    , float()
-    , float()
-    , float()
-    , float()
-    , float()
-    , float()
-    , float()
-    }.
-
--type label() ::
-      speeds
-    | pitch_roll_heading
-    | lat_lon_alt
-    .
-
--type identified() ::
-      #x_plane_datum_speeds{}
-    | #x_plane_datum_pitch_roll_heading{}
-    | #x_plane_datum_lat_lon_alt{}
-    .
-
--type t() ::
-      {non_neg_integer() , anonymous()}
-    | {label()           , identified()}
-    .
-
--spec of_bin(binary()) ->
-    hope_result:t(t(), parsing_error()).
-of_bin(<<Block/binary>>) ->
-    of_bin(Block, ?DEFAULT_MAX_INDEX).
-
--spec of_bin(binary(), non_neg_integer()) ->
-    hope_result:t(t(), parsing_error()).
-of_bin(<<Block/binary>>, MaxIndex) ->
-    case anonymous_of_bin(Block, MaxIndex)
-    of {ok, Anonymous} ->
-            IdentifiedOrIndexed = identify_or_index(Anonymous),
-            {ok, IdentifiedOrIndexed}
-    ;   {error, _}=Error ->
-            Error
-    end.
-
--spec anonymous_of_bin(binary(), non_neg_integer()) ->
-    hope_result:t(anonymous(), parsing_error()).
-anonymous_of_bin(
-    << Index:32/little-integer
-     ,    V1:32/little-float
-     ,    V2:32/little-float
-     ,    V3:32/little-float
-     ,    V4:32/little-float
-     ,    V5:32/little-float
-     ,    V6:32/little-float
-     ,    V7:32/little-float
-     ,    V8:32/little-float
-    >>,
-    MaxIndex
-) ->
-    Anonymous = {Index, V1, V2, V3, V4, V5, V6, V7, V8},
-    if Index > 0 andalso Index =< MaxIndex ->
-        {ok, Anonymous}
-    ;  true ->
-        {error, {block_index_byte_out_of_range, Anonymous}}
-    end;
-anonymous_of_bin(<<Block/binary>>, _) ->
-    % This case shouldn't be possible with a correct packet length, but we want
-    % to allow for possibility of using this module independently of it's
-    % parent, data module.
-    {error, {block_structure_invalid, Block}}.
-
--spec identify_or_index(anonymous()) ->
-    t().
-identify_or_index({3, V1, V2, V3, V4, _, V6, V7, V8}) ->
-    Datum =
-        #x_plane_datum_speeds
-        { vind_kias   = V1
-        , vind_keas   = V2
-        , vtrue_ktas  = V3
-        , vtrue_ktgs  = V4
-
-        , vind_mph    = V6
-        , vtrue_mphas = V7
-        , vtrue_mphgs = V8
-        },
-    {speeds, Datum};
-identify_or_index({17, V1, V2, V3, V4, _, _, _, _}) ->
-    Datum =
-        #x_plane_datum_pitch_roll_heading
-        { pitch_deg  = V1
-        , roll_deg   = V2
-        , hding_true = V3
-        , hding_mag  = V4
-        },
-    {pitch_roll_heading, Datum};
-identify_or_index({20, V1, V2, V3, V4, V5, V6, V7, V8}) ->
-    Datum =
-        #x_plane_datum_lat_lon_alt
-        { lat_deg   = V1
-        , lon_deg   = V2
-        , alt_ftmsl = V3
-        , alt_ftagl = V4
-        , on_runwy  = V5
-        , alt_ind   = V6
-        , lat_south = V7
-        , lon_west  = V8
-        },
-    {lat_lon_alt, Datum};
-identify_or_index({Index, _, _, _, _, _, _, _, _}=Anonymous) ->
-    {Index, Anonymous}.
diff --git a/src/x_plane_datum_defaults.hrl b/src/x_plane_datum_defaults.hrl
deleted file mode 100644 (file)
index 9168e48..0000000
+++ /dev/null
@@ -1 +0,0 @@
--define(DEFAULT_MAX_INDEX, 133). % As of X-Plane 10.36r1
index 03a7fc4..d5bef9b 100644 (file)
@@ -1,7 +1,5 @@
 -module(x_plane_data_SUITE).
 
--include_lib("x_plane_data.hrl").
-
 %% CT callbacks
 -export(
     [ all/0
@@ -40,33 +38,19 @@ t_basic_sanity_check(_Cfg) ->
     Test =
         fun (PacketBase64) ->
             Packet = base64:decode(PacketBase64),
-            MaxIndex = 133,
-            BadIndex = MaxIndex + 1,
-            FakeBlockData = list_to_binary(lists:seq(1, 32)),
-            FakeBlockOk       = <<MaxIndex:32/little-integer, FakeBlockData/binary>>,
-            FakeBlockBadIndex = <<BadIndex:32/little-integer, FakeBlockData/binary>>,
-            {error, {block_index_byte_out_of_range, {BadIndex,_,_,_,_,_,_,_,_}}} =
-                x_plane_data:of_bin(<<Packet/binary, FakeBlockBadIndex/binary>>),
-            {error, packet_unrecognized} =
-                x_plane_data:of_bin(<<"bad-header", Packet/binary>>),
-            {error, packet_length_invalid} =
-                x_plane_data:of_bin(<<Packet/binary, "extra-stuff">>),
-            {ok, Data} =
-                x_plane_data:of_bin(<<Packet/binary, FakeBlockOk/binary>>),
-            {some, #x_plane_datum_speeds{}} =
-                hope_kv_list:get(Data, speeds),
-            {some, #x_plane_datum_pitch_roll_heading{}} =
-                hope_kv_list:get(Data, pitch_roll_heading),
-            {some, #x_plane_datum_lat_lon_alt{}} =
-                hope_kv_list:get(Data, lat_lon_alt),
-            {some, {MaxIndex,_,_,_,_,_,_,_,_}} =
-                hope_kv_list:get(Data, MaxIndex),
+            {error, packet_bad_header} =
+                x_plane_data_raw:of_bin(<<"bad-header", Packet/binary>>),
+            {error, packet_bad_length} =
+                x_plane_data_raw:of_bin(<<Packet/binary, "extra-stuff">>),
+            {ok, {_, Groups}} =
+                x_plane_data_raw:of_bin(<<Packet/binary>>),
+            {some, {_, _, _, _, _, _, _, _}} = kv_list_find(Groups, 3),
+            {some, {_, _, _, _, _, _, _, _}} = kv_list_find(Groups, 17),
+            {some, {_, _, _, _, _, _, _, _}} = kv_list_find(Groups, 20),
             ok
         end,
     lists:foreach(Test, sample_packets_base64_encoded()).
 
-
-
 %% =============================================================================
 %% Sample data
 %% =============================================================================
@@ -74,3 +58,14 @@ t_basic_sanity_check(_Cfg) ->
 sample_packets_base64_encoded() ->
         [ <<"REFUQUADAAAAbcpGQLt81EBfZNlATnUoNwDAecSow2RAnCv6QLrbQTcRAAAA3i8VQFL3ZT6dPfFCx4IFQwDAecQAwHnEAMB5xADAecQUAAAA1ZciQg6ik8JGBv9AdDxoPgAAgD9G/o3CAAAgQgAAlsI=">>
         ].
+
+
+%% =============================================================================
+%% Helpers
+%% =============================================================================
+
+kv_list_find(KVL, K) ->
+    case lists:keyfind(K, 1, KVL)
+    of  false  -> none
+    ;   {K, V} -> {some, V}
+    end.
This page took 0.037276 seconds and 4 git commands to generate.