%% -*-: erlang -*- {mapping, "lwm2m.bind.udp.$number", "emqx_lwm2m.bind_udp", [ {datatype, ip}, {default, "0.0.0.0:5683"} ]}. {mapping, "lwm2m.bind.dtls.$number", "emqx_lwm2m.bind_dtls", [ {datatype, ip}, {default, "0.0.0.0:5684"} ]}. {mapping, "lwm2m.lifetime_min", "emqx_lwm2m.lifetime_min", [ {datatype, {duration, s}}, {default, 0} ]}. {mapping, "lwm2m.lifetime_max", "emqx_lwm2m.lifetime_max", [ {datatype, {duration, s}}, {default, 315360000} %% 10 years ]}. {mapping, "lwm2m.qmode_time_window", "emqx_lwm2m.qmode_time_window", [ {datatype, integer}, {default, 0} ]}. {mapping, "lwm2m.auto_observe", "emqx_lwm2m.auto_observe", [ {datatype, string}, {default, "off"} %% BACKW: v4.3.0 ]}. {mapping, "lwm2m.lb", "emqx_lwm2m.options", [ {datatype, atom}, {default, undefined} ]}. {mapping, "lwm2m.opts.$name", "emqx_lwm2m.options", [ {datatype, bytesize} ]}. {translation, "emqx_lwm2m.auto_observe", fun(Conf) -> case cuttlefish:conf_get("lwm2m.auto_observe", Conf, "off") of "off" -> false; %% BACKW: v4.3.0 "on" -> true; %% BACKW: v4.3.0 Str -> string:tokens(Str, ", ") end end}. {translation, "emqx_lwm2m.bind_udp", fun(Conf) -> Options = cuttlefish_variable:filter_by_prefix("lwm2m.bind.udp", Conf), lists:map(fun({_, Bind}) -> {Ip, Port} = cuttlefish_datatypes:from_string(Bind, ip), Opts = case inet:parse_address(Ip) of {ok, {_,_,_,_} = Address} -> [inet, {ip, Address}]; {ok, {_,_,_,_,_,_,_,_} = Address} -> [inet6, {ip, Address}] end, {Port, Opts} end, Options) end}. {translation, "emqx_lwm2m.bind_dtls", fun(Conf) -> Options = cuttlefish_variable:filter_by_prefix("lwm2m.bind.dtls", Conf), lists:map(fun({_, Bind}) -> {Ip, Port} = cuttlefish_datatypes:from_string(Bind, ip), Opts = case inet:parse_address(Ip) of {ok, {_,_,_,_} = Address} -> [inet, {ip, Address}]; {ok, {_,_,_,_,_,_,_,_} = Address} -> [inet6, {ip, Address}] end, {Port, Opts} end, Options) end}. {translation, "emqx_lwm2m.options", fun(Conf) -> Options = cuttlefish_variable:filter_by_prefix("lwm2m.opts", Conf), Opts = lists:map(fun({[_,_, Key], Value}) -> {list_to_atom(Key), Value} end, Options), case cuttlefish:conf_get("lwm2m.lb", Conf, undefined) of undefined -> ignore; _ -> cuttlefish:warn("The 'lwm2m.lb' option has removed from v4.2.0!") end, Opts end}. {mapping, "lwm2m.mountpoint", "emqx_lwm2m.mountpoint", [ {datatype, string}, {default, ""} ]}. {mapping, "lwm2m.topics.command", "emqx_lwm2m.topics", [ {datatype, string}, {default, "lwm2m/%e/dn/#"} ]}. {mapping, "lwm2m.topics.response", "emqx_lwm2m.topics", [ {datatype, string}, {default, "lwm2m/%e/up/resp"} ]}. {mapping, "lwm2m.topics.notify", "emqx_lwm2m.topics", [ {datatype, string}, {default, "lwm2m/%e/up/notify"} ]}. {mapping, "lwm2m.topics.register", "emqx_lwm2m.topics", [ {datatype, string}, {default, "lwm2m/%e/up/resp"} ]}. {mapping, "lwm2m.topics.update", "emqx_lwm2m.topics", [ {datatype, string}, {default, "lwm2m/%e/up/resp"} ]}. {mapping, "lwm2m.update_msg_publish_condition", "emqx_lwm2m.update_msg_publish_condition", [ {datatype, {enum, [contains_object_list, always]}}, {default, contains_object_list} ]}. {translation, "emqx_lwm2m.topics", fun(Conf) -> Topics = cuttlefish_variable:filter_by_prefix("lwm2m.topics", Conf), Opts = lists:map(fun({[_,_, Key], Value}) -> {list_to_atom(Key), Value} end, Topics), Opts end}. {mapping, "lwm2m.xml_dir", "emqx_lwm2m.xml_dir", [ {datatype, string} ]}. %% Plan to remove v5.0-alpha.1, please use lwm2m.dtls_opts.keyfile instead {mapping, "lwm2m.keyfile", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. %% Plan to remove v5.0-alpha.1, please use lwm2m.dtls_opts.certfile instead {mapping, "lwm2m.certfile", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {mapping, "lwm2m.dtls.keyfile", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {mapping, "lwm2m.dtls.certfile", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {mapping, "lwm2m.dtls.verify", "emqx_lwm2m.dtls_opts", [ {default, verify_none}, {datatype, {enum, [verify_none, verify_peer]}} ]}. {mapping, "lwm2m.dtls.cacertfile", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {mapping, "lwm2m.dtls.fail_if_no_peer_cert", "emqx_lwm2m.dtls_opts", [ {datatype, {enum, [true, false]}} ]}. {mapping, "lwm2m.dtls.ciphers", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {mapping, "lwm2m.dtls.psk_ciphers", "emqx_lwm2m.dtls_opts", [ {datatype, string} ]}. {translation, "emqx_lwm2m.dtls_opts", fun(Conf) -> Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end, %% compatible with before v4.2 %% It plan to remove at v5.0-alpha.1 OldKey = cuttlefish:conf_get("lwm2m.keyfile", Conf, undefined), OldCert = cuttlefish:conf_get("lwm2m.certfile", Conf, undefined), %% Ciphers SplitFun = fun(undefined) -> []; (S) -> string:tokens(S, ",") end, Ciphers = case cuttlefish:conf_get("lwm2m.dtls.ciphers", Conf, undefined) of undefined -> []; C -> [{ciphers, SplitFun(C)}] end, PskCiphers = case cuttlefish:conf_get("lwm2m.dtls.psk_ciphers", Conf, undefined) of undefined -> []; C2 -> Psk = lists:map(fun("PSK-AES128-CBC-SHA") -> "RSA-PSK-AES128-CBC-SHA"; ("PSK-AES256-CBC-SHA") -> "RSA-PSK-AES256-CBC-SHA"; ("PSK-3DES-EDE-CBC-SHA") -> "RSA-PSK-3DES-EDE-CBC-SHA"; ("PSK-RC4-SHA") -> "RSA-PSK-RC4-SHA"; (Suite) -> Suite end, SplitFun(C2)), [{ciphers, Psk}, {user_lookup_fun, {fun emqx_psk:lookup/3, <<>>}}] end, Ciphers /= [] andalso PskCiphers /= [] andalso cuttlefish:invalid("The 'lwm2m.dtls.ciphers' and 'lwm2m.dtls.psk_ciphers' cannot coexist"), NCiphers = Ciphers ++ PskCiphers, Filter([{verify, cuttlefish:conf_get("lwm2m.dtls.verify", Conf, undefined)}, {keyfile, cuttlefish:conf_get("lwm2m.dtls.keyfile", Conf, OldKey)}, {certfile, cuttlefish:conf_get("lwm2m.dtls.certfile", Conf, OldCert)}, {cacertfile, cuttlefish:conf_get("lwm2m.dtls.cacertfile", Conf, undefined)}, {fail_if_no_peer_cert, cuttlefish:conf_get("lwm2m.dtls.fail_if_no_peer_cert", Conf, undefined)} | NCiphers]) end}.