17 _usbTunnelInterface(*this,
18 _bau.deviceObject().maskVersion(),
19 _bau.deviceObject().manufacturerId())
29 _dataLinkLayer = &layer;
35 _dataLinkLayerPrimary = &layer;
41 return _clientAddress;
46 _clientAddress = value;
55 #ifdef KNX_LOG_TUNNELING
56 print(
"L_data_con: src: ");
66 #elif defined(KNX_TUNNELING)
77 uint8_t data[frame.
dataLength() + (isRf ? 10 : 0)];
92 data[11] = frame.
rfLfn();
106 #ifdef KNX_LOG_TUNNELING
108 print(
"L_data_ind: src: ");
119 #elif defined(KNX_TUNNELING)
136 handleMPropRead(frame);
142 handleMPropWrite(frame);
148 println(
"M_FuncPropCommand_req not implemented");
154 println(
"M_FuncPropStateRead_req not implemented");
179 void CemiServer::handleLData(
CemiFrame& frame)
183 #ifndef KNX_TUNNELING
197 if (((frame.
data())[1] == 0x0A) &&
198 ((frame.
data())[2] == 0x02) &&
199 ((frame.
data())[3] == 0x08) )
204 if ( ((frame.
data())[5] != 0x00) || ((frame.
data())[6] != 0x00) || ((frame.
data())[7] != 0x00) ||
205 ((frame.
data())[8] != 0x00) || ((frame.
data())[9] != 0x00) || ((frame.
data())[10] != 0x00) )
218 if (frame.
rfLfn() == 0xFF)
221 frame.
rfLfn(_frameNumber);
223 _frameNumber = (_frameNumber + 1) & 0x7;
229 #ifdef KNX_LOG_TUNNELING
230 print(
"L_data_req: src: ");
239 void CemiServer::handleMPropRead(
CemiFrame& frame)
241 #ifdef KNX_LOG_TUNNELING
242 print(
"M_PropRead_req: ");
247 uint8_t objectInstance = frame.
data()[3];
248 uint8_t propertyId = frame.
data()[4];
249 uint8_t numberOfElements = frame.
data()[5] >> 4;
250 uint16_t startIndex = frame.
data()[6] | ((frame.
data()[5] & 0x0F) << 8);
251 uint8_t* data =
nullptr;
252 uint32_t dataSize = 0;
254 #ifdef KNX_LOG_TUNNELING
256 print(objectType, DEC);
258 print(objectInstance, DEC);
260 print(propertyId, DEC);
262 print(numberOfElements, DEC);
263 print(
" startIdx: ");
264 print(startIndex, DEC);
277 (numberOfElements == 1))
279 data[0] = (uint8_t) (_clientAddress & 0xFF);
283 (numberOfElements == 1))
285 data[0] = (uint8_t) ((_clientAddress >> 8) & 0xFF);
288 if (data && dataSize && numberOfElements)
290 #ifdef KNX_LOG_TUNNELING
291 printHex(
" <- data: ", data, dataSize);
295 uint8_t responseData[7 + dataSize];
296 memcpy(responseData, frame.
data(), 7);
297 memcpy(&responseData[7], data, dataSize);
299 CemiFrame responseFrame(responseData,
sizeof(responseData));
303 #elif defined(KNX_TUNNELING)
311 uint8_t responseData[7 + 1];
312 memcpy(responseData, frame.
data(),
sizeof(responseData));
316 printHex(
" <- error: ", &responseData[7], 1);
319 CemiFrame responseFrame(responseData,
sizeof(responseData));
323 #elif defined(KNX_TUNNELING)
329 void CemiServer::handleMPropWrite(
CemiFrame& frame)
331 print(
"M_PropWrite_req: ");
335 uint8_t objectInstance = frame.
data()[3];
336 uint8_t propertyId = frame.
data()[4];
337 uint8_t numberOfElements = frame.
data()[5] >> 4;
338 uint16_t startIndex = frame.
data()[6] | ((frame.
data()[5] & 0x0F) << 8);
339 uint8_t* requestData = &frame.
data()[7];
340 uint32_t requestDataSize = frame.
dataLength() - 7;
343 print(objectType, DEC);
345 print(objectInstance, DEC);
347 print(propertyId, DEC);
349 print(numberOfElements, DEC);
350 print(
" startIdx: ");
351 print(startIndex, DEC);
353 printHex(
" -> data: ", requestData, requestDataSize);
358 (numberOfElements == 1))
362 _clientAddress = (_clientAddress & 0xFF00) | requestData[0];
363 print(
"cEMI client address: ");
368 (numberOfElements == 1))
372 _clientAddress = (_clientAddress & 0x00FF) | (requestData[0] << 8);
373 print(
"cEMI client address: ");
378 _bau.
propertyValueWrite((
ObjectType)objectType, objectInstance, propertyId, numberOfElements, startIndex, requestData, requestDataSize);
381 if (numberOfElements)
384 uint8_t responseData[7];
385 memcpy(responseData, frame.
data(),
sizeof(responseData));
389 CemiFrame responseFrame(responseData,
sizeof(responseData));
393 #elif defined(KNX_TUNNELING)
400 uint8_t responseData[7 + 1];
401 memcpy(responseData, frame.
data(),
sizeof(responseData));
405 printHex(
" <- error: ", &responseData[7], 1);
408 CemiFrame responseFrame(responseData,
sizeof(responseData));
412 #elif defined(KNX_TUNNELING)
418 void CemiServer::handleMReset(
CemiFrame& frame)
420 println(
"M_Reset_req: sending M_Reset_ind");
426 uint8_t responseData[1];
427 CemiFrame responseFrame(responseData,
sizeof(responseData));
431 #elif defined(KNX_TUNNELING)
439 _usbTunnelInterface.
loop();
void printHex(const char *suffix, const uint8_t *data, size_t length, bool newline)
uint8_t * pushByteArray(const uint8_t *src, uint32_t size, uint8_t *data)
const uint8_t * popWord(uint16_t &w, const uint8_t *data)
ApduType type()
Get the type of the APDU.
void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t &numberOfElements, uint16_t startIndex, uint8_t **data, uint32_t &length) override
void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t &numberOfElements, uint16_t startIndex, uint8_t *data, uint32_t length) override
DeviceObject & deviceObject()
uint16_t sourceAddress() const
uint8_t * rfSerialOrDoA() const
uint16_t destinationAddress() const
MessageCode messageCode() const
void dataConfirmationToTunnel(CemiFrame &frame)
CemiServer(BauSystemB &bau)
The constructor.
void dataIndicationToTunnel(CemiFrame &frame)
void dataLinkLayerPrimary(DataLinkLayer &layer)
void frameReceived(CemiFrame &frame)
uint16_t clientAddress() const
void dataLinkLayer(DataLinkLayer &layer)
virtual void dataIndicationToTunnel(CemiFrame &frame)
virtual void dataConfirmationToTunnel(CemiFrame &frame)
virtual void dataRequestToTunnel(CemiFrame &frame)
void dataRequestFromTunnel(CemiFrame &frame)
virtual DptMedium mediumType() const =0
uint16_t individualAddress()
void sendCemiFrame(CemiFrame &frame)
ObjectType
Enum for the type of an interface object.
@ OT_DEVICE
Device object.
@ M_FuncPropStateRead_req