|
39 | 39 | import org.slf4j.LoggerFactory;
|
40 | 40 |
|
41 | 41 | import tuwien.auto.calimero.CloseEvent;
|
| 42 | +import tuwien.auto.calimero.DataUnitBuilder; |
42 | 43 | import tuwien.auto.calimero.DetachEvent;
|
43 | 44 | import tuwien.auto.calimero.FrameEvent;
|
44 | 45 | import tuwien.auto.calimero.GroupAddress;
|
45 | 46 | import tuwien.auto.calimero.IndividualAddress;
|
| 47 | +import tuwien.auto.calimero.KNXAddress; |
46 | 48 | import tuwien.auto.calimero.KNXException;
|
47 | 49 | import tuwien.auto.calimero.KNXIllegalArgumentException;
|
| 50 | +import tuwien.auto.calimero.cemi.CEMILData; |
| 51 | +import tuwien.auto.calimero.cemi.CemiTData; |
48 | 52 | import tuwien.auto.calimero.datapoint.CommandDP;
|
49 | 53 | import tuwien.auto.calimero.datapoint.Datapoint;
|
50 | 54 | import tuwien.auto.calimero.device.ProcessCommunicationResponder;
|
|
60 | 64 | import tuwien.auto.calimero.process.ProcessEvent;
|
61 | 65 | import tuwien.auto.calimero.process.ProcessListener;
|
62 | 66 | import tuwien.auto.calimero.secure.KnxSecureException;
|
| 67 | +import tuwien.auto.calimero.secure.SecureApplicationLayer; |
63 | 68 | import tuwien.auto.calimero.secure.Security;
|
64 | 69 |
|
65 | 70 | /**
|
@@ -348,12 +353,13 @@ private void processEvent(String task, ProcessEvent event, ListenerNotification
|
348 | 353 | if (!isHandled) {
|
349 | 354 | logger.trace("Address '{}' is not configured in openHAB", destination);
|
350 | 355 | final String type = switch (event.getServiceCode()) {
|
351 |
| - case 0x80 -> " GROUP_WRITE("; |
352 |
| - case 0x40 -> " GROUP_RESPONSE("; |
353 |
| - case 0x00 -> " GROUP_READ("; |
354 |
| - default -> " ?("; |
| 356 | + case 0x80 -> "GROUP_WRITE"; |
| 357 | + case 0x40 -> "GROUP_RESPONSE"; |
| 358 | + case 0x00 -> "GROUP_READ"; |
| 359 | + default -> "?"; |
355 | 360 | };
|
356 |
| - final String key = destination.toString() + type + event.getASDU().length + ")"; |
| 361 | + final String key = String.format("%2d/%1d/%3d %s(%02d)", destination.getMainGroup(), |
| 362 | + destination.getMiddleGroup(), destination.getSubGroup8(), type, event.getASDU().length); |
357 | 363 | commandExtensionData.unknownGA().compute(key, (k, v) -> v == null ? 1 : v + 1);
|
358 | 364 | }
|
359 | 365 | }
|
@@ -429,7 +435,38 @@ public void linkClosed(@Nullable CloseEvent closeEvent) {
|
429 | 435 |
|
430 | 436 | @Override
|
431 | 437 | public void indication(@Nullable FrameEvent e) {
|
432 |
| - // no-op |
| 438 | + // NetworkLinkListener indication. This implementation is triggered whenever a frame is received. |
| 439 | + // It is not necessary for OH, as we process incoming group writes via different triggers. |
| 440 | + // However, this indication also covers encrypted data secure frames, which would typically |
| 441 | + // be dropped silently by the Calimero library (a log message is only visible when log level for Calimero |
| 442 | + // is set manually). |
| 443 | + |
| 444 | + // Implementation searches for incoming data secure frames which cannot be decoded due to missing key |
| 445 | + if (e != null) { |
| 446 | + final var cemi = e.getFrame(); |
| 447 | + if (!(cemi instanceof CemiTData)) { |
| 448 | + final CEMILData f = (CEMILData) cemi; |
| 449 | + final int ctrl = f.getPayload()[0] & 0xfc; |
| 450 | + if (ctrl == 0) { |
| 451 | + final KNXAddress dst = f.getDestination(); |
| 452 | + if (dst instanceof GroupAddress ga) { |
| 453 | + if (dst.getRawAddress() != 0) { |
| 454 | + final byte[] payload = f.getPayload(); |
| 455 | + final int service = DataUnitBuilder.getAPDUService(payload); |
| 456 | + if (service == SecureApplicationLayer.SecureService) { |
| 457 | + if (!openhabSecurity.groupKeys().containsKey(dst)) { |
| 458 | + logger.trace("Address '{}' cannot be decrypted, group key missing", dst); |
| 459 | + final String key = String.format( |
| 460 | + "%2d/%1d/%3d secure: missing group key, cannot decrypt", ga.getMainGroup(), |
| 461 | + ga.getMiddleGroup(), ga.getSubGroup8()); |
| 462 | + commandExtensionData.unknownGA().compute(key, (k, v) -> v == null ? 1 : v + 1); |
| 463 | + } |
| 464 | + } |
| 465 | + } |
| 466 | + } |
| 467 | + } |
| 468 | + } |
| 469 | + } |
433 | 470 | }
|
434 | 471 |
|
435 | 472 | @Override
|
|
0 commit comments