config.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package main
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path/filepath"
  6. )
  7. // Config holds the daemon configuration
  8. type Config struct {
  9. // Mode: "cloud" (server settings priority) or "lan" (local settings priority)
  10. Mode string `json:"mode"`
  11. // Server settings
  12. APIBase string `json:"api_base"`
  13. ConfigPollingInterval int `json:"cfg_polling_timeout"` // in seconds, default: 30
  14. // Device identity (persisted)
  15. DeviceID string `json:"device_id,omitempty"`
  16. DeviceToken string `json:"device_token,omitempty"`
  17. // BLE settings
  18. BLE struct {
  19. Enabled bool `json:"enabled"`
  20. BatchIntervalMs int `json:"batch_interval_ms"`
  21. UploadEndpoint string `json:"upload_endpoint,omitempty"`
  22. } `json:"ble"`
  23. // WiFi settings
  24. WiFi struct {
  25. MonitorEnabled bool `json:"monitor_enabled"`
  26. ClientEnabled bool `json:"client_enabled"`
  27. SSID string `json:"ssid"`
  28. PSK string `json:"psk"`
  29. BatchIntervalMs int `json:"batch_interval_ms"`
  30. UploadEndpoint string `json:"upload_endpoint,omitempty"`
  31. } `json:"wifi"`
  32. // SSH Tunnel settings (for terminal access)
  33. SSHTunnel struct {
  34. Enabled bool `json:"enabled"`
  35. Server string `json:"server"`
  36. Port int `json:"port"`
  37. User string `json:"user"`
  38. KeyPath string `json:"key_path"`
  39. RemotePort int `json:"remote_port"`
  40. KeepaliveInterval int `json:"keepalive_interval"`
  41. ReconnectDelay int `json:"reconnect_delay"`
  42. } `json:"ssh_tunnel"`
  43. // Dashboard Tunnel settings (for web dashboard access)
  44. DashboardTunnel struct {
  45. Enabled bool `json:"enabled"`
  46. Server string `json:"server"`
  47. Port int `json:"port"`
  48. User string `json:"user"`
  49. RemotePort int `json:"remote_port"`
  50. KeepaliveInterval int `json:"keepalive_interval"`
  51. ReconnectDelay int `json:"reconnect_delay"`
  52. } `json:"dashboard_tunnel"`
  53. // Network settings (eth0 is ALWAYS local, never from server)
  54. Network struct {
  55. NTPServers []string `json:"ntp_servers"`
  56. Eth0 struct {
  57. Static bool `json:"static"`
  58. Address string `json:"address"`
  59. Gateway string `json:"gateway"`
  60. DNS string `json:"dns"`
  61. } `json:"eth0"`
  62. } `json:"network"`
  63. // AP Fallback settings (when no network available for 120s)
  64. APFallback struct {
  65. Password string `json:"password"` // Default: "mybeacon123"
  66. } `json:"ap_fallback"`
  67. // Dashboard settings
  68. Dashboard struct {
  69. Enabled bool `json:"enabled"`
  70. } `json:"dashboard"`
  71. // Local-only settings (never from server)
  72. ZMQAddrBLE string `json:"zmq_addr_ble"`
  73. ZMQAddrWiFi string `json:"zmq_addr_wifi"`
  74. SpoolDir string `json:"spool_dir"`
  75. WiFiIface string `json:"wifi_iface"`
  76. Debug bool `json:"debug"`
  77. }
  78. // DefaultConfig returns a configuration with default values
  79. func DefaultConfig() *Config {
  80. cfg := &Config{
  81. Mode: "cloud",
  82. APIBase: "http://localhost:5000/api/v1",
  83. ConfigPollingInterval: 30,
  84. ZMQAddrBLE: "tcp://127.0.0.1:5555",
  85. ZMQAddrWiFi: "tcp://127.0.0.1:5556",
  86. SpoolDir: "/var/spool/mybeacon",
  87. }
  88. cfg.BLE.Enabled = true
  89. cfg.BLE.BatchIntervalMs = 2500
  90. cfg.WiFi.MonitorEnabled = false
  91. cfg.WiFi.BatchIntervalMs = 10000
  92. cfg.SSHTunnel.Port = 22
  93. cfg.SSHTunnel.KeepaliveInterval = 30
  94. cfg.SSHTunnel.ReconnectDelay = 5
  95. cfg.DashboardTunnel.Port = 22
  96. cfg.DashboardTunnel.KeepaliveInterval = 30
  97. cfg.DashboardTunnel.ReconnectDelay = 5
  98. cfg.Network.NTPServers = []string{"pool.ntp.org"}
  99. cfg.APFallback.Password = "mybeacon"
  100. cfg.Dashboard.Enabled = true
  101. return cfg
  102. }
  103. // LoadConfig loads configuration from a JSON file
  104. func LoadConfig(path string) (*Config, error) {
  105. cfg := DefaultConfig()
  106. data, err := os.ReadFile(path)
  107. if err != nil {
  108. if os.IsNotExist(err) {
  109. return cfg, nil // Use defaults
  110. }
  111. return nil, err
  112. }
  113. if err := json.Unmarshal(data, cfg); err != nil {
  114. return nil, err
  115. }
  116. return cfg, nil
  117. }
  118. // SaveConfig saves configuration to a JSON file
  119. func SaveConfig(path string, cfg *Config) error {
  120. dir := filepath.Dir(path)
  121. if err := os.MkdirAll(dir, 0755); err != nil {
  122. return err
  123. }
  124. data, err := json.MarshalIndent(cfg, "", " ")
  125. if err != nil {
  126. return err
  127. }
  128. return os.WriteFile(path, data, 0600)
  129. }
  130. // DeviceState holds persistent device state
  131. type DeviceState struct {
  132. DeviceID string `json:"device_id"`
  133. DeviceToken string `json:"device_token"`
  134. DevicePassword string `json:"device_password,omitempty"`
  135. }
  136. // LoadDeviceState loads device state from file
  137. func LoadDeviceState(path string) (*DeviceState, error) {
  138. state := &DeviceState{}
  139. data, err := os.ReadFile(path)
  140. if err != nil {
  141. if os.IsNotExist(err) {
  142. return state, nil
  143. }
  144. return nil, err
  145. }
  146. if err := json.Unmarshal(data, state); err != nil {
  147. return nil, err
  148. }
  149. return state, nil
  150. }
  151. // SaveDeviceState saves device state to file
  152. func SaveDeviceState(path string, state *DeviceState) error {
  153. dir := filepath.Dir(path)
  154. if err := os.MkdirAll(dir, 0755); err != nil {
  155. return err
  156. }
  157. data, err := json.MarshalIndent(state, "", " ")
  158. if err != nil {
  159. return err
  160. }
  161. return os.WriteFile(path, data, 0600)
  162. }