mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	save work.
This commit is contained in:
		
							parent
							
								
									96884f768e
								
							
						
					
					
						commit
						27433fe5e1
					
				| @ -19,13 +19,19 @@ add_executable(knx-linux | ||||
| 	../../src/knx/bau.h | ||||
| 	../../src/knx/bau07B0.cpp  | ||||
| 	../../src/knx/bau07B0.h | ||||
| 	../../src/knx/bau27B0.cpp | ||||
|         ../../src/knx/bau091A.cpp | ||||
|         ../../src/knx/bau091A.h | ||||
|         ../../src/knx/bau27B0.cpp | ||||
| 	../../src/knx/bau27B0.h | ||||
| 	../../src/knx/bau57B0.cpp | ||||
| 	../../src/knx/bau57B0.h | ||||
| 	../../src/knx/bau_systemB.cpp  | ||||
| 	../../src/knx/bau_systemB.h | ||||
| 	../../src/knx/bits.cpp  | ||||
|         ../../src/knx/bau_systemB_device.cpp | ||||
|         ../../src/knx/bau_systemB_device.h | ||||
|         ../../src/knx/bau_systemB_coupler.cpp | ||||
|         ../../src/knx/bau_systemB_coupler.h | ||||
|         ../../src/knx/bits.cpp | ||||
| 	../../src/knx/bits.h | ||||
| 	../../src/knx/callback_property.h | ||||
| 	../../src/knx/cemi_frame.cpp | ||||
| @ -40,9 +46,9 @@ add_executable(knx-linux | ||||
| 	../../src/knx/data_property.cpp  | ||||
| 	../../src/knx/data_property.h | ||||
| 	../../src/knx/device_object.cpp  | ||||
| 	../../src/knx/device_object.h | ||||
| 	../../src/knx/dpt.cpp | ||||
| 	../../src/knx/dpt.h | ||||
|         ../../src/knx/device_object.h | ||||
|         ../../src/knx/dpt.cpp | ||||
|         ../../src/knx/dpt.h | ||||
| 	../../src/knx/dptconvert.cpp | ||||
| 	../../src/knx/dptconvert.h | ||||
|         ../../src/knx/function_property.h | ||||
|  | ||||
| @ -1,10 +1,7 @@ | ||||
| #include "knx_facade.h" | ||||
| 
 | ||||
| #include "knx/bau57B0.h" | ||||
| #include "knx/bau27B0.h" | ||||
| #include "knx/bau07B0.h" | ||||
| #include "knx/bau091A.h" | ||||
| 
 | ||||
| #include "knx/group_object_table_object.h" | ||||
| #include "knx/bits.h" | ||||
| #include <time.h> | ||||
| #include <stdlib.h> | ||||
| @ -34,59 +31,17 @@ bool isSendHidReportPossible() | ||||
|     return false; | ||||
| } | ||||
| #if MEDIUM_TYPE == 5 | ||||
| KnxFacade<LinuxPlatform, Bau57B0> knx; | ||||
| KnxFacade<LinuxPlatform, Bau091A> knx; | ||||
| #elif MEDIUM_TYPE == 2 | ||||
| KnxFacade<LinuxPlatform, Bau27B0> knx; | ||||
| KnxFacade<LinuxPlatform, Bau2920> knx; | ||||
| #else | ||||
| #error Only MEDIUM_TYPE IP and RF supported | ||||
| #endif | ||||
| 
 | ||||
| long lastsend = 0; | ||||
| 
 | ||||
| #define CURR knx.getGroupObject(1) | ||||
| #define MAX knx.getGroupObject(2) | ||||
| #define MIN knx.getGroupObject(3) | ||||
| #define RESET knx.getGroupObject(4) | ||||
| 
 | ||||
| void measureTemp() | ||||
| { | ||||
|     long now = millis(); | ||||
|     if ((now - lastsend) < 10000) | ||||
|         return; | ||||
| 
 | ||||
|     lastsend = now; | ||||
|     int r = rand(); | ||||
|     double currentValue = (r * 1.0) / (RAND_MAX * 1.0); | ||||
|     currentValue *= 100; | ||||
|     currentValue -= 50; | ||||
|     //    currentValue *= (670433.28 + 273);
 | ||||
|     //    currentValue -= 273;
 | ||||
|     println(currentValue); | ||||
|     CURR.value(currentValue); | ||||
| 
 | ||||
|     double max = MAX.value(); | ||||
|     if (currentValue > max) | ||||
|         MAX.value(currentValue); | ||||
| 
 | ||||
|     if (currentValue < (double)MIN.value()) | ||||
|         MIN.value(currentValue); | ||||
| } | ||||
| 
 | ||||
| void resetCallback(GroupObject& go) | ||||
| { | ||||
|     if (go.value()) | ||||
|     { | ||||
|         MAX.valueNoSend(-273.0); | ||||
|         MIN.valueNoSend(670433.28); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void appLoop() | ||||
| { | ||||
|     if (!knx.configured()) | ||||
|         return; | ||||
|      | ||||
|     measureTemp(); | ||||
| } | ||||
| 
 | ||||
| void setup() | ||||
| @ -99,18 +54,7 @@ void setup() | ||||
| 
 | ||||
|     if (knx.configured()) | ||||
|     { | ||||
|         CURR.dataPointType(Dpt(9, 1)); | ||||
|         MIN.dataPointType(Dpt(9, 1)); | ||||
|         MIN.value(670433.28); | ||||
|         MAX.dataPointType(Dpt(9, 1)); | ||||
|         MAX.valueNoSend(-273.0); | ||||
|         RESET.dataPointType(Dpt(1, 15)); | ||||
|         RESET.callback(resetCallback); | ||||
|         printf("Timeout: %d\n", knx.paramWord(0)); | ||||
|         printf("Zykl. senden: %d\n", knx.paramByte(2)); | ||||
|         printf("Min/Max senden: %d\n", knx.paramByte(3)); | ||||
|         printf("Aenderung senden: %d\n", knx.paramByte(4)); | ||||
|         printf("Abgleich %d\n", knx.paramByte(5)); | ||||
|         printf("configured %d\n", knx.paramByte(5)); | ||||
|     } | ||||
|     else | ||||
|         println("not configured"); | ||||
|  | ||||
| @ -10,8 +10,7 @@ | ||||
| 
 | ||||
| const SecurityControl ApplicationLayer::noSecurity {.toolAccess=false, .dataSecurity=DataSecurity::none}; | ||||
| 
 | ||||
| ApplicationLayer::ApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau): | ||||
|     _assocTable(assocTable),  _bau(bau) | ||||
| ApplicationLayer::ApplicationLayer(BusAccessUnit& bau) : _bau(bau) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| @ -20,6 +19,11 @@ void ApplicationLayer::transportLayer(TransportLayer& layer) | ||||
|     _transportLayer = &layer; | ||||
| } | ||||
| 
 | ||||
| void ApplicationLayer::associationTableObject(AssociationTableObject& assocTable) | ||||
| { | ||||
|     _assocTable = &assocTable; | ||||
| } | ||||
| 
 | ||||
| #pragma region TL Callbacks | ||||
| 
 | ||||
| void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) | ||||
| @ -29,6 +33,9 @@ void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priori | ||||
| 
 | ||||
