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

		if (data.size() < 7) {
			onInvalidDataReceived(device, data);
			return;
		}
		// First byte: flags
		int offset = 0;
		final int flags = data.getIntValue(Data.FORMAT_UINT8, offset++);

		// See UNIT_* for unit options
		final int unit = (flags & 0x01) == UNIT_mmHg ? UNIT_mmHg : UNIT_kPa;
		final boolean timestampPresent         = (flags & 0x02) != 0;
		final boolean pulseRatePresent         = (flags & 0x04) != 0;
		final boolean userIdPresent            = (flags & 0x08) != 0;
		final boolean measurementStatusPresent = (flags & 0x10) != 0;

		if (data.size() < 7
				+ (timestampPresent ? 7 : 0) + (pulseRatePresent ? 2 : 0)
				+ (userIdPresent ? 1 : 0) + (measurementStatusPresent ? 2 : 0)) {
			onInvalidDataReceived(device, data);
			return;
		}

		// Following bytes - systolic, diastolic and mean arterial pressure
		final float cuffPressure = data.getFloatValue(Data.FORMAT_SFLOAT, offset);
		// final float ignored_1 = data.getFloatValue(Data.FORMAT_SFLOAT, offset + 2);
		// final float ignored_2 = data.getFloatValue(Data.FORMAT_SFLOAT, offset + 4);
		offset += 6;

		// Parse timestamp if present
		Calendar calendar = null;
		if (timestampPresent) {
			calendar = DateTimeDataCallback.readDateTime(data, offset);
			offset += 7;
		}

		// Parse pulse rate if present
		Float pulseRate = null;
		if (pulseRatePresent) {
			pulseRate = data.getFloatValue(Data.FORMAT_SFLOAT, offset);
			offset += 2;
		}

		// Read user id if present
		Integer userId = null;
		if (userIdPresent) {
			userId = data.getIntValue(Data.FORMAT_UINT8, offset);
			offset += 1;
		}

		// Read measurement status if present
		BPMStatus status = null;
		if (measurementStatusPresent) {
			final int measurementStatus = data.getIntValue(Data.FORMAT_UINT16_LE, offset);
			// offset += 2;
			status = new BPMStatus(measurementStatus);
		}

		onIntermediateCuffPressureReceived(device, cuffPressure, unit, pulseRate, userId, status, calendar);
	}
@Test
	public void onIntermediateCuffPressureReceived_full() {
		final DataReceivedCallback callback = new IntermediateCuffPressureDataCallback() {
			@Override
			public void onIntermediateCuffPressureReceived(@NonNull final BluetoothDevice device,
														   final float cuffPressure, final int unit,
														   @Nullable final Float pulseRate, @Nullable final Integer userID,
														   @Nullable final BPMStatus status, @Nullable final Calendar calendar) {
				assertEquals("Cuff pressure", 4.0, cuffPressure, 0);
				assertEquals("Unit: mmHg", 0, unit);
				assertNotNull("Pulse rate set", pulseRate);
				assertEquals("Pulse rate", 60.0, pulseRate, 0);
				assertNotNull("User ID set", userID);
				assertEquals("User ID", 1, userID.intValue());
				assertNotNull("Status set", status);
				assertTrue(status.bodyMovementDetected);
				assertTrue(status.cuffTooLose);
				assertTrue(status.irregularPulseDetected);
				assertTrue(status.pulseRateInRange);
				assertFalse(status.pulseRateExceedsUpperLimit);
				assertFalse(status.pulseRateIsLessThenLowerLimit);
				assertTrue(status.improperMeasurementPosition);
				assertNotNull("Calendar set", calendar);
				assertFalse(calendar.isSet(Calendar.YEAR));
				assertTrue(calendar.isSet(Calendar.MONTH));
				assertTrue(calendar.isSet(Calendar.DATE));
				assertEquals("Month", Calendar.APRIL, calendar.get(Calendar.MONTH));
				assertEquals("Day", 17, calendar.get(Calendar.DATE));
				assertEquals("Hour", 20, calendar.get(Calendar.HOUR_OF_DAY));
				assertEquals("Minute", 41, calendar.get(Calendar.MINUTE));
				assertEquals("Second", 59, calendar.get(Calendar.SECOND));
				assertEquals("Milliseconds", 0, calendar.get(Calendar.MILLISECOND));
			}

			@Override
			public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
				assertEquals("Correct ICP reported as invalid", 1, 2);
			}
		};
		final MutableData data = new MutableData(new byte[19]);
		// Flags
		data.setByte(0b11110, 0);
		// Cuff pressure in mmHg
		data.setValue(4, 0, Data.FORMAT_SFLOAT, 1);
		// Date and Time
		data.setValue(0, Data.FORMAT_UINT16_LE, 7);
		data.setValue(4, Data.FORMAT_UINT8, 9);
		data.setValue(17, Data.FORMAT_UINT8, 10);
		data.setValue(20, Data.FORMAT_UINT8, 11);
		data.setValue(41, Data.FORMAT_UINT8, 12);
		data.setValue(59, Data.FORMAT_UINT8, 13);
		// Pulse rate
		data.setValue(60, 0, Data.FORMAT_SFLOAT, 14);
		// User ID
		data.setValue(1, Data.FORMAT_UINT8, 16);
		// Measurement status
		data.setValue(0b100111, Data.FORMAT_UINT16_LE, 17);

		assertArrayEquals(
				new byte[] { 0x1E, (byte) 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x11, 0x14, 0x29, 0x3B, 0x3C, 0x00, 0x01, 0x27, 0x00 },
				data.getValue()
		);

		callback.onDataReceived(null, data);
	}