knx
ETS configurable knx-stack
bau091A.cpp
Go to the documentation of this file.
1 #include "config.h"
2 #if MASK_VERSION == 0x091A
3 
4 #include "bau091A.h"
5 #include "bits.h"
6 #include <string.h>
7 #include <stdio.h>
8 
9 using namespace std;
10 
11 /* ToDos
12 Announce the line status of sec side 03_05_01 4.4.3
13 implement PID_COUPLER_SERVICES_CONTROL 03_05_01 4.4.7
14 */
15 
18  _routerObj(memory(), 0x200, 0x2000), // the Filtertable of 0x091A IP Routers is fixed at 0x200 and 0x2000 long
19  _ipParameters(_deviceObj, platform),
20  _dlLayerPrimary(_deviceObj, _ipParameters, _netLayer.getPrimaryInterface(), _platform, (DataLinkLayerCallbacks*) this),
21  _dlLayerSecondary(_deviceObj, _netLayer.getSecondaryInterface(), platform, (ITpUartCallBacks&) * this, (DataLinkLayerCallbacks*) this)
22 #ifdef USE_CEMI_SERVER
23  , _cemiServer(*this)
24 #endif
25 {
26  // Before accessing anything of the router object they have to be initialized according to the used medium
27  // Coupler model 1.x
28  _routerObj.initialize1x(DptMedium::KNX_IP, 220);
29 
30  // Mask 091A uses older coupler model 1.x which only uses one router object
31  _netLayer.rtObj(_routerObj);
32 
33  _netLayer.getPrimaryInterface().dataLinkLayer(_dlLayerPrimary);
34  _netLayer.getSecondaryInterface().dataLinkLayer(_dlLayerSecondary);
35 
36 #ifdef USE_CEMI_SERVER
39  _cemiServer.dataLinkLayerPrimary(_dlLayerPrimary);
40  _cemiServer.dataLinkLayer(_dlLayerSecondary); // Secondary I/F is the important one!
41  _dlLayerPrimary.cemiServer(_cemiServer);
42  _dlLayerSecondary.cemiServer(_cemiServer);
43  _memory.addSaveRestore(&_cemiServerObject);
44  uint8_t count = 1;
45  uint16_t suppCommModes = 0x0100;
46  _cemiServerObject.writeProperty(PID_COMM_MODES_SUPPORTED, 1, (uint8_t*)&suppCommModes, count); // set the properties Bit 0 to 1 meaning "LinkLayer supported"
47 #endif
48 
49  _memory.addSaveRestore(&_routerObj);
50 
51  _memory.addSaveRestore(&_ipParameters);
52 
53  // Set Mask Version in Device Object depending on the BAU
54  _deviceObj.maskVersion(0x091A);
55 
56  // Set which interface objects are available in the device object
57  // This differs from BAU to BAU with different medium types.
58  // See PID_IO_LIST
60  prop->write(1, (uint16_t) OT_DEVICE);
61  prop->write(2, (uint16_t) OT_ROUTER);
62  prop->write(3, (uint16_t) OT_APPLICATION_PROG);
63  prop->write(4, (uint16_t) OT_IP_PARAMETER);
64 #if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER)
65  prop->write(5, (uint16_t) OT_SECURITY);
66  prop->write(6, (uint16_t) OT_CEMI_SERVER);
67 #elif defined(USE_DATASECURE)
68  prop->write(5, (uint16_t) OT_SECURITY);
69 #elif defined(USE_CEMI_SERVER)
70  prop->write(5, (uint16_t) OT_CEMI_SERVER);
71 #endif
72 }
73 
75 {
76  switch (idx)
77  {
78  case 0:
79  return &_deviceObj;
80 
81  case 1:
82  return &_routerObj;
83 
84  case 2:
85  return &_appProgram;
86 
87  case 3:
88  return &_ipParameters;
89 #if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER)
90 
91  case 4:
92  return &_secIfObj;
93 
94  case 5:
95  return &_cemiServerObject;
96 #elif defined(USE_CEMI_SERVER)
97 
98  case 4:
99  return &_cemiServerObject;
100 #elif defined(USE_DATASECURE)
101 
102  case 4:
103  return &_secIfObj;
104 #endif
105 
106  default:
107  return nullptr;
108  }
109 }
110 
111 InterfaceObject* Bau091A::getInterfaceObject(ObjectType objectType, uint16_t objectInstance)
112 {
113  // We do not use it right now.
114  // Required for coupler mode as there are multiple router objects for example
115  (void) objectInstance;
116 
117  switch (objectType)
118  {
119  case OT_DEVICE:
120  return &_deviceObj;
121 
122  case OT_ROUTER:
123  return &_routerObj;
124 
125  case OT_APPLICATION_PROG:
126  return &_appProgram;
127 
128  case OT_IP_PARAMETER:
129  return &_ipParameters;
130 #ifdef USE_DATASECURE
131 
132  case OT_SECURITY:
133  return &_secIfObj;
134 #endif
135 #ifdef USE_CEMI_SERVER
136 
137  case OT_CEMI_SERVER:
138  return &_cemiServerObject;
139 #endif
140 
141  default:
142  return nullptr;
143  }
144 }
145 
146 void Bau091A::doMasterReset(EraseCode eraseCode, uint8_t channel)
147 {
148  // Common SystemB objects
149  BauSystemBCoupler::doMasterReset(eraseCode, channel);
150 
151  _ipParameters.masterReset(eraseCode, channel);
152  _routerObj.masterReset(eraseCode, channel);
153 }
154 
156 {
157  return _dlLayerPrimary.enabled() && _dlLayerSecondary.enabled();
158 }
159 
160 void Bau091A::enabled(bool value)
161 {
162  _dlLayerPrimary.enabled(value);
163  _dlLayerSecondary.enabled(value);
164 
165  // ToDo change frame repitition in the TP layer - but default is ok.
166  //_dlLayerSecondary.setFrameRepetition(3,3);
167 }
168 
170 {
171  _dlLayerPrimary.loop();
172  _dlLayerSecondary.loop();
174 }
175 
176 TPAckType Bau091A::isAckRequired(uint16_t address, bool isGrpAddr)
177 {
178  //only called from TpUartDataLinkLayer
180 
181  uint8_t lcconfig = LCCONFIG::PHYS_FRAME_ROUT | LCCONFIG::PHYS_REPEAT | LCCONFIG::BROADCAST_REPEAT | LCCONFIG::GROUP_IACK_ROUT | LCCONFIG::PHYS_IACK_NORMAL; // default value from spec. in case prop is not availible.
182  Property* prop_lcconfig = _routerObj.property(PID_SUB_LCCONFIG);
183 
184  if (lcconfig)
185  prop_lcconfig->read(lcconfig);
186 
187  if (isGrpAddr)
188  {
189  // ACK for broadcasts
190  if (address == 0)
191  {
192  ack = TPAckType::AckReqAck;
193  }
194  else
195  {
196  if(lcconfig & LCCONFIG::GROUP_IACK_ROUT)
197  {
198  // is group address in filter table? ACK if yes, No if not
199  if(_netLayer.isRoutedGroupAddress(address, 1))
200  ack = TPAckType::AckReqAck;
201  else
202  ack = TPAckType::AckReqNone;
203  }
204  else
205  {
206  // all are ACKED
207  ack = TPAckType::AckReqAck;
208  }
209  }
210 #ifdef KNX_TUNNELING
211 
212  if (_dlLayerPrimary.isSentToTunnel(address, isGrpAddr))
213  ack = TPAckType::AckReqAck;
214 
215 #endif
216  }
217  else
218  {
219  if ((lcconfig & LCCONFIG::PHYS_IACK) == LCCONFIG::PHYS_IACK_ALL)
220  ack = TPAckType::AckReqAck;
221  else if ((lcconfig & LCCONFIG::PHYS_IACK) == LCCONFIG::PHYS_IACK_NACK)
222  ack = TPAckType::AckReqNack;
223  else if (_netLayer.isRoutedIndividualAddress(address, 1) || address == _deviceObj.individualAddress()) // Also ACK for our own individual address
224  ack = TPAckType::AckReqAck;
225  else
226  ack = TPAckType::AckReqNone;
227 
228 #ifdef KNX_TUNNELING
229 
230  if (_dlLayerPrimary.isSentToTunnel(address, isGrpAddr))
231  ack = TPAckType::AckReqAck;
232 
233 #endif
234  }
235  return ack;
236 }
237 
239 {
240  // _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
241 
242  if (!_configured)
243  return false;
244 
245  _configured = _routerObj.loadState() == LS_LOADED;
246 #ifdef USE_DATASECURE
248 #endif
249 
250  return _configured;
251 }
252 
254 {
255  return (IpDataLinkLayer*)&_dlLayerPrimary;
256 }
257 
259 {
260  return (TpUartDataLinkLayer*)&_dlLayerSecondary;
261 }
262 #endif
bool enabled() override
Definition: bau091A.cpp:155
bool configured() override
Definition: bau091A.cpp:238
IpDataLinkLayer * getPrimaryDataLinkLayer()
Definition: bau091A.cpp:253
void loop() override
Definition: bau091A.cpp:169
TPAckType isAckRequired(uint16_t address, bool isGrpAddr) override
Definition: bau091A.cpp:176
Bau091A(Platform &platform)
Definition: bau091A.cpp:16
void doMasterReset(EraseCode eraseCode, uint8_t channel) override
Definition: bau091A.cpp:146
InterfaceObject * getInterfaceObject(uint8_t idx)
TpUartDataLinkLayer * getSecondaryDataLinkLayer()
Definition: bau091A.cpp:258
NetworkLayerCoupler _netLayer
void doMasterReset(EraseCode eraseCode, uint8_t channel) override
SecurityInterfaceObject _secIfObj
Memory _memory
Definition: bau_systemB.h:123
ApplicationProgramObject _appProgram
Definition: bau_systemB.h:125
DeviceObject _deviceObj
Definition: bau_systemB.h:124
void dataLinkLayerPrimary(DataLinkLayer &layer)
Definition: cemi_server.cpp:33
void dataLinkLayer(DataLinkLayer &layer)
void setMediumTypeAsSupported(DptMedium dptMedium)
uint16_t maskVersion()
uint16_t individualAddress()
This class represents and interface object.
virtual void masterReset(EraseCode eraseCode, uint8_t channel)
virtual void writeProperty(PropertyID id, uint16_t start, uint8_t *data, uint8_t &count)
Write property of the interface object.
Property * property(PropertyID id)
Gets property with PropertyID id if it exists and nullptr otherwise.
void addSaveRestore(SaveRestore *obj)
Definition: memory.cpp:209
NetworkLayerEntity & getSecondaryInterface()
bool isRoutedIndividualAddress(uint16_t individualAddress, uint8_t srcIfIndex)
void rtObj(RouterObject &rtObj)
NetworkLayerEntity & getPrimaryInterface()
bool isRoutedGroupAddress(uint16_t groupAddress, uint8_t sourceInterfaceIndex)
void dataLinkLayer(DataLinkLayer &layer)
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t *data) const =0
virtual uint8_t write(uint16_t start, uint8_t count, const uint8_t *data)=0
void masterReset(EraseCode eraseCode, uint8_t channel) override
void initialize1x(DptMedium mediumType, uint16_t maxApduSize)
LoadState loadState()
This method returns the LoadState of the interface object.
ObjectType
Enum for the type of an interface object.
@ OT_CEMI_SERVER
cEMI Server Object
@ OT_APPLICATION_PROG
Application program object.
@ OT_IP_PARAMETER
KNXnet/IP Parameter Object.
@ OT_DEVICE
Device object.
@ OT_SECURITY
Security Interface Object.
@ OT_ROUTER
Router Object.
EraseCode
Definition: knx_types.h:242
@ KNX_IP
Definition: knx_types.h:260
@ KNX_TP1
Definition: knx_types.h:257
@ PHYS_IACK_NACK
Definition: knx_types.h:289
@ PHYS_REPEAT
Definition: knx_types.h:282
@ PHYS_IACK_ALL
Definition: knx_types.h:288
@ GROUP_IACK_ROUT
Definition: knx_types.h:285
@ PHYS_IACK
Definition: knx_types.h:286
@ BROADCAST_REPEAT
Definition: knx_types.h:284
@ PHYS_IACK_NORMAL
Definition: knx_types.h:287
@ PHYS_FRAME_ROUT
Definition: knx_types.h:281
TPAckType
Definition: knx_types.h:24
@ AckReqNack
Definition: knx_types.h:26
@ AckReqNone
Definition: knx_types.h:29
@ AckReqAck
Definition: knx_types.h:28
@ PID_SUB_LCCONFIG
Definition: property.h:183
@ PID_COMM_MODES_SUPPORTED
Definition: property.h:159
@ PID_IO_LIST
Definition: property.h:98
@ LS_LOADED
Definition: property.h:200