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

		if (data.size() < 1) {
			onInvalidDataReceived(device, data);
			return;
		}

		// Decode the new data
		int offset = 0;
		final int flags = data.getByte(offset);
		offset += 1;

		final boolean wheelRevPresent = (flags & 0x01) != 0;
		final boolean crankRevPreset = (flags & 0x02) != 0;

		if (data.size() < 1 + (wheelRevPresent ? 6 : 0) + (crankRevPreset ? 4 : 0)) {
			onInvalidDataReceived(device, data);
			return;
		}

		if (wheelRevPresent) {
			final long wheelRevolutions = data.getIntValue(Data.FORMAT_UINT32_LE, offset) & 0xFFFFFFFFL;
			offset += 4;

			final int lastWheelEventTime = data.getIntValue(Data.FORMAT_UINT16_LE, offset); // 1/1024 s
			offset += 2;

			if (mInitialWheelRevolutions < 0)
				mInitialWheelRevolutions = wheelRevolutions;

			// Notify listener about the new measurement
			onWheelMeasurementReceived(device, wheelRevolutions, lastWheelEventTime);
		}

		if (crankRevPreset) {
			final int crankRevolutions = data.getIntValue(Data.FORMAT_UINT16_LE, offset);
			offset += 2;

			final int lastCrankEventTime = data.getIntValue(Data.FORMAT_UINT16_LE, offset);
			// offset += 2;

			// Notify listener about the new measurement
			onCrankMeasurementReceived(device, crankRevolutions, lastCrankEventTime);
		}
	}
@Test
	public void onDistanceChanged() {
		final DataReceivedCallback callback = new CyclingSpeedAndCadenceMeasurementDataCallback() {
			@Override
			public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
				assertEquals("Correct CSC data reported as invalid", 1, 2);
			}

			@Override
			public void onDistanceChanged(@NonNull final BluetoothDevice device, final float totalDistance, final float distance, final float speed) {
				assertEquals("Total distance", 2 * 23.4f, totalDistance, 0.01);
				assertEquals("Distance", 23.4, distance, 0.01);
				assertEquals("Speed", 23.4f, speed, 0.01);
			}

			@Override
			public void onCrankDataChanged(@NonNull final BluetoothDevice device, final float crankCadence, final float gearRatio) {
				assertEquals("Crank data not available and reported", 1, 2);
			}
		};
		final MutableData data = new MutableData(new byte[7]);
		// Flags
		assertTrue(data.setByte(0x01, 0));
		// Wheel revolutions
		assertTrue(data.setValue(10, Data.FORMAT_UINT32_LE, 1));
		assertTrue(data.setValue(0, Data.FORMAT_UINT16_LE, 5));

		callback.onDataReceived(null, data);

		// Update wheel revolutions
		assertTrue(data.setValue(20, Data.FORMAT_UINT32_LE, 1));
		assertTrue(data.setValue(1024, Data.FORMAT_UINT16_LE, 5)); // 1 second
		callback.onDataReceived(null, data);
	}