@Override
	public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
		super.onDataReceived(device, data);

		if (data.size() != 6) {
			onInvalidDataReceived(device, data);
			return;
		}

		final int featuresValue = data.getIntValue(Data.FORMAT_UINT24_LE, 0);
		final int typeAndSampleLocation = data.getIntValue(Data.FORMAT_UINT8, 3);
		final int expectedCrc = data.getIntValue(Data.FORMAT_UINT16_LE, 4);

		final CGMFeatures features = new CGMFeatures(featuresValue);
		if (features.e2eCrcSupported) {
			final int actualCrc = CRC16.MCRF4XX(data.getValue(), 0, 4);
			if (actualCrc != expectedCrc) {
				onContinuousGlucoseMonitorFeaturesReceivedWithCrcError(device, data);
				return;
			}
		} else {
			// If the device doesn't support E2E-safety the value of the field shall be set to 0xFFFF.
			if (expectedCrc != 0xFFFF) {
				onInvalidDataReceived(device, data);
				return;
			}
		}

		@SuppressLint("WrongConstant")
		final int type = typeAndSampleLocation & 0x0F; // least significant nibble
		final int sampleLocation = typeAndSampleLocation >> 4; // most significant nibble

		onContinuousGlucoseMonitorFeaturesReceived(device, features, type, sampleLocation, features.e2eCrcSupported);
	}
@Test
	public void onContinuousGlucoseMeasurementFeaturesReceivedWithCrcError() {
		final DataReceivedCallback callback = new CGMFeatureDataCallback() {
			@Override
			public void onContinuousGlucoseMonitorFeaturesReceived(@NonNull final BluetoothDevice device, @NonNull final CGMFeatures features,
																   final int type, final int sampleLocation, final boolean secured) {
				assertEquals("Wrong CRC but data reported", 1, 2);
			}

			@Override
			public void onContinuousGlucoseMonitorFeaturesReceivedWithCrcError(@NonNull final BluetoothDevice device, @NonNull final Data data) {
				called = true;
			}

			@Override
			public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
				assertEquals("Wrong CRC but invalid data reported", 1, 2);
			}
		};
		final MutableData data = new MutableData(new byte[6]);
		assertTrue(data.setValue(0b11001111001101110, Data.FORMAT_UINT24_LE, 0));
		assertTrue(data.setValue(0x16, Data.FORMAT_UINT8, 3));
		assertTrue(data.setValue(0xBEAF, Data.FORMAT_UINT16_LE, 4));
		called = false;
		//noinspection DataFlowIssue
		callback.onDataReceived(null, data);
		assertTrue(called);
	}