| void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl) | ||||
| { | ||||
|     if (_assocTable == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     uint8_t len = apdu.length(); | ||||
|     uint8_t dataArray[len]; | ||||
|     uint8_t* data = dataArray; | ||||
| @ -45,8 +52,8 @@ void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priori | ||||
|     } | ||||
| 
 | ||||
|     uint16_t startIdx = 0; | ||||
|     int32_t asap = _assocTable.nextAsap(tsap, startIdx); | ||||
|     for (; asap != -1; asap = _assocTable.nextAsap(tsap, startIdx)) | ||||
|     int32_t asap = _assocTable->nextAsap(tsap, startIdx); | ||||
|     for (; asap != -1; asap = _assocTable->nextAsap(tsap, startIdx)) | ||||
|     { | ||||
|         switch (apdu.type()) | ||||
|         { | ||||
| @ -365,12 +372,15 @@ void ApplicationLayer::dataConnectedConfirm(uint16_t tsap, const SecurityControl | ||||
| #pragma endregion | ||||
| void ApplicationLayer::groupValueReadRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl& secCtrl) | ||||
| { | ||||
|     if (_assocTable == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     _savedAsapReadRequest = asap; | ||||
|     CemiFrame frame(1); | ||||
|     APDU& apdu = frame.apdu(); | ||||
|     apdu.type(GroupValueRead); | ||||
|      | ||||
|     int32_t value = _assocTable.translateAsap(asap); | ||||
|     int32_t value = _assocTable->translateAsap(asap); | ||||
|     if (value < 0) | ||||
|         return; // there is no tsap in association table for this asap
 | ||||
|      | ||||
| @ -928,6 +938,9 @@ void ApplicationLayer::propertyExtDataSend(ApduType type, AckType ack, Priority | ||||
| void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|     uint8_t* data,  uint8_t& dataLength) | ||||
| { | ||||
|     if (_assocTable == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     CemiFrame frame(dataLength + 1); | ||||
|     APDU& apdu = frame.apdu(); | ||||
|     apdu.type(type); | ||||
| @ -943,7 +956,7 @@ void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap, | ||||
|         memcpy(apdudata + 1, data, dataLength); | ||||
|     } | ||||
|     // no need to check if there is a tsap. This is a response, so the read got trough
 | ||||
|     uint16_t tsap = (uint16_t)_assocTable.translateAsap(asap); | ||||
|     uint16_t tsap = (uint16_t)_assocTable->translateAsap(asap); | ||||
|     dataGroupRequest(ack, hopType, priority, tsap, apdu, secCtrl); | ||||
|     dataGroupIndication(hopType, priority, tsap, apdu, secCtrl); | ||||
| } | ||||
|  | ||||
| @ -22,12 +22,14 @@ class ApplicationLayer | ||||
|      * @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses. | ||||
|      * @param bau methods are called here depending of the content of the APDU | ||||
|      */ | ||||
|     ApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau); | ||||
|     ApplicationLayer(BusAccessUnit& bau); | ||||
|     /**
 | ||||
|      * Assigns the TransportLayer to which encoded APDU are submitted to. | ||||
|      */ | ||||
|     void transportLayer(TransportLayer& layer); | ||||
| 
 | ||||
|     void associationTableObject(AssociationTableObject& assocTable); | ||||
| 
 | ||||
|     // from transport layer
 | ||||
|     // Note: without data secure feature, the application layer is just used with SecurtyControl.dataSecurity = none
 | ||||
|     // hooks that can be implemented by derived class (e.g. SecureApplicationLayer)
 | ||||
| @ -204,7 +206,7 @@ class ApplicationLayer | ||||
|     uint16_t _savedAsapReadRequest; | ||||
|     uint16_t _savedAsapWriteRequest; | ||||
|     uint16_t _savedAsapResponse; | ||||
|     AssociationTableObject& _assocTable; | ||||
|     AssociationTableObject* _assocTable = nullptr; | ||||
|     BusAccessUnit& _bau; | ||||
| 
 | ||||
|     int32_t _connectedTsap = -1; | ||||
|  | ||||
| @ -8,12 +8,14 @@ | ||||
| using namespace std; | ||||
| 
 | ||||
| Bau07B0::Bau07B0(Platform& platform) | ||||
|     : BauSystemB(platform), | ||||
|       _dlLayer(_deviceObj, _addrTable, _netLayer, _platform) | ||||
|     : BauSystemBDevice(platform), | ||||
|       _dlLayer(_deviceObj, _netLayer, _platform) | ||||
| #ifdef USE_CEMI_SERVER | ||||
|     , _cemiServer(*this) | ||||
| #endif            | ||||
| { | ||||
|     _dlLayer.groupAddressTable(_addrTable); | ||||
| 
 | ||||
|     _netLayer.dataLinkLayer(_dlLayer); | ||||
| #ifdef USE_CEMI_SERVER | ||||
|     _cemiServer.dataLinkLayer(_dlLayer); | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "config.h" | ||||
| #include "bau_systemB.h" | ||||
| #include "bau_systemB_device.h" | ||||
| #include "tpuart_data_link_layer.h" | ||||
| #include "cemi_server.h" | ||||
| #include "cemi_server_object.h" | ||||
| 
 | ||||
| #ifdef USE_TP | ||||
| 
 | ||||
| class Bau07B0 : public BauSystemB | ||||
| class Bau07B0 : public BauSystemBDevice | ||||
| { | ||||
|   public: | ||||
|     Bau07B0(Platform& platform); | ||||
| @ -26,4 +26,4 @@ class Bau07B0 : public BauSystemB | ||||
|     CemiServerObject _cemiServerObject; | ||||
| #endif                                   | ||||
| }; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										121
									
								
								src/knx/bau091A.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								src/knx/bau091A.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | ||||
| #include "config.h" | ||||
| #include "bau091A.h" | ||||
| #include "bits.h" | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #ifdef USE_IP | ||||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| Bau091A::Bau091A(Platform& platform) | ||||
|     : BauSystemBCoupler(platform), | ||||
|       _ipParameters(_deviceObj, platform), | ||||
|       _dlLayerPrimary(_deviceObj, _ipParameters, _netLayer, _platform), | ||||
|       _dlLayerSecondary(_deviceObj, _netLayer, platform) | ||||
| #ifdef USE_CEMI_SERVER | ||||
|       , | ||||
|       _cemiServer(*this) | ||||
| #endif | ||||
| { | ||||
|     _netLayer.dataLinkLayer(_dlLayerSecondary); | ||||
| #ifdef USE_CEMI_SERVER | ||||
|     _cemiServer.dataLinkLayer(_dlLayer); | ||||
|     _dlLayer.cemiServer(_cemiServer); | ||||
|     _memory.addSaveRestore(&_cemiServerObject); | ||||
| #endif | ||||
|     _memory.addSaveRestore(&_ipParameters); | ||||
| 
 | ||||
|     // Set Mask Version in Device Object depending on the BAU
 | ||||
|     _deviceObj.maskVersion(0x091A); | ||||
| 
 | ||||
|     // Set which interface objects are available in the device object
 | ||||
|     // This differs from BAU to BAU with different medium types.
 | ||||
|     // See PID_IO_LIST
 | ||||
|     Property* prop = _deviceObj.property(PID_IO_LIST); | ||||
|     prop->write(1, (uint16_t) OT_DEVICE); | ||||
|     prop->write(2, (uint16_t) OT_ADDR_TABLE); | ||||
|     prop->write(3, (uint16_t) OT_ASSOC_TABLE); | ||||
|     prop->write(4, (uint16_t) OT_GRP_OBJ_TABLE); | ||||
|     prop->write(5, (uint16_t) OT_APPLICATION_PROG); | ||||
|     prop->write(6, (uint16_t) OT_IP_PARAMETER); | ||||
| #if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER) | ||||
|     prop->write(7, (uint16_t) OT_SECURITY); | ||||
|     prop->write(8, (uint16_t) OT_CEMI_SERVER); | ||||
| #elif defined(USE_DATASECURE) | ||||
|     prop->write(7, (uint16_t) OT_SECURITY); | ||||
| #elif defined(USE_CEMI_SERVER) | ||||
|     prop->write(7, (uint16_t) OT_CEMI_SERVER); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| InterfaceObject* Bau091A::getInterfaceObject(uint8_t idx) | ||||
| { | ||||
|     switch (idx) | ||||
|     { | ||||
|         case 0: | ||||
|             return &_deviceObj; | ||||
|         case 4: | ||||
|             return &_appProgram; | ||||
|         case 5: // would be app_program 2
 | ||||
|             return nullptr; | ||||
|         case 6: | ||||
|             return &_ipParameters; | ||||
| #if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER) | ||||
|         case 7: | ||||
|             return &_secIfObj; | ||||
|         case 8: | ||||
|             return &_cemiServerObject; | ||||
| #elif defined(USE_CEMI_SERVER) | ||||
|         case 7: | ||||
|             return &_cemiServerObject; | ||||
| #elif defined(USE_DATASECURE) | ||||
|         case 7: | ||||
|             return &_secIfObj; | ||||
| #endif | ||||
|         default: | ||||
|             return nullptr; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| InterfaceObject* Bau091A::getInterfaceObject(ObjectType objectType, uint8_t objectInstance) | ||||
| { | ||||
|     // We do not use it right now. 
 | ||||
|     // Required for coupler mode as there are multiple router objects for example
 | ||||
|     (void) objectInstance; | ||||
| 
 | ||||
|     switch (objectType) | ||||
|     { | ||||
|         case OT_DEVICE: | ||||
|             return &_deviceObj; | ||||
|         case OT_APPLICATION_PROG: | ||||
|             return &_appProgram; | ||||
|         case OT_IP_PARAMETER: | ||||
|             return &_ipParameters; | ||||
| #ifdef USE_DATASECURE | ||||
|         case OT_SECURITY: | ||||
|             return &_secIfObj; | ||||
| #endif | ||||
| #ifdef USE_CEMI_SERVER | ||||
|         case OT_CEMI_SERVER: | ||||
|             return &_cemiServerObject; | ||||
| #endif | ||||
|         default: | ||||
|             return nullptr; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Bau091A::doMasterReset(EraseCode eraseCode, uint8_t channel) | ||||
| { | ||||
|     // Common SystemB objects
 | ||||
|     BauSystemB::doMasterReset(eraseCode, channel); | ||||
| 
 | ||||
|     _ipParameters.masterReset(eraseCode, channel); | ||||
| } | ||||
| 
 | ||||
| DataLinkLayer& Bau091A::dataLinkLayer() | ||||
| { | ||||
|     return _dlLayerSecondary; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										31
									
								
								src/knx/bau091A.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/knx/bau091A.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "config.h" | ||||
| #ifdef USE_IP | ||||
| #include "bau_systemB_coupler.h" | ||||
| #include "ip_parameter_object.h" | ||||
| #include "ip_data_link_layer.h" | ||||
| #include "tpuart_data_link_layer.h" | ||||
| #include "cemi_server_object.h" | ||||
| 
 | ||||
| class Bau091A : public BauSystemBCoupler | ||||
| { | ||||
|   public: | ||||
|     Bau091A(Platform& platform); | ||||
| 
 | ||||
|   protected: | ||||
|     InterfaceObject* getInterfaceObject(uint8_t idx); | ||||
|     InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance); | ||||
|     DataLinkLayer& dataLinkLayer(); | ||||
| 
 | ||||
|     virtual void doMasterReset(EraseCode eraseCode, uint8_t channel) override; | ||||
|   private: | ||||
|     IpParameterObject _ipParameters; | ||||
|     IpDataLinkLayer _dlLayerPrimary; | ||||
|     TpUartDataLinkLayer _dlLayerSecondary; | ||||
| #ifdef USE_CEMI_SERVER | ||||
|     CemiServer _cemiServer; | ||||
|     CemiServerObject _cemiServerObject; | ||||
| #endif | ||||
| }; | ||||
| #endif | ||||
| @ -7,8 +7,8 @@ | ||||
| using namespace std; | ||||
| 
 | ||||
| Bau27B0::Bau27B0(Platform& platform) | ||||
|     : BauSystemB(platform), | ||||
|       _dlLayer(_deviceObj, _rfMediumObj, _addrTable, _netLayer, _platform) | ||||
|     : BauSystemBDevice(platform), | ||||
|       _dlLayer(_deviceObj, _rfMediumObj, _netLayer, _platform) | ||||
| #ifdef USE_CEMI_SERVER | ||||
|     , _cemiServer(*this) | ||||
| #endif       | ||||
|  | ||||
| @ -2,14 +2,14 @@ | ||||
| 
 | ||||
| #include "config.h" | ||||
| #ifdef USE_RF | ||||
| #include "bau_systemB.h" | ||||
| #include "bau_systemB_device.h" | ||||
| #include "rf_medium_object.h" | ||||
| #include "rf_physical_layer.h" | ||||
| #include "rf_data_link_layer.h" | ||||
| #include "cemi_server.h" | ||||
| #include "cemi_server_object.h" | ||||
| 
 | ||||
| class Bau27B0 : public BauSystemB | ||||
| class Bau27B0 : public BauSystemBDevice | ||||
| { | ||||
|   public: | ||||
|     Bau27B0(Platform& platform); | ||||
|  | ||||
| @ -9,9 +9,9 @@ | ||||
| using namespace std; | ||||
| 
 | ||||
| Bau57B0::Bau57B0(Platform& platform) | ||||
|     : BauSystemB(platform), | ||||
|     : BauSystemBDevice(platform), | ||||
|       _ipParameters(_deviceObj, platform), | ||||
|       _dlLayer(_deviceObj, _addrTable, _ipParameters, _netLayer, _platform) | ||||
|       _dlLayer(_deviceObj, _ipParameters, _netLayer, _platform) | ||||
| #ifdef USE_CEMI_SERVER | ||||
|       , | ||||
|       _cemiServer(*this) | ||||
|  | ||||
| @ -2,12 +2,12 @@ | ||||
| 
 | ||||
| #include "config.h" | ||||
| #ifdef USE_IP | ||||
| #include "bau_systemB.h" | ||||
| #include "bau_systemB_device.h" | ||||
| #include "ip_parameter_object.h" | ||||
| #include "ip_data_link_layer.h" | ||||
| #include "cemi_server_object.h" | ||||
| 
 | ||||
| class Bau57B0 : public BauSystemB | ||||
| class Bau57B0 : public BauSystemBDevice | ||||
| { | ||||
|   public: | ||||
|     Bau57B0(Platform& platform); | ||||
|  | ||||
| @ -14,41 +14,17 @@ enum NmReadSerialNumberType | ||||
| static constexpr auto kFunctionPropertyResultBufferMaxSize = 64; | ||||
| static constexpr auto kRestartProcessTime = 3; | ||||
| 
 | ||||
| BauSystemB::BauSystemB(Platform& platform): _memory(platform, _deviceObj), _addrTable(_memory), | ||||
|     _assocTable(_memory), _groupObjTable(_memory), _appProgram(_memory), | ||||
|     _platform(platform), | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer(_deviceObj, _secIfObj, _assocTable, _addrTable, *this), | ||||
| #else | ||||
|     _appLayer(_assocTable, *this), | ||||
| #endif | ||||
|     _transLayer(_appLayer, _addrTable), _netLayer(_transLayer) | ||||
| BauSystemB::BauSystemB(Platform& platform): _memory(platform, _deviceObj), | ||||
|      _appProgram(_memory), | ||||
|     _platform(platform) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     _secIfObj.secureApplicationLayer(_appLayer); | ||||
| #endif | ||||
|     _appLayer.transportLayer(_transLayer); | ||||
|     _transLayer.networkLayer(_netLayer); | ||||
|     _memory.addSaveRestore(&_deviceObj); | ||||
|     _memory.addSaveRestore(&_appProgram); | ||||
|     _memory.addSaveRestore(&_addrTable); | ||||
|     _memory.addSaveRestore(&_assocTable); | ||||
|     _memory.addSaveRestore(&_groupObjTable); | ||||
| #ifdef USE_DATASECURE | ||||
|     _memory.addSaveRestore(&_secIfObj); | ||||
| #endif | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::loop() | ||||
| { | ||||
|     dataLinkLayer().loop(); | ||||
|     _transLayer.loop(); | ||||
|     sendNextGroupTelegram(); | ||||
|     nextRestartState(); | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer.loop(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool BauSystemB::enabled() | ||||
| @ -61,74 +37,6 @@ void BauSystemB::enabled(bool value) | ||||
|     dataLinkLayer().enabled(value); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::sendNextGroupTelegram() | ||||
| { | ||||
|     if(!configured()) | ||||
|         return; | ||||
|      | ||||
|     static uint16_t startIdx = 1; | ||||
| 
 | ||||
|     GroupObjectTableObject& table = _groupObjTable; | ||||
|     uint16_t objCount = table.entryCount(); | ||||
| 
 | ||||
|     for (uint16_t asap = startIdx; asap <= objCount; asap++) | ||||
|     { | ||||
|         GroupObject& go = table.get(asap); | ||||
| 
 | ||||
|         ComFlag flag = go.commFlag(); | ||||
|         if (flag != ReadRequest && flag != WriteRequest) | ||||
|             continue; | ||||
| 
 | ||||
|         if (!go.communicationEnable()) | ||||
|             continue; | ||||
| 
 | ||||
|         SecurityControl goSecurity; | ||||
|         goSecurity.toolAccess = false; // Secured group communication never uses the toolkey. ETS knows all keys, also the group keys.
 | ||||
| 
 | ||||
| #ifdef USE_DATASECURE | ||||
|         // Get security flags from Security Interface Object for this group object
 | ||||
|         goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| #else | ||||
|         goSecurity.dataSecurity = DataSecurity::none; | ||||
| #endif | ||||
| 
 | ||||
|         if (flag == WriteRequest && go.transmitEnable()) | ||||
|         { | ||||
|             uint8_t* data = go.valueRef(); | ||||
|             _appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data, | ||||
|                 go.sizeInTelegram()); | ||||
|         } | ||||
|         else if (flag == ReadRequest) | ||||
|         { | ||||
|             _appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity); | ||||
|         } | ||||
| 
 | ||||
|         go.commFlag(Transmitting); | ||||
| 
 | ||||
|         startIdx = asap + 1; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     startIdx = 1; | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::updateGroupObject(GroupObject & go, uint8_t * data, uint8_t length) | ||||
| { | ||||
|     uint8_t* goData = go.valueRef(); | ||||
|     if (length != go.valueSize()) | ||||
|     { | ||||
|         go.commFlag(Error); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     memcpy(goData, data, length); | ||||
| 
 | ||||
|     go.commFlag(Updated); | ||||
|     GroupObjectUpdatedHandler handler = go.callback(); | ||||
|     if (handler) | ||||
|         handler(go); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::readMemory() | ||||
| { | ||||
|     _memory.readMemory(); | ||||
| @ -139,21 +47,16 @@ void BauSystemB::writeMemory() | ||||
|     _memory.writeMemory(); | ||||
| } | ||||
| 
 | ||||
| DeviceObject& BauSystemB::deviceObject() | ||||
| { | ||||
|     return _deviceObj; | ||||
| } | ||||
| 
 | ||||
| GroupObjectTableObject& BauSystemB::groupObjectTable() | ||||
| { | ||||
|     return _groupObjTable; | ||||
| } | ||||
| 
 | ||||
| ApplicationProgramObject& BauSystemB::parameters() | ||||
| { | ||||
|     return _appProgram; | ||||
| } | ||||
| 
 | ||||
| DeviceObject& BauSystemB::deviceObject() | ||||
| { | ||||
|     return _deviceObj; | ||||
| } | ||||
| 
 | ||||
| bool BauSystemB::configured() | ||||
| { | ||||
|     // _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
 | ||||
| @ -161,10 +64,7 @@ bool BauSystemB::configured() | ||||
|     if (!_configured) | ||||
|         return false; | ||||
|      | ||||
|     _configured = _groupObjTable.loadState() == LS_LOADED | ||||
|         && _addrTable.loadState() == LS_LOADED | ||||
|         && _assocTable.loadState() == LS_LOADED | ||||
|         && _appProgram.loadState() == LS_LOADED; | ||||
|     _configured = _appProgram.loadState() == LS_LOADED; | ||||
|      | ||||
|     return _configured; | ||||
| } | ||||
| @ -233,7 +133,7 @@ void BauSystemB::deviceDescriptorReadIndication(Priority priority, HopCountType | ||||
|      | ||||
|     uint8_t data[2]; | ||||
|     pushWord(_deviceObj.maskVersion(), data); | ||||
|     _appLayer.deviceDescriptorReadResponse(AckRequested, priority, hopType, asap, secCtrl, descriptorType, data); | ||||
|     applicationLayer().deviceDescriptorReadResponse(AckRequested, priority, hopType, asap, secCtrl, descriptorType, data); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, | ||||
| @ -248,7 +148,7 @@ void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, | ||||
| void BauSystemB::memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, | ||||
|     uint16_t memoryAddress) | ||||
| { | ||||
|     _appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress, | ||||
|     applicationLayer().memoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress, | ||||
|         _memory.toAbsolute(memoryAddress)); | ||||
| } | ||||
| 
 | ||||
| @ -256,27 +156,17 @@ void BauSystemB::memoryExtWriteIndication(Priority priority, HopCountType hopTyp | ||||
| { | ||||
|     _memory.writeMemory(memoryAddress, number, data); | ||||
| 
 | ||||
|     _appLayer.memoryExtWriteResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress)); | ||||
|     applicationLayer().memoryExtWriteResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress)); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::memoryExtReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint32_t memoryAddress) | ||||
| { | ||||
|     _appLayer.memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress)); | ||||
|     applicationLayer().memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress)); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::doMasterReset(EraseCode eraseCode, uint8_t channel) | ||||
| { | ||||
|     _addrTable.masterReset(eraseCode, channel); | ||||
|     _assocTable.masterReset(eraseCode, channel); | ||||
|     _groupObjTable.masterReset(eraseCode, channel); | ||||
|     _appProgram.masterReset(eraseCode, channel); | ||||
| #ifdef USE_DATASECURE | ||||
|     // If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
 | ||||
|     // and disable security mode.
 | ||||
|     // FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
 | ||||
|     // Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
 | ||||
|     _secIfObj.masterReset(eraseCode, channel); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, RestartType restartType, EraseCode eraseCode, uint8_t channel) | ||||
| @ -290,7 +180,7 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp | ||||
|         uint8_t errorCode = checkmasterResetValidity(eraseCode, channel); | ||||
|         // We send the restart response now before actually applying the reset values
 | ||||
|         // Processing time is kRestartProcessTime (example 3 seconds) that we require for the applying the master reset with restart
 | ||||
|         _appLayer.restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0); | ||||
|         applicationLayer().restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0); | ||||
|         doMasterReset(eraseCode, channel); | ||||
|     } | ||||
|     else | ||||
| @ -307,12 +197,12 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp | ||||
| 
 | ||||
| void BauSystemB::authorizeIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint32_t key) | ||||
| { | ||||
|     _appLayer.authorizeResponse(AckRequested, priority, hopType, asap, secCtrl, 0); | ||||
|     applicationLayer().authorizeResponse(AckRequested, priority, hopType, asap, secCtrl, 0); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint32_t memoryAddress) | ||||
| { | ||||
|     _appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress, | ||||
|     applicationLayer().userMemoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress, | ||||
|         _memory.toAbsolute(memoryAddress)); | ||||
| } | ||||
| 
 | ||||
| @ -336,7 +226,7 @@ void BauSystemB::propertyDescriptionReadIndication(Priority priority, HopCountTy | ||||
|     if (obj) | ||||
|         obj->readPropertyDescription(pid, propertyIndex, writeEnable, type, numberOfElements, access); | ||||
| 
 | ||||
|     _appLayer.propertyDescriptionReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, pid, propertyIndex, | ||||
|     applicationLayer().propertyDescriptionReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, pid, propertyIndex, | ||||
|         writeEnable, type, numberOfElements, access); | ||||
| } | ||||
| 
 | ||||
| @ -362,7 +252,7 @@ void BauSystemB::propertyValueExtWriteIndication(Priority priority, HopCountType | ||||
| 
 | ||||
|     if (confirmed) | ||||
|     { | ||||
|         _appLayer.propertyValueExtWriteConResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, numberOfElements, startIndex, returnCode); | ||||
|         applicationLayer().propertyValueExtWriteConResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, numberOfElements, startIndex, returnCode); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -390,7 +280,7 @@ void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hop | ||||
|     if (elementCount == 0) | ||||
|         size = 0; | ||||
|      | ||||
|     _appLayer.propertyValueReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, elementCount, | ||||
|     applicationLayer().propertyValueReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, elementCount, | ||||
|                                         startIndex, data, size); | ||||
| } | ||||
| 
 | ||||
| @ -418,7 +308,7 @@ void BauSystemB::propertyValueExtReadIndication(Priority priority, HopCountType | ||||
|     if (elementCount == 0) | ||||
|         size = 0; | ||||
| 
 | ||||
|     _appLayer.propertyValueExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, elementCount, | ||||
|     applicationLayer().propertyValueExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, elementCount, | ||||
|                                            startIndex, data, size); | ||||
| } | ||||
| 
 | ||||
