diff --git a/src/knx/bits.h b/src/knx/bits.h index c5ce526f..fe58f48d 100644 --- a/src/knx/bits.h +++ b/src/knx/bits.h @@ -94,6 +94,14 @@ void printHex(const char* suffix, const uint8_t *data, size_t length, bool newli #define printHex(...) do {} while(0) #endif +#ifdef KNX_ACTIVITYCALLBACK +#define KNX_ACTIVITYCALLBACK_DIR 0x00 +#define KNX_ACTIVITYCALLBACK_DIR_RECV 0x00 +#define KNX_ACTIVITYCALLBACK_DIR_SEND 0x01 +#define KNX_ACTIVITYCALLBACK_IPUNICAST 0x02 +#define KNX_ACTIVITYCALLBACK_NET 0x04 +#endif + const uint8_t* popByte(uint8_t& b, const uint8_t* data); const uint8_t* popWord(uint16_t& w, const uint8_t* data); const uint8_t* popInt(uint32_t& i, const uint8_t* data); diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index b75c1ecc..e2f601e2 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -9,6 +9,9 @@ DataLinkLayer::DataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, Platform& platform) : _deviceObject(devObj), _networkLayerEntity(netLayerEntity), _platform(platform) { +#ifdef KNX_ACTIVITYCALLBACK + _netIndex = netLayerEntity.getEntityIndex(); +#endif } #ifdef USE_CEMI_SERVER diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index 9e4d6884..0270d31f 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -42,5 +42,8 @@ class DataLinkLayer Platform& _platform; #ifdef USE_CEMI_SERVER CemiServer* _cemiServer; -#endif +#endif +#ifdef KNX_ACTIVITYCALLBACK + uint8_t _netIndex = 0; +#endif }; diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index 43a7a595..b18f4d2a 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -30,6 +30,9 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame) if(isSendLimitReached()) return false; bool success = sendBytes(packet.data(), packet.totalLength()); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); +#endif dataConReceived(frame, success); return success; } @@ -51,6 +54,10 @@ void IpDataLinkLayer::loop() || buffer[1] != KNXIP_PROTOCOL_VERSION) return; +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); +#endif + uint16_t code; popWord(code, buffer + 2); switch ((KnxIpServiceType)code) @@ -67,6 +74,9 @@ void IpDataLinkLayer::loop() KnxIpSearchResponse searchResponse(_ipParameters, _deviceObject); auto hpai = searchRequest.hpai(); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); +#endif _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength()); break; } diff --git a/src/knx/network_layer_entity.cpp b/src/knx/network_layer_entity.cpp index 6e51736d..6463d830 100644 --- a/src/knx/network_layer_entity.cpp +++ b/src/knx/network_layer_entity.cpp @@ -23,6 +23,11 @@ DptMedium NetworkLayerEntity::mediumType() const return _dataLinkLayer->mediumType(); } +uint8_t NetworkLayerEntity::getEntityIndex() +{ + return _entityIndex; +} + void NetworkLayerEntity::dataIndication(AckType ack, AddressType addrType, uint16_t destination, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source) { _netLayer.dataIndication(ack, addrType, destination, format, npdu, priority, source, _entityIndex); diff --git a/src/knx/network_layer_entity.h b/src/knx/network_layer_entity.h index e20d6114..82db48cf 100644 --- a/src/knx/network_layer_entity.h +++ b/src/knx/network_layer_entity.h @@ -19,6 +19,7 @@ class NetworkLayerEntity DataLinkLayer& dataLinkLayer(); DptMedium mediumType() const; + uint8_t getEntityIndex(); // from data link layer void dataIndication(AckType ack, AddressType addType, uint16_t destination, FrameFormat format, NPDU& npdu, diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp index 22bbf133..a17b2a4d 100644 --- a/src/knx/tpuart_data_link_layer.cpp +++ b/src/knx/tpuart_data_link_layer.cpp @@ -7,6 +7,7 @@ #include "device_object.h" #include "address_table_object.h" #include "cemi_frame.h" +#include "knx_facade.h" #include #include @@ -546,8 +547,10 @@ TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) { //printHex("=>", buffer, length); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); +#endif CemiFrame frame(buffer, length); - frameReceived(frame); } @@ -653,6 +656,9 @@ bool TpUartDataLinkLayer::sendSingleFrameByte() if (_TxByteCnt >= _sendBufferLength) { _TxByteCnt = 0; +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); +#endif return false; } return true; diff --git a/src/knx_facade.h b/src/knx_facade.h index 7facf61c..c1fb0ca9 100644 --- a/src/knx_facade.h +++ b/src/knx_facade.h @@ -70,6 +70,9 @@ typedef uint8_t* (*SaveCallback)(uint8_t* buffer); typedef void (*IsrFunctionPtr)(); typedef void (*ProgLedOnCallback)(); typedef void (*ProgLedOffCallback)(); +#ifdef KNX_ACTIVITYCALLBACK +typedef void (*ActivityCallback)(uint8_t info); +#endif template class KnxFacade : private SaveRestore { @@ -187,6 +190,21 @@ template class KnxFacade : private SaveRestore _progLedOnCallback = progLedOnCallback; } +#ifdef KNX_ACTIVITYCALLBACK + /// @brief sets the Callback Function indicating sent or received telegrams + /// @param activityCallback + /// @details the info parameter + void setActivityCallback(ActivityCallback activityCallback) + { + _activityCallback = activityCallback; + } + + void Activity(uint8_t info) + { + if(_activityCallback) + _activityCallback(info); + } +#endif int32_t buttonPin() { @@ -414,6 +432,9 @@ template class KnxFacade : private SaveRestore B& _bau; ProgLedOnCallback _progLedOnCallback = 0; ProgLedOffCallback _progLedOffCallback = 0; +#ifdef KNX_ACTIVITYCALLBACK + ActivityCallback _activityCallback = 0; +#endif uint32_t _ledPinActiveOn = KNX_LED_ACTIVE_ON; uint32_t _ledPin = KNX_LED; int32_t _buttonPin = KNX_BUTTON;