Packages
grizzly
5.2.7
9.1.4
9.1.2
9.1.1
9.1.0
9.0.0
8.15.3
8.15.2
8.15.1
8.15.0
8.14.0
8.13.0
8.12.0
8.11.3
8.11.2
8.11.1
8.11.0
8.10.0
8.9.0
8.8.1
8.8.0
8.7.1
8.7.0
8.6.12
8.6.11
8.6.10
8.6.9
8.6.8
8.6.7
retired
8.6.6
8.6.5
8.6.4
8.6.3
8.6.2
8.6.1
8.6.0
8.5.3
8.5.2
8.5.1
8.5.0
8.4.0
8.3.0
8.2.3
8.2.2
8.2.1
8.2.0
8.1.0
8.0.1
8.0.0
7.4.3
7.4.2
7.4.1
7.4.0
7.3.0
7.2.0
7.1.4
7.1.3
7.1.2
7.1.1
7.1.0
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.8.8
6.8.7
6.8.6
6.8.5
6.8.4
6.8.3
6.8.2
6.8.1
6.8.0
6.7.1
6.7.0
6.6.1
6.6.0
6.5.1
6.5.0
6.4.0
6.3.0
6.2.0
6.1.1
6.1.0
6.0.1
6.0.0
5.4.1
5.4.0
5.3.0
5.2.8
5.2.7
5.2.6
5.2.5
5.2.4
5.2.3
5.2.2
5.2.1
5.2.0
5.1.2
5.1.1
5.1.0
5.0.2
5.0.1
5.0.0
4.0.1
4.0.0
3.0.0
2.1.0
2.0.0
1.0.1
1.0.0
0.22.7
0.22.6
0.22.5
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.2
0.20.1
0.20.0
0.19.1
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.9.0-rc.4
0.9.0-rc.3
0.9.0-rc.2
0.9.0-rc.1
0.9.0-rc.0
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
Elixir Z-Wave library
Current section
Files
Jump to
Current section
Files
lib/grizzly/zipgateway/config.ex
defmodule Grizzly.ZIPGateway.Config do
@moduledoc false
# This module is for making the `zipgateway.cfg` file
require Logger
alias Grizzly.Supervisor
@type t :: %__MODULE__{
ca_cert: Path.t(),
cert: Path.t(),
priv_key: Path.t(),
eeprom_file: Path.t() | nil,
tun_script: Path.t(),
pvs_storage_file: Path.t(),
provisioning_config_file: Path.t(),
pan_ip: :inet.ip_address(),
lan_ip: :inet.ip_address(),
lan_gw6: String.t(),
psk: String.t(),
manufacturer_id: non_neg_integer() | nil,
hardware_version: non_neg_integer() | nil,
product_id: non_neg_integer() | nil,
product_type: non_neg_integer() | nil,
serial_log: String.t() | nil,
extra_classes: [byte()],
unsolicited_destination: {:inet.ip_address(), :inet.port_number()},
database_file: Path.t() | nil,
rf_region: Supervisor.rf_region() | nil,
power_level: {Supervisor.tx_power(), Supervisor.measured_power()} | nil
}
defstruct ca_cert: "./Portal.ca_x509.pem",
cert: "./ZIPR.x509_1024.pem",
priv_key: "./ZIPR.key_1024.pem",
eeprom_file: nil,
tun_script: "./zipgateway.tun",
pvs_storage_file: "/root/provisioning_list_store.dat",
provisioning_config_file: "/data/zipgateway_provisioning_list.cfg",
pan_ip: {0xFD00, 0xBBBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
lan_ip: {0xFD00, 0xAAAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
lan_gw6: "::1",
psk: "123456789012345678901234567890AA",
serial_log: nil,
product_id: nil,
product_type: nil,
hardware_version: nil,
manufacturer_id: nil,
extra_classes: [0x85, 0x59, 0x5A, 0x8E, 0x6C, 0x8F],
unsolicited_destination: {{0xFD00, 0xAAAA, 0, 0, 0, 0, 0, 0x0002}, 41230},
database_file: nil,
identify_script: nil,
rf_region: nil,
power_level: nil
@doc """
Make a new `ZipgatewayCfg.t()` from the supplied options
"""
@spec new(map()) :: t()
def new(opts \\ %{}) do
opts =
Map.take(opts, [
:manufacturer_id,
:hardware_version,
:product_id,
:product_type,
:serial_log,
:tun_script,
:lan_ip,
:pan_ip,
:database_file,
:eeprom_file,
:rf_region,
:power_level
])
struct(__MODULE__, opts)
end
@doc """
Write the contents of the `ZipgatewayCfg.t()` to the file system
"""
@spec write(t(), Path.t()) :: :ok | {:error, File.posix()}
def write(cfg, path) do
contents = __MODULE__.to_string(cfg)
File.write(path, contents)
end
@doc """
Turn the `ZipgatewayCfg.t()` into a string
"""
@spec to_string(t()) :: String.t()
def to_string(cfg) do
"""
ZipCaCert=#{cfg.ca_cert}
ZipCert=#{cfg.cert}
ZipPrivKey=#{cfg.priv_key}
TunScript=#{cfg.tun_script}
PVSStorageFile=#{cfg.pvs_storage_file}
ProvisioningConfigFile=#{cfg.provisioning_config_file}
ZipLanGw6=#{cfg.lan_gw6}
ZipPSK=#{cfg.psk}
"""
|> maybe_put_config_item(cfg, :serial_log, "SerialLog")
|> maybe_put_config_item(cfg, :product_id, "ZipProductID")
|> maybe_put_config_item(cfg, :manufacturer_id, "ZipManufacturerID")
|> maybe_put_config_item(cfg, :hardware_version, "ZipHardwareVersion")
|> maybe_put_config_item(cfg, :product_type, "ZipProductType")
|> maybe_put_config_item(cfg, :extra_classes, "ExtraClasses")
|> maybe_put_config_item(cfg, :pan_ip, "ZipPanIp6")
|> maybe_put_config_item(cfg, :lan_ip, "ZipLanIp6")
|> maybe_put_config_item(cfg, :unsolicited_destination, nil)
|> maybe_put_config_item(cfg, :database_file, "ZipGwDatabase")
|> maybe_put_config_item(cfg, :eeprom_file, "Eepromfile")
|> maybe_put_config_item(cfg, :identify_script, "ZipNodeIdentifyScript")
|> maybe_put_config_item(cfg, :rf_region, "ZWRFRegion")
|> maybe_put_config_item(cfg, :power_level, "")
end
@doc """
Ensure required files are on disk and contain the correct contents
This is useful to ensure other tools provided by `zipgateway` can work.
"""
@spec ensure_files(t()) :: t()
def ensure_files(config) do
:ok = ensure_provisioning_list_config(config.provisioning_config_file)
config
end
defp ensure_provisioning_list_config(provisioning_list_config_path) do
if File.exists?(provisioning_list_config_path) do
:ok
else
contents = """
# Provisioning list for Z/IP Gateway Smart Start devices.
ZIPGateway Smart Start Provisioning List Configuration, version = 1.0.
"""
case File.write(provisioning_list_config_path, contents) do
:ok ->
:ok
{:error, reason} ->
Logger.warn("Failed to write provision list file: #{inspect(reason)}")
end
end
end
defp maybe_put_config_item(config_string, cfg, :extra_classes = field, cfg_name) do
case Map.get(cfg, field) do
nil ->
config_string
extra_command_classes ->
extra_command_classes_string = Enum.join(extra_command_classes, " ")
config_string <> "#{cfg_name}= #{extra_command_classes_string}\n"
end
end
defp maybe_put_config_item(config_string, cfg, :unsolicited_destination, _) do
{ip, port} = cfg.unsolicited_destination
ip_string =
ip
|> :inet.ntoa()
|> Kernel.to_string()
config_string <>
"ZipUnsolicitedDestinationIp6=#{ip_string}\n" <>
"ZipUnsolicitedDestinationPort=#{port}\n"
end
defp maybe_put_config_item(config_string, cfg, :identify_script = field, cfg_name) do
case Map.get(cfg, field) do
nil ->
script_path = Application.app_dir(:grizzly, ["priv", "indicator.sh"])
config_string <> "#{cfg_name}=#{script_path}\n"
script_path ->
config_string <> "#{cfg_name}=#{script_path}\n"
end
end
defp maybe_put_config_item(config_string, cfg, :power_level = field, _cfg_name) do
case Map.get(cfg, field) do
nil ->
config_string
{tx_powerlevel, measured_dbm} ->
config_string <>
"NormalTxPowerLevel=#{tx_powerlevel}\nMeasured0dBmPower=#{measured_dbm}\n"
end
end
defp maybe_put_config_item(config_string, cfg, field, cfg_name)
when field in [:pan_ip, :lan_ip] do
ip =
cfg
|> Map.get(field)
|> :inet.ntoa()
|> List.to_string()
config_string <> "#{cfg_name}=#{ip}\n"
end
defp maybe_put_config_item(config_string, cfg, :rf_region, cfg_name) do
case Map.get(cfg, :rf_region) do
nil ->
config_string
region ->
config_string <> "#{cfg_name}=#{rf_region(region)}\n"
end
end
defp maybe_put_config_item(config_string, cfg, field, cfg_name) do
cfg_item = Map.get(cfg, field)
if cfg_item != nil do
config_string <> "#{cfg_name}=#{cfg_item}\n"
else
config_string
end
end
defp rf_region(:eu), do: 0x00
defp rf_region(:us), do: 0x01
defp rf_region(:anz), do: 0x02
defp rf_region(:hk), do: 0x03
defp rf_region(:id), do: 0x05
defp rf_region(:il), do: 0x06
defp rf_region(:ru), do: 0x07
defp rf_region(:cn), do: 0x08
defp rf_region(:us_lr), do: 0x09
defp rf_region(:jp), do: 0x20
defp rf_region(:kr), do: 0x21
end