| @ -441,7 +331,7 @@ void BauSystemB::functionPropertyCommandIndication(Priority priority, HopCountTy | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     _appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength); | ||||
|     applicationLayer().functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, | ||||
| @ -463,7 +353,7 @@ void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     _appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength); | ||||
|     applicationLayer().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, | ||||
| @ -519,7 +409,7 @@ void BauSystemB::functionPropertyExtCommandIndication(Priority priority, HopCoun | ||||
|         resultData[0] = ReturnCodes::GenericError; | ||||
|     } | ||||
| 
 | ||||
|     _appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength); | ||||
|     applicationLayer().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, | ||||
| @ -566,13 +456,13 @@ void BauSystemB::functionPropertyExtStateIndication(Priority priority, HopCountT | ||||
|         resultData[0] = ReturnCodes::GenericError; | ||||
|     } | ||||
| 
 | ||||
|     _appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength); | ||||
|     applicationLayer().functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) | ||||
| { | ||||
|     if (_deviceObj.progMode()) | ||||
|         _appLayer.individualAddressReadResponse(AckRequested, hopType, secCtrl); | ||||
|         applicationLayer().individualAddressReadResponse(AckRequested, hopType, secCtrl); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::individualAddressWriteIndication(HopCountType hopType, const SecurityControl &secCtrl, uint16_t newaddress) | ||||
| @ -598,85 +488,10 @@ void BauSystemB::individualAddressSerialNumberReadIndication(Priority priority, | ||||
|     if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6)) | ||||
|     { | ||||
|         uint8_t emptyDomainAddress[6] = {0x00}; | ||||
|         _appLayer.IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber); | ||||
|         applicationLayer().IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
|     if (status) | ||||
|         go.commFlag(Ok); | ||||
|     else | ||||
|         go.commFlag(Error); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
|     if (status) | ||||
|         go.commFlag(Ok); | ||||
|     else | ||||
|         go.commFlag(Error); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     DataSecurity requiredGoSecurity; | ||||
| 
 | ||||
