Skip to content

Commit bf766a0

Browse files
Add net ids stats (#315)
* Add net ids stats * Update src/cli/hpr_cli_info.erl Co-authored-by: Michael Jeffrey <[email protected]> * net id str and int --------- Co-authored-by: Michael Jeffrey <[email protected]>
1 parent 6ab270e commit bf766a0

File tree

5 files changed

+117
-1
lines changed

5 files changed

+117
-1
lines changed

src/cli/hpr_cli_info.erl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@ info_usage() ->
3737
"\n\n",
3838
"info key - Print HPR's Public Key\n"
3939
"info ips - Export all connected hotspots IPs to /tmp/hotspot_ip.json\n"
40+
"info netids - Export net ids stats as json to /tmp/net_ids.json\n"
4041
]
4142
].
4243

4344
info_cmd() ->
4445
[
4546
[["info", "key"], [], [], fun info_key/3],
46-
[["info", "ips"], [], [], fun info_ips/3]
47+
[["info", "ips"], [], [], fun info_ips/3],
48+
[["info", "netids"], [], [], fun info_netids/3]
4749
].
4850

4951
info_key(["info", "key"], [], []) ->
@@ -77,6 +79,29 @@ info_ips(["info", "ips"], [], []) ->
7779
info_ips(_, _, _) ->
7880
usage.
7981

82+
info_netids(["info", "netids"], [], []) ->
83+
List = lists:map(
84+
fun({NetID, Count}) ->
85+
#{
86+
net_id_str => hpr_utils:net_id_display(NetID),
87+
net_id_int => NetID,
88+
count => Count
89+
}
90+
end,
91+
hpr_netid_stats:export()
92+
),
93+
Json = jsx:encode(List),
94+
case file:open("/tmp/net_ids.json", [write]) of
95+
{ok, File} ->
96+
file:write(File, Json),
97+
file:close(File),
98+
c_text("Exported to /tmp/net_ids.json");
99+
{error, Reason} ->
100+
c_text("Failed to export ~p", [Reason])
101+
end;
102+
info_netids(_, _, _) ->
103+
usage.
104+
80105
%%--------------------------------------------------------------------
81106
%% Helpers
82107
%%--------------------------------------------------------------------

src/grpc/packet_router/hpr_packet_up.erl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
encode/1,
2020
decode/1,
2121
type/1,
22+
net_id/1,
2223
md/1, md/2
2324
]).
2425

@@ -167,6 +168,24 @@ type(Packet) ->
167168
{undefined, 0}
168169
end.
169170

