diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 436ad7a..6156d5d 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -575,6 +575,29 @@ void ApplicationLayer::functionPropertyStateResponse(AckType ack, Priority prior dataIndividualRequest(ack, hopType, priority, asap, apdu, secCtrl); } +void ApplicationLayer::functionPropertyExtStateResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, + uint16_t objectType, uint8_t objectInstance, uint16_t propertyId, uint8_t* resultData, uint8_t resultLength) +{ + CemiFrame frame(6 + resultLength + 1); + APDU& apdu = frame.apdu(); + apdu.type(FunctionPropertyStateResponse); + uint8_t* data = apdu.data() + 1; + + data[0] = ((uint16_t)objectType) >> 8; + data[1] = ((uint16_t)objectType) & 0xFF; + data[2] = objectInstance >> 4; + data[3] = ((objectInstance&0x0F) << 4) | (propertyId >> 8); + data[4] = (propertyId & 0xFF); + // data[5] must contain the return code + if (resultLength > 0) + memcpy(&data[5], resultData, resultLength); + + if (asap == _connectedTsap) + dataConnectedRequest(asap, priority, apdu, secCtrl); + else + dataIndividualRequest(ack, hopType, priority, asap, apdu, secCtrl); +} + void ApplicationLayer::propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex) { @@ -848,6 +871,24 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior case FunctionPropertyState: _bau.functionPropertyStateIndication(priority, hopType, tsap, secCtrl, data[1], data[2], &data[3], apdu.length() - 4); //TODO: check length break; + case FunctionPropertyExtCommand: + { + ObjectType objectType = (ObjectType)(((data[1] & 0xff) << 8) | (data[2] & 0xff)); + uint8_t objectInstance = ((data[3] & 0xff) << 4) | ((data[4] & 0xff) >> 4); + uint16_t propertyId = ((data[5] & 0xf) << 8) | (data[6] & 0xff); + uint8_t* functionInput = &data[7]; + _bau.functionPropertyExtCommandIndication(priority, hopType, tsap, secCtrl, objectType, objectInstance, propertyId, functionInput, apdu.length() - 8); //TODO: check length + break; + } + case FunctionPropertyExtState: + { + ObjectType objectType = (ObjectType)(((data[1] & 0xff) << 8) | (data[2] & 0xff)); + uint8_t objectInstance = ((data[3] & 0xff) << 4) | ((data[4] & 0xff) >> 4); + uint16_t propertyId = ((data[5] & 0xf) << 8) | (data[6] & 0xff); + uint8_t* functionInput = &data[7]; + _bau.functionPropertyExtStateIndication(priority, hopType, tsap, secCtrl, objectType, objectInstance, propertyId, functionInput, apdu.length() - 8); //TODO: check length + break; + } case PropertyDescriptionRead: _bau.propertyDescriptionReadIndication(priority, hopType, tsap, secCtrl, data[1], data[2], data[3]); break; diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index 6abd6b5..268e15a 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -108,6 +108,8 @@ class ApplicationLayer uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length); void functionPropertyStateResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t *resultData, uint8_t resultLength); + void functionPropertyExtStateResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, + uint16_t objectType, uint8_t objectInstance, uint16_t propertyId, uint8_t* resultData, uint8_t resultLength); void propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex); void propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, diff --git a/src/knx/bau.cpp b/src/knx/bau.cpp index bf90c9e..7865af3 100644 --- a/src/knx/bau.cpp +++ b/src/knx/bau.cpp @@ -114,6 +114,14 @@ void BusAccessUnit::functionPropertyStateIndication(Priority priority, HopCountT { } +void BusAccessUnit::functionPropertyExtCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t* data, uint8_t length) +{ +} + +void BusAccessUnit::functionPropertyExtStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t* data, uint8_t length) +{ +} + void BusAccessUnit::propertyValueReadResponseConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length, bool status) { } diff --git a/src/knx/bau.h b/src/knx/bau.h index 91fd117..9d84b95 100644 --- a/src/knx/bau.h +++ b/src/knx/bau.h @@ -52,6 +52,10 @@ class BusAccessUnit uint8_t propertyId, uint8_t* data, uint8_t length); virtual void functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t* data, uint8_t length); + virtual void functionPropertyExtCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length); + virtual void functionPropertyExtStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length); virtual void propertyValueReadResponseConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length, bool status); virtual void propertyValueReadAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index ff674cc..7795302 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -330,6 +330,32 @@ void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType _appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength); } +void BauSystemB::functionPropertyExtCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length) +{ + uint8_t resultData[kFunctionPropertyResultBufferMaxSize]; + uint8_t resultLength = sizeof(resultData); // tell the callee the maximum size of the buffer + + InterfaceObject* obj = getInterfaceObject(objectType, objectInstance); + if(obj) + obj->command((PropertyID)propertyId, data, length, resultData, resultLength); + + _appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength); +} + +void BauSystemB::functionPropertyExtStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length) +{ + uint8_t resultData[kFunctionPropertyResultBufferMaxSize]; + uint8_t resultLength = sizeof(resultData); // tell the callee the maximum size of the buffer + + InterfaceObject* obj = getInterfaceObject(objectType, objectInstance); + if(obj) + obj->state((PropertyID)propertyId, data, length, resultData, resultLength); + + _appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength); +} + void BauSystemB::individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) { if (_deviceObj.progMode()) diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index f80b7aa..c88327b 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -63,6 +63,10 @@ class BauSystemB : protected BusAccessUnit uint8_t propertyId, uint8_t* data, uint8_t length); void functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t* data, uint8_t length); + void functionPropertyExtCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length); + void functionPropertyExtStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance, + uint8_t propertyId, uint8_t* data, uint8_t length); void individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) override; void individualAddressWriteIndication(HopCountType hopType, const SecurityControl &secCtrl, uint16_t newaddress) override; void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress, diff --git a/src/knx/knx_types.h b/src/knx/knx_types.h index 300d82a..b1c7173 100644 --- a/src/knx/knx_types.h +++ b/src/knx/knx_types.h @@ -155,6 +155,9 @@ enum ApduType // Application Layer Services on Point-to-point Connection-Oriented Communication Mode (mandatory) // Application Layer Services on Point-to-point Connectionless Communication Mode (either optional or mandatory) + FunctionPropertyExtCommand = 0x1D4, + FunctionPropertyExtState = 0x1D5, + FunctionPropertyExtStateResponse = 0x1D6, MemoryRead = 0x200, MemoryResponse = 0x240, MemoryWrite = 0x280,