package rpc import ( "regexp" "strings" ) // DeviceUIDLength is the length of device UID's const DeviceUIDLength = 32 // DeviceUIDInvalid is the defacto invalid UID from the RPC specification const DeviceUIDInvalid = "00000000000000000000000000000000" // VersionMap is a map of versions type VersionMap map[VersionKey]string // DeviceInfo is the device:info result devices type DeviceInfo struct { Type DeviceType `json:"type" msgpack:"type"` // Type is the device type Version VersionMap `json:"version" msgpack:"version"` // Version is the Sem-ver firmware or hardware version } // DeviceData is the device:data result for devices type DeviceData struct { State DeviceState `json:"state" msgpack:"state"` // State is the device state Error bool `json:"error" msgpack:"error"` // Error is whether there is an error Errors []ErrorCode `json:"errors,omitempty" msgpack:"errors,omitempty"` // Errors is the list of errors } // DeviceType is a type which represent device types type DeviceType string // nolint: golint const ( DeviceTypeCRM3000 DeviceType = "crm-3000" DeviceTypeCRTMGateway DeviceType = "crtm-gateway" DeviceTypeCRTMSensor DeviceType = "crtm-sensor" DeviceTypeDNCM DeviceType = "dncm" DeviceTypeTWS3000DUM DeviceType = "tws-3000-dum" DeviceTypeTWS3000DUU DeviceType = "tws-3000-duu" DeviceTypeGRB3000 DeviceType = "greenhub-3000" DeviceTypeTWS3000WUM DeviceType = "tws-3000-wum" DeviceTypeZKL3000 DeviceType = "zkl-3000" DeviceTypeZKL3000RC DeviceType = "zkl-3000-rc" DeviceTypeZKL3000RCC DeviceType = "zkl-3000-rcc" DeviceTypeReedSensor DeviceType = "reed-sensor" DeviceTypeService DeviceType = "service" ) // VersionKey is a version key type VersionKey string // nolint: golint const ( VersionKeyFwService VersionKey = "fw-service" VersionKeyFwCRM VersionKey = "fw-crm" VersionKeyHwCRM VersionKey = "hw-crm" VersionKeyFwGateway VersionKey = "fw-gateway" VersionKeyHwGateway VersionKey = "hw-gateway" VersionKeyFwCRTM VersionKey = "fw-crtm" VersionKeyHwCRTM VersionKey = "hw-crtm" VersionKeyFwDNCM VersionKey = "fw-dncm" VersionKeyHwDNCM VersionKey = "hw-dncm" VersionKeyFwGRB VersionKey = "fw-grb" VersionKeyHwGRB VersionKey = "hw-grb" VersionKeyFwDUM VersionKey = "fw-dum" VersionKeyHwDUM VersionKey = "hw-dum" VersionKeyFwDUU VersionKey = "fw-duu" VersionKeyHwDUU VersionKey = "hw-duu" VersionKeyFwWUMMain VersionKey = "fw-main" VersionKeyHwWUMMain VersionKey = "hw-main" VersionKeyFwWUMMonitor VersionKey = "fw-monitor" VersionKeyHwWUMMonitor VersionKey = "hw-monitor" VersionKeyFwZKLMain VersionKey = "fw-main" VersionKeyHwZKLMain VersionKey = "hw-main" VersionKeyFwZKLWcpu VersionKey = "fw-wcpu" VersionKeyFwZKLRCMain VersionKey = "fw-main" VersionKeyHwZKLRCMain VersionKey = "hw-main" VersionKeyFwZKLRCWcpu VersionKey = "fw-wcpu" VersionKeyFwZKLRCSwitchConrol VersionKey = "fw-switch_control" VersionKeyFwZKLRCSwitchMeas VersionKey = "fw-switch_meas" VersionKeyFwZKLRCSwitchDrive VersionKey = "fw-switch_drive" VersionKeyHwZKLRCSwitch VersionKey = "hw-switch" ) // nolint: gochecknoglobals var reVersionKey = regexp.MustCompile(`^hw-[a-z_]|^fw-[a-z_]`) // IsValid checks if the key matches the required pattern func (v VersionKey) IsValid() bool { return reVersionKey.MatchString(string(v)) } // DeviceState is a state which a devices resides in type DeviceState string // nolint: golint const ( DeviceStateService DeviceState = "service" DeviceStateIdle DeviceState = "idle" DeviceStateArmed DeviceState = "armed" DeviceStateActive DeviceState = "active" ) // Device UID prefixes from the RPC specification // nolint: golint const ( DeviceUIDPrefixRegular string = "00" DeviceUIDPrefixLegacy string = "01" DeviceUIDPrefixSimulator string = "02" DeviceUIDPrefixXBee string = "03" DeviceUIDPrefixNBIoT string = "04" DeviceUIDPrefixLoRa string = "05" DeviceUIDPrefixService string = "fe" DeviceUIDPrefixServiceNBIoT string = DeviceUIDPrefixService + "00" DeviceUIDPrefixServiceLoRa string = DeviceUIDPrefixService + "01" DeviceUIDPrefixServiceCP3000 string = DeviceUIDPrefixService + "02" DeviceUIDPrefixMock string = "ff" ) // GenerateDeviceUID uses a 2 character prefix and a suffix and concatenates them // to a single Device UID, it returns an error when the suffix is too long or // when the prefix is invalid. It also makes sure the resulting UID is lowercase. func GenerateDeviceUID(prefix, suffix string) (string, error) { length := len(prefix) + len(suffix) if length > DeviceUIDLength { return DeviceUIDInvalid, ErrDeviceUIDTooLong } return strings.ToLower(prefix + strings.Repeat("0", DeviceUIDLength-length) + suffix), nil } // IsValid checks: // - Type may not be empty // - Version must contain at least one element // - All version keys are valid func (d *DeviceInfo) IsValid() bool { if string(d.Type) == "" { return false } if len(d.Version) == 0 { return false } for component := range d.Version { if !component.IsValid() { return false } } return true }