Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3298d360 authored by Eiji's avatar Eiji Committed by Paul Colta
Browse files

HDMI: Fix BCD handling error

isValidHour/isValidMinute accept a parameter as BCD encoded value, but they check it without translating to raw value, so valid hour/minute may be detected as an error;
e.g.
18:00 is within 23:00 but 0x18(24) is over 23
* 0x18 should be decoded  (0x10 >> 4) x 10 + 0x08 = 18

Fix to translate the parameter before checking by isWithinRange.

Bug: 357733495
Change-Id: Id0cfb1211048b1f2eaebf3db5814e3da0f34e5b9
parent 2d8aff7e
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -486,6 +486,7 @@ public class HdmiCecMessageValidator {
     * @return true if the hour is valid
     */
    private static boolean isValidHour(int value) {
        value = bcdToDecimal(value);
        return isWithinRange(value, 0, 23);
    }

@@ -497,6 +498,7 @@ public class HdmiCecMessageValidator {
     * @return true if the minute is valid
     */
    private static boolean isValidMinute(int value) {
        value = bcdToDecimal(value);
        return isWithinRange(value, 0, 59);
    }

@@ -508,9 +510,23 @@ public class HdmiCecMessageValidator {
     * @return true if the duration hours is valid
     */
    private static boolean isValidDurationHours(int value) {
        value = bcdToDecimal(value);
        return isWithinRange(value, 0, 99);
    }

    /**
     * Convert BCD value to decimal value.
     *
     * @param value BCD value
     * @return decimal value
     */
    private static int bcdToDecimal(int value) {
        int tens = (value & 0xF0) >> 4;
        int ones = (value & 0x0F);

        return tens * 10 + ones;
    }

    /**
     * Check if the given value is a valid recording sequence. A valid value is adheres to range
     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+49 −49
Original line number Diff line number Diff line
@@ -249,120 +249,120 @@ public class HdmiCecMessageValidatorTest {
        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:13:AD:06")
                .isEqualTo(ERROR_PARAMETER_SHORT);
        // Out of range Day of Month
        assertMessageValidity("04:34:20:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:20:0C:22:15:08:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        // Out of range Month of Year
        assertMessageValidity("04:33:0C:00:10:1E:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:33:0C:00:16:30:04:48:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Hour
        assertMessageValidity("04:34:04:0C:18:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:04:0C:24:15:08:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Minute
        assertMessageValidity("04:33:0C:08:10:50:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:33:0C:08:16:60:04:48:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Duration Hours
        assertMessageValidity("04:34:04:0C:16:0F:64:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:04:0C:22:15:9A:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Minute
        assertMessageValidity("04:33:0C:08:10:1E:04:64:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:33:0C:08:16:30:04:60:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("04:34:04:0C:16:0F:08:37:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:04:0C:22:15:08:55:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("04:33:0C:08:10:1E:04:30:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:33:0C:08:16:30:04:48:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
        // Out of range Analogue Broadcast Type
        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:04:0C:22:15:08:55:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
        // Out of range Analogue Frequency
        assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:33:0C:08:16:30:04:48:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
        // Out of range Broadcast System
        assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:34:04:0C:22:15:08:55:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
    }

    @Test
    public void isValid_setDigitalTimer_clearDigitalTimer() {
        // Services identified by Digital IDs - ARIB Broadcast System
        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
        assertMessageValidity("04:99:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
        // Service identified by Digital IDs - ATSC Broadcast System
        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39:5A").isEqualTo(OK);
        assertMessageValidity("04:97:1E:07:18:32:80:40:01:01:8B:5E:39:5A").isEqualTo(OK);
        // Service identified by Digital IDs - DVB Broadcast System
        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
        assertMessageValidity("04:99:05:0C:06:10:25:59:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
        // Service identified by Channel - 1 part channel number
        assertMessageValidity("04:97:12:06:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(OK);
        assertMessageValidity("04:97:12:06:12:45:90:25:08:91:04:00:B1").isEqualTo(OK);
        // Service identified by Channel - 2 part channel number
        assertMessageValidity("04:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(OK);
        assertMessageValidity("04:99:15:09:00:15:00:45:04:82:09:C8:72:C8").isEqualTo(OK);

        assertMessageValidity("4F:97:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30")
        assertMessageValidity("4F:97:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75:30")
                .isEqualTo(ERROR_DESTINATION);
        assertMessageValidity("F0:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("F0:99:15:09:00:15:00:45:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("04:97:1E:12:20:58:01:01:8B:5E:39:5A")
                .isEqualTo(ERROR_PARAMETER_SHORT);
        // Out of range Day of Month
        assertMessageValidity("04:99:24:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC")
        assertMessageValidity("04:99:24:0C:06:10:25:59:40:19:8B:44:03:11:04:FC")
                .isEqualTo(ERROR_PARAMETER);
        // Out of range Month of Year
        assertMessageValidity("04:97:12:10:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:97:12:10:12:45:90:25:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Hour
        assertMessageValidity("04:99:0C:08:20:05:04:1E:00:00:C4:C2:11:D8:75:30")
        assertMessageValidity("04:99:0C:08:24:05:04:30:00:00:C4:C2:11:D8:75:30")
                .isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Minute
        assertMessageValidity("04:97:15:09:00:4B:00:2D:04:82:09:C8:72:C8")
        assertMessageValidity("04:97:15:09:00:60:00:45:04:82:09:C8:72:C8")
                .isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Duration Hours
        assertMessageValidity("04:99:1E:07:12:20:78:28:01:01:8B:5E:39:5A")
        assertMessageValidity("04:99:1E:07:18:32:9A:40:01:01:8B:5E:39:5A")
                .isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Minute
        assertMessageValidity("04:97:05:0C:06:0A:19:48:40:19:8B:44:03:11:04:FC")
        assertMessageValidity("04:97:05:0C:06:10:25:60:40:19:8B:44:03:11:04:FC")
                .isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("04:99:12:06:0C:2D:5A:19:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:99:12:06:12:45:90:25:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("04:97:0C:08:15:05:04:1E:A1:00:C4:C2:11:D8:75:30")
                .isEqualTo(ERROR_PARAMETER);

        // Invalid Digital Broadcast System
        assertMessageValidity("04:99:1E:07:12:20:50:28:01:04:8B:5E:39:5A")
        assertMessageValidity("04:99:1E:07:18:32:80:40:01:04:8B:5E:39:5A")
                .isEqualTo(ERROR_PARAMETER);
        // Invalid Digital Broadcast System
        assertMessageValidity("04:97:05:0C:06:0A:19:3B:40:93:8B:44:03:11:04:FC")
        assertMessageValidity("04:97:05:0C:06:10:25:59:40:93:8B:44:03:11:04:FC")
                .isEqualTo(ERROR_PARAMETER);
        // Insufficient data for ARIB Broadcast system
        assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75")
        assertMessageValidity("04:99:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75")
                .isEqualTo(ERROR_PARAMETER);
        // Insufficient data for ATSC Broadcast system
        assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:97:1E:07:18:32:80:40:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
        // Insufficient data for DVB Broadcast system
        assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04")
        assertMessageValidity("04:99:05:0C:06:10:25:59:40:19:8B:44:03:11:04")
                .isEqualTo(ERROR_PARAMETER);
        // Insufficient data for 2 part channel number
        assertMessageValidity("04:97:15:09:00:0F:00:2D:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:97:15:09:00:15:00:45:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
        // Invalid Channel Number format
        assertMessageValidity("04:99:12:06:0C:2D:5A:19:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:99:12:06:12:45:90:25:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
    }

    @Test
    public void isValid_setExternalTimer_clearExternalTimer() {
        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(OK);
        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(OK);
        assertMessageValidity("40:A1:0C:08:21:05:04:30:02:04:20").isEqualTo(OK);
        assertMessageValidity("40:A2:14:09:18:40:75:25:10:05:10:00").isEqualTo(OK);

        assertMessageValidity("4F:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(ERROR_DESTINATION);
        assertMessageValidity("F4:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
        assertMessageValidity("4F:A1:0C:08:21:05:04:30:02:04:20").isEqualTo(ERROR_DESTINATION);
        assertMessageValidity("F4:A2:14:09:18:40:75:25:10:05:10:00").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("40:A1:0C:08:21:05:04:30:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
        // Out of range Day of Month
        assertMessageValidity("40:A2:28:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:28:09:18:40:75:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        // Out of range Month of Year
        assertMessageValidity("40:A1:0C:0F:15:05:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A1:0C:0F:21:05:04:30:02:04:20").isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Hour
        assertMessageValidity("40:A2:14:09:1A:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:14:09:24:40:75:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        // Out of range Start Time - Minute
        assertMessageValidity("40:A1:0C:08:15:48:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A1:0C:08:21:60:04:30:02:04:20").isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Duration Hours
        assertMessageValidity("40:A2:14:09:12:28:66:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:14:09:18:40:9A:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
        // Out of range Duration - Minute
        assertMessageValidity("40:A1:0C:08:15:05:04:3F:02:04:20").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A1:0C:08:21:05:04:60:02:04:20").isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:14:09:18:40:75:25:84:05:10:00").isEqualTo(ERROR_PARAMETER);
        // Invalid Recording Sequence
        assertMessageValidity("40:A1:0C:08:15:05:04:1E:94:04:20").isEqualTo(ERROR_PARAMETER);
        // Invalid external source specifier
        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:08:10:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:14:09:18:40:75:25:10:08:10:00").isEqualTo(ERROR_PARAMETER);
        // Invalid External PLug
        assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("04:A1:0C:08:21:05:04:30:02:04:00").isEqualTo(ERROR_PARAMETER);
        // Invalid Physical Address
        assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:10").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:A2:14:09:18:40:75:25:10:05:10:10").isEqualTo(ERROR_PARAMETER);
    }

    @Test
@@ -395,9 +395,9 @@ public class HdmiCecMessageValidatorTest {
        // Non programmed - Invalid not programmed error info
        assertMessageValidity("40:35:DE").isEqualTo(ERROR_PARAMETER);
        // Programmed - Might not be enough space available - Invalid duration hours
        assertMessageValidity("40:35:BB:96:1C").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:35:BB:9A:28").isEqualTo(ERROR_PARAMETER);
        // Not programmed - Duplicate - Invalid duration minutes
        assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER);
        assertMessageValidity("40:35:EE:82:60").isEqualTo(ERROR_PARAMETER);
    }

    @Test