Skip to content

Commit

Permalink
Only create new credentials once packet is selected (#1020)
Browse files Browse the repository at this point in the history
* Only create new credentials once packet is selected

* Undo

* Fix rx delay

* More fixes

* Last fix
i
  • Loading branch information
macpie authored Nov 30, 2023
1 parent dfb4604 commit 2405448
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 83 deletions.
3 changes: 1 addition & 2 deletions include/router_device_worker.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
-record(join_cache, {
uuid :: router_utils:uuid_v4(),
rssi :: float(),
join_accept_args :: #join_accept_args{},
app_key :: binary(),
packet_selected ::
{
Packet :: blockchain_helium_packet_v1:packet(),
Expand All @@ -54,7 +54,6 @@
HoldTime :: non_neg_integer()
}
],
device :: router_device:device(),
pid :: pid()
}).

Expand Down
120 changes: 43 additions & 77 deletions src/device/router_device_worker.erl
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ handle_cast(
lager:info("app_eui or dev_eui changed, unsetting devaddr"),
[]
end,

DeviceUpdates = [
{name, router_device:name(APIDevice)},
{dev_eui, router_device:dev_eui(APIDevice)},
Expand Down Expand Up @@ -553,14 +552,11 @@ handle_cast(
{noreply, State}
end;
handle_cast(
{join, Packet0, PacketTime, HoldTime, PubKeyBin, Region, APIDevice, AppKey, Pid},
{join, Packet0, PacketTime, HoldTime, PubKeyBin, Region, _APIDevice, AppKey, Pid},
#state{
db = DB,
cf = CF,
device = Device0,
join_cache = Cache0,
offer_cache = OfferCache,
channels_worker = ChannelsWorker,
last_dev_nonce = LastDevNonce
} = State
) ->
Expand All @@ -573,17 +569,14 @@ handle_cast(
validate_join(
Packet0,
PubKeyBin,
Region,
APIDevice,
AppKey,
Device0,
OfferCache
)
of
{error, _Reason} ->
lager:debug("failed to validate join ~p", [_Reason]),
{noreply, State};
{ok, Device1, DevNonce, JoinAcceptArgs, BalanceNonce} ->
{ok, DevNonce, BalanceNonce} ->
NewRSSI = blockchain_helium_packet_v1:signal_strength(Packet0),
case maps:get(DevNonce, Cache0, undefined) of
undefined when LastDevNonce == DevNonce ->
Expand All @@ -594,13 +587,11 @@ handle_cast(
JoinCache = #join_cache{
uuid = router_utils:uuid_v4(),
rssi = NewRSSI,
join_accept_args = JoinAcceptArgs,
app_key = AppKey,
packet_selected = {Packet0, PubKeyBin, Region, PacketTime, HoldTime},
device = Device1,
pid = Pid
},
Cache1 = maps:put(DevNonce, JoinCache, Cache0),
ok = save_and_update(DB, CF, ChannelsWorker, Device1),
Timeout = max(
0,
router_utils:join_timeout() -
Expand All @@ -614,14 +605,13 @@ handle_cast(
ok = router_utils:event_join_request(
JoinCache#join_cache.uuid,
PacketTime,
Device1,
Device0,
PubKeyBin,
Packet0,
Region,
BalanceNonce
),
{noreply, State#state{
device = Device1,
join_cache = Cache1,
adr_engine = undefined,
downlink_handled_at = {undefined, erlang:system_time(millisecond)},
Expand All @@ -637,7 +627,7 @@ handle_cast(
ok = router_utils:event_join_request(
UUID,
PacketTime,
Device1,
Device0,
PubKeyBin,
Packet0,
Region,
Expand Down Expand Up @@ -1014,36 +1004,41 @@ handle_info(stop_queue_updates, State) ->
handle_info(
{join_timeout, DevNonce},
#state{
db = DB,
cf = CF,
channels_worker = ChannelsWorker,
device = Device,
device = Device0,
join_cache = JoinCache
} = State
) ->
Join =
#join_cache{
join_accept_args = JoinAcceptArgs,
packet_selected = PacketSelected,
packets = Packets,
device = Device0,
pid = Pid
pid = Pid,
app_key = AppKey
} = maps:get(DevNonce, JoinCache),
#join_accept_args{
region = Region,
app_nonce = _N,
dev_addr = _D,
app_key = _K
} = JoinAcceptArgs,
{Packet, PubKeyBin, _Region, _PacketTime, _HoldTime} = PacketSelected,

{Packet, PubKeyBin, Region, _PacketTime, _HoldTime} = PacketSelected,

{ok, Device1, JoinAcceptArgs} = handle_join(
Packet,
PubKeyBin,
Region,
AppKey,
Device0
),

lager:debug("join timeout for ~p / selected ~p out of ~p", [
DevNonce,
lager:pr(Packet, blockchain_helium_packet_v1),
erlang:length(Packets) + 1
]),
Plan = lora_plan:region_to_plan(Region),
Metadata = lorawan_rxdelay:adjust_on_join(Device),
Device1 = router_device:metadata(Metadata, Device),
Metadata = lorawan_rxdelay:adjust_on_join(Device1),
Device2 = router_device:metadata(Metadata, Device1),
DownlinkPacket = new_join_downlink(
craft_join_reply(Device1, JoinAcceptArgs),
craft_join_reply(Device2, JoinAcceptArgs),
Packet,
Plan
),
Expand All @@ -1061,11 +1056,13 @@ handle_info(
true
),
ok = router_device_channels_worker:handle_join(ChannelsWorker, Join),
_ = erlang:spawn(router_utils, maybe_update_trace, [router_device:id(Device0)]),
ok = router_utils:event_join_accept(Device0, PubKeyBin, DownlinkPacket, Region),
_ = erlang:spawn(router_utils, maybe_update_trace, [router_device:id(Device2)]),
ok = router_utils:event_join_accept(Device2, PubKeyBin, DownlinkPacket, Region),
ok = save_and_update(DB, CF, ChannelsWorker, Device2),
{noreply, State#state{
last_dev_nonce = DevNonce,
join_cache = maps:remove(DevNonce, JoinCache)
join_cache = maps:remove(DevNonce, JoinCache),
device = Device2
}};
handle_info(
{frame_timeout, FCnt, _PacketTime, BalanceNonce},
Expand Down Expand Up @@ -1247,15 +1244,10 @@ maybe_send_queue_update(Device, #state{queue_updates = {ForwardPid, LabelID, _}}
-spec validate_join(
Packet :: blockchain_helium_packet_v1:packet(),
PubKeyBin :: libp2p_crypto:pubkey_to_bin(),
Region :: atom(),
APIDevice :: router_device:device(),
AppKey :: binary(),
Device :: router_device:device(),
OfferCache :: map()
) ->
{ok, router_device:device(), binary(), #join_accept_args{}, {
Balance :: non_neg_integer(), Nonce :: non_neg_integer()
}}
{ok, binary(), {Balance :: non_neg_integer(), Nonce :: non_neg_integer()}}
| {error, any()}.
validate_join(
#packet_pb{
Expand All @@ -1264,9 +1256,6 @@ validate_join(
DevNonce:2/binary, _MIC:4/binary>> = Payload
} = Packet,
PubKeyBin,
Region,
APIDevice,
AppKey,
Device,
OfferCache
) when MType == ?JOIN_REQ ->
Expand All @@ -1282,36 +1271,17 @@ validate_join(
{error, _} = Error ->
Error;
{ok, Balance, Nonce} ->
{ok, UpdatedDevice, JoinAcceptArgs} = handle_join(
Packet,
PubKeyBin,
Region,
APIDevice,
AppKey,
Device
),
{ok, UpdatedDevice, DevNonce, JoinAcceptArgs, {Balance, Nonce}}
{ok, DevNonce, {Balance, Nonce}}
end;
false ->
OrgID = maps:get(organization_id, router_device:metadata(Device), undefined),
{Balance, Nonce} = router_console_dc_tracker:current_balance(OrgID),
{ok, UpdatedDevice, JoinAcceptArgs} = handle_join(
Packet,
PubKeyBin,
Region,
APIDevice,
AppKey,
Device
),
{ok, UpdatedDevice, DevNonce, JoinAcceptArgs, {Balance, Nonce}}
{ok, DevNonce, {Balance, Nonce}}
end
end;
validate_join(
_Packet,
_PubKeyBin,
_Region,
_APIDevice,
_AppKey,
_Device,
_OfferCache
) ->
Expand All @@ -1327,7 +1297,6 @@ validate_join(
blockchain_helium_packet_v1:packet(),
libp2p_crypto:pubkey_to_bin(),
atom(),
router_device:device(),
binary(),
router_device:device()
) -> {ok, router_device:device(), #join_accept_args{}}.
Expand All @@ -1339,7 +1308,6 @@ handle_join(
} = Packet,
PubKeyBin,
HotspotRegion,
APIDevice,
AppKey,
Device0
) ->
Expand All @@ -1358,33 +1326,22 @@ handle_join(
),
{ok, DevAddr} = router_device_devaddr:allocate(Device0, PubKeyBin),

DeviceName = router_device:name(APIDevice),
%% don't set the join nonce here yet as we have not chosen the best join request yet
{AppEUI, DevEUI} = {lorawan_utils:reverse(AppEUI0), lorawan_utils:reverse(DevEUI0)},

Region = dualplan_region(Packet, HotspotRegion),
DRIdx = packet_datarate_index(Region, Packet),

NewKeys = [{NwkSKey, AppSKey} | router_device:keys(Device0)],
NewDevaddrs = [DevAddr | router_device:devaddrs(Device0)],

DeviceUpdates = [
{name, DeviceName},
{dev_eui, DevEUI},
{app_eui, AppEUI},
{keys, NewKeys},
{devaddrs, NewDevaddrs},
{fcnt, undefined},
{fcntdown, 0},
%% only do channel correction for 915 right now
{channel_correction, Region /= 'US915'},
{location, PubKeyBin},
{metadata,
lorawan_rxdelay:bootstrap(
maps:merge(
router_device:metadata(Device0),
router_device:metadata(APIDevice)
)
)},
{last_known_datarate, DRIdx},
{region, Region}
],
Expand All @@ -1393,6 +1350,7 @@ handle_join(

ok = handle_join_skf(NewKeys, NewDevaddrs, MultiBuy),

{AppEUI, DevEUI} = {lorawan_utils:reverse(AppEUI0), lorawan_utils:reverse(DevEUI0)},
lager:debug(
"Join DevEUI ~s with AppEUI ~s tried to join with nonce ~p region ~p via ~s",
[
Expand Down Expand Up @@ -2231,13 +2189,21 @@ get_device(DB, CF, DeviceID) ->
{ok, APIDevice} ->
lager:info("got device: ~p", [APIDevice]),
IsActive = router_device:is_active(APIDevice),
BootstrappedMeta = lorawan_rxdelay:bootstrap(
maps:merge(
router_device:metadata(Device0),
router_device:metadata(APIDevice)
)
),
DeviceUpdates = [
{name, router_device:name(APIDevice)},
{dev_eui, router_device:dev_eui(APIDevice)},
{app_eui, router_device:app_eui(APIDevice)},
{metadata,
maps:merge(
lorawan_rxdelay:maybe_update(APIDevice, Device0),
lorawan_rxdelay:maybe_update(
APIDevice, router_device:metadata(BootstrappedMeta, Device0)
),
router_device:metadata(APIDevice)
)},
{is_active, IsActive}
Expand Down
7 changes: 3 additions & 4 deletions test/router_device_worker_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -766,10 +766,9 @@ evict_keys_join_test(Config) ->

#{} = test_utils:join_device(Config),

[
{_Pid0, {router_ics_skf_worker, update, [Updates] = _Args0}, ok},
{_Pid1, {router_ics_skf_worker, handle_cast, _Args1}, _Return1}
] = meck:history(router_ics_skf_worker),
[{_Pid0, {router_ics_skf_worker, update, [Updates] = _Args0}, ok} | _] = meck:history(
router_ics_skf_worker
),

%% Expected updates
%% 1 Add
Expand Down

0 comments on commit 2405448

Please sign in to comment.