|     // Get security flags from Security Interface Object for this group object
 | ||||
|     requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| 
 | ||||
|     if (secCtrl.dataSecurity != requiredGoSecurity) | ||||
|     { | ||||
|         println("GroupValueRead: access denied due to wrong security flags"); | ||||
|         return; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.readEnable()) | ||||
|         return; | ||||
|      | ||||
|     uint8_t* data = go.valueRef(); | ||||
|     _appLayer.groupValueReadResponse(AckRequested, asap, priority, hopType, secCtrl, data, go.sizeInTelegram()); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* data, | ||||
|     uint8_t dataLength) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.responseUpdateEnable()) | ||||
|         return; | ||||
| 
 | ||||
|     updateGroupObject(go, data, dataLength); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     DataSecurity requiredGoSecurity; | ||||
| 
 | ||||
|     // Get security flags from Security Interface Object for this group object
 | ||||
|     requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| 
 | ||||
|     if (secCtrl.dataSecurity != requiredGoSecurity) | ||||
|     { | ||||
|         println("GroupValueWrite: access denied due to wrong security flags"); | ||||
|         return; | ||||
|     } | ||||
| #endif | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.writeEnable()) | ||||
|         return; | ||||
| 
 | ||||
|     updateGroupObject(go, data, dataLength); | ||||
| } | ||||
| 
 | ||||
