84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
|
|
// Package config 加载 IoT Server 的 MQTT、协议密钥和内部接口配置。
|
||
|
|
package config
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/hex"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"gopkg.in/yaml.v3"
|
||
|
|
)
|
||
|
|
|
||
|
|
type MQTT struct {
|
||
|
|
Broker string `yaml:"Broker"`
|
||
|
|
ClientID string `yaml:"ClientID"`
|
||
|
|
Username string `yaml:"Username"`
|
||
|
|
Password string `yaml:"Password"`
|
||
|
|
UpTopic string `yaml:"UpTopic"`
|
||
|
|
DownTopic string `yaml:"DownTopic"`
|
||
|
|
AckTopic string `yaml:"AckTopic"`
|
||
|
|
QoS byte `yaml:"QoS"`
|
||
|
|
TLS bool `yaml:"TLS"`
|
||
|
|
CAFile string `yaml:"CAFile"`
|
||
|
|
CertificateFile string `yaml:"CertificateFile"`
|
||
|
|
PrivateKeyFile string `yaml:"PrivateKeyFile"`
|
||
|
|
}
|
||
|
|
type HTTP struct {
|
||
|
|
Address string `yaml:"Address"`
|
||
|
|
InternalToken string `yaml:"InternalToken"`
|
||
|
|
CallbackURL string `yaml:"CallbackURL"`
|
||
|
|
}
|
||
|
|
type Protocol struct {
|
||
|
|
Key1 string `yaml:"Key1"`
|
||
|
|
Key2 string `yaml:"Key2"`
|
||
|
|
Key3 string `yaml:"Key3"`
|
||
|
|
}
|
||
|
|
type Config struct {
|
||
|
|
Service string `yaml:"Service"`
|
||
|
|
MQTT MQTT `yaml:"MQTT"`
|
||
|
|
HTTP HTTP `yaml:"HTTP"`
|
||
|
|
Protocol Protocol `yaml:"Protocol"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func Load(path string) (Config, error) {
|
||
|
|
var cfg Config
|
||
|
|
data, err := os.ReadFile(path)
|
||
|
|
if err != nil {
|
||
|
|
return cfg, err
|
||
|
|
}
|
||
|
|
if err = yaml.Unmarshal(data, &cfg); err != nil {
|
||
|
|
return cfg, err
|
||
|
|
}
|
||
|
|
override(&cfg.MQTT.Password, "HEQI_IOT_MQTT_PASSWORD")
|
||
|
|
override(&cfg.HTTP.InternalToken, "HEQI_IOT_INTERNAL_TOKEN")
|
||
|
|
override(&cfg.Protocol.Key1, "HEQI_IOT_KEY_1")
|
||
|
|
override(&cfg.Protocol.Key2, "HEQI_IOT_KEY_2")
|
||
|
|
override(&cfg.Protocol.Key3, "HEQI_IOT_KEY_3")
|
||
|
|
if cfg.MQTT.Broker == "" || cfg.HTTP.Address == "" || cfg.HTTP.InternalToken == "" {
|
||
|
|
return cfg, fmt.Errorf("MQTT.Broker、HTTP.Address 和 HTTP.InternalToken 必填")
|
||
|
|
}
|
||
|
|
return cfg, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (cfg Config) Keys() (map[byte][]byte, error) {
|
||
|
|
result := map[byte][]byte{}
|
||
|
|
for id, value := range map[byte]string{1: cfg.Protocol.Key1, 2: cfg.Protocol.Key2, 3: cfg.Protocol.Key3} {
|
||
|
|
if strings.TrimSpace(value) == "" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
decoded, err := hex.DecodeString(value)
|
||
|
|
if err != nil || len(decoded) != 16 {
|
||
|
|
return nil, fmt.Errorf("Protocol.Key%d 必须是 32 位十六进制 AES-128 密钥", id)
|
||
|
|
}
|
||
|
|
result[id] = decoded
|
||
|
|
}
|
||
|
|
return result, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func override(target *string, name string) {
|
||
|
|
if value := os.Getenv(name); value != "" {
|
||
|
|
*target = value
|
||
|
|
}
|
||
|
|
}
|