Skip to content

Commit b6a31bb

Browse files
committed
Optionally react to grisp_netman network events to determin if there is connectivity.
1 parent 107b626 commit b6a31bb

File tree

5 files changed

+86
-5
lines changed

5 files changed

+86
-5
lines changed

src/grisp_connect_app.erl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818

1919
start(_StartType, _StartArgs) ->
2020
logger:add_handlers(grisp_connect),
21+
case grisp_connect_utils:using_grisp_netman() of
22+
true ->
23+
grisp_connect_netman:add_handler();
24+
false ->
25+
ok
26+
end,
2127
grisp_connect_sup:start_link().
2228

2329
stop(_State) ->

src/grisp_connect_client.erl

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
% Internal API
2121
-export([reboot/0]).
22+
-export([lan_connected/0]).
23+
-export([lan_disconnected/0]).
2224

2325
% Behaviour gen_statem callback functions
2426
-export([init/1, terminate/3, code_change/4, callback_mode/0]).
@@ -106,6 +108,11 @@ notify(Method, Type, Params) ->
106108
reboot() ->
107109
erlang:send_after(1000, ?MODULE, reboot).
108110

111+
lan_connected() ->
112+
gen_statem:cast(?MODULE, ?FUNCTION_NAME).
113+
114+
lan_disconnected() ->
115+
gen_statem:cast(?MODULE, ?FUNCTION_NAME).
109116

110117
%--- Behaviour gen_statem Callback Functions -----------------------------------
111118

@@ -134,8 +141,7 @@ init([]) ->
134141

135142
terminate(Reason, _State, Data) ->
136143
conn_close(Data, Reason),
137-
persistent_term:erase({?MODULE, self()}),
138-
ok.
144+
persistent_term:erase({?MODULE, self()}).
139145

140146
code_change(_Vsn, State, Data, _Extra) -> {ok, State, Data}.
141147

@@ -160,8 +166,23 @@ idle(cast, connect, Data) ->
160166
% If the device do not have an IP address, it will wait a fixed amount of time
161167
% and check again, without incrementing the retry counter.
162168
waiting_network(enter, _OldState, _Data) ->
163-
% First IP check do not have any delay
164-
{keep_state_and_data, [{state_timeout, 0, check_ip}]};
169+
Actions = case grisp_connect_utils:using_grisp_netman() of
170+
true ->
171+
case grisp_netman:connection_status() of
172+
S when S =:= lan orelse S =:= internet ->
173+
?MODULE:lan_connected();
174+
disconnected ->
175+
ok
176+
end,
177+
[];
178+
_ ->
179+
[{state_timeout, 0, check_ip}]
180+
end,
181+
{keep_state_and_data, Actions};
182+
waiting_network(cast, lan_connected, Data) ->
183+
?LOG_DEBUG(#{description => <<"Connected to LAN">>,
184+
event => lan_connected}),
185+
{next_state, connecting, Data};
165186
waiting_network(state_timeout, check_ip, Data) ->
166187
case grisp_connect_utils:check_inet_ipv4() of
167188
{ok, IP} ->
@@ -225,6 +246,15 @@ connected(cast, {notify, Method, Type, Params}, Data) ->
225246
% Common event handling appended as last match case to each state_function
226247
handle_common(cast, connect, State, _Data) when State =/= idle ->
227248
keep_state_and_data;
249+
handle_common(cast, lan_connected, State, _Data)
250+
when State =/= waiting_network ->
251+
keep_state_and_data;
252+
handle_common(cast, lan_disconnected, State, Data)
253+
when State =/= idle, State =/= waiting_network ->
254+
Reason = lan_disconnected,
255+
?LOG_WARNING(#{description => <<"LAN connection lost">>,
256+
event => lan_disconnected}),
257+
reconnect(conn_close(Data, Reason), Reason);
228258
handle_common({call, From}, is_connected, State, _) when State =/= connected ->
229259
{keep_state_and_data, [{reply, From, false}]};
230260
handle_common({call, From}, wait_connected, _State,

src/grisp_connect_netman.erl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
-module(grisp_connect_netman).
2+
3+
-behaviour(gen_event).
4+
5+
-export([add_handler/0, remove_handler/0]).
6+
-export([init/1, handle_event/2, handle_call/2]).
7+
8+
-include_lib("kernel/include/logger.hrl").
9+
10+
add_handler() ->
11+
gen_event:add_handler(grisp_netman_event, ?MODULE, []).
12+
13+
remove_handler() ->
14+
gen_event:delete_handler(grisp_netman_event, ?MODULE, []).
15+
16+
% Behaviour gen_event callbacks ------------------------------------------------
17+
18+
init([]) ->
19+
{ok, #{}}.
20+
21+
handle_event({connection_status, _IfName, Status}, State) ->
22+
case Status of
23+
S when S =:= lan orelse S =:= internet ->
24+
grisp_connect_client:lan_connected();
25+
disconnected ->
26+
% If one interface went down,
27+
% check if the global connectivity is still maintained
28+
% by any other interface
29+
case grisp_netman:connection_status() of
30+
S when S =:= lan orelse S =:= internet ->
31+
ok;
32+
disconnected ->
33+
grisp_connect_client:lan_disconnected()
34+
end
35+
end,
36+
{ok, State}.
37+
38+
handle_call(Request, State) ->
39+
?LOG_WARNING("Unexpected grisp_netman_event call: ~p", [Request]),
40+
{reply, unexpected_call, State}.

src/grisp_connect_utils.erl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
%--- Exports -------------------------------------------------------------------
55

66
% API functions
7+
-export([using_grisp_netman/0]).
78
-export([retry_delay/1]).
89
-export([check_inet_ipv4/0]).
910

1011

1112
%--- API Functions -------------------------------------------------------------
1213

14+
using_grisp_netman() ->
15+
RunningApps = application:which_applications(),
16+
lists:keymember(grisp_netman, 1, RunningApps).
17+
1318
check_inet_ipv4() ->
1419
case get_ip_of_valid_interfaces() of
1520
{ok, {IP1, _, _, _} = IP} when IP1 =/= 127 -> {ok, IP};

test/grisp_connect_reconnect_SUITE.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ reconnect_on_closed_frame_test(_) ->
8787
%--- Internal Functions --------------------------------------------------------
8888

8989
connection_gun_pid() ->
90-
{_, {data, _, _, _, _, ConnPid, _, _, _, _}} = sys:get_state(grisp_connect_client),
90+
{_, {data, _, _, _, _, ConnPid, _, _, _, _, _}} = sys:get_state(grisp_connect_client),
9191
% Depends on the internal state of jarl_connection
9292
{_, {data, _, _, _, _, _, _, _, _, _, _, _, _, GunPid, _, _, _}} = sys:get_state(ConnPid),
9393
GunPid.

0 commit comments

Comments
 (0)