| void BauSystemB::addSaveRestore(SaveRestore* obj) | ||||
| { | ||||
|     _memory.addSaveRestore(obj); | ||||
| @ -684,12 +499,12 @@ void BauSystemB::addSaveRestore(SaveRestore* obj) | ||||
| 
 | ||||
| bool BauSystemB::restartRequest(uint16_t asap, const SecurityControl secCtrl) | ||||
| { | ||||
|     if (_appLayer.isConnected()) | ||||
|     if (applicationLayer().isConnected()) | ||||
|         return false; | ||||
|     _restartState = Connecting; // order important, has to be set BEFORE connectRequest
 | ||||
|     _restartSecurity = secCtrl; | ||||
|     _appLayer.connectRequest(asap, SystemPriority); | ||||
|     _appLayer.deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, secCtrl, 0); | ||||
|     applicationLayer().connectRequest(asap, SystemPriority); | ||||
|     applicationLayer().deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, secCtrl, 0); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| @ -721,7 +536,7 @@ void BauSystemB::nextRestartState() | ||||
|             /* connection confirmed, we send restartRequest, but we wait a moment (sending ACK etc)... */ | ||||
|             if (millis() - _restartDelay > 30) | ||||
|             { | ||||
|                 _appLayer.restartRequest(AckRequested, SystemPriority, NetworkLayerParameter, _restartSecurity); | ||||
|                 applicationLayer().restartRequest(AckRequested, SystemPriority, NetworkLayerParameter, _restartSecurity); | ||||
|                 _restartState = Restarted; | ||||
|                 _restartDelay = millis(); | ||||
|             } | ||||
| @ -730,7 +545,7 @@ void BauSystemB::nextRestartState() | ||||
|             /* restart is finished, we send a discommect */ | ||||
|             if (millis() - _restartDelay > 30) | ||||
|             { | ||||
|                 _appLayer.disconnectRequest(SystemPriority); | ||||
|                 applicationLayer().disconnectRequest(SystemPriority); | ||||
|                 _restartState = Idle; | ||||
|             } | ||||
|         default: | ||||
| @ -753,7 +568,7 @@ void BauSystemB::systemNetworkParameterReadIndication(Priority priority, HopCoun | ||||
|             if (_deviceObj.progMode() && (objectType == OT_DEVICE) && (propertyId == PID_SERIAL_NUMBER)) | ||||
|             { | ||||
|                 // Send reply. testResult data is KNX serial number
 | ||||
|                 _appLayer.systemNetworkParameterReadResponse(priority, hopType, secCtrl, objectType, propertyId, | ||||
|                 applicationLayer().systemNetworkParameterReadResponse(priority, hopType, secCtrl, objectType, propertyId, | ||||
|                                                              testInfo, testInfoLength, (uint8_t*)_deviceObj.propertyData(PID_SERIAL_NUMBER), 6); | ||||
|             } | ||||
|         break; | ||||
|  | ||||
| @ -2,10 +2,6 @@ | ||||
| 
 | ||||
| #include "config.h" | ||||
| #include "bau.h" | ||||
| #include "device_object.h" | ||||
| #include "address_table_object.h" | ||||
| #include "association_table_object.h" | ||||
| #include "group_object_table_object.h" | ||||
| #include "security_interface_object.h" | ||||
| #include "application_program_object.h" | ||||
| #include "application_layer.h" | ||||
| @ -21,9 +17,8 @@ class BauSystemB : protected BusAccessUnit | ||||
|   public: | ||||
|     BauSystemB(Platform& platform); | ||||
|     virtual void loop(); | ||||
|     DeviceObject& deviceObject(); | ||||
|     GroupObjectTableObject& groupObjectTable(); | ||||
|     ApplicationProgramObject& parameters(); | ||||
|     DeviceObject& deviceObject(); | ||||
|     Memory& memory(); | ||||
|     bool configured(); | ||||
|     bool enabled(); | ||||
| @ -43,6 +38,8 @@ class BauSystemB : protected BusAccessUnit | ||||
| 
 | ||||
|   protected: | ||||
|     virtual DataLinkLayer& dataLinkLayer() = 0; | ||||
|     virtual ApplicationLayer& applicationLayer() = 0; | ||||
| 
 | ||||
|     void memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, | ||||
|                                uint16_t memoryAddress, uint8_t* data) override; | ||||
|     void memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, | ||||
| @ -80,14 +77,6 @@ class BauSystemB : protected BusAccessUnit | ||||
|     void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress, | ||||
|                                                       uint8_t* knxSerialNumber) override; | ||||
|     void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) override; | ||||
|     void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                      uint8_t* data, uint8_t dataLength, bool status) override; | ||||
|     void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override; | ||||
|     void groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) override; | ||||
|     void groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                        uint8_t* data, uint8_t dataLength) override; | ||||
|     void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                    uint8_t* data, uint8_t dataLength) override; | ||||
|     void systemNetworkParameterReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t objectType, | ||||
|                                               uint16_t propertyId, uint8_t* testInfo, uint16_t testinfoLength) override; | ||||
|     void systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t objectType, | ||||
| @ -96,8 +85,6 @@ class BauSystemB : protected BusAccessUnit | ||||
| 
 | ||||
|     virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0; | ||||
|     virtual InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance) = 0; | ||||
|     void sendNextGroupTelegram(); | ||||
|     void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length); | ||||
|     void nextRestartState(); | ||||
| 
 | ||||
|     virtual void doMasterReset(EraseCode eraseCode, uint8_t channel); | ||||
| @ -110,21 +97,10 @@ class BauSystemB : protected BusAccessUnit | ||||
|         Restarted | ||||
|     }; | ||||
| 
 | ||||
|     DeviceObject _deviceObj; | ||||
|     Memory _memory; | ||||
|     AddressTableObject _addrTable; | ||||
|     AssociationTableObject _assocTable; | ||||
|     GroupObjectTableObject _groupObjTable; | ||||
|     DeviceObject _deviceObj; | ||||
|     ApplicationProgramObject _appProgram; | ||||
|     Platform& _platform; | ||||
| #ifdef USE_DATASECURE | ||||
|     SecureApplicationLayer _appLayer; | ||||
|     SecurityInterfaceObject _secIfObj; | ||||
| #else | ||||
|     ApplicationLayer _appLayer; | ||||
| #endif | ||||
|     TransportLayer _transLayer; | ||||
|     NetworkLayer _netLayer; | ||||
|     bool _configured = true; | ||||
|     RestartState _restartState = Idle; | ||||
|     SecurityControl _restartSecurity; | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/knx/bau_systemB_coupler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/knx/bau_systemB_coupler.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| #include "bau_systemB_coupler.h" | ||||
| #include "bits.h" | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| BauSystemBCoupler::BauSystemBCoupler(Platform& platform) : | ||||
|     BauSystemB(platform), | ||||
|     _platform(platform), | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer(_deviceObj, _secIfObj, *this), | ||||
| #else | ||||
|     _appLayer(*this), | ||||
| #endif | ||||
|     _transLayer(_appLayer), _netLayer(_deviceObj, _transLayer) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     _secIfObj.secureApplicationLayer(_appLayer); | ||||
| #endif | ||||
|     _appLayer.transportLayer(_transLayer); | ||||
|     _transLayer.networkLayer(_netLayer); | ||||
|     _memory.addSaveRestore(&_deviceObj); | ||||
|     _memory.addSaveRestore(&_appProgram); | ||||
| #ifdef USE_DATASECURE | ||||
|     _memory.addSaveRestore(&_secIfObj); | ||||
| #endif | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ApplicationLayer& BauSystemBCoupler::applicationLayer() | ||||
| { | ||||
|     return _appLayer; | ||||
| } | ||||
| 
 | ||||