171+
-spec net_id(Packet :: packet()) -> {ok, lora_subnet:net_id()} | {error, any()}.
172+
net_id(Packet) ->
173+
case ?MODULE:payload(Packet) of
174+
<<?JOIN_REQUEST:3, _:5, _AppEUI:64/integer-unsigned-little,
175+
_DevEUI:64/integer-unsigned-little, _DevNonce:2/binary, _MIC:4/binary>> ->
176+
{error, join};
177+
(<<FType:3, _:5, DevAddr:32/integer-unsigned-little, _ADR:1, _ADRACKReq:1, _ACK:1, _RFU:1,
178+
FOptsLen:4, _FCnt:16/little-unsigned-integer, _FOpts:FOptsLen/binary,
179+
PayloadAndMIC/binary>>) when
180+
(FType == ?UNCONFIRMED_UP orelse FType == ?CONFIRMED_UP) andalso
181+
%% MIC is 4 bytes, so the binary must be at least that long
182+
erlang:byte_size(PayloadAndMIC) >= 4
183+
->
184+
lora_subnet:parse_netid(DevAddr, little);
185+
_ ->
186+
{error, undefined}
187+
end.
188+
170189
-spec md(PacketUp :: packet()) -> ok.
171190
md(PacketUp) ->
172191
?MODULE:md(PacketUp, #{}).

src/hpr_routing.erl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ handle_packet(PacketUp, Opts) ->
5555
hpr_metrics:observe_packet_up(PacketUpType, Error, 0, Timestamp),
5656
Error;
5757
ok ->
58+
ok = hpr_netid_stats:maybe_report_net_id(PacketUp),
5859
do_handle_packet(PacketUp, Timestamp)
5960
end.
6061

@@ -500,6 +501,7 @@ foreach_setup() ->
500501
ok = hpr_route_ets:init(),
501502
ok = hpr_multi_buy:init(),
502503
ok = hpr_device_stats:init(),
504+
ok = hpr_netid_stats:init(),
503505
meck:new(hpr_gateway_location, [passthrough]),
504506
meck:expect(hpr_gateway_location, get, fun(_) -> {error, not_implemented} end),
505507
ok.
@@ -509,6 +511,7 @@ foreach_cleanup(ok) ->
509511
true = ets:delete(hpr_route_devaddr_ranges_ets),
510512
true = ets:delete(hpr_route_eui_pairs_ets),
511513
true = ets:delete(hpr_device_stats_ets),
514+
true = ets:delete(hpr_netid_stats_ets),
512515
lists:foreach(
513516
fun(RouteETS) ->
514517
SKFETS = hpr_route_ets:skf_ets(RouteETS),

src/hpr_sup.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ init([]) ->
5858

5959
ok = timing("packet routing cache", fun() -> hpr_routing_cache:init_ets() end),
6060
ok = timing("device stats", fun() -> hpr_device_stats:init() end),
61+
ok = timing("net_id stats", fun() -> hpr_netid_stats:init() end),
6162
ok = timing("routing throttles", fun() -> hpr_routing:init() end),
6263
ok = timing("multi buy", fun() -> hpr_multi_buy:init() end),
6364
ok = timing("packet_router streams", fun() -> hpr_protocol_router:init() end),

src/metrics/hpr_netid_stats.erl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
-module(hpr_netid_stats).
2+
3+
-export([
4+
init/0,
5+
maybe_report_net_id/1,
6+
export/0
7+
]).
8+
9+
-define(ETS, hpr_netid_stats_ets).
10+
11+
-spec init() -> ok.
12+
init() ->
13+
ets:new(?ETS, [
14+
public,
15+
named_table,
16+
set,
17+
{write_concurrency, true}
18+
]),
19+
ok.
20+
21+
-spec maybe_report_net_id(PacketUp :: hpr_packet_up:packet()) -> ok.
22+
maybe_report_net_id(PacketUp) ->
23+
case hpr_packet_up:net_id(PacketUp) of
24+
{error, _Reason} ->
25+
ok;
26+
{ok, NetId} ->
27+
ets:update_counter(
28+
?ETS, NetId, {2, 1}, {default, 0}
29+
),
30+
ok
31+
end.
32+
33+
-spec export() -> list({non_neg_integer(), non_neg_integer()}).
34+
export() ->
35+
ets:tab2list(?ETS).
36+
37+
%% ------------------------------------------------------------------
38+
%% EUNIT Tests
39+
%% ------------------------------------------------------------------
40+
-ifdef(TEST).
41+
42+
-include_lib("eunit/include/eunit.hrl").
43+
44+
all_test_() ->
45+
{foreach, fun foreach_setup/0, fun foreach_cleanup/1, [
46+
?_test(test_maybe_report_net_id())
47+
]}.
48+
49+
foreach_setup() ->
50+
ok = ?MODULE:init(),
51+
ok.
52+
53+
foreach_cleanup(ok) ->
54+
_ = catch ets:delete(?ETS),
55+
ok.
56+
57+
test_maybe_report_net_id() ->
58+
PacketUp = test_utils:uplink_packet_up(#{}),
59+
60+
?assertEqual(ok, maybe_report_net_id(PacketUp)),
61+
?assertEqual(ok, maybe_report_net_id(PacketUp)),
62+
?assertEqual(ok, maybe_report_net_id(PacketUp)),
63+
64+
?assertEqual([{0, 3}], ets:tab2list(?ETS)),
65+
66+
ok.
67+
68+
-endif.

0 commit comments

Comments
 (0)