diff --git a/Makefile b/Makefile index 9ca544c2..3ea8c9c9 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ $(REBAR3): @chmod a+x rebar3 upgrade: $(REBAR3) - @$(REBAR3) upgrade + @$(REBAR3) upgrade --all clean: $(REBAR3) @$(REBAR3) clean --all diff --git a/rebar.config b/rebar.config index 41f4f594..26e2876a 100644 --- a/rebar.config +++ b/rebar.config @@ -15,17 +15,17 @@ ]}. {deps, [ - {lager, "3.7.0"}, + {lager, "3.9.2"}, {eid, {git, "https://github.com/jur0/eid.git", {tag, "0.6.0"}}}, - {cowlib, {git, "https://github.com/ninenines/cowlib", {tag, "2.6.0"}}}, - {cowboy, {git, "https://github.com/ninenines/cowboy", {tag, "2.5.0"}}}, - {gun, {git, "https://github.com/ninenines/gun.git", {tag, "1.3.0"}}}, - {jsx, "2.10.0"}, - {iso8601, "1.3.1"}, + {cowlib, "2.11.0"}, + {cowboy, "2.9.0"}, + {gun, "1.3.3"}, + {jsx, "3.1.0"}, + {iso8601, "1.3.3"}, {cbor, {git, "https://github.com/yjh0502/cbor-erlang.git", {ref, "b5c9dbc2de15753b2db15e13d88c11738c2ac292"}}}, - {gen_smtp, "0.15.0"}, - {amqp_client, "3.7.18"}, - {emqtt, {git, "https://github.com/emqx/emqtt.git", {tag, "v1.1.1"}}}, + {gen_smtp, "1.2.0"}, + {amqp_client, "3.10.5"}, + {emqtt, "1.2.1"}, {erlmongo, {git, "https://github.com/SergejJurecko/erlmongo.git", {ref, "f0d03cd4592f7bf28059b81214b61c28ccf046c0"}}}, {prometheus_cowboy, "0.1.8"} ]}. diff --git a/src/lorawan_admin_connections.erl b/src/lorawan_admin_connections.erl index a9ee6feb..fd70dc52 100644 --- a/src/lorawan_admin_connections.erl +++ b/src/lorawan_admin_connections.erl @@ -51,7 +51,7 @@ handle_get(Req, #state{app=undefined}=State) -> fun(Conn) -> filter_matches(Conn, Filter) end, - get_connections(pg2:which_groups(), [])), + get_connections(pg:which_groups(), [])), {jsx:encode(Items), Req, State}; handle_get(Req, #state{app=App}=State) -> {jsx:encode(get_connection(App)), Req, State}. @@ -82,7 +82,7 @@ get_connections([], Acc)-> Acc. get_connection(App) -> - case pg2:get_members({backend, App}) of + case pg:get_members({backend, App}) of List when is_list(List) -> lists:foldl( fun(Pid, Acc) -> diff --git a/src/lorawan_admin_feed.erl b/src/lorawan_admin_feed.erl index a445bb31..34fb7746 100644 --- a/src/lorawan_admin_feed.erl +++ b/src/lorawan_admin_feed.erl @@ -34,7 +34,7 @@ get_filters(Req) -> end. websocket_init(#state{table=Table} = State) -> - ok = pg2:join({feed, Table}, self()), + ok = pg:join({feed, Table}, self()), {reply, {text, encoded_records(State)}, State}. websocket_handle({ping, _}, State) -> @@ -69,7 +69,7 @@ lists_match(_, _) -> notify(Scope) -> Table = element(1, Scope), - case pg2:get_members({feed, Table}) of + case pg:get_members({feed, Table}) of {error, _Error} -> ok; List when is_list(List) -> diff --git a/src/lorawan_backend_factory.erl b/src/lorawan_backend_factory.erl index d8996fc5..84cd100d 100644 --- a/src/lorawan_backend_factory.erl +++ b/src/lorawan_backend_factory.erl @@ -97,11 +97,10 @@ item_deleted(#connector{}=Connector) -> stop_connector(Connector). -start_connector(#connector{connid=Id, app=App, uri=Uri, enabled=true, +start_connector(#connector{connid=Id, app=_App, uri=Uri, enabled=true, failed=Failed}=Connector) when Failed == undefined; Failed == [] -> case find_module(Uri) of {ok, Module} -> - pg2:create({backend, App}), apply(Module, start_connector, [Connector]); {error, Error} -> lorawan_utils:throw_error({connector, Id}, Error) @@ -171,7 +170,7 @@ nodes_with_backend(App) -> [], mnesia:dirty_index_read(profile, App, #profile.app)). send_to_connectors(App, Message) -> - case pg2:get_members({backend, App}) of + case pg:get_members({backend, App}) of {error, _Error} -> % the application is internal or not defined ok; diff --git a/src/lorawan_connector.erl b/src/lorawan_connector.erl index f39df632..c7eddc2d 100644 --- a/src/lorawan_connector.erl +++ b/src/lorawan_connector.erl @@ -168,14 +168,14 @@ build_access_token(Res0, AccessKey) -> build_access_token(Res0, AccessKey, 60*60*24*7). % expires in a week build_access_token(Res0, AccessKey, Expiry) -> - Res = http_uri:encode(Res0), + Res = uri_string:quote(Res0), % seconds since the UNIX epoch Now = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) - calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}}), ToSign = lists:flatten( io_lib:format("~s~n~B", [Res, Now+Expiry])), - Sig = http_uri:encode(base64:encode_to_string( - crypto:hmac(sha256, base64:decode(AccessKey), ToSign))), + Sig = uri_string:quote(base64:encode_to_string( + crypto:mac(hmac, sha256, base64:decode(AccessKey), ToSign))), io_lib:format("SharedAccessSignature sr=~s&sig=~s&se=~B", [Res, Sig, Now+Expiry]). diff --git a/src/lorawan_connector_amqp.erl b/src/lorawan_connector_amqp.erl index a5c5425e..1045cea9 100644 --- a/src/lorawan_connector_amqp.erl +++ b/src/lorawan_connector_amqp.erl @@ -26,7 +26,7 @@ start_link(Connector) -> init([#connector{connid=Id, app=App, publish_uplinks=PubUp, publish_events=PubEv, received=Cons}=Connector]) -> process_flag(trap_exit, true), - ok = pg2:join({backend, App}, self()), + ok = pg:join({backend, App}, self()), self() ! connect, try {ok, #state{ diff --git a/src/lorawan_connector_http.erl b/src/lorawan_connector_http.erl index 69b2de4f..d0eb5763 100644 --- a/src/lorawan_connector_http.erl +++ b/src/lorawan_connector_http.erl @@ -35,7 +35,7 @@ start_link(Connector) -> init([#connector{connid=Id, app=App, publish_uplinks=PubUp, publish_events=PubEv, name=UserName, pass=Password}=Conn]) -> - ok = pg2:join({backend, App}, self()), + ok = pg:join({backend, App}, self()), try {ok, ensure_gun( #state{conn=Conn, @@ -165,14 +165,15 @@ ensure_gun(#state{conn=#connector{uri= <<"http:">>}, pid=undefined}=State) -> State; ensure_gun(#state{conn=#connector{connid=ConnId, uri=Uri}, pid=undefined}=State) -> lager:debug("Connecting ~s to ~s", [ConnId, Uri]), + #{scheme := Scheme, host := Host, port := Port, path := Path} = uri_string:parse(binary_to_list(Uri)), {ConnPid, Prefix} = - case http_uri:parse(binary_to_list(Uri), [{scheme_defaults, [{http, 80}, {https, 443}]}]) of - {ok, {http, _UserInfo, HostName, Port, Path, _Query}} -> - {ok, Pid} = gun:open(HostName, Port), + case Scheme of + "http" -> + {ok, Pid} = gun:open(Host, Port), {Pid, Path}; - {ok, {https, _UserInfo, HostName, Port, Path, _Query}} -> + "https" -> Opts = application:get_env(lorawan_server, ssl_options, []), - {ok, Pid} = gun:open(HostName, Port, #{transport=>ssl, transport_opts=>Opts}), + {ok, Pid} = gun:open(Host, Port, #{transport=>ssl, transport_opts=>Opts}), {Pid, Path} end, MRef = monitor(process, ConnPid), diff --git a/src/lorawan_connector_mongodb.erl b/src/lorawan_connector_mongodb.erl index 6a584e71..1ea97b6c 100644 --- a/src/lorawan_connector_mongodb.erl +++ b/src/lorawan_connector_mongodb.erl @@ -27,7 +27,7 @@ start_link(Connector) -> init([#connector{connid=Id, app=App, uri= <<"mongodb://", Servers0/binary>>, publish_uplinks=PubUp, publish_events=PubEv}=Connector]) -> process_flag(trap_exit, true), - ok = pg2:join({backend, App}, self()), + ok = pg:join({backend, App}, self()), lager:debug("Connecting ~s to mongodb ~s", [Id, Servers0]), Pool = binary_to_atom(Id, latin1), % connect diff --git a/src/lorawan_connector_mqtt.erl b/src/lorawan_connector_mqtt.erl index 62839c95..998c6559 100644 --- a/src/lorawan_connector_mqtt.erl +++ b/src/lorawan_connector_mqtt.erl @@ -27,7 +27,7 @@ start_link(Connector) -> init([#connector{connid=Id, app=App, uri=Uri, client_id=ClientId, name=UserName, pass=Password, subscribe=Sub, publish_uplinks=PubUp, publish_events=PubEv, received=Cons}=Connector]) -> process_flag(trap_exit, true), - ok = pg2:join({backend, App}, self()), + ok = pg:join({backend, App}, self()), self() ! nodes_changed, timer:send_interval(60*1000, ping), try @@ -140,14 +140,14 @@ connect(Vers, Arguments, Conn) -> connection_args([Uri, ClientId, UserName, Password], Conn) -> lager:debug("Connecting ~s to ~p, id ~p, user ~p", [Conn#connector.connid, Uri, ClientId, UserName]), - {ok, ConnUri} = http_uri:parse(binary_to_list(Uri), [{scheme_defaults, [{mqtt, 1883}, {mqtts, 8883}]}]), - {Scheme, _UserInfo, HostName, Port, _Path, _Query} = ConnUri, + ConnUri = uri_string:parse(binary_to_list(Uri)), + #{scheme := Scheme, host := Host, port := Port} = ConnUri, lists:append([ - [{host, HostName}, + [{host, Host}, {port, Port}, {keepalive, 0}], - auth_args(HostName, Conn#connector.auth, ClientId, UserName, Password), - ssl_args(Scheme, Conn) + auth_args(Host, Conn#connector.auth, ClientId, UserName, Password), + ssl_args(list_to_atom(Scheme), Conn) ]). connect0([Ver | Rest], CArgs) -> diff --git a/src/lorawan_connector_ws.erl b/src/lorawan_connector_ws.erl index 3ee5f9f9..92543802 100644 --- a/src/lorawan_connector_ws.erl +++ b/src/lorawan_connector_ws.erl @@ -116,7 +116,7 @@ validate_key(_Else, _) -> websocket_init(#state{conn=#connector{connid=Id, app=App}, bindings=Bindings} = State) -> lager:debug("WebSocket connector ~p with ~p", [Id, Bindings]), - ok = pg2:join({backend, App}, self()), + ok = pg:join({backend, App}, self()), {ok, State}. websocket_handle({text, Msg}, State) -> diff --git a/src/lorawan_gw_lns.erl b/src/lorawan_gw_lns.erl index 63695b62..b05b909c 100644 --- a/src/lorawan_gw_lns.erl +++ b/src/lorawan_gw_lns.erl @@ -110,7 +110,7 @@ handle_message(#{router:=Router}, #state{mac=undefined}=State) -> ID6 = lorawan_eid:as_id6(MAC), % determine own address [#config{admin_url=Prefix}] = mnesia:dirty_read(config, <<"main">>), - {ok, {Scheme, _, Host, Port, Path, _}} = http_uri:parse(Prefix), + #{scheme := Scheme, host := Host, port := Port, path := Path} = uri_string:parse(Prefix), Scheme2 = case Scheme of http -> <<"ws">>; diff --git a/src/lorawan_mac.erl b/src/lorawan_mac.erl index c7e8d999..b5e7d2f3 100644 --- a/src/lorawan_mac.erl +++ b/src/lorawan_mac.erl @@ -57,7 +57,7 @@ ingest_join_frame(MAC, Msg, AppEUI, DevEUI, DevNonce, MIC) -> [D] when D#device.appeui /= undefined, D#device.appeui /= AppEUI -> {error, {device, DevEUI}, {bad_appeui, binary_to_hex(AppEUI)}, aggregated}; [D] -> - case crypto:cmac(aes_cbc128, D#device.appkey, Msg, 4) of + case crypto:macN(cmac, aes_128_cbc, D#device.appkey, Msg, 4) of MIC -> verify_join(MAC, D, DevNonce); _MIC2 -> @@ -70,7 +70,7 @@ ingest_data_frame(_MAC, MType, Msg, FOpts, FRMPayload, MIC, when MType == 2#010; MType == 2#100 -> case accept_node_frame(DevAddr, FCnt) of {ok, Fresh, {Network, Profile, Node}} -> - case crypto:cmac(aes_cbc128, Node#node.nwkskey, + case crypto:macN(cmac, aes_128_cbc, Node#node.nwkskey, <<(b0(MType band 1, DevAddr, Node#node.fcntup, byte_size(Msg)))/binary, Msg/binary>>, 4) of MIC -> ok = lorawan_admin:write( @@ -381,10 +381,10 @@ handle_accept(Gateways, {Network, Profile, Device}, DevAddr, DevNonce) -> create_node(Gateways, {#network{netid=NetID}=Network, Profile, #device{deveui=DevEUI, appkey=AppKey}}, AppNonce, DevAddr, DevNonce) -> - NwkSKey = crypto:block_encrypt(aes_ecb, AppKey, - padded(16, <<16#01, AppNonce/binary, NetID/binary, DevNonce/binary>>)), - AppSKey = crypto:block_encrypt(aes_ecb, AppKey, - padded(16, <<16#02, AppNonce/binary, NetID/binary, DevNonce/binary>>)), + NwkSKey = crypto:crypto_one_time(aes_ecb, AppKey, + padded(16, <<16#01, AppNonce/binary, NetID/binary, DevNonce/binary>>), true), + AppSKey = crypto:crypto_one_time(aes_ecb, AppKey, + padded(16, <<16#02, AppNonce/binary, NetID/binary, DevNonce/binary>>), true), [Device] = mnesia:read(device, DevEUI, write), Device2 = append_join({calendar:universal_time(), DevNonce}, Device#device{node=DevAddr}), @@ -447,10 +447,10 @@ encode_accept(#network{netid=NetID, rx1_delay=RxDelay, cflist=CFList}, #device{a MHDR = <<2#001:3, 0:3, 0:2>>, MACPayload = <>, - MIC = crypto:cmac(aes_cbc128, AppKey, <>, 4), + MIC = crypto:macN(cmac, aes_128_cbc, AppKey, <>, 4), % yes, decrypt; see LoRaWAN specification, Section 6.2.5 - PHYPayload = crypto:block_decrypt(aes_ecb, AppKey, padded(16, <>)), + PHYPayload = crypto:crypto_one_time(aes_ecb, AppKey, padded(16, <>), false), {ok, Node, <>}. encode_cflist(List) when is_list(List), length(List) > 0, length(List) =< 5 -> @@ -531,7 +531,7 @@ sign_frame(Confirmed, DevAddr, NwkSKey, FCnt, MACPayload) -> true -> 2#101 end, Msg = <>, - MIC = crypto:cmac(aes_cbc128, NwkSKey, <<(b0(1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4), + MIC = crypto:macN(cmac, aes_128_cbc, NwkSKey, <<(b0(1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4), <>. bool_to_pending(true) -> 1; @@ -543,11 +543,11 @@ cipher(Bin, Key, Dir, DevAddr, FCnt) -> cipher(Bin, Key, Dir, DevAddr, FCnt, 1, <<>>). cipher(<>, Key, Dir, DevAddr, FCnt, I, Acc) -> - Si = crypto:block_encrypt(aes_ecb, Key, ai(Dir, DevAddr, FCnt, I)), + Si = crypto:crypto_one_time(aes_ecb, Key, ai(Dir, DevAddr, FCnt, I), true), cipher(Rest, Key, Dir, DevAddr, FCnt, I+1, <<(binxor(Block, Si, <<>>))/binary, Acc/binary>>); cipher(<<>>, _Key, _Dir, _DevAddr, _FCnt, _I, Acc) -> Acc; cipher(<>, Key, Dir, DevAddr, FCnt, I, Acc) -> - Si = crypto:block_encrypt(aes_ecb, Key, ai(Dir, DevAddr, FCnt, I)), + Si = crypto:crypto_one_time(aes_ecb, Key, ai(Dir, DevAddr, FCnt, I), true), <<(binxor(LastBlock, binary:part(Si, 0, byte_size(LastBlock)), <<>>))/binary, Acc/binary>>. ai(Dir, DevAddr, FCnt, I) -> diff --git a/test/test_forwarder.erl b/test/test_forwarder.erl index 85f00772..86015229 100644 --- a/test/test_forwarder.erl +++ b/test/test_forwarder.erl @@ -80,10 +80,10 @@ handle_info({pull_expired, Token}, #state{pull_tokens=Tokens}=State) -> handle_info({udp, Socket, _, _, <<1, _:16, 3, Data/binary>>}, #state{socket=Socket, motes=Motes}=State) -> Pk = jsx:decode(Data, [{labels, atom}]), - TxPk = proplists:get_value(txpk, Pk), - Frame = proplists:get_value(data, TxPk), + TxPk = maps:get(txpk, Pk), + Frame = maps:get(data, TxPk), % send to the device that opened the window - get_mote(proplists:get_value(tmst, TxPk), Motes) ! {ok, Frame}, + get_mote(maps:get(tmst, TxPk), Motes) ! {ok, Frame}, {noreply, State}. store_rxpk(Mote, Frame, #state{motes=Motes, rxpks=Pks}=State) -> diff --git a/test/test_mote.erl b/test/test_mote.erl index 436deb46..6cc6cffe 100644 --- a/test/test_mote.erl +++ b/test/test_mote.erl @@ -82,7 +82,7 @@ encode_frame(MType, FCnt, ADR, ADRACKReq, ACK, FOpts, FPort, FData, <> end, Msg = <>, - MIC = crypto:cmac(aes_cbc128, NwkSKey, <<(b0(MType band 1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4), + MIC = crypto:macN(cmac, aes_128_cbc, NwkSKey, <<(b0(MType band 1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4), <>. process_frame(PHYPayload, State) -> @@ -100,7 +100,7 @@ process_frame0(MType, Msg, MIC, #state{devaddr=DevAddr, nwkskey=NwkSKey, appskey <> -> {Port, Payload} end, DevAddr = reverse(DevAddr0), - case crypto:cmac(aes_cbc128, NwkSKey, <<(b0(MType band 1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4) of + case crypto:macN(cmac, aes_128_cbc, NwkSKey, <<(b0(MType band 1, DevAddr, FCnt, byte_size(Msg)))/binary, Msg/binary>>, 4) of MIC -> case FPort of 0 when FOptsLen == 0 ->