| void BauSystemBCoupler::loop() | ||||
| { | ||||
|     dataLinkLayer().loop(); | ||||
|     _transLayer.loop(); | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer.loop(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool BauSystemBCoupler::configured() | ||||
| { | ||||
|     // _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
 | ||||
|      | ||||
|     if (!_configured) | ||||
|         return false; | ||||
|      | ||||
|     _configured = _appProgram.loadState() == LS_LOADED; | ||||
|      | ||||
|     return _configured; | ||||
| } | ||||
| 
 | ||||
| void BauSystemBCoupler::doMasterReset(EraseCode eraseCode, uint8_t channel) | ||||
| { | ||||
| } | ||||
							
								
								
									
										53
									
								
								src/knx/bau_systemB_coupler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/knx/bau_systemB_coupler.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "config.h" | ||||
| #include "bau_systemB.h" | ||||
| #include "device_object.h" | ||||
| #include "address_table_object.h" | ||||
| #include "association_table_object.h" | ||||
| #include "group_object_table_object.h" | ||||
| #include "security_interface_object.h" | ||||
| #include "application_program_object.h" | ||||
| #include "application_layer.h" | ||||
| #include "secure_application_layer.h" | ||||
| #include "transport_layer.h" | ||||
| #include "network_layer.h" | ||||
| #include "data_link_layer.h" | ||||
| #include "platform.h" | ||||
| #include "memory.h" | ||||
| 
 | ||||
| class BauSystemBCoupler : public BauSystemB | ||||
| { | ||||
|   public: | ||||
|     BauSystemBCoupler(Platform& platform); | ||||
|     virtual void loop(); | ||||
|     bool configured(); | ||||
| 
 | ||||
|   protected: | ||||
|     virtual DataLinkLayer& dataLinkLayer() = 0; | ||||
|     virtual ApplicationLayer& applicationLayer() override; | ||||
| 
 | ||||
|     virtual void doMasterReset(EraseCode eraseCode, uint8_t channel); | ||||
| 
 | ||||
|     enum RestartState | ||||
|     { | ||||
|         Idle, | ||||
|         Connecting, | ||||
|         Connected, | ||||
|         Restarted | ||||
|     }; | ||||
| 
 | ||||
|     Platform& _platform; | ||||
| #ifdef USE_DATASECURE | ||||
|     SecureApplicationLayer _appLayer; | ||||
|     SecurityInterfaceObject _secIfObj; | ||||
| #else | ||||
|     ApplicationLayer _appLayer; | ||||
| #endif | ||||
|     TransportLayer _transLayer; | ||||
|     NetworkLayer _netLayer; | ||||
|     bool _configured = true; | ||||
|     RestartState _restartState = Idle; | ||||
|     SecurityControl _restartSecurity; | ||||
|     uint32_t _restartDelay = 0; | ||||
| }; | ||||
							
								
								
									
										227
									
								
								src/knx/bau_systemB_device.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								src/knx/bau_systemB_device.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,227 @@ | ||||
| #include "bau_systemB_device.h" | ||||
| #include "bits.h" | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| BauSystemBDevice::BauSystemBDevice(Platform& platform) : | ||||
|     BauSystemB(platform), | ||||
|     _addrTable(_memory), | ||||
|     _assocTable(_memory), _groupObjTable(_memory), | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer(_deviceObj, _secIfObj, *this), | ||||
| #else | ||||
|     _appLayer(*this), | ||||
| #endif | ||||
|     _transLayer(_appLayer), _netLayer(_deviceObj, _transLayer) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     _secIfObj.secureApplicationLayer(_appLayer); | ||||
| #endif | ||||
|     _appLayer.transportLayer(_transLayer); | ||||
|     _appLayer.associationTableObject(_assocTable); | ||||
|     _appLayer.groupAddressTable(_addrTable); | ||||
|     _transLayer.networkLayer(_netLayer); | ||||
|     _transLayer.groupAddressTable(_addrTable); | ||||
| 
 | ||||
|     _memory.addSaveRestore(&_deviceObj); | ||||
|     _memory.addSaveRestore(&_addrTable); | ||||
|     _memory.addSaveRestore(&_assocTable); | ||||
|     _memory.addSaveRestore(&_groupObjTable); | ||||
| #ifdef USE_DATASECURE | ||||
|     _memory.addSaveRestore(&_secIfObj); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| ApplicationLayer& BauSystemBDevice::applicationLayer() | ||||
| { | ||||
|     return _appLayer; | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::loop() | ||||
| { | ||||
|     dataLinkLayer().loop(); | ||||
|     _transLayer.loop(); | ||||
|     sendNextGroupTelegram(); | ||||
|     nextRestartState(); | ||||
| #ifdef USE_DATASECURE | ||||
|     _appLayer.loop(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::sendNextGroupTelegram() | ||||
| { | ||||
|     if(!configured()) | ||||
|         return; | ||||
|      | ||||
|     static uint16_t startIdx = 1; | ||||
| 
 | ||||
|     GroupObjectTableObject& table = _groupObjTable; | ||||
|     uint16_t objCount = table.entryCount(); | ||||
| 
 | ||||
|     for (uint16_t asap = startIdx; asap <= objCount; asap++) | ||||
|     { | ||||
|         GroupObject& go = table.get(asap); | ||||
| 
 | ||||
|         ComFlag flag = go.commFlag(); | ||||
|         if (flag != ReadRequest && flag != WriteRequest) | ||||
|             continue; | ||||
| 
 | ||||
|         if (!go.communicationEnable()) | ||||
|             continue; | ||||
| 
 | ||||
|         SecurityControl goSecurity; | ||||
|         goSecurity.toolAccess = false; // Secured group communication never uses the toolkey. ETS knows all keys, also the group keys.
 | ||||
| 
 | ||||
| #ifdef USE_DATASECURE | ||||
|         // Get security flags from Security Interface Object for this group object
 | ||||
|         goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| #else | ||||
|         goSecurity.dataSecurity = DataSecurity::none; | ||||
| #endif | ||||
| 
 | ||||
|         if (flag == WriteRequest && go.transmitEnable()) | ||||
|         { | ||||
|             uint8_t* data = go.valueRef(); | ||||
|             _appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data, | ||||
|                 go.sizeInTelegram()); | ||||
|         } | ||||
|         else if (flag == ReadRequest) | ||||
|         { | ||||
|             _appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity); | ||||
|         } | ||||
| 
 | ||||
|         go.commFlag(Transmitting); | ||||
| 
 | ||||
|         startIdx = asap + 1; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     startIdx = 1; | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::updateGroupObject(GroupObject & go, uint8_t * data, uint8_t length) | ||||
| { | ||||
|     uint8_t* goData = go.valueRef(); | ||||
|     if (length != go.valueSize()) | ||||
|     { | ||||
|         go.commFlag(Error); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     memcpy(goData, data, length); | ||||
| 
 | ||||
|     go.commFlag(Updated); | ||||
|     GroupObjectUpdatedHandler handler = go.callback(); | ||||
|     if (handler) | ||||
|         handler(go); | ||||
| } | ||||
| 
 | ||||
| GroupObjectTableObject& BauSystemBDevice::groupObjectTable() | ||||
| { | ||||
|     return _groupObjTable; | ||||
| } | ||||
| 
 | ||||
| bool BauSystemBDevice::configured() | ||||
| { | ||||
|     // _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
 | ||||
|      | ||||
|     if (!_configured) | ||||
|         return false; | ||||
|      | ||||
|     _configured = _groupObjTable.loadState() == LS_LOADED | ||||
|         && _addrTable.loadState() == LS_LOADED | ||||
|         && _assocTable.loadState() == LS_LOADED | ||||
|         && _appProgram.loadState() == LS_LOADED; | ||||
|      | ||||
|     return _configured; | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::doMasterReset(EraseCode eraseCode, uint8_t channel) | ||||
| { | ||||
|     _addrTable.masterReset(eraseCode, channel); | ||||
|     _assocTable.masterReset(eraseCode, channel); | ||||
|     _groupObjTable.masterReset(eraseCode, channel); | ||||
|     _appProgram.masterReset(eraseCode, channel); | ||||
| #ifdef USE_DATASECURE | ||||
|     // If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
 | ||||
|     // and disable security mode.
 | ||||
|     // FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
 | ||||
|     // Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
 | ||||
|     _secIfObj.masterReset(eraseCode, channel); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
|     if (status) | ||||
|         go.commFlag(Ok); | ||||
|     else | ||||
|         go.commFlag(Error); | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
|     if (status) | ||||
|         go.commFlag(Ok); | ||||
|     else | ||||
|         go.commFlag(Error); | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     DataSecurity requiredGoSecurity; | ||||
| 
 | ||||
|     // Get security flags from Security Interface Object for this group object
 | ||||
|     requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| 
 | ||||
|     if (secCtrl.dataSecurity != requiredGoSecurity) | ||||
|     { | ||||
|         println("GroupValueRead: access denied due to wrong security flags"); | ||||
|         return; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.readEnable()) | ||||
|         return; | ||||
|      | ||||
|     uint8_t* data = go.valueRef(); | ||||
|     _appLayer.groupValueReadResponse(AckRequested, asap, priority, hopType, secCtrl, data, go.sizeInTelegram()); | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* data, | ||||
|     uint8_t dataLength) | ||||
| { | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.responseUpdateEnable()) | ||||
|         return; | ||||
| 
 | ||||
|     updateGroupObject(go, data, dataLength); | ||||
| } | ||||
| 
 | ||||
| void BauSystemBDevice::groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength) | ||||
| { | ||||
| #ifdef USE_DATASECURE | ||||
|     DataSecurity requiredGoSecurity; | ||||
| 
 | ||||
|     // Get security flags from Security Interface Object for this group object
 | ||||
|     requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap); | ||||
| 
 | ||||
|     if (secCtrl.dataSecurity != requiredGoSecurity) | ||||
|     { | ||||
|         println("GroupValueWrite: access denied due to wrong security flags"); | ||||
|         return; | ||||
|     } | ||||
| #endif | ||||
|     GroupObject& go = _groupObjTable.get(asap); | ||||
| 
 | ||||
|     if (!go.communicationEnable() || !go.writeEnable()) | ||||
|         return; | ||||
| 
 | ||||
|     updateGroupObject(go, data, dataLength); | ||||
| } | ||||
							
								
								
									
										56
									
								
								src/knx/bau_systemB_device.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/knx/bau_systemB_device.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "config.h" | ||||
| #include "bau_systemB.h" | ||||
| #include "device_object.h" | ||||
| #include "address_table_object.h" | ||||
| #include "association_table_object.h" | ||||
| #include "group_object_table_object.h" | ||||
| #include "security_interface_object.h" | ||||
| #include "application_program_object.h" | ||||
| #include "application_layer.h" | ||||
| #include "secure_application_layer.h" | ||||
| #include "transport_layer.h" | ||||
| #include "network_layer.h" | ||||
| #include "data_link_layer.h" | ||||
| #include "platform.h" | ||||
| #include "memory.h" | ||||
| 
 | ||||
| class BauSystemBDevice : public BauSystemB | ||||
| { | ||||
|   public: | ||||
|     BauSystemBDevice(Platform& platform); | ||||
|     virtual void loop(); | ||||
|     GroupObjectTableObject& groupObjectTable(); | ||||
|     Memory& memory(); | ||||
|     bool configured(); | ||||
| 
 | ||||
|   protected: | ||||
|     virtual ApplicationLayer& applicationLayer() override; | ||||
| 
 | ||||
|     void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                      uint8_t* data, uint8_t dataLength, bool status) override; | ||||
|     void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override; | ||||
|     void groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) override; | ||||
|     void groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                        uint8_t* data, uint8_t dataLength) override; | ||||
|     void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, | ||||
|                                    uint8_t* data, uint8_t dataLength) override; | ||||
| 
 | ||||
|     void sendNextGroupTelegram(); | ||||
|     void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length); | ||||
| 
 | ||||
|     virtual void doMasterReset(EraseCode eraseCode, uint8_t channel); | ||||
| 
 | ||||
|     AddressTableObject _addrTable; | ||||
|     AssociationTableObject _assocTable; | ||||
|     GroupObjectTableObject _groupObjTable; | ||||
| #ifdef USE_DATASECURE | ||||
|     SecureApplicationLayer _appLayer; | ||||
|     SecurityInterfaceObject _secIfObj; | ||||
| #else | ||||
|     ApplicationLayer _appLayer; | ||||
| #endif | ||||
|     TransportLayer _transLayer; | ||||
|     NetworkLayer _netLayer; | ||||
| }; | ||||
| @ -6,9 +6,8 @@ | ||||
| #include "address_table_object.h" | ||||
| #include "cemi_server.h" | ||||
| 
 | ||||
