Commit 39d0dc52 authored by andymck's avatar andymck
Browse files

country & region specific channel mapping

parent eeb52dd1
Showing with 568 additions and 154 deletions
+568 -154
......@@ -22,6 +22,20 @@
{dkg_stop_timeout, 15000},
{write_failed_txns, true},
{radio_device, undefined},
{stabilization_period_start, 2}
{stabilization_period_start, 2},
%% dont perform regionalised checks in dev envs
%% we only realy need the params below if this file is changed to specify a radio device
%% as without one miner_lora is not started
%% including the params anyway in case someone needs it in a dev env
{override_reg_domain_check, true},
%% use defaults below for dev envs in US / zone 2 locations
{default_reg_region, 'US915'},
{default_reg_geo_zone, 'zone2'},
{default_reg_freq_list, [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3]}
%% use defaults below for dev envs in EU / zone 1 locations
%%{default_reg_region, 'EU868'},
%%{default_reg_geo_zone, 'zone1'},
%%{default_reg_freq_list, [867.1, 867.3, 867.5, 867.7, 867.9, 868.1, 868.3, 868.5]}
]}
].
......@@ -76,6 +76,17 @@
{127,0,0,1}, 31341} },
{default_routers, ["/p2p/112qB3YaH5bZkCnKA5uRH7tBtGNv2Y5B4smv1jsmvGUzgKT71QpE", "/p2p/1124CJ9yJaHq4D6ugyPCDnSBzQik61C1BqD9VMh1vsUmjwt16HNB"]},
{mark_mods, [miner_hbbft_handler]},
{stabilization_period_start, 187000}
{stabilization_period_start, 187000},
{reg_domains_file, "countries_reg_domains.csv"},
{frequency_data, #{'US915' => [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3],
'EU868' => [867.1, 867.3, 867.5, 867.7, 867.9, 868.1, 868.3, 868.5],
'EU433' => [433.175, 433.375, 433.575],
'CN470' => [486.3, 486.5, 486.7, 486.9, 487.1, 487.3, 487.5, 487.7 ],
'CN779' => [779.5, 779.7, 779.9],
'AU915' => [916.8, 917.0, 917.2, 917.4, 917.5, 917.6, 917.8, 918.0, 918.2],
'AS923' => [923.2, 923.4, 923.6, 923.8, 924.0, 924.2, 924.4, 924.5, 924.6, 924.8],
'KR920' => [922.1, 922.3, 922.5, 922.7, 922.9, 923.1, 923.3],
'IN865' => [865.0625, 865.4025, 865.985]}
}
]}
].
......@@ -26,6 +26,18 @@
{dkg_stop_timeout, 15000},
{write_failed_txns, true},
{radio_device, undefined},
{stabilization_period_start, 2}
{stabilization_period_start, 2},
%% dont perform regionalised checks in test envs
%% we only realy need the params below if this file is changed to specify a radio device
%% OR if a test starts miner_lora manually
{override_reg_domain_check, true},
%% use defaults below for test envs in US / zone 2 locations
{default_reg_region, 'US915'},
{default_reg_geo_zone, 'zone2'},
{default_reg_freq_list, [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3]}
%% use defaults below for test envs in EU / zone 1 locations
%%{default_reg_region, 'EU868'},
%%{default_reg_geo_zone, 'zone1'},
%%{default_reg_freq_list, [867.1, 867.3, 867.5, 867.7, 867.9, 868.1, 868.3, 868.5]}
]}
].
AF,33.93911,67.709953,Afghanistan,,zone1
AL,41.153332,20.168331,Albania,EU868,zone1
DZ,28.033886,1.659626,Algeria,,zone1
AS,-14.270972,-170.132217,American Samoa,,zone2
AD,42.546245,1.601554,Andorra,EU868,zone1
AO,-11.202692,17.873887,Angola,EU868,zone1
AI,18.220554,-63.068615,Anguilla,,zone2
AQ,-75.250973,-0.071389,Antarctica,,zone1
AG,17.060816,-61.796428,Antigua and Barbuda,,zone2
AR,-38.416097,-63.616672,Argentina,AU915,zone3
AM,40.069099,45.038189,Armenia,,zone1
AW,12.52111,-69.968338,Aruba,,zone2
AU,-25.274398,133.775136,Australia,AU915,zone3
AT,47.516231,14.550072,Austria,EU868,zone1
AZ,40.143105,47.576927,Azerbaijan,,zone1
BS,25.03428,-77.39628,Bahamas,,zone2
BH,25.930414,50.637772,Bahrain,EU868,zone1
BD,23.684994,90.356331,Bangladesh,,zone3
BB,13.193887,-59.543198,Barbados,,zone2
BY,53.709807,27.953389,Belarus,,zone1
BE,50.503887,4.469936,Belgium,EU868,zone1
BZ,17.189877,-88.49765,Belize,,zone2
BJ,9.30769,2.315834,Benin,,zone1
BM,32.321384,-64.75737,Bermuda,,zone2
BT,27.514162,90.433601,Bhutan,,zone3
BO,-16.290154,-63.588653,Bolivia,US915,zone2
BA,43.915886,17.679076,Bosnia and Herzegovina,EU868,zone1
BW,-22.328474,24.684866,Botswana,EU868,zone1
BV,-54.423199,3.413194,Bouvet Island,,zone1
BR,-14.235004,-51.92528,Brazil,AU915,zone3
IO,-6.343194,71.876519,British Indian Ocean Territory,,zone2
VG,18.420695,-64.639968,British Virgin Islands,,zone2
BN,4.535277,114.727669,Brunei,AS923,zone3
BG,42.733883,25.48583,Bulgaria,EU868,zone1
BF,12.238333,-1.561593,Burkina Faso,,zone1
BI,-3.373056,29.918886,Burundi,,zone1
KH,12.565679,104.990963,Cambodia,AS923,zone3
CM,7.369722,12.354722,Cameroon,,zone1
CA,56.130366,-106.346771,Canada,US915,zone1
CV,16.002082,-24.013197,Cape Verde,,zone1
KY,19.513469,-80.566956,Cayman Islands,,zone2
CF,6.611111,20.939444,Central African Republic,,zone1
TD,15.454166,18.732207,Chad,,zone1
CL,-35.675147,-71.542969,Chile,AU915,zone3
CN,35.86166,104.195397,China,CN470,zone3
CX,-10.447525,105.690449,Christmas Island,,zone3
CC,-12.164165,96.870956,Cocos [Keeling] Islands,,zone3
CO,4.570868,-74.297333,Colombia,US915,zone2
KM,-11.875001,43.872219,Comoros,,zone1
CD,-4.038333,21.758664,Congo [DRC],,zone1
CG,-0.228021,15.827659,Congo [Republic],EU868,zone1
CK,-21.236736,-159.777671,Cook Islands,,zone3
CR,9.748917,-83.753428,Costa Rica,US915,zone2
CI,7.539989,-5.54708,Côte d'Ivoire,,zone1
HR,45.1,15.2,Croatia,EU868,zone1
CU,21.521757,-77.781167,Cuba,,zone2
CY,35.126413,33.429859,Cyprus,EU868,zone1
CZ,49.817492,15.472962,Czech Republic,EU868,zone1
DK,56.26392,9.501785,Denmark,EU868,zone1
DJ,11.825138,42.590275,Djibouti,,zone1
DM,15.414999,-61.370976,Dominica,,zone2
DO,18.735693,-70.162651,Dominican Republic,US915,zone2
EC,-1.831239,-78.183406,Ecuador,US915,zone2
EG,26.820553,30.802498,Egypt,,zone1
SV,13.794185,-88.89653,El Salvador,,zone2
GQ,1.650801,10.267895,Equatorial Guinea,,zone3
ER,15.179384,39.782334,Eritrea,,zone1
EE,58.595272,25.013607,Estonia,EU868,zone1
ET,9.145,40.489673,Ethiopia,,zone1
FK,-51.796253,-59.523613,Falkland Islands [Islas Malvinas],,zone2
FO,61.892635,-6.911806,Faroe Islands,,zone1
FJ,-16.578193,179.414413,Fiji,,zone3
FI,61.92411,25.748151,Finland,EU868,zone1
FR,46.227638,2.213749,France,EU868,zone1
GF,3.933889,-53.125782,French Guiana,,zone1
PF,-17.679742,-149.406843,French Polynesia,,zone1
TF,-49.280366,69.348557,French Southern Territories,,zone1
GA,-0.803689,11.609444,Gabon,,zone1
GM,13.443182,-15.310139,Gambia,,zone1
GZ,31.354676,34.308825,Gaza Strip,,zone1
GE,42.315407,43.356892,Georgia,,zone1
DE,51.165691,10.451526,Germany,EU868,zone1
GH,7.946527,-1.023194,Ghana,,zone1
GI,36.137741,-5.345374,Gibraltar,,zone1
GR,39.074208,21.824312,Greece,EU868,zone1
GL,71.706936,-42.604303,Greenland,,zone2
GD,12.262776,-61.604171,Grenada,,zone2
GP,16.995971,-62.067641,Guadeloupe,,zone2
GU,13.444304,144.793731,Guam,,zone2
GT,15.783471,-90.230759,Guatemala,,zone2
GG,49.465691,-2.585278,Guernsey,,zone1
GN,9.945587,-9.696645,Guinea,,zone1
GW,11.803749,-15.180413,Guinea-Bissau,,zone1
GY,4.860416,-58.93018,Guyana,US915,zone2
HT,18.971187,-72.285215,Haiti,,zone2
HM,-53.08181,73.504158,Heard Island and McDonald Islands,,zone3
HN,15.199999,-86.241905,Honduras,,zone2
HK,22.396428,114.109497,Hong Kong,AS923,zone3
HU,47.162494,19.503304,Hungary,EU868,zone1
IS,64.963051,-19.020835,Iceland,EU868,zone1
IN,20.593684,78.96288,India,IN865,zone3
ID,-0.789275,113.921327,Indonesia,AS923,zone3
IR,32.427908,53.688046,Iran,,zone1
IQ,33.223191,43.679291,Iraq,,zone1
IE,53.41291,-8.24389,Ireland,EU868,zone1
IM,54.236107,-4.548056,Isle of Man,EU868,zone1
IL,31.046051,34.851612,Israel,,zone1
IT,41.87194,12.56738,Italy,EU868,zone1
JM,18.109581,-77.297508,Jamaica,,zone2
JP,36.204824,138.252924,Japan,AS923,zone3
JE,49.214439,-2.13125,Jersey,EU868,zone1
JO,30.585164,36.238414,Jordan,,zone1
KZ,48.019573,66.923684,Kazakhstan,,zone1
KE,-0.023559,37.906193,Kenya,,zone1
KI,-3.370417,-168.734039,Kiribati,,zone1
XK,42.602636,20.902977,Kosovo,,zone1
KW,29.31166,47.481766,Kuwait,,zone1
KG,41.20438,74.766098,Kyrgyzstan,,zone1
LA,19.85627,102.495496,Laos,AS923,zone3
LV,56.879635,24.603189,Latvia,EU868,zone1
LB,33.854721,35.862285,Lebanon,,zone1
LS,-29.609988,28.233608,Lesotho,EU868,zone1
LR,6.428055,-9.429499,Liberia,,zone1
LY,26.3351,17.228331,Libya,,zone1
LI,47.166,9.555373,Liechtenstein,EU868,zone1
LT,55.169438,23.881275,Lithuania,EU868,zone1
LU,49.815273,6.129583,Luxembourg,EU868,zone1
MO,22.198745,113.543873,Macau,,zone3
MK,41.608635,21.745275,Macedonia [FYROM],,zone1
MG,-18.766947,46.869107,Madagascar,EU868,zone1
MW,-13.254308,34.301525,Malawi,EU868,zone1
MY,4.210484,101.975766,Malaysia,,zone3
MV,3.202778,73.22068,Maldives,,zone3
ML,17.570692,-3.996166,Mali,,zone3
MT,35.937496,14.375416,Malta,EU868,zone1
MH,7.131474,171.184478,Marshall Islands,,zone3
MQ,14.641528,-61.024174,Martinique,,zone2
MR,21.00789,-10.940835,Mauritania,,zone1
MU,-20.348404,57.552152,Mauritius,EU868,zone1
YT,-12.8275,45.166244,Mayotte,,zone1
MX,23.634501,-102.552784,Mexico,US915,zone2
FM,7.425554,150.550812,Micronesia,,zone3
MD,47.411631,28.369885,Moldova,EU868,zone1
MC,43.750298,7.412841,Monaco,,zone1
MN,46.862496,103.846656,Mongolia,,zone1
ME,42.708678,19.37439,Montenegro,EU868,zone1
MS,16.742498,-62.187366,Montserrat,,zone1
MA,31.791702,-7.09262,Morocco,,zone1
MZ,-18.665695,35.529562,Mozambique,EU868,zone1
MM,21.913965,95.956223,Myanmar [Burma],,zone1
NA,-22.95764,18.49041,Namibia,EU868,zone1
NR,-0.522778,166.931503,Nauru,,zone3
NP,28.394857,84.124008,Nepal,,zone3
NL,52.132633,5.291266,Netherlands,EU868,zone1
AN,12.226079,-69.060087,Netherlands Antilles,,zone1
NC,-20.904305,165.618042,New Caledonia,,zone3
NZ,-40.900557,174.885971,New Zealand,AU915,zone3
NI,12.865416,-85.207229,Nicaragua,,zone2
NE,17.607789,8.081666,Niger,,zone1
NG,9.081999,8.675277,Nigeria,,zone1
NU,-19.054445,-169.867233,Niue,,zone1
NF,-29.040835,167.954712,Norfolk Island,,zone3
KP,40.339852,127.510093,North Korea,,zone1
MP,17.33083,145.38469,Northern Mariana Islands,,zone3
NO,60.472024,8.468946,Norway,EU868,zone1
OM,21.512583,55.923255,Oman,,zone1
PK,30.375321,69.345116,Pakistan,,zone3
PW,7.51498,134.58252,Palau,,zone3
PS,31.952162,35.233154,Palestinian Territories,,zone1
PA,8.537981,-80.782127,Panama,US915,zone2
PG,-6.314993,143.95555,Papua New Guinea,,zone3
PY,-23.442503,-58.443832,Paraguay,US915,zone2
PE,-9.189967,-75.015152,Peru,US915,zone2
PH,12.879721,121.774017,Philippines,EU868,zone1
PN,-24.703615,-127.439308,Pitcairn Islands,,zone2
PL,51.919438,19.145136,Poland,EU868,zone1
PT,39.399872,-8.224454,Portugal,EU868,zone1
PR,18.220833,-66.590149,Puerto Rico,US915,zone1
QA,25.354826,51.183884,Qatar,,zone1
RE,-21.115141,55.536384,Réunion,,zone1
RO,45.943161,24.96676,Romania,EU868,zone1
RU,61.52401,105.318756,Russia,EU868,zone1
RW,-1.940278,29.873888,Rwanda,,zone1
SH,-24.143474,-10.030696,Saint Helena,,zone1
KN,17.357822,-62.782998,Saint Kitts and Nevis,,zone2
LC,13.909444,-60.978893,Saint Lucia,,zone2
PM,46.941936,-56.27111,Saint Pierre and Miquelon,,zone2
VC,12.984305,-61.287228,Saint Vincent and the Grenadines,,zone2
WS,-13.759029,-172.104629,Samoa,,zone2
SM,43.94236,12.457777,San Marino,,zone1
ST,0.18636,6.613081,São Tomé and Príncipe,,zone1
SA,23.885942,45.079162,Saudi Arabia,EU868,zone1
SN,14.497401,-14.452362,Senegal,,zone1
RS,44.016521,21.005859,Serbia,EU868,zone1
SC,-4.679574,55.491977,Seychelles,EU868,zone1
SL,8.460555,-11.779889,Sierra Leone,,zone1
SG,1.352083,103.819836,Singapore,AS923,zone3
SK,48.669026,19.699024,Slovakia,EU868,zone1
SI,46.151241,14.995463,Slovenia,EU868,zone1
SB,-9.64571,160.156194,Solomon Islands,,zone1
SO,5.152149,46.199616,Somalia,,zone1
ZA,-30.559482,22.937506,South Africa,EU868,zone1
GS,-54.429579,-36.587909,South Georgia and the South Sandwich Islands,,zone2
KR,35.907757,127.766922,South Korea,KR920,zone3
ES,40.463667,-3.74922,Spain,EU868,zone3
LK,7.873054,80.771797,Sri Lanka,,zone3
SD,12.862807,30.217636,Sudan,,zone1
SR,3.919305,-56.027783,Suriname,US915,zone2
SJ,77.553604,23.670272,Svalbard and Jan Mayen,,zone1
SZ,-26.522503,31.465866,Swaziland,,zone1
SE,60.128161,18.643501,Sweden,EU868,zone1
CH,46.818188,8.227512,Switzerland,EU868,zone1
SY,34.802075,38.996815,Syria,,zone1
TW,23.69781,120.960515,Taiwan,AS923,zone3
TJ,38.861034,71.276093,Tajikistan,,zone1
TZ,-6.369028,34.888822,Tanzania,EU868,zone1
TH,15.870032,100.992541,Thailand,AS923,zone3
TL,-8.874217,125.727539,Timor-Leste,,zone3
TG,8.619543,0.824782,Togo,,zone1
TK,-8.967363,-171.855881,Tokelau,,zone3
TO,-21.178986,-175.198242,Tonga,,zone1
TT,10.691803,-61.222503,Trinidad and Tobago,,zone2
TN,33.886917,9.537499,Tunisia,,zone1
TR,38.963745,35.243322,Turkey,EU868,zone1
TM,38.969719,59.556278,Turkmenistan,,zone1
TC,21.694025,-71.797928,Turks and Caicos Islands,,zone2
TV,-7.109535,177.64933,Tuvalu,,zone3
UM,,,U.S. Minor Outlying Islands,US915,zone2
VI,18.335765,-64.896335,U.S. Virgin Islands,US915,zone2
UG,1.373333,32.290275,Uganda,,zone1
UA,48.379433,31.16558,Ukraine,,zone1
AE,23.424076,53.847818,United Arab Emirates,EU868,zone1
GB,55.378051,-3.435973,United Kingdom,EU868,zone1
US,37.09024,-95.712891,United States,US915,zone2
UY,-32.522779,-55.765835,Uruguay,US915,zone2
UZ,41.377491,64.585262,Uzbekistan,,zone1
VU,-15.376706,166.959158,Vanuatu,,zone3
VA,41.902916,12.453389,Vatican City,EU868,zone1
VE,6.42375,-66.58973,Venezuela,US915,zone2
VN,14.058324,108.277199,Vietnam,AS923,zone3
WF,-13.768752,-177.156097,Wallis and Futuna,,zone2
EH,24.215527,-12.885834,Western Sahara,,zone1
YE,15.552727,48.516388,Yemen,,zone1
ZM,-13.133897,27.849332,Zambia,EU868,zone1
ZW,-19.015438,29.154857,Zimbabwe,EU868,zone1
\ No newline at end of file
......@@ -4,7 +4,7 @@
{<<"base64url">>,{pkg,<<"base64url">>,<<"1.0.1">>},1},
{<<"blockchain">>,
{git,"https://github.com/helium/blockchain-core.git",
{ref,"f5687d0e56dae6d0deac99c0f367c8d28daf44da"}},
{ref,"e693d6d23140198b6ddb59abb3656098267c3254"}},
0},
{<<"clique">>,
{git,"https://github.com/helium/clique.git",
......@@ -74,7 +74,7 @@
0},
{<<"helium_proto">>,
{git,"https://github.com/helium/proto.git",
{ref,"53c67c8e19b86d6f29a0c52b83c144af506ba347"}},
{ref,"59d944e8b98c7d945afe9a9e253ba257ac97be45"}},
1},
{<<"inert">>,
{git,"https://github.com/msantos/inert",
......
......@@ -30,7 +30,8 @@ register_all_usage() ->
info_name_usage(),
info_block_age_usage(),
info_p2p_status_usage(),
info_summary_usage()
info_summary_usage(),
info_region_usage()
]).
register_all_cmds() ->
......@@ -44,7 +45,8 @@ register_all_cmds() ->
info_name_cmd(),
info_block_age_cmd(),
info_p2p_status_cmd(),
info_summary_cmd()
info_summary_cmd(),
info_region_cmd()
]).
%%
%% info
......@@ -199,6 +201,33 @@ info_p2p_status(["info", "p2p_status"], [], []) ->
info_p2p_status([_, _, _], [], []) ->
usage.
%%
%% info region
%%
info_region_cmd() ->
[
[["info", "region"], [], [], fun info_region/3]
].
info_region_usage() ->
[["info", "region"],
["info region \n\n",
" Get the frequency region this miner is operating in \n\n"
" If undefined, the region has not yet been confirmed or cannot be determined\n"
" Until a region is confirmed, the miner will block tx\n"
]
].
info_region(["info", "region"], [], []) ->
case miner_lora:region() of
{ok, undefined} ->
{exit_status, 1, [clique_status:text("undefined")]};
{ok, Region} ->
[clique_status:text(atom_to_list(Region))]
end;
info_region([_, _, _], [], []) ->
usage.
%%
%% info summary
......
%%%-------------------------------------------------------------------
%% @doc
%% == Router Handler ==
%% @end
%%%-------------------------------------------------------------------
-module(router_handler).
-behavior(libp2p_framed_stream).
-include_lib("helium_proto/include/blockchain_state_channel_v1_pb.hrl").
%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------
-export([
server/4,
client/2,
version/0
]).
%% ------------------------------------------------------------------
%% libp2p_framed_stream Function Exports
%% ------------------------------------------------------------------
-export([
init/3,
handle_data/3,
handle_info/3
]).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
-record(state, {}).
%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------
server(Connection, Path, _TID, Args) ->
libp2p_framed_stream:server(?MODULE, Connection, [Path | Args]).
client(Connection, Args) ->
libp2p_framed_stream:client(?MODULE, Connection, Args).
-spec version() -> string().
version() ->
"simple_http/1.0.0".
%% ------------------------------------------------------------------
%% libp2p_framed_stream Function Definitions
%% ------------------------------------------------------------------
init(server, _Conn, _Args) ->
lager:info("init server with ~p", [_Args]),
{ok, #state{}};
init(client, _Conn, _Args) ->
lager:info("init client with ~p", [_Args]),
{ok, #state{}}.
handle_data(_Type, Bin, State) ->
case decode(Bin) of
{ok, #blockchain_state_channel_response_v1_pb{accepted=false}} ->
ok;
{ok, #blockchain_state_channel_response_v1_pb{accepted=true, downlink=Downlink}} ->
case Downlink of
undefined ->
ok;
#packet_pb{}=Packet ->
%% ok, try to send this out
spawn(fun() -> miner_lora:send(Packet) end),
ok
end;
{error, _Reason} ->
lager:warning("got error decoding blockchain_state_channel_message ~p", [_Reason])
end,
{noreply, State}.
handle_info(_Type, {send, Data}, State) ->
lager:debug("~p sending data ~p", [_Type, Data]),
{noreply, State, Data};
handle_info(_Type, _Msg, State) ->
lager:warning("~p got info ~p", [_Type, _Msg]),
{noreply, State}.
%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------
-spec decode(binary()) -> {ok, #blockchain_state_channel_response_v1_pb{}} | {error, any()}.
decode(Bin) ->
case blockchain_state_channel_v1_pb:decode_msg(Bin, blockchain_state_channel_message_v1_pb) of
#blockchain_state_channel_message_v1_pb{msg={response, Resp}} ->
{ok, Resp};
{error, _Reason}=Error ->
Error;
Msg ->
{error, {unknown_msg, Msg}}
end.
%% ------------------------------------------------------------------
%% EUNIT Tests
%% ------------------------------------------------------------------
-ifdef(TEST).
-endif.
......@@ -9,7 +9,10 @@
send_poc/5,
port/0,
position/0,
location_ok/0
location_ok/0,
reg_domain_data_for_addr/2,
reg_domain_data_for_countrycode/1,
region/0
]).
-export([
......@@ -43,12 +46,28 @@
sig_fun,
pubkey_bin,
mirror_socket,
latlong
latlong,
reg_domain_confirmed = false :: boolean(),
reg_region :: atom(),
reg_geo_zone :: atom(),
reg_freq_list :: [float()]
}).
-record(country, {
short_code::binary(),
lat::binary(),
long::binary(),
name::binary(),
region::atom(),
geo_zone::atom()
}).
-type state() :: #state{}.
-type gateway() :: #gateway{}.
-type helium_packet() :: #packet_pb{}.
-type freq_data() :: {Region::atom(), GeoZone::atom(), Freqs::[float]}.
-define(COUNTRY_FREQ_DATA, country_freq_data).
%% in meters
-define(MAX_WANDER_DIST, 75).
......@@ -71,12 +90,15 @@ handle_response(Resp) ->
end.
-spec send(helium_packet()) -> ok | {error, any()}.
send(#packet_pb{payload=Payload, timestamp=When, signal_strength=Power, frequency=Freq, datarate=DataRate}) ->
gen_server:call(?MODULE, {send, Payload, When, Freq, DataRate, Power, true}, 11000).
send(#packet_pb{payload=Payload, frequency=Freq, timestamp=When, signal_strength=Power, datarate=DataRate} = Packet) ->
lager:debug("got download packet ~p via freq ~p", [Packet, Freq]),
%% this is used for downlink packets that have been assigned a downlink frequency by the router, so just use the supplied frequency
ChannelSelectorFun = fun(_FreqList) -> Freq end,
gen_server:call(?MODULE, {send, Payload, When, ChannelSelectorFun, DataRate, Power, true}, 11000).
-spec send_poc(binary(), any(), float(), iolist(), any()) -> ok | {error, any()}.
send_poc(Payload, When, Freq, DataRate, Power) ->
gen_server:call(?MODULE, {send, Payload, When, Freq, DataRate, Power, false}, 11000).
-spec send_poc(binary(), any(), function(), iolist(), any()) -> ok | {error, any()}.
send_poc(Payload, When, ChannelSelectorFun, DataRate, Power) ->
gen_server:call(?MODULE, {send, Payload, When, ChannelSelectorFun, DataRate, Power, false}, 11000).
-spec port() -> {ok, inet:port_number()} | {error, any()}.
port() ->
......@@ -110,11 +132,48 @@ location_ok() ->
%% this terrible thing is to fake out dialyzer
application:get_env(miner, loc_ok_default, true).
-spec reg_domain_data_for_addr(undefined | blockchain:blockchain(), libp2p_crypto:pubkey_bin())-> {error, any()} | {ok, freq_data()}.
reg_domain_data_for_addr(Chain, Addr)->
Ledger = blockchain:ledger(Chain),
{ok, Gw} = blockchain_ledger_v1:find_gateway_info(Addr, Ledger),
%% check if the miner has asserted its location, if not we will try other methods to determine this
case blockchain_ledger_gateway_v2:location(Gw) of
undefined ->
{error, location_not_asserted};
_H3Location ->
%% location has been asserted, we can proceed...
case country_code_for_addr(Addr) of
{ok, CC} ->
%% use country code to get regulatory domain data
?MODULE:reg_domain_data_for_countrycode(CC);
{error, Reason} ->
{error, Reason}
end
end.
-spec reg_domain_data_for_countrycode(binary()) -> {ok, freq_data() | {error, any()}}.
reg_domain_data_for_countrycode(CC)->
case ets:lookup(?COUNTRY_FREQ_DATA, CC) of
[{_Key, Res}] ->
lager:debug("found countrycode data ~p", [Res]),
FreqMap = application:get_env(miner, frequency_data, #{}),
freq_data(Res, FreqMap);
_ ->
lager:warning("Country code ~p not found",[CC]),
{error, countrycode_not_found}
end.
-spec region() -> {ok, atom()}.
region()->
gen_server:call(?MODULE, region, 5000).
%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------
init(Args) ->
lager:info("init with args ~p", [Args]),
UDPIP = maps:get(radio_udp_bind_ip, Args),
UDPPort = maps:get(radio_udp_bind_port, Args),
{ok, Socket} = gen_udp:open(UDPPort, [binary, {reuseaddr, true}, {active, 100}, {ip, UDPIP}]),
......@@ -125,18 +184,50 @@ init(Args) ->
{ok, S} = gen_udp:open(P, [binary, {active, true}]),
S
end,
%% cloud/miner pro will never assert location and so we dont want to
%% use regulatory domain checks for these miners
%% allow them to override the regulatory domain checks and be able to transmit from startup
%% default region and freq data is expected to be supplied by these miners
%% if not we will default to US902-928
{RegDomainConfirmed, DefaultRegRegion, DefaultRegGeoZone, DefaultRegFreqList} =
case maps:get(override_reg_domain_check, Args, false) of
true ->
lager:info("overriding regulatory domain checks, using values from Args", []),
{true, maps:get(default_reg_region, Args),
maps:get(default_reg_geo_zone, Args),
maps:get(default_reg_freq_list, Args)};
_ ->
%% not overriding domain checks, so initialize with source data and defaults
ets:new(?COUNTRY_FREQ_DATA, [named_table, public]),
ok = init_ets(),
erlang:send_after(5000, self(), reg_domain_timeout),
{false, undefined, undefined, undefined}
end,
{ok, #state{socket=Socket,
sig_fun = maps:get(sig_fun, Args),
mirror_socket = {MirrorSocket, undefined},
pubkey_bin = blockchain_swarm:pubkey_bin()}}.
handle_call({send, Payload, When, Freq, DataRate, Power, IPol}, From, #state{socket=Socket,
gateways=Gateways,
packet_timers=Timers}=State) ->
pubkey_bin = blockchain_swarm:pubkey_bin(),
reg_domain_confirmed = RegDomainConfirmed,
reg_region = DefaultRegRegion,
reg_geo_zone = DefaultRegGeoZone,
reg_freq_list = DefaultRegFreqList}}.
handle_call({send, _Payload, _When, _ChannelSelectorFun, _DataRate, _Power, _IPol}, _From,
#state{reg_domain_confirmed = false}=State) ->
lager:debug("ignoring send request as regulatory domain not yet confirmed", []),
{reply, {error, reg_domain_unconfirmed}, State};
handle_call({send, Payload, When, ChannelSelectorFun, DataRate, Power, IPol}, From,
#state{ socket=Socket,
gateways=Gateways,
packet_timers=Timers,
reg_freq_list = Freqs}=State) ->
case select_gateway(Gateways) of
{error, _}=Error ->
{reply, Error, State};
{ok, #gateway{ip=IP, port=Port}} ->
%% the fun is set by the sender and is used to deterministically route data via channels
LocalFreq = ChannelSelectorFun(Freqs),
Token = mk_token(Timers),
%% TODO we should check this for regulatory compliance
BinJSX = jsx:encode(
......@@ -147,7 +238,7 @@ handle_call({send, Payload, When, Freq, DataRate, Power, IPol}, From, #state{soc
<<"powe">> => trunc(Power),
%% TODO gps time?
<<"tmst">> => When,
<<"freq">> => Freq,
<<"freq">> => LocalFreq,
<<"modu">> => <<"LORA">>,
<<"datr">> => list_to_binary(DataRate),
<<"codr">> => <<"4/5">>,
......@@ -158,6 +249,7 @@ handle_call({send, Payload, When, Freq, DataRate, Power, IPol}, From, #state{soc
}),
Packet = <<?PROTOCOL_2:8/integer-unsigned, Token/binary, ?PULL_RESP:8/integer-unsigned, BinJSX/binary>>,
maybe_mirror(State#state.mirror_socket, Packet),
lager:debug("sending packet via channel: ~p",[LocalFreq]),
ok = gen_udp:send(Socket, IP, Port, Packet),
%% TODO a better timeout would be good here
Ref = erlang:send_after(10000, self(), {tx_timeout, Token}),
......@@ -195,6 +287,9 @@ handle_call(position, _From, #state{pubkey_bin = Addr} = State) ->
[C, E, S]),
{reply, {error, position_calc_error}, State}
end;
handle_call(region, _From, #state{reg_region = Region} = State) ->
{reply, {ok, Region}, State};
handle_call(_Msg, _From, State) ->
lager:warning("rcvd unknown call msg: ~p", [_Msg]),
{reply, ok, State}.
......@@ -203,6 +298,30 @@ handle_cast(_Msg, State) ->
lager:warning("rcvd unknown cast msg: ~p", [_Msg]),
{noreply, State}.
handle_info(reg_domain_timeout, #state{reg_domain_confirmed=false, pubkey_bin=Addr} = State) ->
lager:debug("checking regulatory domain for address ~p", [Addr]),
%% dont crash if any of this goes wrong, just try again in a bit
try
Chain = blockchain_worker:blockchain(),
case ?MODULE:reg_domain_data_for_addr(Chain, Addr) of
{error, Reason}->
lager:debug("cannot confirm regulatory domain for miner ~p, reason: ~p", [Reason]),
%% the hotspot has not yet asserted its location, transmits will remain disabled
%% we will check again after a period
erlang:send_after(30000, self(), reg_domain_timeout),
{noreply, State};
{ok, {Region, GeoZone, FrequencyList}} ->
lager:info("confirmed regulatory domain for miner ~p. region: ~p, geozone: ~p, freqlist: ~p",
[Addr, Region, GeoZone, FrequencyList]),
{noreply, State#state{ reg_domain_confirmed = true, reg_region = Region,
reg_geo_zone = GeoZone, reg_freq_list = FrequencyList}}
end
catch
_Type:Exception ->
lager:warning("error whilst checking regulatory domain: ~p. Will try again...",[Exception]),
erlang:send_after(30000, self(), reg_domain_timeout),
{noreply, State}
end;
handle_info({tx_timeout, Token}, #state{packet_timers=Timers}=State) ->
case maps:find(Token, Timers) of
{ok, {send, _Ref, From}} ->
......@@ -261,7 +380,8 @@ handle_udp_packet(<<?PROTOCOL_2:8/integer-unsigned,
Token:2/binary,
?PUSH_DATA:8/integer-unsigned,
MAC:64/integer,
JSON/binary>>, IP, Port, #state{socket=Socket, gateways=Gateways}=State) ->
JSON/binary>>, IP, Port, #state{socket=Socket, gateways=Gateways,
reg_domain_confirmed = RegDomainConfirmed}=State) ->
lager:info("PUSH_DATA ~p from ~p on ~p", [jsx:decode(JSON), MAC, Port]),
Gateway =
case maps:find(MAC, Gateways) of
......@@ -272,15 +392,16 @@ handle_udp_packet(<<?PROTOCOL_2:8/integer-unsigned,
end,
Packet = <<?PROTOCOL_2:8/integer-unsigned, Token/binary, ?PUSH_ACK:8/integer-unsigned>>,
maybe_mirror(State#state.mirror_socket, Packet),
ok = gen_udp:send(Socket, IP, Port, Packet),
maybe_send_udp_ack(Socket, IP, Port, Packet, RegDomainConfirmed),
handle_json_data(jsx:decode(JSON, [return_maps]), Gateway, State);
handle_udp_packet(<<?PROTOCOL_2:8/integer-unsigned,
Token:2/binary,
?PULL_DATA:8/integer-unsigned,
MAC:64/integer>>, IP, Port, #state{socket=Socket, gateways=Gateways}=State) ->
MAC:64/integer>>, IP, Port, #state{socket=Socket, gateways=Gateways,
reg_domain_confirmed = RegDomainConfirmed}=State) ->
Packet = <<?PROTOCOL_2:8/integer-unsigned, Token/binary, ?PULL_ACK:8/integer-unsigned>>,
maybe_mirror(State#state.mirror_socket, Packet),
ok = gen_udp:send(Socket, IP, Port, Packet),
maybe_send_udp_ack(Socket, IP, Port, Packet, RegDomainConfirmed),
lager:info("PULL_DATA from ~p on ~p", [MAC, Port]),
Gateway =
case maps:find(MAC, Gateways) of
......@@ -365,6 +486,10 @@ maybe_update_gps(#{<<"lati">> := Lat, <<"long">> := Long}, State) ->
State#state{latlong = {Lat, Long}};
maybe_update_gps(_Status, State) ->
State.
maybe_send_udp_ack(_Socket, _IP, _Port, _Packet, false = _RegDomainConfirmed)->
ok;
maybe_send_udp_ack(Socket, IP, Port, Packet, _RegDomainConfirmed)->
ok = gen_udp:send(Socket, IP, Port, Packet).
-spec sort_packets(list()) -> list().
sort_packets(Packets) ->
......@@ -378,7 +503,9 @@ sort_packets(Packets) ->
-spec handle_packets(list(), gateway(), state()) -> state().
handle_packets([], _Gateway, State) ->
State;
handle_packets([Packet|Tail], Gateway, State) ->
handle_packets(_Packets, _Gateway, #state{reg_domain_confirmed = false} = State) ->
State;
handle_packets([Packet|Tail], Gateway, #state{reg_region = Region} = State) ->
Data = base64:decode(maps:get(<<"data">>, Packet)),
case route(Data) of
error ->
......@@ -396,12 +523,12 @@ handle_packets([Packet|Tail], Gateway, State) ->
);
{Type, RoutingInfo} ->
lager:notice("Routing ~p", [RoutingInfo]),
erlang:spawn(fun() -> send_to_router(Type, RoutingInfo, Packet) end)
erlang:spawn(fun() -> send_to_router(Type, RoutingInfo, Packet, Region) end)
end,
handle_packets(Tail, Gateway, State).
-spec route(binary()) -> any().
route(Pkt) ->
route(Pkt) ->
case longfi:deserialize(Pkt) of
error ->
route_non_longfi(Pkt);
......@@ -447,8 +574,8 @@ maybe_mirror({_, undefined}, _) ->
maybe_mirror({Sock, Destination}, Packet) ->
gen_udp:send(Sock, Destination, Packet).
-spec send_to_router(lorawan, blockchain_helium_packet:routing_info(), map()) -> ok.
send_to_router(Type, RoutingInfo, Packet) ->
-spec send_to_router(lorawan, blockchain_helium_packet:routing_info(), map(), atom()) -> ok.
send_to_router(Type, RoutingInfo, Packet, Region) ->
Data = base64:decode(maps:get(<<"data">>, Packet)),
RSSI = maps:get(<<"rssi">>, Packet),
SNR = maps:get(<<"lsnr">>, Packet),
......@@ -457,4 +584,59 @@ send_to_router(Type, RoutingInfo, Packet) ->
Freq = maps:get(<<"freq">>, Packet),
DataRate = maps:get(<<"datr">>, Packet),
HeliumPacket = blockchain_helium_packet_v1:new(RoutingInfo, Type, Data, Time, RSSI, Freq, DataRate, SNR),
blockchain_state_channels_client:packet(HeliumPacket, application:get_env(miner, default_routers, [])).
blockchain_state_channels_client:packet(HeliumPacket, application:get_env(miner, default_routers, []), Region).
-spec country_code_for_addr(libp2p_crypto:pubkey_bin()) -> {ok, binary()} | {error, failed_to_find_geodata_for_addr}.
country_code_for_addr(Addr)->
B58Addr = libp2p_crypto:bin_to_b58(Addr),
URL = "https://api.helium.io/v1/hotspots/" ++ B58Addr,
case httpc:request(get, {URL, []}, [{timeout, 5000}],[]) of
{ok, {{_HTTPVersion, 200, _RespBody}, _Headers, JSONBody}} = Resp ->
lager:debug("hotspot info response: ~p", [Resp]),
%% body will be a list of geocode info of which one key will be the country code
Body = jsx:decode(list_to_binary(JSONBody), [return_maps]),
%% return the country code from the returned response
CC = maps:get(<<"short_country">>, maps:get(<<"geocode">>, maps:get(<<"data">>, Body)), undefined),
{ok, CC};
_ ->
{error, failed_to_find_geodata_for_addr}
end.
-spec freq_data(#country{}, map())-> {ok, freq_data()}.
freq_data(#country{region = undefined} = _Country, _FreqMap)->
{error, region_not_set};
freq_data(#country{region = Region, geo_zone = Zone}= _Country, FreqMap)->
case maps:get(Region, FreqMap, undefined) of
undefined ->
lager:warning("frequency data not found for region ~p",[Region]),
{error, frequency_not_found_for_region};
F->
{ok, {Region, Zone, F}}
end.
-spec init_ets() -> ok.
init_ets() ->
PrivDir = code:priv_dir(miner),
File = application:get_env(miner, reg_domains_file, "countries_reg_domains.csv"),
lager:debug("loading csv file from ~p", [PrivDir ++ "/" ++ File]),
{ok, F} = file:open(PrivDir ++ "/" ++ File, [read, raw, binary, {read_ahead, 8192}]),
ok = csv_rows_to_ets(F),
ok = file:close(F).
-spec csv_rows_to_ets(pid())-> ok | {error, any()}.
csv_rows_to_ets(F) ->
try file:read_line(F) of
{ok, Line} ->
CP = binary:compile_pattern([<<$,>>, <<$\n>>]),
[ShortCode, Lat, Long, Country, Region, GeoZone] = binary:split(Line, CP, [global, trim]),
Rec = #country{short_code=ShortCode, lat=Lat, long=Long, name=Country,
region=binary_to_atom(Region, utf8), geo_zone=binary_to_atom(GeoZone, utf8)},
ets:insert(?COUNTRY_FREQ_DATA, {ShortCode, Rec}),
csv_rows_to_ets(F);
eof ->
ok
catch
error:Reason ->
lager:warning("failed to read file ~p, error: ~p", [F, Reason]),
{error, Reason}
end.
......@@ -104,13 +104,24 @@ init(_Args) ->
OnionServer =
case application:get_env(miner, radio_device, undefined) of
{RadioBindIP, RadioBindPort, RadioSendIP, RadioSendPort} ->
%% check if we are overriding domain checks ( for lora )
%% If true then we expect default config data to be supplied, otherwise it defaults to undefined
%% and will be set by miner lora based on geolocation data of the miners asserted location
MaybeOverrideRegDomainChecks = application:get_env(miner, override_reg_domain_check, false),
DefaultRegRegion = application:get_env(miner, default_reg_region, undefined),
DefaultRegGeoZone = application:get_env(miner, default_reg_geo_zone, undefined),
DefaultRegFreqList = application:get_env(miner, default_reg_freq_list, undefined),
OnionOpts = #{
radio_udp_bind_ip => RadioBindIP,
radio_udp_bind_port => RadioBindPort,
radio_udp_send_ip => RadioSendIP,
radio_udp_send_port => RadioSendPort,
ecdh_fun => ECDHFun,
sig_fun => SigFun
sig_fun => SigFun,
override_reg_domain_check => MaybeOverrideRegDomainChecks,
default_reg_region => DefaultRegRegion,
default_reg_geo_zone => DefaultRegGeoZone,
default_reg_freq_list => DefaultRegFreqList
},
[?WORKER(miner_onion_server, [OnionOpts]),
?WORKER(miner_lora, [OnionOpts])];
......
......@@ -284,11 +284,12 @@ decrypt(Type, IV, OnionCompactKey, Tag, CipherText, RSSI, Stream, #state{ecdh_fu
Packet = longfi:serialize(<<0:128/integer-unsigned-little>>, longfi:new(monolithic, 0, 1, 0, NextPacket, #{})),
%% deterministally pick a channel based on the layerdata
<<IntData:16/integer-unsigned-little>> = Data,
Freq = lists:nth((IntData rem 8) + 1, ?CHANNELS),
%% TODO calculate some kind of delay here
case miner_lora:location_ok() of
true ->
erlang:spawn(fun() -> miner_lora:send_poc(Packet, immediate, Freq, "SF10BW125", ?TX_POWER) end),
%% the fun below will be executed by miner_lora:send and supplied with the localised lists of channels
ChannelSelectorFun = fun(FreqList) -> lists:nth((IntData rem 8) + 1, FreqList) end,
erlang:spawn(fun() -> miner_lora:send_poc(Packet, immediate, ChannelSelectorFun, "SF10BW125", ?TX_POWER) end),
erlang:spawn(fun() -> ?MODULE:send_receipt(Data, OnionCompactKey, Type, os:system_time(nanosecond), RSSI, Stream)end);
false ->
ok
......
......@@ -630,7 +630,10 @@ init_per_testcase(Mod, TestCase, Config0) ->
ct_rpc:call(Miner, application, set_env, [miner, radio_device, {{127,0,0,1}, UDPPort, {127,0,0,1}, TCPPort}]),
ct_rpc:call(Miner, application, set_env, [miner, stabilization_period_start, 2]),
ct_rpc:call(Miner, application, set_env, [miner, default_routers, [DefaultRouters]]),
ct_rpc:call(Miner, application, set_env, [miner, override_reg_domain_check, true]),
ct_rpc:call(Miner, application, set_env, [miner, default_reg_region, 'US915']),
ct_rpc:call(Miner, application, set_env, [miner, default_reg_geo_zone, 'zone2']),
ct_rpc:call(Miner, application, set_env, [miner, default_reg_freq_list, [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3]]),
{ok, _StartedApps} = ct_rpc:call(Miner, application, ensure_all_started, [miner]),
ok
end,
......
......@@ -37,6 +37,8 @@ all() ->
%%--------------------------------------------------------------------
basic(Config) ->
application:ensure_all_started(lager),
lager:set_loglevel(lager_console_backend, debug),
lager:set_loglevel({lager_file_backend, "log/console.log"}, debug),
BaseDir = ?config(base_dir, Config),
Ledger = blockchain_ledger_v1:new(BaseDir),
......@@ -76,7 +78,11 @@ basic(Config) ->
radio_udp_bind_port => 5678,
radio_udp_send_ip => {127,0,0,1},
radio_udp_send_port => Port,
sig_fun => libp2p_crypto:mk_sig_fun(PrivateKey)
sig_fun => libp2p_crypto:mk_sig_fun(PrivateKey),
override_reg_domain_check => true,
default_reg_region => 'US915',
default_reg_geo_zone => 'zone2',
default_reg_freq_list => [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3]
}),
......@@ -154,7 +160,11 @@ basic(Config) ->
radio_udp_bind_port => 5678,
radio_udp_send_ip => {127,0,0,1},
radio_udp_send_port => Port,
sig_fun => libp2p_crypto:mk_sig_fun(PrivateKey2)
sig_fun => libp2p_crypto:mk_sig_fun(PrivateKey2),
override_reg_domain_check => true,
default_reg_region => 'US915',
default_reg_geo_zone => 'zone2',
default_reg_freq_list => [903.9, 904.1, 904.3, 904.5, 904.7, 904.9, 905.1, 905.3]
}),
%% set up the gateway
......
......@@ -251,9 +251,9 @@ packets_expiry_test(Config) ->
Payload2 = crypto:strong_rand_bytes(24+rand:uniform(23)),
Packet1 = blockchain_helium_packet_v1:new({eui, 16#deadbeef, 16#deadc0de}, Payload1), %% pretend this is a join
Packet2 = blockchain_helium_packet_v1:new({devaddr, 1207959553}, Payload2), %% pretend this is a packet after join
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, [], 'US915']),
%% wait ExpireWithin + 3 more blocks to be safe
ok = miner_ct_utils:wait_for_gte(height, Miners, Height + ExpireWithin + 3),
......@@ -354,15 +354,15 @@ multi_clients_packets_expiry_test(Config) ->
Packet2 = blockchain_helium_packet_v1:new({devaddr, 1207959553}, <<"p2">>), %% first device transmitting
Packet3 = blockchain_helium_packet_v1:new({eui, 16#dead, 16#beef}, <<"p3">>), %% second device joining
Packet4 = blockchain_helium_packet_v1:new({devaddr, 1207959554}, <<"p4">>), %% second device transmitting
ok = ct_rpc:call(ClientNode1, blockchain_state_channels_client, packet, [Packet1, []]),
ok = ct_rpc:call(ClientNode1, blockchain_state_channels_client, packet, [Packet1, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode1, blockchain_state_channels_client, packet, [Packet2, []]),
ok = ct_rpc:call(ClientNode1, blockchain_state_channels_client, packet, [Packet2, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet1, []]), %% duplicate from client 2
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet1, [], 'US915']), %% duplicate from client 2
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet3, []]),
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet3, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet4, []]),
ok = ct_rpc:call(ClientNode2, blockchain_state_channels_client, packet, [Packet4, [], 'US915']),
%% check state_channel appears on the ledger
{ok, SC} = get_ledger_state_channel(RouterNode, ID, RouterPubkeyBin),
......@@ -480,9 +480,9 @@ replay_test(Config) ->
%% Use client node to send some packets
Packet1 = blockchain_helium_packet_v1:new({devaddr, 1207959553}, <<"p1">>),
Packet2 = blockchain_helium_packet_v1:new({devaddr, 1207959553}, <<"p2">>),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, [], 'US915']),
%% wait ExpireWithin + 3 more blocks to be safe
ok = miner_ct_utils:wait_for_gte(height, Miners, Height + ExpireWithin + 3),
......@@ -676,9 +676,9 @@ multi_oui_test(Config) ->
ct:pal("ActiveSCID: ~p", [ActiveSCID]),
%% Sent two packets
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet1, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet2, [], 'US915']),
%% wait ExpireWithin + 10 more blocks to be safe, we expect sc1 to have closed
ok = miner_ct_utils:wait_for_gte(height, Miners, Height + ExpireWithin + 5),
......@@ -694,11 +694,11 @@ multi_oui_test(Config) ->
%% we know whatever sc was active has closed now
%% so send three more packets
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet3, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet3, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet4, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet4, [], 'US915']),
timer:sleep(timer:seconds(1)),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet5, []]),
ok = ct_rpc:call(ClientNode, blockchain_state_channels_client, packet, [Packet5, [], 'US915']),
%% get this new active sc id
ActiveSCID2 = ct_rpc:call(RouterNode1, blockchain_state_channels_server, active_sc_id, []),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment