This is an automated email from the ASF dual-hosted git repository. cdutz pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit e1560adad7144424707429a85bbb6013de4e2082 Author: Christofer Dutz <[email protected]> AuthorDate: Fri Jan 22 12:00:42 2021 +0100 - Made the Reader detect the case of a property not existing or not having the permission to read. --- plc4go/internal/plc4go/knxnetip/KnxNetIpReader.go | 56 ++++++++++++++++------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/plc4go/internal/plc4go/knxnetip/KnxNetIpReader.go b/plc4go/internal/plc4go/knxnetip/KnxNetIpReader.go index 6040399..b69cc5f 100644 --- a/plc4go/internal/plc4go/knxnetip/KnxNetIpReader.go +++ b/plc4go/internal/plc4go/knxnetip/KnxNetIpReader.go @@ -282,6 +282,11 @@ func (m KnxNetIpReader) disconnectFromDevice(sourceAddress driverModel.KnxAddres return nil } +type readPropertyResult struct { + plcValue apiValues.PlcValue + responseCode apiModel.PlcResponseCode +} + func (m KnxNetIpReader) readDeviceProperty(field KnxNetIpDevicePropertyAddressPlcField, counter uint8) (apiModel.PlcResponseCode, apiValues.PlcValue) { // TODO: We'll add this as time progresses, for now we only support fully qualified addresses if field.IsPatternField() { @@ -317,7 +322,7 @@ func (m KnxNetIpReader) readDeviceProperty(field KnxNetIpDevicePropertyAddressPl false, true, counter, nil, &apci, &extendedApci, nil, data, true, 3, false, false))) - result := make(chan apiValues.PlcValue) + result := make(chan readPropertyResult) err = m.connection.SendRequest( request, // Even if there are multiple messages being exchanged because of the request @@ -375,26 +380,41 @@ func (m KnxNetIpReader) readDeviceProperty(field KnxNetIpDevicePropertyAddressPl _, _ = readBuffer.ReadUint8(8) _, _ = readBuffer.ReadUint8(8) - _ /*count*/, _ = readBuffer.ReadUint8(4) + count, _ := readBuffer.ReadUint8(4) _ /*index*/, _ = readBuffer.ReadUint16(12) - // Read the data payload. - dataLength := dataFrameExt.DataLength - 5 + // If the return is a count of 0, then we can't access this property (Doesn't exist or not allowed to) + // As we don't have a return code for "doesn't exist or doesn't have access to" we'll stick to "not found" + // as this can be understood as "found no property we have access to" + // ("03_03_07 Application Layer v01.06.02 AS" Page 52) + var propResult readPropertyResult + if count == 0 { + propResult = readPropertyResult{ + responseCode: apiModel.PlcResponseCode_NOT_FOUND, + } + } else { + // Read the data payload. + dataLength := dataFrameExt.DataLength - 5 + + // Depending on the object id and property id, parse the remaining data accordingly. + property := driverModel.KnxInterfaceObjectProperty_PID_UNKNOWN + for i := driverModel.KnxInterfaceObjectProperty_PID_UNKNOWN; i < driverModel.KnxInterfaceObjectProperty_PID_SUNBLIND_SENSOR_BASIC_ENABLE_TOGGLE_MODE; i++ { + // If the propertyId matches and this is either a general object or the object id matches, add it to the result + if i.PropertyId() == uint8(propertyId) && (i.ObjectType().Code() == "G" || i.ObjectType().Code() == strconv.Itoa(objectId)) { + property = i + break + } + } - // Depending on the object id and property id, parse the remaining data accordingly. - property := driverModel.KnxInterfaceObjectProperty_PID_UNKNOWN - for i := driverModel.KnxInterfaceObjectProperty_PID_UNKNOWN; i < driverModel.KnxInterfaceObjectProperty_PID_SUNBLIND_SENSOR_BASIC_ENABLE_TOGGLE_MODE; i++ { - // If the propertyId matches and this is either a general object or the object id matches, add it to the result - if i.PropertyId() == uint8(propertyId) && (i.ObjectType().Code() == "G" || i.ObjectType().Code() == strconv.Itoa(objectId)) { - property = i - break + // Parse the payload according to the specified datatype + dataType := property.PropertyDataType() + plcValue := readwrite.ParsePropertyDataType(*readBuffer, dataType, dataLength) + propResult = readPropertyResult{ + plcValue: plcValue, + responseCode: apiModel.PlcResponseCode_OK, } } - // Parse the payload according to the specified datatype - dataType := property.PropertyDataType() - plcValue := readwrite.ParsePropertyDataType(*readBuffer, dataType, dataLength) - // Send back an ACK controlType := driverModel.ControlType_ACK _ = m.connection.Send( @@ -407,14 +427,16 @@ func (m KnxNetIpReader) readDeviceProperty(field KnxNetIpDevicePropertyAddressPl nil, nil, nil, true, driverModel.CEMIPriority_SYSTEM, false, false)))) - result <- plcValue + result <- propResult return nil }, time.Second*5) select { case value := <-result: - return apiModel.PlcResponseCode_OK, value + responseCode := value.responseCode + plcValue := value.plcValue + return responseCode, plcValue /*case <-time.After(time.Second * 5): return apiModel.PlcResponseCode_REMOTE_ERROR, nil*/ }
