Skip to content
Browse files

Packet decoding

  • Loading branch information...
1 parent 49531c2 commit be3019027bb37c01779f4b2bdaa3ec93a0cd5451 @brendonh committed Feb 8, 2010
Showing with 206 additions and 12 deletions.
  1. +1 −1 Makefile
  2. +2 −1 include/slerl.hrl
  3. +1 −1 priv/messages.yrl
  4. +1 −1 src/slerl_app.erl
  5. +114 −2 src/slerl_message.erl
  6. +51 −0 src/slerl_sandbox.erl
  7. +36 −6 src/slerl_sim.erl
View
2 Makefile
@@ -30,7 +30,7 @@ run: run_prereqs
$(ERL_CMD) -s ${PKG_NAME}_app launch
test: run_prereqs
- $(ERL_CMD) -noshell -s slerl_message test -s init stop
+ $(ERL_CMD) -noshell -s slerl_sandbox test -s init stop
parser:
erl -noshell -eval 'yecc:yecc("priv/messages.yrl", "src/slerl_message_template_parser.erl").' -s init stop
View
3 include/slerl.hrl
@@ -26,7 +26,8 @@
message,
zerocoded,
reliable=false,
- resend=false
+ resend=false,
+ extra
}).
View
2 priv/messages.yrl
@@ -121,6 +121,6 @@ parse_type("U16Quat") -> not_used;
parse_type("S16Array") -> not_used.
precalc_messageID(high, Number) -> <<Number:1/integer-unit:8>>;
-precalc_messageID(fixed, Number) -> <<Number:1/integer-unit:8>>;
+precalc_messageID(fixed, Number) -> <<Number:1/integer-unit:32>>;
precalc_messageID(medium, Number) -> <<255:1/integer-unit:8, Number:1/integer-unit:8>>;
precalc_messageID(low, Number) -> <<255:1/integer-unit:8, 255:1/integer-unit:8, Number:1/integer-unit:16>>.
View
2 src/slerl_app.erl
@@ -28,7 +28,7 @@ launch() ->
application:start(inets),
application:start(ssl),
- {ok, _MTid} = slerl_message:parse_message_template(),
+ ok = slerl_message:parse_message_template(),
application:start(slerl),
{ok, [Bits]} = file:consult("login.config"),
View
116 src/slerl_message.erl
@@ -10,18 +10,30 @@
-include("slerl.hrl").
-include("slerl_util.hrl").
--export([parse_message_template/0, build_message/2, test/0]).
+-export([parse_message_template/0, build_message/2, parse_message/2, test/0]).
-export([zero_encode/1, zero_decode/1]).
parse_message_template() ->
Content = slerl_message_template_lexer:scan_file("priv/message_template.msg"),
{ok, {_Version, Messages}} = slerl_message_template_parser:parse(Content),
+
Tid = ets:new(slerl_messages, [set, protected, named_table]),
ets:insert(Tid, Messages),
- {ok, Tid}.
+
+ Tid2 = ets:new(slerl_messageByID, [set, protected, named_table]),
+ ets:insert(Tid2, [{messageID(M), M}
+ || {_, M} <- Messages]),
+
+ ok.
+messageID(#messageDef{frequency=fixed}=M) -> {low, M#messageDef.number - 16#FFFF0000};
+messageID(M) -> {M#messageDef.frequency, M#messageDef.number}.
+%%-------------------------------------------------------------------
+%% Message construction
+%%-------------------------------------------------------------------
+
build_message(Name, Args) ->
Message = ets:lookup_element(slerl_messages, Name, 2),
Blocks = build_blocks(Message#messageDef.blocks, Args),
@@ -88,6 +100,106 @@ build_parameter({ipport, 2}, Val) -> <<Val:2/unsigned-integer-little-unit:8>>.
+%%-------------------------------------------------------------------
+%% Message parsing
+%%-------------------------------------------------------------------
+
+parse_message(<<255, 255, LowID:1/integer-unit:16, Rest/binary>>, Message) ->
+ parse_message2({low, LowID}, Rest, Message);
+parse_message(<<255, MedID:1/integer-unit:8, Rest/binary>>, Message) ->
+ parse_message2({medium, MedID}, Rest, Message);
+parse_message(<<HighID:1/integer-unit:8, Rest/binary>>, Message) ->
+ parse_message2({high, HighID}, Rest, Message).
+
+parse_message2(MID, Rest, Message) ->
+ Spec = ets:lookup_element(slerl_messageByID, MID, 2),
+
+ Decoded = if Message#message.zerocoded -> zero_decode(Rest);
+ true -> Rest end,
+ {Blocks, Tail} = parse_blocks(Spec#messageDef.blocks, Decoded, []),
+ {Message#message{spec=Spec, message=Blocks}, Tail}.
+
+
+parse_blocks([], Tail, Buff) ->
+ {lists:reverse(Buff), Tail};
+parse_blocks([Block|Blocks], Bin, Buff) ->
+ {Fields, Tail} = parse_block(Block, Bin),
+ parse_blocks(Blocks, Tail, [Fields|Buff]).
+
+
+parse_block(#blockDef{quantity=single}=B, Bin) ->
+ {Parameters, Tail} = parse_parameters(B#blockDef.parameters, Bin, []),
+ {{B#blockDef.name, Parameters}, Tail};
+parse_block(#blockDef{quantity=multiple, repeats=Repeats}=B, Bin) ->
+ {Parameters, Tail} = parse_multiple(B#blockDef.parameters, Bin, [], Repeats),
+ {{B#blockDef.name, Parameters}, Tail};
+parse_block(#blockDef{quantity=variable}=B, <<Repeats:1/integer-unit:8, Bin/binary>>) ->
+ {Parameters, Tail} = parse_multiple(B#blockDef.parameters, Bin, [], Repeats),
+ {{B#blockDef.name, Parameters}, Tail}.
+
+
+parse_multiple(_, Bin, Buff, 0) ->
+ {lists:reverse(Buff), Bin};
+parse_multiple(PS, Bin, Buff, Repeats) ->
+ {P, Tail} = parse_parameters(PS, Bin, []),
+ parse_multiple(PS, Tail, [P|Buff], Repeats-1).
+
+
+parse_parameters([], Tail, Buff) ->
+ {lists:reverse(Buff), Tail};
+parse_parameters([{Name,Type}|Rest], Bin, Buff) ->
+ {Val, Tail} = parse_parameter(Type, Bin),
+ parse_parameters(Rest, Tail, [{Name, Val}|Buff]).
+
+
+parse_parameter({fixed, Len}, Bin) ->
+ <<Val:Len/binary, Rest/binary>> = Bin,
+ {Val, Rest};
+parse_parameter({variable, 1}, <<Len:1/integer-unit:8, Bin/binary>>) ->
+ <<Val:Len/binary, Rest/binary>> = Bin,
+ {Val, Rest};
+parse_parameter({variable, 2}, <<Len:1/integer-little-unit:16, Bin/binary>>) ->
+ <<Val:Len/binary, Rest/binary>> = Bin,
+ {Val, Rest};
+parse_parameter({uint, 1}, <<Val:1/unsigned-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({uint, 2}, <<Val:2/unsigned-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({uint, 4}, <<Val:4/unsigned-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({uint, 8}, <<Val:8/unsigned-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({int, 1}, <<Val:1/signed-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({int, 2}, <<Val:2/signed-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({int, 4}, <<Val:4/signed-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({int, 8}, <<Val:8/signed-integer-little-unit:8, Rest/binary>>) -> {Val, Rest};
+parse_parameter({float, 4}, <<Val:1/float-little-unit:32, Rest/binary>>) -> {Val, Rest};
+parse_parameter({float, 8}, <<Val:1/float-little-unit:64, Rest/binary>>) -> {Val, Rest};
+parse_parameter(
+ {vector3, 12},
+ <<X:1/float-little-unit:32, Y:1/float-little-unit:32, Z:1/float-little-unit:32, Rest/binary>>) ->
+ {{X,Y,Z}, Rest};
+parse_parameter(
+ {vector3, 24},
+ <<X:1/float-little-unit:64, Y:1/float-little-unit:64, Z:1/float-little-unit:64, Rest/binary>>) ->
+ {{X,Y,Z}, Rest};
+parse_parameter(
+ {vector4, 16},
+ <<X:1/float-little-unit:32, Y:1/float-little-unit:32,
+ Z:1/float-little-unit:32, W:1/float-little-unit:32, Rest/binary>>) ->
+ {{X,Y,Z,W}, Rest};
+parse_parameter(
+ {quaternion, 12},
+ <<X:1/float-little-unit:32, Y:1/float-little-unit:32, Z:1/float-little-unit:32, Rest/binary>>) ->
+ {{X,Y,Z}, Rest};
+parse_parameter({uuid, 16}, <<Val:16/binary, Rest/binary>>) -> {Val, Rest};
+parse_parameter({bool, 1}, <<1, Rest/binary>>) -> {true, Rest};
+parse_parameter({bool, 1}, <<0, Rest/binary>>) -> {false, Rest};
+parse_parameter({ipaddr, 4}, <<N1,N2,N3,N4, Rest/binary>>) -> {{N1,N2,N3,N4}, Rest};
+parse_parameter({ipport, 2}, <<Val:2/unsigned-integer-little-unit:8, Rest/binary>>) -> {Val, Rest}.
+
+
+
+%%-------------------------------------------------------------------
+%% Utilities
+%%-------------------------------------------------------------------
+
zero_encode(B) ->
zero_encode(B, []).
View
51 src/slerl_sandbox.erl
@@ -0,0 +1,51 @@
+-module(slerl_sandbox).
+
+-include("slerl.hrl").
+-include("slerl_util.hrl").
+
+-export([test/0]).
+
+
+-define(MSGS, [
+<<208,0,0,0,1,0,255,255,1,131,203,30,34,250,125,1,73,132,140,125,10,66,122,63,
+ 212,162,7,72,111,116,116,105,101,0,1,9,86,101,115,117,118,105,110,111,0,1,1,
+ 0,25,1,0,1,0,0,0,1,1>>,
+<<192,0,0,0,2,0,255,255,0,1,148,6,12,16,20,21,8,82,111,99,104,105,97,108,0,20,
+ 160,65,0,2,128,63,115,127,143,63,215,110,208,87,241,59,68,236,60,255,225,202,
+ 183,9,146,32,207,166,26,157,35,47,231,99,62,115,82,41,244,193,199,140,159,
+ 242,157,17,41,95,79,51,92,205,180,28,99,51,142,222,0,1,55,196,253,133,91,1,
+ 93,119,17,47,200,23,156,218,189,57,138,155,107,19,145,77,195,51,186,50,31,
+ 183,9,146,32,207,166,26,157,35,47,231,99,62,115,82,41,244,193,199,140,159,
+ 242,157,17,41,95,79,51,92,205,180,28,99,51,142,222,0,1,55,196,253,133,91,1,
+ 93,119,17,47,200,23,156,218,189,57,138,155,107,19,145,77,195,51,186,50,31,0,
+ 2,160,65,0,2,160,65,0,2,160,65,0,2,160,65,0,2,180,66,0,2,180,66,0,2,180,66,0,
+ 2,180,66,236,227,113,26,22,183,79,46,166,113,100,127,148,234,218,92,5,0,3,1,
+ 0,3,7,68,97,108,108,97,115,0,1,4,48,50,51,0,1,23,77,97,105,110,108,97,110,
+ 100,32,47,32,70,117,108,108,32,82,101,103,105,111,110,0,1>>,
+<<64,0,0,0,3,0,255,255,0,250,203,30,34,250,125,1,73,132,140,125,10,66,122,63,
+ 212,162,5,139,228,8,155,132,66,195,155,218,219,152,34,66,199,46,84,131,76,67,
+ 45,146,22,67,160,137,179,65,0,0,128,63,0,0,0,0,0,0,0,0,0,27,4,0,0,95,4,0,138,
+ 205,111,75,33,0,83,101,99,111,110,100,32,76,105,102,101,32,83,101,114,118,
+ 101,114,32,49,46,51,52,46,51,46,49,52,51,48,51,56,0>>,
+<<0,0,0,0,4,0,255,255,255,251,1,2,0,0,0>>,
+<<64,0,0,0,5,0,255,255,0,138,0,0,200,66>>,
+<<64,0,0,0,6,0,255,255,1,66,1,63,50,74,226,157,165,79,73,135,50,229,102,9,109,
+ 70,251>>,
+<<0,0,0,0,7,0,255,15,1,124,3,173,169,113,5,174,187,163,132,169,182,8,87,244,
+ 136,110,46,59,150,80,199,74,17,130,20,83,107,202,14,175,137,13,16,32,87,172,
+ 58,160,2,90,158,75,206,228,230,230,203>>,
+<<0,0,0,0,8,0,255,6,1,205,151,6,0,0,255,255,1,203,30,34,250,125,1,73,132,140,
+ 125,10,66,122,63,212,162>>,
+<<0,0,0,0,9,0,255,6,1,205,151,6,0,0,255,255,1,203,30,34,250,125,1,73,132,140,
+ 125,10,66,122,63,212,162>>,
+<<0,0,0,0,10,0,255,6,1,205,151,6,0,0,255,255,1,203,30,34,250,125,1,73,132,140,
+ 125,10,66,122,63,212,162>>,
+<<0,0,0,0,11,0,255,6,1,205,151,6,0,0,255,255,1,203,30,34,250,125,1,73,132,140,
+ 125,10,66,122,63,212,162>>]).
+
+
+
+test() ->
+ slerl_message:parse_message_template(),
+ %slerl_sim:parse_packet(hd(?MSGS), none).
+ [slerl_sim:parse_packet(M, none) || M <- ?MSGS].
View
42 src/slerl_sim.erl
@@ -13,7 +13,7 @@
-include("slerl_util.hrl").
%% API
--export([start_link/2]).
+-export([start_link/2, parse_packet/2]).
%% gen_fsm callbacks
-export([init/1, state_name/2, state_name/3, handle_event/3,
@@ -70,11 +70,20 @@ handle_event(_Event, StateName, State) ->
{next_state, StateName, State}.
-handle_sync_event(Event, From, StateName, State) ->
+handle_sync_event(_Event, _From, StateName, State) ->
Reply = ok,
{reply, Reply, StateName, State}.
+handle_info({udp, Socket, IP, Port, Packet}, StateName,
+ #state{socket=Socket, sim=#sim{ip=IP, port=Port}}=State) ->
+ io:format("~p~n", [Packet]),
+ {next_state, StateName, State};
+
+handle_info({udp, Socket, IP, Port, Packet}, StateName, State) ->
+ ?DBG({udp_mismatch, Socket, IP, Port, State, Packet}),
+ {next_state, StateName, State};
+
handle_info(Info, StateName, State) ->
?DBG({info, Info}),
{next_state, StateName, State}.
@@ -103,6 +112,9 @@ send(Packet, State) ->
reliable(M) -> M#message{reliable=true}.
+bool(1) -> true;
+bool(0) -> false.
+
unbool(true) -> 1;
unbool(false) -> 0.
@@ -127,12 +139,31 @@ build_packet(Message, State) ->
+
+parse_packet(<<Zeroed:1/integer-unit:1, Reliable:1/integer-unit:1,
+ Resent:1/integer-unit:1, _Acks:1/integer-unit:1,
+ 0:4/integer-unit:1,
+ _Sequence:4/integer-unit:8, ExtraHeader:1/integer-unit:8,
+ Rest/binary>>, _State) ->
+ Skeleton = #message{zerocoded=bool(Zeroed), reliable=bool(Reliable), resend=bool(Resent)},
+ {Message,Tail} = parse_packet2(ExtraHeader, Rest, Skeleton),
+ ?DBG({Message, Tail}),
+ ok.
+
+
+parse_packet2(0, Rest, Message) ->
+ slerl_message:parse_message(Rest, Message);
+parse_packet2(Count, Packet, Message) ->
+ <<Extra:Count/binary, Rest/binary>> = Packet,
+ slerl_message:parse_message(Rest, Message#message{extra=Extra}).
+
+
send_connect_packets(State) ->
State1 = use_circuit_code(State),
State2 = complete_agent_movement(State1),
- State3 = agent_update(State2),
- State4 = ping(State3),
- State4.
+ %State3 = agent_update(State2),
+ %State4 = ping(State3),
+ State2.
use_circuit_code(State) ->
Sim = State#state.sim,
@@ -162,7 +193,6 @@ complete_agent_movement(State) ->
agent_update(State) ->
Sim = State#state.sim,
- Code = Sim#sim.circuitCode,
Message = slerl_message:build_message(
'AgentUpdate',

0 comments on commit be30190

Please sign in to comment.
Something went wrong with that request. Please try again.