1 -module (lwes_channel
).
3 -behaviour (gen_server
).
5 -include_lib ("lwes.hrl").
8 -include_lib("eunit/include/eunit.hrl").
12 -export ([ start_link
/1,
19 %% gen_server callbacks
28 -record (state
, {socket
, channel
, type
, callback
}).
29 -record (callback
, {function, format
, state
}).
30 -record (channel
, {ip
, port
, is_multicast
, type
, ref
}).
32 %%====================================================================
34 %%====================================================================
35 start_link (Channel
) ->
36 gen_server:start_link (?MODULE
, [Channel
], []).
38 open (Type
, Ip
, Port
) ->
42 is_multicast
= is_multicast (Ip
),
46 { ok
, _Pid
} = lwes_channel_manager:open_channel (Channel
),
49 register_callback (Channel
, CallbackFunction
, EventType
, CallbackState
) ->
50 find_and_call ( Channel
,
51 { register, CallbackFunction
, EventType
, CallbackState
}).
53 send_to (Channel
, Msg
) ->
54 find_and_call (Channel
, { send
, Msg
}).
57 find_and_cast (Channel
, stop
).
59 %%====================================================================
60 %% gen_server callbacks
61 %%====================================================================
62 init ([ Channel
= #channel
{
65 is_multicast
= IsMulticast
,
70 case {Type
, IsMulticast
} of
73 [ { reuseaddr
, true
},
76 { multicast_loop
, false
},
77 { add_membership
, {Ip
, {0,0,0,0}}},
81 gen_udp:open ( Port
, [ binary ]);
83 gen_udp:open ( 0, [ binary ])
85 lwes_channel_manager:register_channel (Channel
, self()),
86 { ok
, #state
{ socket
= Socket
,
92 handle_call ({ register, Function
, Format
, Accum
},
95 channel
= #channel
{type
= listener
}
99 State#state
{ callback
= #callback
{ function = Function
,
103 handle_call ({ send
, Packet
},
107 channel
= #channel
{ ip
= Ip
, port
= Port
}
110 gen_udp:send (Socket
, Ip
, Port
, Packet
),
113 handle_call (Request
, From
, State
) ->
114 error_logger:warning_msg
115 ("lwes_channel unrecognized call ~p from ~p~n",[Request
, From
]),
116 { reply
, ok
, State
}.
118 handle_cast (stop
, State
) ->
119 {stop
, normal
, State
};
120 handle_cast (Request
, State
) ->
121 error_logger:warning_msg
122 ("lwes_channel unrecognized cast ~p~n",[Request
]),
125 % skip if we don't have a handler
126 handle_info ( {udp
, _
, _
, _
, _
},
133 handle_info ( Packet
= {udp
, _
, _
, _
, _
},
136 callback
= #callback
{ function = Function
,
143 _
-> lwes_event:from_udp_packet (Packet
, Format
)
145 NewCbState
= Function (Event
, CbState
),
147 State#state
{ callback
= #callback
{ function = Function
,
149 state
= NewCbState
} }
152 handle_info ( Request
, State
) ->
153 error_logger:warning_msg
154 ("lwes_channel unrecognized info ~p~n",[Request
]),
157 terminate (_Reason
, #state
{socket
= Socket
, channel
= Channel
}) ->
158 gen_udp:close (Socket
),
159 lwes_channel_manager:unregister_channel (Channel
).
161 code_change (_OldVsn
, State
, _Extra
) ->
164 %%====================================================================
165 %% Internal functions
166 %%====================================================================
167 is_multicast ({N1
, _
, _
, _
}) when N1
>= 224, N1
=< 239 ->
172 find_and_call (Channel
, Msg
) ->
173 case lwes_channel_manager:find_channel (Channel
) of
177 gen_server:call ( Pid
, Msg
)
180 find_and_cast (Channel
, Msg
) ->
181 case lwes_channel_manager:find_channel (Channel
) of
185 gen_server:cast ( Pid
, Msg
)
188 %%====================================================================
190 %%====================================================================