knx
ETS configurable knx-stack
ip_data_link_layer.cpp
Go to the documentation of this file.
1 #include "config.h"
2 #ifdef USE_IP
3 
4 #include "ip_data_link_layer.h"
5 
6 #include "bits.h"
7 #include "platform.h"
8 #include "device_object.h"
10 #include "knx_ip_search_request.h"
11 #include "knx_ip_search_response.h"
14 #include "knx_facade.h"
15 #ifdef KNX_TUNNELING
16  #include "knx_ip_connect_request.h"
17  #include "knx_ip_connect_response.h"
18  #include "knx_ip_state_request.h"
19  #include "knx_ip_state_response.h"
23  #include "knx_ip_tunneling_ack.h"
26  #include "knx_ip_config_request.h"
27 #endif
28 
29 #include <stdio.h>
30 #include <string.h>
31 
32 #define KNXIP_HEADER_LEN 0x6
33 #define KNXIP_PROTOCOL_VERSION 0x10
34 
35 #define MIN_LEN_CEMI 10
36 
38  NetworkLayerEntity& netLayerEntity, Platform& platform, DataLinkLayerCallbacks* dllcb) : DataLinkLayer(devObj, netLayerEntity, platform), _ipParameters(ipParam), _dllcb(dllcb)
39 {
40 }
41 
42 bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
43 {
44  KnxIpRoutingIndication packet(frame);
45 
46  // only send 50 packet per second: see KNX 3.2.6 p.6
47  if (isSendLimitReached())
48  return false;
49 
50  bool success = sendBytes(packet.data(), packet.totalLength());
51 #ifdef KNX_ACTIVITYCALLBACK
52 
53  if (_dllcb)
54  _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR));
55 
56 #endif
57  dataConReceived(frame, success);
58  return success;
59 }
60 
61 #ifdef KNX_TUNNELING
63 {
65  {
66  for (int i = 0; i < KNX_TUNNELING; i++)
67  if (tunnels[i].ChannelId != 0 && tunnels[i].IndividualAddress == frame.sourceAddress())
68  sendFrameToTunnel(&tunnels[i], frame);
69 
70  //TODO check if source is from tunnel
71  return;
72  }
73 
74  KnxIpTunnelConnection* tun = nullptr;
75 
76  for (int i = 0; i < KNX_TUNNELING; i++)
77  {
78  if (tunnels[i].IndividualAddress == frame.sourceAddress())
79  continue;
80 
81  if (tunnels[i].IndividualAddress == frame.destinationAddress())
82  {
83  tun = &tunnels[i];
84  break;
85  }
86  }
87 
88  if (tun == nullptr)
89  {
90  for (int i = 0; i < KNX_TUNNELING; i++)
91  {
92  if (tunnels[i].IsConfig)
93  {
94 #ifdef KNX_LOG_TUNNELING
95  println("Found config Channel");
96 #endif
97  tun = &tunnels[i];
98  break;
99  }
100  }
101  }
102 
103  if (tun == nullptr)
104  {
105 #ifdef KNX_LOG_TUNNELING
106  print("Found no Tunnel for IA: ");
107  println(frame.destinationAddress(), 16);
108 #endif
109  return;
110  }
111 
112  sendFrameToTunnel(tun, frame);
113 }
114 
116 {
117  if (frame.addressType() == AddressType::GroupAddress)
118  {
119  for (int i = 0; i < KNX_TUNNELING; i++)
120  if (tunnels[i].ChannelId != 0 && tunnels[i].IndividualAddress == frame.sourceAddress())
121  sendFrameToTunnel(&tunnels[i], frame);
122 
123  //TODO check if source is from tunnel
124  return;
125  }
126 
127  KnxIpTunnelConnection* tun = nullptr;
128 
129  for (int i = 0; i < KNX_TUNNELING; i++)
130  {
131  if (tunnels[i].IndividualAddress == frame.destinationAddress())
132  continue;
133 
134  if (tunnels[i].IndividualAddress == frame.sourceAddress())
135  {
136  tun = &tunnels[i];
137  break;
138  }
139  }
140 
141  if (tun == nullptr)
142  {
143  for (int i = 0; i < KNX_TUNNELING; i++)
144  {
145  if (tunnels[i].IsConfig)
146  {
147 #ifdef KNX_LOG_TUNNELING
148  println("Found config Channel");
149 #endif
150  tun = &tunnels[i];
151  break;
152  }
153  }
154  }
155 
156  if (tun == nullptr)
157  {
158 #ifdef KNX_LOG_TUNNELING
159  print("Found no Tunnel for IA: ");
160  println(frame.destinationAddress(), 16);
161 #endif
162  return;
163  }
164 
165  sendFrameToTunnel(tun, frame);
166 }
167 
169 {
170  if (frame.addressType() == AddressType::GroupAddress)
171  {
172  for (int i = 0; i < KNX_TUNNELING; i++)
173  if (tunnels[i].ChannelId != 0 && tunnels[i].IndividualAddress != frame.sourceAddress())
174  sendFrameToTunnel(&tunnels[i], frame);
175 
176  return;
177  }
178 
179  KnxIpTunnelConnection* tun = nullptr;
180 
181  for (int i = 0; i < KNX_TUNNELING; i++)
182  {
183  if (tunnels[i].ChannelId == 0 || tunnels[i].IndividualAddress == frame.sourceAddress())
184  continue;
185 
186  if (tunnels[i].IndividualAddress == frame.destinationAddress())
187  {
188  tun = &tunnels[i];
189  break;
190  }
191  }
192 
193  if (tun == nullptr)
194  {
195  for (int i = 0; i < KNX_TUNNELING; i++)
196  {
197  if (tunnels[i].IsConfig)
198  {
199 #ifdef KNX_LOG_TUNNELING
200  println("Found config Channel");
201 #endif
202  tun = &tunnels[i];
203  break;
204  }
205  }
206  }
207 
208  if (tun == nullptr)
209  {
210 #ifdef KNX_LOG_TUNNELING
211  print("Found no Tunnel for IA: ");
212  println(frame.destinationAddress(), 16);
213 #endif
214  return;
215  }
216 
217  sendFrameToTunnel(tun, frame);
218 }
219 
220 void IpDataLinkLayer::sendFrameToTunnel(KnxIpTunnelConnection* tunnel, CemiFrame& frame)
221 {
222 #ifdef KNX_LOG_TUNNELING
223  print("Send to Channel: ");
224  println(tunnel->ChannelId, 16);
225 #endif
226  KnxIpTunnelingRequest req(frame);
227  req.connectionHeader().sequenceCounter(tunnel->SequenceCounter_S++);
228  req.connectionHeader().length(LEN_CH);
229  req.connectionHeader().channelId(tunnel->ChannelId);
230 
231  if (frame.messageCode() != L_data_req && frame.messageCode() != L_data_con && frame.messageCode() != L_data_ind)
232  req.serviceTypeIdentifier(DeviceConfigurationRequest);
233 
234  _platform.sendBytesUniCast(tunnel->IpAddress, tunnel->PortData, req.data(), req.totalLength());
235 }
236 
238 {
239  if (addr == 0)
240  return false; // 0.0.0 is not a valid tunnel address and is used as default value
241 
242  for (int i = 0; i < KNX_TUNNELING; i++)
243  if (tunnels[i].IndividualAddress == addr)
244  return true;
245 
246  return false;
247 }
248 
249 bool IpDataLinkLayer::isSentToTunnel(uint16_t address, bool isGrpAddr)
250 {
251  if (isGrpAddr)
252  {
253  for (int i = 0; i < KNX_TUNNELING; i++)
254  if (tunnels[i].ChannelId != 0)
255  return true;
256 
257  return false;
258  }
259  else
260  {
261  for (int i = 0; i < KNX_TUNNELING; i++)
262  if (tunnels[i].ChannelId != 0 && tunnels[i].IndividualAddress == address)
263  return true;
264 
265  return false;
266  }
267 }
268 #endif
269 
271 {
272  if (!_enabled)
273  return;
274 
275 #ifdef KNX_TUNNELING
276 
277  for (int i = 0; i < KNX_TUNNELING; i++)
278  {
279  if (tunnels[i].ChannelId != 0)
280  {
281  if (millis() - tunnels[i].lastHeartbeat > 120000)
282  {
283 #ifdef KNX_LOG_TUNNELING
284  print("Closed Tunnel 0x");
285  print(tunnels[i].ChannelId, 16);
286  println(" due to no heartbeat in 2 minutes");
287 #endif
288  KnxIpDisconnectRequest discReq;
289  discReq.channelId(tunnels[i].ChannelId);
290  discReq.hpaiCtrl().length(LEN_IPHPAI);
291  discReq.hpaiCtrl().code(IPV4_UDP);
292  discReq.hpaiCtrl().ipAddress(tunnels[i].IpAddress);
293  discReq.hpaiCtrl().ipPortNumber(tunnels[i].PortCtrl);
294  _platform.sendBytesUniCast(tunnels[i].IpAddress, tunnels[i].PortCtrl, discReq.data(), discReq.totalLength());
295  tunnels[i].Reset();
296  }
297 
298  break;
299  }
300  }
301 
302 #endif
303 
304 
305  uint8_t buffer[512];
306  uint16_t remotePort = 0;
307  uint32_t remoteAddr = 0;
308  int len = _platform.readBytesMultiCast(buffer, 512, remoteAddr, remotePort);
309 
310  if (len <= 0)
311  return;
312 
313  if (len < KNXIP_HEADER_LEN)
314  return;
315 
316  if (buffer[0] != KNXIP_HEADER_LEN
317  || buffer[1] != KNXIP_PROTOCOL_VERSION)
318  return;
319 
320 #ifdef KNX_ACTIVITYCALLBACK
321 
322  if (_dllcb)
323  _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR));
324 
325 #endif
326 
327  uint16_t code;
328  popWord(code, buffer + 2);
329 
330  switch ((KnxIpServiceType)code)
331  {
332  case RoutingIndication:
333  {
334  KnxIpRoutingIndication routingIndication(buffer, len);
335  frameReceived(routingIndication.frame());
336  break;
337  }
338 
339  case SearchRequest:
340  {
341  KnxIpSearchRequest searchRequest(buffer, len);
342  KnxIpSearchResponse searchResponse(_ipParameters, _deviceObject);
343 
344  auto hpai = searchRequest.hpai();
345 #ifdef KNX_ACTIVITYCALLBACK
346 
347  if (_dllcb)
348  _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST));
349 
350 #endif
351  _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength());
352  break;
353  }
354 
355  case SearchRequestExt:
356  {
357 #if KNX_SERVICE_FAMILY_CORE >= 2
358  loopHandleSearchRequestExtended(buffer, len);
359 #endif
360  break;
361  }
362 
363 #ifdef KNX_TUNNELING
364 
365  case ConnectRequest:
366  {
367  loopHandleConnectRequest(buffer, len, remoteAddr, remotePort);
368  break;
369  }
370 
372  {
373  loopHandleConnectionStateRequest(buffer, len);
374  break;
375  }
376 
377  case DisconnectRequest:
378  {
379  loopHandleDisconnectRequest(buffer, len);
380  break;
381  }
382 
383  case DescriptionRequest:
384  {
385  loopHandleDescriptionRequest(buffer, len);
386  break;
387  }
388 
390  {
391  loopHandleDeviceConfigurationRequest(buffer, len);
392  break;
393  }
394 
395  case TunnelingRequest:
396  {
397  loopHandleTunnelingRequest(buffer, len);
398  return;
399  }
400 
402  {
403  //TOOD nothing to do now
404  //println("got Ack");
405  break;
406  }
407 
408  case TunnelingAck:
409  {
410  //TOOD nothing to do now
411  //println("got Ack");
412  break;
413  }
414 
415 #endif
416 
417  default:
418  print("Unhandled service identifier: ");
419  println(code, HEX);
420  break;
421  }
422 }
423 
424 #if KNX_SERVICE_FAMILY_CORE >= 2
425 void IpDataLinkLayer::loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t length)
426 {
427  KnxIpSearchRequestExtended searchRequest(buffer, length);
428 
429  if (searchRequest.srpByProgMode)
430  {
431  println("srpByProgMode");
432 
433  if (!knx.progMode())
434  return;
435  }
436 
437  if (searchRequest.srpByMacAddr)
438  {
439  println("srpByMacAddr");
440  const uint8_t* x = _ipParameters.propertyData(PID_MAC_ADDRESS);
441 
442  for (int i = 0; i < 6; i++)
443  if (searchRequest.srpMacAddr[i] != x[i])
444  return;
445  }
446 
447 #define LEN_SERVICE_FAMILIES 2
448 #if MASK_VERSION == 0x091A
449 #ifdef KNX_TUNNELING
450 #define LEN_SERVICE_DIB (2 + 4 * LEN_SERVICE_FAMILIES)
451 #else
452 #define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
453 #endif
454 #else
455 #ifdef KNX_TUNNELING
456 #define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
457 #else
458 #define LEN_SERVICE_DIB (2 + 2 * LEN_SERVICE_FAMILIES)
459 #endif
460 #endif
461 
462  //defaults: "Device Information DIB", "Extended Device Information DIB" and "Supported Services DIB".
463  int dibLength = LEN_DEVICE_INFORMATION_DIB + LEN_SERVICE_DIB + LEN_EXTENDED_DEVICE_INFORMATION_DIB;
464 
465  if (searchRequest.srpByService)
466  {
467  println("srpByService");
468  uint8_t length = searchRequest.srpServiceFamilies[0];
469  uint8_t* currentPos = searchRequest.srpServiceFamilies + 2;
470 
471  for (int i = 0; i < (length - 2) / 2; i++)
472  {
473  uint8_t serviceFamily = (currentPos + i * 2)[0];
474  uint8_t version = (currentPos + i * 2)[1];
475 
476  switch (serviceFamily)
477  {
478  case Core:
479  if (version > KNX_SERVICE_FAMILY_CORE)
480  return;
481 
482  break;
483 
484  case DeviceManagement:
485  if (version > KNX_SERVICE_FAMILY_DEVICE_MANAGEMENT)
486  return;
487 
488  break;
489 
490  case Tunnelling:
491  if (version > KNX_SERVICE_FAMILY_TUNNELING)
492  return;
493 
494  break;
495 
496  case Routing:
497  if (version > KNX_SERVICE_FAMILY_ROUTING)
498  return;
499 
500  break;
501  }
502  }
503  }
504 
505  if (searchRequest.srpRequestDIBs)
506  {
507  //println("srpRequestDIBs");
508  if(searchRequest.requestedDIB(IP_CONFIG))
509  dibLength += LEN_IP_CONFIG_DIB; //16
510 
511  if (searchRequest.requestedDIB(IP_CUR_CONFIG))
512  dibLength += LEN_IP_CURRENT_CONFIG_DIB; //20
513 
514  if (searchRequest.requestedDIB(KNX_ADDRESSES))
515  {
516  uint16_t length = 0;
518  dibLength += 4 + length * 2;
519  }
520 
521  if (searchRequest.requestedDIB(MANUFACTURER_DATA))
522  dibLength += 0; //4 + n
523 
524  if (searchRequest.requestedDIB(TUNNELING_INFO))
525  {
526  uint16_t length = 0;
528  dibLength += 4 + length * 4;
529  }
530  }
531 
532  KnxIpSearchResponseExtended searchResponse(_ipParameters, _deviceObject, dibLength);
533 
534  searchResponse.setDeviceInfo(_ipParameters, _deviceObject); //DescriptionTypeCode::DeviceInfo 1
535  searchResponse.setSupportedServices(); //DescriptionTypeCode::SUPP_SVC_FAMILIES 2
536  searchResponse.setExtendedDeviceInfo(); //DescriptionTypeCode::EXTENDED_DEVICE_INFO 8
537 
538  if (searchRequest.srpRequestDIBs)
539  {
540  if (searchRequest.requestedDIB(IP_CONFIG))
541  searchResponse.setIpConfig(_ipParameters);
542 
543  if (searchRequest.requestedDIB(IP_CUR_CONFIG))
544  searchResponse.setIpCurrentConfig(_ipParameters);
545 
546  if (searchRequest.requestedDIB(KNX_ADDRESSES))
547  searchResponse.setKnxAddresses(_ipParameters, _deviceObject);
548 
549  if (searchRequest.requestedDIB(MANUFACTURER_DATA))
550  {
551  //println("requested MANUFACTURER_DATA but not implemented");
552  }
553 
554  if (searchRequest.requestedDIB(TUNNELING_INFO))
555  searchResponse.setTunnelingInfo(_ipParameters, _deviceObject, tunnels);
556  }
557 
558  if(searchResponse.totalLength() > 500)
559  {
560  printf("skipped response length > 500. Length: %d bytes\n", searchResponse.totalLength());
561  return;
562  }
563 
564  _platform.sendBytesUniCast(searchRequest.hpai().ipAddress(), searchRequest.hpai().ipPortNumber(), searchResponse.data(), searchResponse.totalLength());
565 }
566 #endif
567 
568 #ifdef KNX_TUNNELING
569 void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length, uint32_t& src_addr, uint16_t& src_port)
570 {
571  KnxIpConnectRequest connRequest(buffer, length);
572 #ifdef KNX_LOG_TUNNELING
573  println("Got Connect Request!");
574 
575  switch (connRequest.cri().type())
576  {
578  println("Device Management Connection");
579  break;
580 
581  case TUNNEL_CONNECTION:
582  println("Tunnel Connection");
583  break;
584 
585  case REMLOG_CONNECTION:
586  println("RemLog Connection");
587  break;
588 
589  case REMCONF_CONNECTION:
590  println("RemConf Connection");
591  break;
592 
593  case OBJSVR_CONNECTION:
594  println("ObjectServer Connection");
595  break;
596  }
597 
598  print("Data Endpoint: ");
599  uint32_t ip = connRequest.hpaiData().ipAddress();
600  print(ip >> 24);
601  print(".");
602  print((ip >> 16) & 0xFF);
603  print(".");
604  print((ip >> 8) & 0xFF);
605  print(".");
606  print(ip & 0xFF);
607  print(":");
608  println(connRequest.hpaiData().ipPortNumber());
609  print("Ctrl Endpoint: ");
610  ip = connRequest.hpaiCtrl().ipAddress();
611  print(ip >> 24);
612  print(".");
613  print((ip >> 16) & 0xFF);
614  print(".");
615  print((ip >> 8) & 0xFF);
616  print(".");
617  print(ip & 0xFF);
618  print(":");
619  println(connRequest.hpaiCtrl().ipPortNumber());
620 #endif
621 
622  //We only support 0x03 and 0x04!
623  if (connRequest.cri().type() != TUNNEL_CONNECTION && connRequest.cri().type() != DEVICE_MGMT_CONNECTION)
624  {
625 #ifdef KNX_LOG_TUNNELING
626  println("Only Tunnel/DeviceMgmt Connection ist supported!");
627 #endif
629  _platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
630  return;
631  }
632 
633  if (connRequest.cri().type() == TUNNEL_CONNECTION && connRequest.cri().layer() != 0x02) //LinkLayer
634  {
635  //We only support 0x02!
636 #ifdef KNX_LOG_TUNNELING
637  println("Only LinkLayer ist supported!");
638 #endif
640  _platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
641  return;
642  }
643 
644  // data preparation
645 
646  uint32_t srcIP = connRequest.hpaiCtrl().ipAddress() ? connRequest.hpaiCtrl().ipAddress() : src_addr;
647  uint16_t srcPort = connRequest.hpaiCtrl().ipPortNumber() ? connRequest.hpaiCtrl().ipPortNumber() : src_port;
648 
649  // read current elements in PID_ADDITIONAL_INDIVIDUAL_ADDRESSES
650  uint16_t propCount = 0;
652  const uint8_t* addresses;
653 
654  if (propCount == KNX_TUNNELING)
655  {
656  addresses = _ipParameters.propertyData(PID_ADDITIONAL_INDIVIDUAL_ADDRESSES);
657  }
658  else // no tunnel PA configured, that means device is unconfigured and has 15.15.0
659  {
660  uint8_t addrbuffer[KNX_TUNNELING * 2];
661  addresses = (uint8_t*)addrbuffer;
662 
663  for (int i = 0; i < KNX_TUNNELING; i++)
664  {
665  addrbuffer[i * 2 + 1] = i + 1;
666  addrbuffer[i * 2] = _deviceObject.individualAddress() / 0x0100;
667  }
668 
669  uint8_t count = KNX_TUNNELING;
670  _ipParameters.writeProperty(PID_ADDITIONAL_INDIVIDUAL_ADDRESSES, 1, addrbuffer, count);
671 #ifdef KNX_LOG_TUNNELING
672  println("no Tunnel-PAs configured, using own subnet");
673 #endif
674  }
675 
676  _ipParameters.readPropertyLength(PID_CUSTOM_RESERVED_TUNNELS_CTRL, propCount);
677  const uint8_t* tunCtrlBytes = nullptr;
678 
679  if (propCount == KNX_TUNNELING)
680  tunCtrlBytes = _ipParameters.propertyData(PID_CUSTOM_RESERVED_TUNNELS_CTRL);
681 
682  _ipParameters.readPropertyLength(PID_CUSTOM_RESERVED_TUNNELS_IP, propCount);
683  const uint8_t* tunCtrlIp = nullptr;
684 
685  if (propCount == KNX_TUNNELING)
686  tunCtrlIp = _ipParameters.propertyData(PID_CUSTOM_RESERVED_TUNNELS_IP);
687 
688  bool resTunActive = (tunCtrlBytes && tunCtrlIp);
689 #ifdef KNX_LOG_TUNNELING
690 
691  if (resTunActive)
692  println("Reserved Tunnel Feature active");
693 
694  if (tunCtrlBytes)
695  printHex("tunCtrlBytes", tunCtrlBytes, KNX_TUNNELING);
696 
697  if (tunCtrlIp)
698  printHex("tunCtrlIp", tunCtrlIp, KNX_TUNNELING * 4);
699 
700 #endif
701 
702  // check if there is a reserved tunnel for the source
703  int firstFreeTunnel = -1;
704  int firstResAndFreeTunnel = -1;
705  int firstResAndOccTunnel = -1;
706  bool tunnelResActive[KNX_TUNNELING] = {0};
707  uint8_t tunnelResOptions[KNX_TUNNELING] = {0};
708 
709  for (int i = 0; i < KNX_TUNNELING; i++)
710  {
711  if (resTunActive)
712  {
713  tunnelResActive[i] = *(tunCtrlBytes + i) & 0x80;
714  tunnelResOptions[i] = (*(tunCtrlBytes + i) & 0x60) >> 5;
715  }
716 
717  if(resTunActive && tunnelResActive[i]) // tunnel reserve feature active for this tunnel
718  {
719 #ifdef KNX_LOG_TUNNELING
720  print("tunnel reserve feature active for this tunnel: ");
721  print(tunnelResActive[i]);
722  print(" options: ");
723  println(tunnelResOptions[i]);
724 #endif
725 
726  uint32_t rIP = 0;
727  popInt(rIP, tunCtrlIp + 4 * i);
728 
729  if (srcIP == rIP && connRequest.cri().type() == TUNNEL_CONNECTION)
730  {
731  // reserved tunnel for this ip found
732  if (tunnels[i].ChannelId == 0) // check if it is free
733  {
734  if (firstResAndFreeTunnel < 0)
735  firstResAndFreeTunnel = i;
736  }
737  else
738  {
739  if (firstResAndOccTunnel < 0)
740  firstResAndOccTunnel = i;
741  }
742  }
743  }
744  else
745  {
746  if (tunnels[i].ChannelId == 0 && firstFreeTunnel < 0)
747  firstFreeTunnel = i;
748  }
749  }
750 
751 #ifdef KNX_LOG_TUNNELING
752  print("firstFreeTunnel: ");
753  print(firstFreeTunnel);
754  print(" firstResAndFreeTunnel: ");
755  print(firstResAndFreeTunnel);
756  print(" firstResAndOccTunnel: ");
757  println(firstResAndOccTunnel);
758 #endif
759 
760 
761  uint8_t tunIdx = 0xff;
762 
763  if (resTunActive & (firstResAndFreeTunnel >= 0 || firstResAndOccTunnel >= 0)) // tunnel reserve feature active (for this src)
764  {
765  if (firstResAndFreeTunnel >= 0)
766  {
767  tunIdx = firstResAndFreeTunnel;
768  }
769  else if (firstResAndOccTunnel >= 0)
770  {
771  if (tunnelResOptions[firstResAndOccTunnel] == 1) // decline req
772  {
773  ; // do nothing => decline
774  }
775  else if (tunnelResOptions[firstResAndOccTunnel] == 2) // close current tunnel connection on this tunnel and assign to this request
776  {
777  KnxIpDisconnectRequest discReq;
778  discReq.channelId(tunnels[firstResAndOccTunnel].ChannelId);
779  discReq.hpaiCtrl().length(LEN_IPHPAI);
780  discReq.hpaiCtrl().code(IPV4_UDP);
781  discReq.hpaiCtrl().ipAddress(tunnels[firstResAndOccTunnel].IpAddress);
782  discReq.hpaiCtrl().ipPortNumber(tunnels[firstResAndOccTunnel].PortCtrl);
783  _platform.sendBytesUniCast(tunnels[firstResAndOccTunnel].IpAddress, tunnels[firstResAndOccTunnel].PortCtrl, discReq.data(), discReq.totalLength());
784  tunnels[firstResAndOccTunnel].Reset();
785 
786 
787  tunIdx = firstResAndOccTunnel;
788  }
789  else if (tunnelResOptions[firstResAndOccTunnel] == 3) // use the first unreserved tunnel (if one)
790  {
791  if (firstFreeTunnel >= 0)
792  tunIdx = firstFreeTunnel;
793  else
794  ; // do nothing => decline
795  }
796 
797  //else
798  // should not happen
799  // do nothing => decline
800  }
801 
802  //else
803  // should not happen
804  // do nothing => decline
805  }
806  else
807  {
808  if (firstFreeTunnel >= 0)
809  tunIdx = firstFreeTunnel;
810 
811  //else
812  // do nothing => decline
813  }
814 
815  KnxIpTunnelConnection* tun = nullptr;
816 
817  if (tunIdx != 0xFF)
818  {
819  tun = &tunnels[tunIdx];
820 
821  uint16_t tunPa = 0;
822  popWord(tunPa, addresses + (tunIdx * 2));
823 
824  //check if this PA is in use (should not happen, only when there is one pa wrongly assigned to more then one tunnel)
825  for (int x = 0; x < KNX_TUNNELING; x++)
826  if (tunnels[x].IndividualAddress == tunPa)
827  {
828 #ifdef KNX_LOG_TUNNELING
829  println("cannot use tunnel because PA is already in use");
830 #endif
831  tunIdx = 0xFF;
832  tun = nullptr;
833  break;
834  }
835  if(tun)
836  tun->IndividualAddress = tunPa;
837 
838  }
839 
840  if (tun == nullptr)
841  {
842  println("no free tunnel availible");
844  _platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
845  return;
846  }
847 
848  if (connRequest.cri().type() == DEVICE_MGMT_CONNECTION)
849  tun->IsConfig = true;
850 
851  // the channel ID shall be unique on this tunnel server. catch the rare case of a double channel ID
852  bool channelIdInUse;
853 
854  do
855  {
856  _lastChannelId++;
857  channelIdInUse = false;
858 
859  for (int x = 0; x < KNX_TUNNELING; x++)
860  if (tunnels[x].ChannelId == _lastChannelId)
861  channelIdInUse = true;
862  } while (channelIdInUse);
863 
864  tun->ChannelId = _lastChannelId;
865  tun->lastHeartbeat = millis();
866 
867  if (_lastChannelId == 255)
868  _lastChannelId = 0;
869 
870  tun->IpAddress = srcIP;
871  tun->PortData = connRequest.hpaiData().ipPortNumber()?connRequest.hpaiData().ipPortNumber():srcPort;
872  tun->PortCtrl = connRequest.hpaiCtrl().ipPortNumber()?connRequest.hpaiCtrl().ipPortNumber():srcPort;
873 
874  print("New Tunnel-Connection[");
875  print(tunIdx);
876  print("], Channel: 0x");
877  print(tun->ChannelId, 16);
878  print(" PA: ");
879  print(tun->IndividualAddress >> 12);
880  print(".");
881  print((tun->IndividualAddress >> 8) & 0xF);
882  print(".");
883  print(tun->IndividualAddress & 0xFF);
884 
885  print(" with ");
886  print(tun->IpAddress >> 24);
887  print(".");
888  print((tun->IpAddress >> 16) & 0xFF);
889  print(".");
890  print((tun->IpAddress >> 8) & 0xFF);
891  print(".");
892  print(tun->IpAddress & 0xFF);
893  print(":");
894  print(tun->PortData);
895 
896  if (tun->PortData != tun->PortCtrl)
897  {
898  print(" (Ctrlport: ");
899  print(tun->PortCtrl);
900  print(")");
901  }
902 
903  if (tun->IsConfig)
904  {
905  print(" (Config-Channel)");
906  }
907 
908  println();
909 
910 
911  KnxIpConnectResponse connRes(_ipParameters, tun->IndividualAddress, 3671, tun->ChannelId, connRequest.cri().type());
912  _platform.sendBytesUniCast(tun->IpAddress, tun->PortCtrl, connRes.data(), connRes.totalLength());
913 }
914 
915 void IpDataLinkLayer::loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t length)
916 {
917  KnxIpStateRequest stateRequest(buffer, length);
918 
919  KnxIpTunnelConnection* tun = nullptr;
920 
921  for (int i = 0; i < KNX_TUNNELING; i++)
922  {
923  if (tunnels[i].ChannelId == stateRequest.channelId())
924  {
925  tun = &tunnels[i];
926  break;
927  }
928  }
929 
930  if (tun == nullptr)
931  {
932 #ifdef KNX_LOG_TUNNELING
933  print("Channel ID nicht gefunden: ");
934  println(stateRequest.channelId());
935 #endif
936  KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
937  _platform.sendBytesUniCast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes.data(), stateRes.totalLength());
938  return;
939  }
940 
941  //TODO check knx connection!
942  //if no connection return E_KNX_CONNECTION
943 
944  //TODO check when to send E_DATA_CONNECTION
945 
946  tun->lastHeartbeat = millis();
947  KnxIpStateResponse stateRes(tun->ChannelId, E_NO_ERROR);
948  _platform.sendBytesUniCast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes.data(), stateRes.totalLength());
949 }
950 
951 void IpDataLinkLayer::loopHandleDisconnectRequest(uint8_t* buffer, uint16_t length)
952 {
953  KnxIpDisconnectRequest discReq(buffer, length);
954 
955 #ifdef KNX_LOG_TUNNELING
956  print(">>> Disconnect Channel ID: ");
957  println(discReq.channelId());
958 #endif
959 
960  KnxIpTunnelConnection* tun = nullptr;
961 
962  for (int i = 0; i < KNX_TUNNELING; i++)
963  {
964  if (tunnels[i].ChannelId == discReq.channelId())
965  {
966  tun = &tunnels[i];
967  break;
968  }
969  }
970 
971  if (tun == nullptr)
972  {
973 #ifdef KNX_LOG_TUNNELING
974  print("Channel ID nicht gefunden: ");
975  println(discReq.channelId());
976 #endif
978  _platform.sendBytesUniCast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes.data(), discRes.totalLength());
979  return;
980  }
981 
982 
984  _platform.sendBytesUniCast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes.data(), discRes.totalLength());
985  tun->Reset();
986 }
987 
988 void IpDataLinkLayer::loopHandleDescriptionRequest(uint8_t* buffer, uint16_t length)
989 {
990  KnxIpDescriptionRequest descReq(buffer, length);
991  KnxIpDescriptionResponse descRes(_ipParameters, _deviceObject);
992  _platform.sendBytesUniCast(descReq.hpaiCtrl().ipAddress(), descReq.hpaiCtrl().ipPortNumber(), descRes.data(), descRes.totalLength());
993 }
994 
995 void IpDataLinkLayer::loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length)
996 {
997  KnxIpConfigRequest confReq(buffer, length);
998 
999  KnxIpTunnelConnection* tun = nullptr;
1000 
1001  for (int i = 0; i < KNX_TUNNELING; i++)
1002  {
1003  if (tunnels[i].ChannelId == confReq.connectionHeader().channelId())
1004  {
1005  tun = &tunnels[i];
1006  break;
1007  }
1008  }
1009 
1010  if (tun == nullptr)
1011  {
1012  print("Channel ID nicht gefunden: ");
1013  println(confReq.connectionHeader().channelId());
1014  KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
1015  _platform.sendBytesUniCast(0, 0, stateRes.data(), stateRes.totalLength());
1016  return;
1017  }
1018 
1019  KnxIpTunnelingAck tunnAck;
1021  tunnAck.connectionHeader().length(4);
1022  tunnAck.connectionHeader().channelId(tun->ChannelId);
1023  tunnAck.connectionHeader().sequenceCounter(confReq.connectionHeader().sequenceCounter());
1024  tunnAck.connectionHeader().status(E_NO_ERROR);
1025  _platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
1026 
1027  tun->lastHeartbeat = millis();
1028  _cemiServer->frameReceived(confReq.frame());
1029 }
1030 
1031 void IpDataLinkLayer::loopHandleTunnelingRequest(uint8_t* buffer, uint16_t length)
1032 {
1033  KnxIpTunnelingRequest tunnReq(buffer, length);
1034 
1035  KnxIpTunnelConnection* tun = nullptr;
1036 
1037  for (int i = 0; i < KNX_TUNNELING; i++)
1038  {
1039  if (tunnels[i].ChannelId == tunnReq.connectionHeader().channelId())
1040  {
1041  tun = &tunnels[i];
1042  break;
1043  }
1044  }
1045 
1046  if (tun == nullptr)
1047  {
1048 #ifdef KNX_LOG_TUNNELING
1049  print("Channel ID nicht gefunden: ");
1050  println(tunnReq.connectionHeader().channelId());
1051 #endif
1052  KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
1053  _platform.sendBytesUniCast(0, 0, stateRes.data(), stateRes.totalLength());
1054  return;
1055  }
1056 
1057  uint8_t sequence = tunnReq.connectionHeader().sequenceCounter();
1058 
1059  if (sequence == tun->SequenceCounter_R)
1060  {
1061 #ifdef KNX_LOG_TUNNELING
1062  print("Received SequenceCounter again: ");
1063  println(tunnReq.connectionHeader().sequenceCounter());
1064 #endif
1065  //we already got this one
1066  //so just ack it
1067  KnxIpTunnelingAck tunnAck;
1068  tunnAck.connectionHeader().length(4);
1069  tunnAck.connectionHeader().channelId(tun->ChannelId);
1070  tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
1071  tunnAck.connectionHeader().status(E_NO_ERROR);
1072  _platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
1073  return;
1074  }
1075  else if ((uint8_t)(sequence - 1) != tun->SequenceCounter_R)
1076  {
1077 #ifdef KNX_LOG_TUNNELING
1078  print("Wrong SequenceCounter: got ");
1079  print(tunnReq.connectionHeader().sequenceCounter());
1080  print(" expected ");
1081  println((uint8_t)(tun->SequenceCounter_R + 1));
1082 #endif
1083  //Dont handle it
1084  return;
1085  }
1086 
1087  KnxIpTunnelingAck tunnAck;
1088  tunnAck.connectionHeader().length(4);
1089  tunnAck.connectionHeader().channelId(tun->ChannelId);
1090  tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
1091  tunnAck.connectionHeader().status(E_NO_ERROR);
1092  _platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
1093 
1094  tun->SequenceCounter_R = tunnReq.connectionHeader().sequenceCounter();
1095 
1096  if (tunnReq.frame().sourceAddress() == 0)
1097  tunnReq.frame().sourceAddress(tun->IndividualAddress);
1098 
1099  _cemiServer->frameReceived(tunnReq.frame());
1100 }
1101 #endif
1102 
1104 {
1105  // _print("own address: ");
1106  // _println(_deviceObject.individualAddress());
1107  if (value && !_enabled)
1108  {
1109  _platform.setupMultiCast(_ipParameters.propertyValue<uint32_t>(PID_ROUTING_MULTICAST_ADDRESS), KNXIP_MULTICAST_PORT);
1110  _enabled = true;
1111  return;
1112  }
1113 
1114  if (!value && _enabled)
1115  {
1117  _enabled = false;
1118  return;
1119  }
1120 }
1121 
1123 {
1124  return _enabled;
1125 }
1126 
1128 {
1129  return DptMedium::KNX_IP;
1130 }
1131 
1132 bool IpDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length)
1133 {
1134  if (!_enabled)
1135  return false;
1136 
1137  return _platform.sendBytesMultiCast(bytes, length);
1138 }
1139 
1140 bool IpDataLinkLayer::isSendLimitReached()
1141 {
1142  uint32_t curTime = millis() / 100;
1143 
1144  // check if the countbuffer must be adjusted
1145  if (_frameCountTimeBase >= curTime)
1146  {
1147  uint32_t timeBaseDiff = _frameCountTimeBase - curTime;
1148 
1149  if (timeBaseDiff > 10)
1150  timeBaseDiff = 10;
1151 
1152  for (uint32_t i = 0; i < timeBaseDiff ; i++)
1153  {
1154  _frameCountBase++;
1155  _frameCountBase = _frameCountBase % 10;
1156  _frameCount[_frameCountBase] = 0;
1157  }
1158 
1159  _frameCountTimeBase = curTime;
1160  }
1161  else // _frameCountTimeBase < curTime => millis overflow, reset
1162  {
1163  for (int i = 0; i < 10 ; i++)
1164  _frameCount[i] = 0;
1165 
1166  _frameCountBase = 0;
1167  _frameCountTimeBase = curTime;
1168  }
1169 
1170  //check if we are over the limit
1171  uint16_t sum = 0;
1172 
1173  for (int i = 0; i < 10 ; i++)
1174  sum += _frameCount[i];
1175 
1176  if (sum > 50)
1177  {
1178  println("Dropping packet due to 50p/s limit");
1179  return true; // drop packet
1180  }
1181  else
1182  {
1183  _frameCount[_frameCountBase]++;
1184  //print("sent packages in last 1000ms: ");
1185  //print(sum);
1186  //print(" curTime: ");
1187  //println(curTime);
1188  return false;
1189  }
1190 }
1191 #endif
void print(const char *s)
void println(const char *s)
void printHex(const char *suffix, const uint8_t *data, size_t length, bool newline)
Definition: bits.cpp:12
const uint8_t * popInt(uint32_t &i, const uint8_t *data)
Definition: bits.cpp:41
const uint8_t * popWord(uint16_t &w, const uint8_t *data)
Definition: bits.cpp:34
uint32_t millis()
uint16_t sourceAddress() const
Definition: cemi_frame.cpp:303
uint16_t destinationAddress() const
Definition: cemi_frame.cpp:315
MessageCode messageCode() const
Definition: cemi_frame.cpp:126
AddressType addressType() const
Definition: cemi_frame.cpp:281
void frameReceived(CemiFrame &frame)
uint16_t individualAddress()
const uint8_t * propertyData(PropertyID id)
virtual void writeProperty(PropertyID id, uint16_t start, uint8_t *data, uint8_t &count)
Write property of the interface object.
virtual void readPropertyLength(PropertyID id, uint16_t &length)
Read length of a property of the interface object.
T propertyValue(PropertyID id)
void status(uint8_t status)
Definition: knx_ip_ch.cpp:39
void sequenceCounter(uint8_t sequenceCounter)
Definition: knx_ip_ch.cpp:29
void channelId(uint8_t channelId)
Definition: knx_ip_ch.cpp:19
void length(uint8_t value)
Definition: knx_ip_ch.cpp:14
IpHostProtocolAddressInformation & hpaiCtrl()
uint8_t * data()
uint16_t totalLength() const
uint16_t serviceTypeIdentifier() const
IpHostProtocolAddressInformation & hpai()
virtual bool sendBytesMultiCast(uint8_t *buffer, uint16_t len)
Definition: platform.cpp:97
virtual void closeMultiCast()
Definition: platform.cpp:94
virtual void setupMultiCast(uint32_t addr, uint16_t port)
Definition: platform.cpp:91
virtual bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t *buffer, uint16_t len)
Definition: platform.cpp:102
virtual int readBytesMultiCast(uint8_t *buffer, uint16_t maxLen)
Definition: platform.cpp:107
KnxFacade< SamdPlatform, Bau07B0 > knx(buttonEvent)
Definition: knx_facade.h:514
@ E_CONNECTION_ID
@ E_TUNNELING_LAYER
@ E_NO_MORE_CONNECTIONS
@ E_CONNECTION_TYPE
@ REMLOG_CONNECTION
Definition: knx_ip_cri.h:15
@ OBJSVR_CONNECTION
Definition: knx_ip_cri.h:17
@ TUNNEL_CONNECTION
Definition: knx_ip_cri.h:14
@ DEVICE_MGMT_CONNECTION
Definition: knx_ip_cri.h:13
@ REMCONF_CONNECTION
Definition: knx_ip_cri.h:16
@ IP_CONFIG
Definition: knx_ip_dib.h:12
@ TUNNELING_INFO
Definition: knx_ip_dib.h:16
@ MANUFACTURER_DATA
Definition: knx_ip_dib.h:15
@ KNX_ADDRESSES
Definition: knx_ip_dib.h:14
@ IP_CUR_CONFIG
Definition: knx_ip_dib.h:13
KnxIpServiceType
Definition: knx_ip_frame.h:15
@ SearchRequestExt
Definition: knx_ip_frame.h:26
@ DisconnectRequest
Definition: knx_ip_frame.h:24
@ DeviceConfigurationAck
Definition: knx_ip_frame.h:29
@ ConnectRequest
Definition: knx_ip_frame.h:20
@ ConnectionStateRequest
Definition: knx_ip_frame.h:22
@ TunnelingAck
Definition: knx_ip_frame.h:31
@ DeviceConfigurationRequest
Definition: knx_ip_frame.h:28
@ DescriptionRequest
Definition: knx_ip_frame.h:18
@ SearchRequest
Definition: knx_ip_frame.h:16
@ TunnelingRequest
Definition: knx_ip_frame.h:30
@ RoutingIndication
Definition: knx_ip_frame.h:32
@ L_data_con
Definition: knx_types.h:42
@ L_data_req
Definition: knx_types.h:41
@ L_data_ind
Definition: knx_types.h:43
DptMedium
Definition: knx_types.h:254
@ KNX_IP
Definition: knx_types.h:260
@ GroupAddress
Definition: knx_types.h:35
@ IndividualAddress
Definition: knx_types.h:34
@ PID_MAC_ADDRESS
Definition: property.h:128
@ PID_ADDITIONAL_INDIVIDUAL_ADDRESSES
Definition: property.h:117
@ PID_CUSTOM_RESERVED_TUNNELS_IP
Definition: property.h:143
@ PID_CUSTOM_RESERVED_TUNNELS_CTRL
Definition: property.h:142
@ PID_ROUTING_MULTICAST_ADDRESS
Definition: property.h:130