@Override
    public void frameReceived(final FrameEvent e) {
      try {
        // with EMI1 frames, there is the possibility we receive some left-over Get-Value responses
        // from BCU switching during link setup, silently discard them
        final byte[] emi1 = e.getFrameBytes();
        if (emi1 != null && BcuSwitcher.isEmi1GetValue(emi1[0] & 0xff)) return;

        final CEMI cemi = onReceive(e);
        if (cemi instanceof CEMIDevMgmt) {
          // XXX check .con correctly (required for setting cEMI link layer mode)
          final int mc = cemi.getMessageCode();
          if (mc == CEMIDevMgmt.MC_PROPWRITE_CON) {
            final CEMIDevMgmt f = (CEMIDevMgmt) cemi;
            if (f.isNegativeResponse())
              logger.error("L-DM negative response, " + f.getErrorMessage());
          }
        }
        // from this point on, we are only dealing with L_Data
        if (!(cemi instanceof CEMILData)) return;
        final CEMILData f = (CEMILData) cemi;
        final int mc = f.getMessageCode();
        if (mc == CEMILData.MC_LDATA_IND) {
          addEvent(l -> l.indication(new FrameEvent(source, f)));
          logger.debug("indication {}", f.toString());
        } else if (mc == CEMILData.MC_LDATA_CON) {
          addEvent(l -> l.confirmation(new FrameEvent(source, f)));
          logger.debug("confirmation of {}", f.getDestination());
        } else
          logger.warn("unspecified frame event - ignored, msg code = 0x" + Integer.toHexString(mc));
      } catch (final KNXFormatException | RuntimeException ex) {
        logger.warn(
            "received unspecified frame {}", DataUnitBuilder.toHex(e.getFrameBytes(), ""), ex);
      }
    }
    public void frameReceived(final FrameEvent e) {
      try {
        final CEMI frame = e.getFrame();

        final CEMIBusMon mon;
        if (frame == null) mon = (CEMIBusMon) CEMIFactory.fromEmiBusmon(e.getFrameBytes());
        else if (frame instanceof CEMIBusMon) mon = (CEMIBusMon) frame;
        else {
          logger.warn(
              "received unsupported frame type with msg code 0x"
                  + Integer.toHexString(frame.getMessageCode()));
          return;
        }
        logger.trace("received monitor indication");
        final AbstractMonitor netmon = (AbstractMonitor) source;
        MonitorFrameEvent mfe = new MonitorFrameEvent(netmon, mon);
        if (decode) {
          try {
            final RawFrame rf =
                RawFrameFactory.create(netmon.medium.getMedium(), mon.getPayload(), 0, extBusmon);
            mfe = new MonitorFrameEvent(netmon, mon, rf);
          } catch (final KNXFormatException ex) {
            logger.error("decoding raw frame", ex);
            mfe = new MonitorFrameEvent(netmon, mon, ex);
            // workaround for PL, BCU might not have switched to ext. busmonitor
            if (extBusmon) {
              extBusmon = false;
              logger.warn("disable extended busmonitor mode, maybe this helps");
            }
          }
        }
        addEvent(new Indication(mfe));
      } catch (final KNXFormatException kfe) {
        logger.warn("unspecified frame event - ignored", kfe);
      } catch (final RuntimeException rte) {
        logger.warn("unspecified frame event - ignored", rte);
      }
    }
 /**
  * Returns a cEMI representation, e.g., cEMI L-Data, using the received frame event for EMI and
  * cEMI formats. Override this method if the used message format does not conform to the supported
  * EMI 1/2 or cEMI format.
  *
  * @param e the received frame event
  * @return the constructed cEMI message, e.g., cEMI L-Data
  * @throws KNXFormatException on unsupported frame formats, or errors in the frame format
  */
 protected CEMI onReceive(final FrameEvent e) throws KNXFormatException {
   final CEMI f = e.getFrame();
   return f != null ? f : CEMIFactory.createFromEMI(e.getFrameBytes());
 }