| DataLinkLayer::DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,  | ||||
|     NetworkLayer& layer, Platform& platform) : | ||||
|     _deviceObject(devObj), _groupAddressTable(addrTab),  _networkLayer(layer), _platform(platform) | ||||
| DataLinkLayer::DataLinkLayer(DeviceObject& devObj, NetworkLayer& layer, Platform& platform) : | ||||
|     _deviceObject(devObj), _networkLayer(layer), _platform(platform) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| @ -115,18 +114,6 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (addrType == InduvidualAddress && destination != _deviceObject.induvidualAddress()) | ||||
|             return; | ||||
| 
 | ||||
|         if (addrType == GroupAddress && !_groupAddressTable.contains(destination)) | ||||
|             return; | ||||
| 
 | ||||
| //        if (frame.npdu().octetCount() > 0)
 | ||||
| //        {
 | ||||
| //            _print("-> DLL ");
 | ||||
| //            frame.apdu().printPDU();
 | ||||
| //        }
 | ||||
| 
 | ||||
|         _networkLayer.dataIndication(ack, addrType, destination, type, npdu, priority, source); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,6 @@ | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include "device_object.h" | ||||
| #include "address_table_object.h" | ||||
| #include "knx_types.h" | ||||
| #include "network_layer.h" | ||||
| #include "cemi_server.h" | ||||
| @ -12,7 +11,7 @@ | ||||
| class DataLinkLayer | ||||
| { | ||||
|   public: | ||||
|     DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer, | ||||
|     DataLinkLayer(DeviceObject& devObj, NetworkLayer& layer, | ||||
|                   Platform& platform); | ||||
| 
 | ||||
| #ifdef USE_CEMI_SERVER | ||||
| @ -36,7 +35,6 @@ class DataLinkLayer | ||||
|     virtual bool sendFrame(CemiFrame& frame) = 0; | ||||
|     uint8_t* frameData(CemiFrame& frame); | ||||
|     DeviceObject& _deviceObject; | ||||
|     AddressTableObject& _groupAddressTable; | ||||
|     NetworkLayer& _networkLayer; | ||||
|     Platform& _platform; | ||||
| #ifdef USE_CEMI_SERVER | ||||
|  | ||||
| @ -5,7 +5,6 @@ | ||||
| #include "bits.h" | ||||
| #include "platform.h" | ||||
| #include "device_object.h" | ||||
| #include "address_table_object.h" | ||||
| #include "knx_ip_routing_indication.h" | ||||
| #include "knx_ip_search_request.h" | ||||
| #include "knx_ip_search_response.h" | ||||
| @ -18,8 +17,8 @@ | ||||
| 
 | ||||
| #define MIN_LEN_CEMI 10 | ||||
| 
 | ||||
| IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, IpParameterObject& ipParam,  | ||||
|     NetworkLayer& layer, Platform& platform) : DataLinkLayer(devObj, addrTab, layer, platform), _ipParameters(ipParam) | ||||
| IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam, | ||||
|     NetworkLayer& layer, Platform& platform) : DataLinkLayer(devObj, layer, platform), _ipParameters(ipParam) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ class IpDataLinkLayer : public DataLinkLayer | ||||
|     using DataLinkLayer::_deviceObject; | ||||
| 
 | ||||
|   public: | ||||
|     IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, IpParameterObject& ipParam, NetworkLayer& layer, | ||||
|     IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam, NetworkLayer& layer, | ||||
|                     Platform& platform); | ||||
| 
 | ||||
|     void loop(); | ||||
| @ -25,4 +25,4 @@ class IpDataLinkLayer : public DataLinkLayer | ||||
| 
 | ||||
|     IpParameterObject& _ipParameters; | ||||
| }; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "data_link_layer.h" | ||||
| #include "bits.h" | ||||
| 
 | ||||
| NetworkLayer::NetworkLayer(TransportLayer& layer): _transportLayer(layer) | ||||
| NetworkLayer::NetworkLayer(DeviceObject &deviceObj, TransportLayer& layer): _transportLayer(layer), _deviceObj(deviceObj) | ||||
| { | ||||
| 
 | ||||
| } | ||||
| @ -27,6 +27,21 @@ void NetworkLayer::hopCount(uint8_t value) | ||||
| void NetworkLayer::dataIndication(AckType ack, AddressType addrType, uint16_t destination, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source) | ||||
| { | ||||
|     HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter; | ||||
| 
 | ||||
|     // Only for devices which are not a coupler
 | ||||
|     if (addrType == InduvidualAddress && destination != _deviceObj.induvidualAddress()) | ||||
|         return; | ||||
| 
 | ||||
|     // TODO: remove. getTSAP() will return 0 later anyway. Get rid of dependency to GAT
 | ||||
|     //if (addrType == GroupAddress && !_groupAddressTable.contains(destination))
 | ||||
|     //    return;
 | ||||
| 
 | ||||
| //        if (frame.npdu().octetCount() > 0)
 | ||||
| //        {
 | ||||
| //            _print("-> DLL ");
 | ||||
| //            frame.apdu().printPDU();
 | ||||
| //        }
 | ||||
| 
 | ||||
|     if (addrType == InduvidualAddress) | ||||
|     { | ||||
|         //if (npdu.octetCount() > 0)
 | ||||
|  | ||||
| @ -5,11 +5,12 @@ | ||||
| #include "npdu.h" | ||||
| #include "transport_layer.h" | ||||
| class DataLinkLayer; | ||||
| class DeviceObject; | ||||
| 
 | ||||
| class NetworkLayer | ||||
| { | ||||
|   public: | ||||
|     NetworkLayer(TransportLayer& layer); | ||||
|     NetworkLayer(DeviceObject& deviceObj, TransportLayer& layer); | ||||
| 
 | ||||
|     void dataLinkLayer(DataLinkLayer& layer); | ||||
|     uint8_t hopCount() const; | ||||
| @ -38,4 +39,6 @@ class NetworkLayer | ||||
|     uint8_t _hopCount = 6; | ||||
|     DataLinkLayer* _dataLinkLayer = 0; | ||||
|     TransportLayer& _transportLayer; | ||||
|     DeviceObject& _deviceObj; | ||||
| 
 | ||||
| }; | ||||
|  | ||||
| @ -73,9 +73,9 @@ bool RfDataLinkLayer::sendFrame(CemiFrame& frame) | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| RfDataLinkLayer::RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, AddressTableObject& addrTab, | ||||
| RfDataLinkLayer::RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, | ||||
|                                          NetworkLayer& layer, Platform& platform) | ||||
|     : DataLinkLayer(devObj, addrTab, layer, platform), | ||||
|     : DataLinkLayer(devObj, layer, platform), | ||||
|       _rfMediumObj(rfMediumObj), | ||||
|       _rfPhy(*this, platform) | ||||
| { | ||||
| @ -377,4 +377,4 @@ void RfDataLinkLayer::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuffer | ||||
|     delete tx_frame; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -16,12 +16,11 @@ class RfDataLinkLayer : public DataLinkLayer | ||||
|     friend class RfPhysicalLayer; | ||||
| 
 | ||||
|     using DataLinkLayer::_deviceObject; | ||||
|     using DataLinkLayer::_groupAddressTable; | ||||
|     using DataLinkLayer::_platform; | ||||
| 
 | ||||
|   public: | ||||
|     RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, AddressTableObject& addrTab, NetworkLayer& layer, | ||||
|                         Platform& platform); | ||||
|     RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, NetworkLayer& layer, | ||||
|                     Platform& platform); | ||||
| 
 | ||||
|     void loop(); | ||||
|     void enabled(bool value); | ||||
| @ -60,4 +59,4 @@ class RfDataLinkLayer : public DataLinkLayer | ||||
|     uint16_t calcCrcRF(uint8_t* buffer, uint32_t offset, uint32_t len); | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -23,18 +23,25 @@ static constexpr uint8_t kSecureDataPdu = 0; | ||||
| static constexpr uint8_t kSecureSyncRequest = 2; | ||||
| static constexpr uint8_t kSecureSyncResponse = 3; | ||||
| 
 | ||||
| SecureApplicationLayer::SecureApplicationLayer(DeviceObject &deviceObj, SecurityInterfaceObject &secIfObj, AssociationTableObject& assocTable, AddressTableObject &addrTab, BusAccessUnit& bau): | ||||
|     ApplicationLayer(assocTable, bau), | ||||
| SecureApplicationLayer::SecureApplicationLayer(DeviceObject &deviceObj, SecurityInterfaceObject &secIfObj, BusAccessUnit& bau): | ||||
|     ApplicationLayer(bau), | ||||
|     _secIfObj(secIfObj), | ||||
|     _deviceObj(deviceObj), | ||||
|     _addrTab(addrTab) | ||||
|     _deviceObj(deviceObj) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void SecureApplicationLayer::groupAddressTable(AddressTableObject &addrTable) | ||||
| { | ||||
|     _addrTab = &addrTable; | ||||
| } | ||||
| 
 | ||||
| /* from transport layer */ | ||||
| 
 | ||||
