Skip to content

Commit

Permalink
fix(plc4go/cbus): fix broken wildcards
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Apr 4, 2023
1 parent 500f94f commit eecde5a
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 132 deletions.
2 changes: 1 addition & 1 deletion plc4go/internal/cbus/Browser.go
Expand Up @@ -60,7 +60,7 @@ func (m Browser) BrowseQuery(ctx context.Context, browseRequest apiModel.PlcBrow
allAttributes := false
var attributes []readWriteModel.Attribute
if unitAddress := query.unitAddress; unitAddress != nil {
units = append(units, *unitAddress)
units = append(units, unitAddress)
} else {
// TODO: check if we still want the option to brute force all addresses
installedUnitAddressBytes, err := m.getInstalledUnitAddressBytes(ctx)
Expand Down
12 changes: 6 additions & 6 deletions plc4go/internal/cbus/Query.go
Expand Up @@ -35,11 +35,11 @@ import (
type UnitInfoQuery interface {
apiModel.PlcQuery

GetUnitAddress() *readWriteModel.UnitAddress
GetUnitAddress() readWriteModel.UnitAddress
GetAttribute() *readWriteModel.Attribute
}

func NewUnitInfoQuery(unitAddress *readWriteModel.UnitAddress, attribute *readWriteModel.Attribute, numElements uint16) UnitInfoQuery {
func NewUnitInfoQuery(unitAddress readWriteModel.UnitAddress, attribute *readWriteModel.Attribute, numElements uint16) UnitInfoQuery {
return &unitInfoQuery{
unitAddress: unitAddress,
tagType: UNIT_INFO,
Expand All @@ -50,15 +50,15 @@ func NewUnitInfoQuery(unitAddress *readWriteModel.UnitAddress, attribute *readWr

type unitInfoQuery struct {
tagType TagType
unitAddress *readWriteModel.UnitAddress
unitAddress readWriteModel.UnitAddress
attribute *readWriteModel.Attribute
numElements uint16
}

func (u unitInfoQuery) GetQueryString() string {
unitAddressString := "*"
if u.unitAddress != nil {
unitAddressString = fmt.Sprintf("%d", (*u.unitAddress).GetAddress())
unitAddressString = fmt.Sprintf("%d", u.unitAddress.GetAddress())
}
attributeString := "*"
if u.attribute != nil {
Expand Down Expand Up @@ -87,7 +87,7 @@ func (u unitInfoQuery) GetTagType() TagType {
return u.tagType
}

func (u unitInfoQuery) GetUnitAddress() *readWriteModel.UnitAddress {
func (u unitInfoQuery) GetUnitAddress() readWriteModel.UnitAddress {
return u.unitAddress
}

Expand All @@ -109,7 +109,7 @@ func (u unitInfoQuery) SerializeWithWriteBuffer(ctx context.Context, writeBuffer
}

if unitAddress := u.unitAddress; unitAddress != nil {
if err := (*unitAddress).SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
if err := unitAddress.SerializeWithWriteBuffer(ctx, writeBuffer); err != nil {
return err
}
}
Expand Down
152 changes: 61 additions & 91 deletions plc4go/internal/cbus/TagHandler.go
Expand Up @@ -69,9 +69,9 @@ func NewTagHandler() TagHandler {
statusRequestPattern: regexp.MustCompile(`^status/(?:(?P<bridges>b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})(?:-b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})){0,5})/)?(?P<statusRequestType>(?P<binary>binary)|level=0x(?P<startingGroupAddressLabel>00|20|40|60|80|A0|C0|E0))/(?P<application>.*)$`),
calPattern: regexp.MustCompile(`^cal/(?:(?P<bridges>b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})(?:-b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})){0,5})-)?(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}))/(?P<calType>reset|recall=\[(?P<recallParamNo>\w+), ?(?P<recallCount>\d+)]|identify=(?P<identifyAttribute>\w+)|getStatus=(?P<getStatusParamNo>\w+), ?(?P<getStatusCount>\d+)|write=\[(?P<writeParamNo>\w+), ?(?P<writeCode>0[xX][0-9a-fA-F][0-9a-fA-F])]|identifyReply=(?P<replyAttribute>\w+)|reply=(?P<replyParamNo>\w+)|status=(?P<statusApplication>.*)|statusExtended=(?P<statusExtendedApplication>.*))$`),
salPattern: regexp.MustCompile(`^sal/(?:(?P<bridges>b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})(?:-b(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3})){0,5})/)?(?P<application>.*)/(?P<salCommand>.*)$`),
salMonitorPattern: regexp.MustCompile(`^salmonitor/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}))/(?P<application>.+)$`),
mmiMonitorPattern: regexp.MustCompile(`^mmimonitor/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}))/(?P<application>.+)$`),
unityQuery: regexp.MustCompile(`^info/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}))/(?P<identifyAttribute>.+)$`),
salMonitorPattern: regexp.MustCompile(`^salmonitor/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}|\*))/(?P<application>.+|\*)$`),
mmiMonitorPattern: regexp.MustCompile(`^mmimonitor/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}|\*))/(?P<application>.+|\*)$`),
unityQuery: regexp.MustCompile(`^info/(?P<unitAddress>u?(?:(?:0x)?[A-Fa-f0-9]{1,2}|\d{1,3}|\*))/(?P<identifyAttribute>.+|\*)$`),
}
}

Expand Down Expand Up @@ -132,7 +132,7 @@ func (m TagHandler) ParseQuery(query string) (apiModel.PlcQuery, error) {
}

func (m TagHandler) handleStatusRequestPattern(match map[string]string) (apiModel.PlcTag, error) {
bridgeAddresses, err := extractBridges(match)
bridgeAddresses, err := m.extractBridges(match)
if err != nil {
return nil, errors.Wrap(err, "error extracting bridges")
}
Expand All @@ -154,7 +154,7 @@ func (m TagHandler) handleStatusRequestPattern(match map[string]string) (apiMode
return nil, errors.Errorf("Unknown statusRequestType%s", statusRequestArgument)
}
}
application, err := applicationIdFromArgument(match["application"])
application, err := m.applicationIdFromArgument(match["application"])
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from argument")
}
Expand All @@ -165,23 +165,12 @@ func (m TagHandler) handleCalPattern(match map[string]string) (apiModel.PlcTag,
var unitAddress readWriteModel.UnitAddress
unitAddressArgument := match["unitAddress"]
unitAddressArgument = strings.TrimPrefix(unitAddressArgument, "u")
if strings.HasPrefix(unitAddressArgument, "0x") {
decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
if err != nil {
return nil, errors.Wrap(err, "Not a valid hex")
}
if len(decodedHex) != 1 {
return nil, errors.Errorf("Hex must be exatly one byte")
}
unitAddress = readWriteModel.NewUnitAddress(decodedHex[0])
} else {
atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
if err != nil {
return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
}
unitAddress = readWriteModel.NewUnitAddress(byte(atoi))
var err error
unitAddress, err = m.unitAddressFromArgument(unitAddressArgument, false)
if err != nil {
return nil, errors.Wrap(err, "error getting unit address from argument")
}
bridgeAddresses, err := extractBridges(match)
bridgeAddresses, err := m.extractBridges(match)
if err != nil {
return nil, errors.Wrap(err, "error extracting bridges")
}
Expand Down Expand Up @@ -291,11 +280,11 @@ func (m TagHandler) handleCalPattern(match map[string]string) (apiModel.PlcTag,
}

func (m TagHandler) handleSALPattern(match map[string]string) (apiModel.PlcTag, error) {
bridgeAddresses, err := extractBridges(match)
bridgeAddresses, err := m.extractBridges(match)
if err != nil {
return nil, errors.Wrap(err, "error extracting bridges")
}
application, err := applicationIdFromArgument(match["application"])
application, err := m.applicationIdFromArgument(match["application"])
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from argument")
}
Expand Down Expand Up @@ -323,23 +312,10 @@ func (m TagHandler) handleSALMonitorPattern(match map[string]string) (apiModel.P
{
unitAddressArgument := match["unitAddress"]
unitAddressArgument = strings.TrimPrefix(unitAddressArgument, "u")
if unitAddressArgument == "*" {
unitAddress = nil
} else if strings.HasPrefix(unitAddressArgument, "0x") {
decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
if err != nil {
return nil, errors.Wrap(err, "Not a valid hex")
}
if len(decodedHex) != 1 {
return nil, errors.Errorf("Hex must be exatly one byte")
}
unitAddress = readWriteModel.NewUnitAddress(decodedHex[0])
} else {
atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
if err != nil {
return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
}
unitAddress = readWriteModel.NewUnitAddress(byte(atoi))
var err error
unitAddress, err = m.unitAddressFromArgument(unitAddressArgument, true)
if err != nil {
return nil, errors.Wrap(err, "error getting unit address from argument")
}
}

Expand All @@ -349,7 +325,7 @@ func (m TagHandler) handleSALMonitorPattern(match map[string]string) (apiModel.P
if applicationIdArgument == "*" {
application = nil
} else {
applicationId, err := applicationIdFromArgument(applicationIdArgument)
applicationId, err := m.applicationIdFromArgument(applicationIdArgument)
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from argument")
}
Expand All @@ -365,23 +341,10 @@ func (m TagHandler) handleMMIMonitorPattern(match map[string]string) (apiModel.P
{
unitAddressArgument := match["unitAddress"]
unitAddressArgument = strings.TrimPrefix(unitAddressArgument, "u")
if unitAddressArgument == "*" {
unitAddress = nil
} else if strings.HasPrefix(unitAddressArgument, "0x") {
decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
if err != nil {
return nil, errors.Wrap(err, "Not a valid hex")
}
if len(decodedHex) != 1 {
return nil, errors.Errorf("Hex must be exatly one byte")
}
unitAddress = readWriteModel.NewUnitAddress(decodedHex[0])
} else {
atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
if err != nil {
return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
}
unitAddress = readWriteModel.NewUnitAddress(byte(atoi))
var err error
unitAddress, err = m.unitAddressFromArgument(unitAddressArgument, true)
if err != nil {
return nil, errors.Wrap(err, "error getting unit address from argument")
}
}

Expand All @@ -391,7 +354,7 @@ func (m TagHandler) handleMMIMonitorPattern(match map[string]string) (apiModel.P
if applicationIdArgument == "*" {
application = nil
} else {
applicationId, err := applicationIdFromArgument(applicationIdArgument)
applicationId, err := m.applicationIdFromArgument(applicationIdArgument)
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from argument")
}
Expand All @@ -403,30 +366,13 @@ func (m TagHandler) handleMMIMonitorPattern(match map[string]string) (apiModel.P
}

func (m TagHandler) handleUnitQuery(match map[string]string) (apiModel.PlcQuery, error) {
var unitAddress *readWriteModel.UnitAddress
var unitAddress readWriteModel.UnitAddress
unitAddressArgument := match["unitAddress"]
unitAddressArgument = strings.TrimPrefix(unitAddressArgument, "u")
if unitAddressArgument == "*" {
unitAddress = nil
} else if strings.HasPrefix(unitAddressArgument, "0x") {
decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
if err != nil {
return nil, errors.Wrap(err, "Not a valid hex")
}
if len(decodedHex) != 1 {
return nil, errors.Errorf("Hex must be exatly one byte")
}
var unitAddressVar readWriteModel.UnitAddress
unitAddressVar = readWriteModel.NewUnitAddress(decodedHex[0])
unitAddress = &unitAddressVar
} else {
atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
if err != nil {
return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
}
var unitAddressVar readWriteModel.UnitAddress
unitAddressVar = readWriteModel.NewUnitAddress(byte(atoi))
unitAddress = &unitAddressVar
var err error
unitAddress, err = m.unitAddressFromArgument(unitAddressArgument, true)
if err != nil {
return nil, errors.Wrap(err, "error getting unit address from argument")
}

var attribute *readWriteModel.Attribute
Expand Down Expand Up @@ -462,7 +408,30 @@ func (m TagHandler) handleUnitQuery(match map[string]string) (apiModel.PlcQuery,
return NewUnitInfoQuery(unitAddress, attribute, 1), nil
}

func applicationIdFromArgument(applicationIdArgument string) (readWriteModel.ApplicationIdContainer, error) {
func (m TagHandler) unitAddressFromArgument(unitAddressArgument string, allowWildcard bool) (readWriteModel.UnitAddress, error) {
if unitAddressArgument == "*" && allowWildcard {
return nil, nil
}

if strings.HasPrefix(unitAddressArgument, "0x") {
decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
if err != nil {
return nil, errors.Wrap(err, "Not a valid hex")
}
if len(decodedHex) != 1 {
return nil, errors.Errorf("Hex must be exatly one byte")
}
return readWriteModel.NewUnitAddress(decodedHex[0]), nil
}

atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
if err != nil {
return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
}
return readWriteModel.NewUnitAddress(byte(atoi)), nil
}

func (m TagHandler) applicationIdFromArgument(applicationIdArgument string) (readWriteModel.ApplicationIdContainer, error) {
if strings.HasPrefix(applicationIdArgument, "0x") {
decodedHex, err := hex.DecodeString(applicationIdArgument[2:])
if err != nil {
Expand All @@ -473,6 +442,7 @@ func applicationIdFromArgument(applicationIdArgument string) (readWriteModel.App
}
return readWriteModel.ApplicationIdContainer(decodedHex[0]), nil
}

if atoi, err := strconv.ParseUint(applicationIdArgument, 10, 8); err == nil {
return readWriteModel.ApplicationIdContainer(atoi), nil
}
Expand Down Expand Up @@ -538,15 +508,7 @@ func applicationIdFromArgument(applicationIdArgument string) (readWriteModel.App
}
}

func c2nl[T CommandAndArgumentsCount](t []T) []CommandAndArgumentsCount {
result := make([]CommandAndArgumentsCount, len(t))
for i, e := range t {
result[i] = e
}
return result
}

func extractBridges(match map[string]string) ([]readWriteModel.BridgeAddress, error) {
func (m TagHandler) extractBridges(match map[string]string) ([]readWriteModel.BridgeAddress, error) {
var bridgeAddresses []readWriteModel.BridgeAddress
if match["bridges"] != "" {
for _, bridge := range strings.Split(match["bridges"], "-") {
Expand All @@ -571,3 +533,11 @@ func extractBridges(match map[string]string) ([]readWriteModel.BridgeAddress, er
}
return bridgeAddresses, nil
}

func c2nl[T CommandAndArgumentsCount](t []T) []CommandAndArgumentsCount {
result := make([]CommandAndArgumentsCount, len(t))
for i, e := range t {
result[i] = e
}
return result
}

0 comments on commit eecde5a

Please sign in to comment.