Current section
Files
Jump to
Current section
Files
stdlib/Network/UDP.erl
%%---------------------------------------------------------------------------
%% |
%% Module : UDP
%% Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
%% License : BSD-style (see the LICENSE file)
%%
%% Maintainer : Feng Lee, feng@emqx.io
%% Yang M, yangm@emqx.io
%% Stability : experimental
%% Portability : portable
%%
%% The UDP FFI module.
%%
%%---------------------------------------------------------------------------
-module('Network.UDP.FFI').
-include("../Foreign.hrl").
-export([ open/1
, openWith/2
, recv/2
, recvTimeout/3
, send/4
, sendTo/4
, close/1
, controllingProcess/2
]).
open(Port) ->
?IO(returnVal(gen_udp:open(Port))).
openWith(Port, Options) ->
?IO(returnVal(gen_udp:open(Port, parseOpts(Options)))).
recv(Socket, Length) ->
?IO(wrap(returnVal(gen_udp:recv(Socket, Length)))).
recvTimeout(Socket, Length, Timeout) ->
?IO(wrap(returnVal(gen_udp:recv(Socket, Length, unwrap(Timeout))))).
send(Socket, Hostname, PortNumber, Packet) ->
?IO(return(gen_udp:send(Socket, Hostname, PortNumber, Packet))).
sendTo(Socket, IpAddress, PortNumber, Packet) ->
?IO(return(gen_udp:send(Socket, unwrap(IpAddress), PortNumber, Packet))).
close(Socket) ->
?IO(return(gen_udp:close(Socket))).
controllingProcess(Socket, Pid) ->
?IO(return(gen_udp:controlling_process(Socket, Pid))).
returnVal({ok, Socket}) -> Socket;
returnVal({error, Reason}) -> error(Reason).
return(ok) -> ok;
return({error, Reason}) -> error(Reason).
parseOpts(Opts) -> parseOpts(Opts, [binary]).
parseOpts([{'Active', B}|Opts], Acc) ->
parseOpts(Opts, [{active, B}|Acc]);
parseOpts([{'ActiveN', N}|Opts], Acc) ->
parseOpts(Opts, [{active, N}|Acc]);
parseOpts([{'AddMembership', Addr1, Addr2}|Opts], Acc) ->
parseOpts(Opts, [{add_membership, unwrap(Addr1), unwrap(Addr2)}|Acc]);
parseOpts([{'Broadcast', B}|Opts], Acc) ->
parseOpts(Opts, [{broadcast, B}|Acc]);
parseOpts([{'Buffer', N}|Opts], Acc) ->
parseOpts(Opts, [{buffer, N}|Acc]);
parseOpts([{'Deliver', A}|Opts], Acc) ->
parseOpts(Opts, [{deliver, A}|Acc]);
parseOpts([{'Dontroute', B}|Opts], Acc) ->
parseOpts(Opts, [{dontroute, B}|Acc]);
parseOpts([{'DropMembership', Addr1, Addr2}|Opts], Acc) ->
parseOpts(Opts, [{drop_membership, unwrap(Addr1), unwrap(Addr2)}|Acc]);
parseOpts([{'Header', N}|Opts], Acc) ->
parseOpts(Opts, [{header, N}|Acc]);
parseOpts([{'HighMsgqWatermark', N}|Opts], Acc) ->
parseOpts(Opts, [{high_msgq_watermark, N}|Acc]);
parseOpts([{'LowMsgqWatermark', N}|Opts], Acc) ->
parseOpts(Opts, [{low_msgq_watermark, N}|Acc]);
parseOpts([{'MulticastIf', Addr}|Opts], Acc) ->
parseOpts(Opts, [{multicast_if, unwrap(Addr)}|Acc]);
parseOpts([{'MulticastTTL', N}|Opts], Acc) ->
parseOpts(Opts, [{multicast_ttl, N}|Acc]);
parseOpts([{'Priority', N}|Opts], Acc) ->
parseOpts(Opts, [{priority, N}|Acc]);
parseOpts([{'Raw', N1, N2, Bin}|Opts], Acc) ->
parseOpts(Opts, [{raw, N1, N2, Bin}|Acc]);
parseOpts([{'ReadPackets', N}|Opts], Acc) ->
parseOpts(Opts, [{read_packets, N}|Acc]);
parseOpts([{'Recbuf', N}|Opts], Acc) ->
parseOpts(Opts, [{recbuf, N}|Acc]);
parseOpts([{'ReuseAddr', B}|Opts], Acc) ->
parseOpts(Opts, [{reuseaddr, B}|Acc]);
parseOpts([{'Sndbuf', N}|Opts], Acc) ->
parseOpts(Opts, [{sndbuf, N}|Acc]);
parseOpts([{'ToS', N}|Opts], Acc) ->
parseOpts(Opts, [{tos, N}|Acc]);
parseOpts([{'Tclass', N}|Opts], Acc) ->
parseOpts(Opts, [{tclass, N}|Acc]);
parseOpts([{'TTL', N}|Opts], Acc) ->
parseOpts(Opts, [{ttl, N}|Acc]);
parseOpts([{'RecvToS', B}|Opts], Acc) ->
parseOpts(Opts, [{recvtos, B}|Acc]);
parseOpts([{'RecvTclass', B}|Opts], Acc) ->
parseOpts(Opts, [{recvtclass, B}|Acc]);
parseOpts([{'RecvTTL', B}|Opts], Acc) ->
parseOpts(Opts, [{recvttl, B}|Acc]);
parseOpts([{'Ipv6only', B}|Opts], Acc) ->
parseOpts(Opts, [{ipv6_v6only, B}|Acc]);
parseOpts([], Acc) -> Acc.
unwrap({'Ip4Address', Addr}) -> Addr;
unwrap({'Ip6Address', Addr}) -> Addr;
unwrap({'Infinity'}) -> infinity;
unwrap({'Timeout', I}) -> I.
wrap({Address, Port, Packet}) ->
{wrapAddr(Address), Port, Packet}.
wrapAddr(Addr) when size(Addr) == 4 ->
{'Ip4Address', Addr};
wrapAddr(Addr) when size(Addr) == 6 ->
{'Ip6Address', Addr}.