100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
package eebus
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
|
|
"github.com/evcc-io/evcc/util"
|
|
"github.com/evcc-io/evcc/util/machine"
|
|
)
|
|
|
|
const (
|
|
BrandName string = "EVCC"
|
|
Model string = "HEMS"
|
|
)
|
|
|
|
// used as common name in cert generation
|
|
var DeviceCode = util.Getenv("EEBUS_DEVICE_CODE", "EVCC_HEMS_01")
|
|
|
|
type Certificate struct {
|
|
Public string `json:"public"`
|
|
Private string `json:"private"`
|
|
}
|
|
|
|
type Config struct {
|
|
URI_ string `mapstructure:"uri" json:"uri,omitempty"` // TODO deprecated
|
|
Port int `json:"port"`
|
|
ShipID string `json:"shipid"`
|
|
Interfaces []string `json:"interfaces,omitempty"`
|
|
Certificate Certificate `json:"certificate"`
|
|
Secret string `json:"secret,omitempty"` // hex SHIP pairing secret
|
|
}
|
|
|
|
// IsConfigured returns true if the EEbus server is configured
|
|
func (c Config) IsConfigured() bool {
|
|
return len(c.Certificate.Public) > 0 && len(c.Certificate.Private) > 0
|
|
}
|
|
|
|
// Redacted implements the redactor interface used by the tee publisher
|
|
func (c Config) Redacted() any {
|
|
return Config{
|
|
URI_: c.URI_,
|
|
Port: c.Port,
|
|
ShipID: c.ShipID,
|
|
Interfaces: c.Interfaces,
|
|
Certificate: Certificate{
|
|
Public: c.Certificate.Public,
|
|
Private: util.Masked(c.Certificate.Private),
|
|
},
|
|
}
|
|
}
|
|
|
|
func createShipID() string {
|
|
protectedID := machine.ProtectedID("evcc-eebus")
|
|
return fmt.Sprintf("%s-%0x", "EVCC", protectedID[:8])
|
|
}
|
|
|
|
// CreatePairingSecret returns a 16-byte SHIP pairing secret as hex string.
|
|
func CreatePairingSecret() (string, error) {
|
|
b := make([]byte, 16)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return "", err
|
|
}
|
|
return hex.EncodeToString(b), nil
|
|
}
|
|
|
|
func DefaultConfig(conf *Config) (*Config, error) {
|
|
cert, err := CreateCertificate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
public, private, err := GetX509KeyPair(cert)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// preserve a configured port (e.g. EVCC_EEBUS_PORT), default otherwise
|
|
port := conf.Port
|
|
if port == 0 {
|
|
port = 4712
|
|
}
|
|
|
|
secret, err := CreatePairingSecret()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res := Config{
|
|
Port: port,
|
|
ShipID: createShipID(),
|
|
Secret: secret,
|
|
Certificate: Certificate{
|
|
Public: public,
|
|
Private: private,
|
|
},
|
|
}
|
|
|
|
return &res, nil
|
|
}
|