| void SecureApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) | ||||
| { | ||||
|     if (_addrTab == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     println("dataGroupIndication"); | ||||
| 
 | ||||
|     if (apdu.type() == SecureService) | ||||
| @ -293,12 +300,15 @@ void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap) | ||||
| 
 | ||||
| void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl) | ||||
| { | ||||
|     if (_addrTab == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     println("dataGroupRequest"); | ||||
| 
 | ||||
|     if (secCtrl.dataSecurity != DataSecurity::none) | ||||
|     { | ||||
|         apdu.frame().sourceAddress(_deviceObj.induvidualAddress()); | ||||
|         apdu.frame().destinationAddress(_addrTab.getGroupAddress(tsap)); | ||||
|         apdu.frame().destinationAddress(_addrTab->getGroupAddress(tsap)); | ||||
|         apdu.frame().addressType(GroupAddress); | ||||
| 
 | ||||
|         uint16_t secureApduLength = apdu.length() + 3 + 6 + 4; // 3(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
 | ||||
| @ -507,7 +517,10 @@ void SecureApplicationLayer::blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_ | ||||
| 
 | ||||
| uint16_t SecureApplicationLayer::groupAddressIndex(uint16_t groupAddr) | ||||
| { | ||||
|     return _addrTab.getTsap(groupAddr); | ||||
|     // Just for safety reasons, we should never get here, because the dataGroupIndication will return already return early without doing anything
 | ||||
|     if (_addrTab == nullptr) | ||||
|         return 0; | ||||
|     return _addrTab->getTsap(groupAddr); | ||||
| } | ||||
| 
 | ||||
| const uint8_t* SecureApplicationLayer::securityKey(uint16_t addr, bool isGroupAddress) | ||||
|  | ||||
| @ -28,7 +28,9 @@ class SecureApplicationLayer :  public ApplicationLayer | ||||
|      * @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses. | ||||
|      * @param bau methods are called here depending of the content of the APDU | ||||
|      */ | ||||
|     SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, AssociationTableObject& assocTable, AddressTableObject& addrTab, BusAccessUnit& bau); | ||||
|     SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, BusAccessUnit& bau); | ||||
| 
 | ||||
|     void groupAddressTable(AddressTableObject& addrTable); | ||||
| 
 | ||||
|     void clearFailureLog(); | ||||
|     void getFailureCounters(uint8_t* data); | ||||
| @ -150,5 +152,5 @@ class SecureApplicationLayer :  public ApplicationLayer | ||||
| 
 | ||||
|     SecurityInterfaceObject& _secIfObj; | ||||
|     DeviceObject& _deviceObj; | ||||
|     AddressTableObject& _addrTab; | ||||
|     AddressTableObject* _addrTab = nullptr; | ||||
| }; | ||||
|  | ||||
| @ -265,23 +265,39 @@ void TpUartDataLinkLayer::loop() | ||||
|                 if (!_isEcho) | ||||
|                 { | ||||
|                     uint8_t c = 0x10; | ||||
|                     //ceck if individual or group address
 | ||||
|                     if ((buffer[6] & 0x80) == 0) | ||||
| 
 | ||||
|                     // If this is not a nullptr we consider this a device to be a coupler
 | ||||
|                     // TODO: Improve for coupler mode, only ACK according to filter tables
 | ||||
|                     if (_groupAddressTable) | ||||
|                     { | ||||
|                         //check if individual or group address
 | ||||
|                         if ((buffer[6] & 0x80) == 0) | ||||
|                         { | ||||
|                             //individual
 | ||||
|                             if (_deviceObject.induvidualAddress() == getWord(buffer + 4)) | ||||
|                             { | ||||
|                                 c |= 0x01; | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             //group
 | ||||
|                             if (_groupAddressTable->contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0) | ||||
|                             { | ||||
|                                 c |= 0x01; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         // TODO: test for only our coupler
 | ||||
|                         //individual
 | ||||
|                         if (_deviceObject.induvidualAddress() == getWord(buffer + 4)) | ||||
|                         { | ||||
|                             c |= 0x01; | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         //group
 | ||||
|                         if (_groupAddressTable.contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0) | ||||
|                         { | ||||
|                             c |= 0x01; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     _platform.writeUart(c); | ||||
|                 } | ||||
|             } | ||||
| @ -412,12 +428,17 @@ void TpUartDataLinkLayer::stopChip() | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, | ||||
| TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, | ||||
|                                          NetworkLayer& layer, Platform& platform) | ||||
|     : DataLinkLayer(devObj, addrTab, layer, platform) | ||||
|     : DataLinkLayer(devObj, layer, platform) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void TpUartDataLinkLayer::groupAddressTable(AddressTableObject &addrTable) | ||||
| { | ||||
|     _groupAddressTable = &addrTable; | ||||
| } | ||||
| 
 | ||||
| void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) | ||||
| { | ||||
|     //printHex("=>", buffer, length);
 | ||||
| @ -548,4 +569,4 @@ void TpUartDataLinkLayer::loadNextTxFrame() | ||||
|     } | ||||
|     delete tx_frame; | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -11,13 +11,15 @@ | ||||
| class TpUartDataLinkLayer : public DataLinkLayer | ||||
| { | ||||
|     using DataLinkLayer::_deviceObject; | ||||
|     using DataLinkLayer::_groupAddressTable; | ||||
|     using DataLinkLayer::_platform; | ||||
| 
 | ||||
|   public: | ||||
|     TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer, | ||||
|     TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayer& layer, | ||||
|                         Platform& platform); | ||||
| 
 | ||||
|     ; | ||||
|     void groupAddressTable(AddressTableObject& addrTable); | ||||
| 
 | ||||
|     void loop(); | ||||
|     void enabled(bool value); | ||||
|     bool enabled() const; | ||||
| @ -62,5 +64,7 @@ class TpUartDataLinkLayer : public DataLinkLayer | ||||
|     void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success); | ||||
|     bool resetChip(); | ||||
|     void stopChip(); | ||||
| 
 | ||||
|     AddressTableObject* _groupAddressTable = nullptr; | ||||
| }; | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| @ -7,8 +7,8 @@ | ||||
| #include "bits.h" | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| TransportLayer::TransportLayer(ApplicationLayer& layer, AddressTableObject& gat): _savedFrame(0),  | ||||
|     _savedFrameConnecting(0), _applicationLayer(layer), _groupAddressTable(gat) | ||||
| TransportLayer::TransportLayer(ApplicationLayer& layer): _savedFrame(0), | ||||
|     _savedFrameConnecting(0), _applicationLayer(layer) | ||||
| { | ||||
|     _currentState = Closed; | ||||
| } | ||||
| @ -18,6 +18,11 @@ void TransportLayer::networkLayer(NetworkLayer& layer) | ||||
|     _networkLayer = &layer; | ||||
| } | ||||
| 
 | ||||
| void TransportLayer::groupAddressTable(AddressTableObject &addrTable) | ||||
| { | ||||
|     _groupAddressTable = &addrTable; | ||||
| } | ||||
| 
 | ||||
| void TransportLayer::dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu) | ||||
| { | ||||
|     //if (tpdu.apdu().length() > 0)
 | ||||
| @ -361,7 +366,10 @@ void TransportLayer::dataIndividualConfirm(AckType ack, uint16_t destination, Ho | ||||
| 
 | ||||
| void TransportLayer::dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu) | ||||
| { | ||||
|     uint16_t tsap = _groupAddressTable.getTsap(destination); | ||||
|     if (_groupAddressTable == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     uint16_t tsap = _groupAddressTable->getTsap(destination); | ||||
|     if (tsap == 0) | ||||
|         return; | ||||
|      | ||||
| @ -395,7 +403,10 @@ void TransportLayer::dataSystemBroadcastConfirm(AckType ack, HopCountType hopTyp | ||||
| 
 | ||||
| void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) | ||||
| { | ||||
|     uint16_t groupAdress = _groupAddressTable.getGroupAddress(tsap); | ||||
|     if (_groupAddressTable == nullptr) | ||||
|         return; | ||||
| 
 | ||||
|     uint16_t groupAdress = _groupAddressTable->getGroupAddress(tsap); | ||||
|     TPDU& tpdu = apdu.frame().tpdu(); | ||||
|     _networkLayer->dataGroupRequest(ack, groupAdress, hopType, priority, tpdu); | ||||
| } | ||||
|  | ||||
| @ -16,8 +16,9 @@ enum StateType { Closed, OpenIdle, OpenWait, Connecting }; | ||||
| class TransportLayer | ||||
| { | ||||
| public: | ||||
|     TransportLayer(ApplicationLayer& layer, AddressTableObject& gat); | ||||
|     TransportLayer(ApplicationLayer& layer); | ||||
|     void networkLayer(NetworkLayer& layer); | ||||
|     void groupAddressTable(AddressTableObject& addrTable); | ||||
| 
 | ||||
| #pragma region from network layer | ||||
|     void dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu); | ||||
| @ -115,6 +116,6 @@ private: | ||||
|     uint8_t _maxRepCount = 3; | ||||
| #pragma endregion | ||||
|     ApplicationLayer& _applicationLayer; | ||||
|     AddressTableObject& _groupAddressTable; | ||||
|     AddressTableObject* _groupAddressTable; | ||||
|     NetworkLayer* _networkLayer; | ||||
| }; | ||||
|  | ||||
| @ -27,6 +27,7 @@ | ||||
|    #include "linux_platform.h" | ||||
|    #include "knx/bau57B0.h" | ||||
|    #include "knx/bau27B0.h" | ||||
|    #include "knx/bau091A.h" | ||||
| #endif | ||||
| 
 | ||||
| void buttonUp(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user