From 76afa00fa3fed16cd7d765e7c3082699ddd5e34c Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Tue, 27 Oct 2020 15:58:00 +0530 Subject: [PATCH 1/3] CEC : Add set timer program title message validator Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ia9d3491177115f0c466408860dd635be4efc4a35 --- .../android/server/hdmi/HdmiCecMessageValidator.java | 2 ++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 66d9f607d5d42..c5b1893e6c205 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -131,6 +131,8 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SET_TIMER_PROGRAM_TITLE, new AsciiValidator(1, 14), DEST_DIRECT); // Messages for the System Information. FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index a034643233e20..3d2e39d7e90af 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -129,6 +129,17 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:9A:07").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_setTimerProgramTitle() { + assertMessageValidity("40:67:47:61:6D:65:20:6F:66:20:54:68:72:6F:6E:65:73").isEqualTo(OK); + assertMessageValidity("40:67:4A").isEqualTo(OK); + + assertMessageValidity("4F:67:47:4F:54").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F4:67:47:4F:54").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:67").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:67:47:9A:54").isEqualTo(ERROR_PARAMETER); + } + @Test public void isValid_setMenuLanguage() { assertMessageValidity("4F:32:53:50:41").isEqualTo(OK); From a5e8c275dd9b34b1cb2767f09367f9101e5cac32 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Wed, 7 Oct 2020 13:28:12 +0530 Subject: [PATCH 2/3] CEC: Add Digital Timer validator Used to validate and message parameters Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: I60d845acf7ae9d9f26b129bab49ed28450d39a00 --- .../server/hdmi/HdmiCecMessageValidator.java | 117 ++++++++++++++++++ .../hdmi/HdmiCecMessageValidatorTest.java | 61 +++++++++ 2 files changed, 178 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index c5b1893e6c205..4ff67cdb92d39 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -125,10 +125,14 @@ public class HdmiCecMessageValidator { // TODO: Handle messages for the Timer Programming. addValidationInfo( Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_CLEAR_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_CLEAR_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SET_DIGITAL_TIMER, new DigitalTimerValidator(), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT); addValidationInfo( @@ -461,6 +465,95 @@ public class HdmiCecMessageValidator { return isWithinRange(value, 0, 31); } + /** + * Check if the given value is a ARIB type. A valid value is one which falls within the range + * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value Digital Broadcast System + * @return true if the Digital Broadcast System is ARIB type + */ + private boolean isAribDbs(int value) { + return (value == 0x00 || isWithinRange(value, 0x08, 0x0A)); + } + + /** + * Check if the given value is a ATSC type. A valid value is one which falls within the range + * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value Digital Broadcast System + * @return true if the Digital Broadcast System is ATSC type + */ + private boolean isAtscDbs(int value) { + return (value == 0x01 || isWithinRange(value, 0x10, 0x12)); + } + + /** + * Check if the given value is a DVB type. A valid value is one which falls within the range + * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value Digital Broadcast System + * @return true if the Digital Broadcast System is DVB type + */ + private boolean isDvbDbs(int value) { + return (value == 0x02 || isWithinRange(value, 0x18, 0x1B)); + } + + /** + * Check if the given value is a valid Digital Broadcast System. A valid value is one which + * falls within the range description defined in CEC 1.4 Specification : Operand Descriptions + * (Section 17) + * + * @param value Digital Broadcast System + * @return true if the Digital Broadcast System is valid + */ + private boolean isValidDigitalBroadcastSystem(int value) { + return (isAribDbs(value) || isAtscDbs(value) || isDvbDbs(value)); + } + + /** + * Check if the given value is a valid Digital Service Identification. A valid value is one + * which falls within the range description defined in CEC 1.4 Specification : Operand + * Descriptions (Section 17) + * + * @param params Digital Timer Message parameters + * @param offset start offset of Digital Service Identification + * @return true if the Digital Service Identification is valid + */ + private boolean isValidDigitalServiceIdentification(byte[] params, int offset) { + // MSB contains Service Identification Method + int serviceIdentificationMethod = params[offset] & 0x80; + // Last 7 bits contains Digital Broadcast System + int digitalBroadcastSystem = params[offset] & 0x7F; + offset = offset + 1; + if (serviceIdentificationMethod == 0x00) { + // Services identified by Digital IDs + if (isAribDbs(digitalBroadcastSystem)) { + // Validate ARIB type have 6 byte data + return params.length - offset >= 6; + } else if (isAtscDbs(digitalBroadcastSystem)) { + // Validate ATSC type have 4 byte data + return params.length - offset >= 4; + } else if (isDvbDbs(digitalBroadcastSystem)) { + // Validate DVB type have 6 byte data + return params.length - offset >= 6; + } + } else if (serviceIdentificationMethod == 0x80) { + // Services identified by Channel + if (isValidDigitalBroadcastSystem(digitalBroadcastSystem)) { + // First 6 bits contain Channel Number Format + int channelNumberFormat = params[offset] & 0xFC; + if (channelNumberFormat == 0x04) { + // Validate it contains 1-part Channel Number data (16 bits) + return params.length - offset >= 3; + } else if (channelNumberFormat == 0x08) { + // Validate it contains Major Channel Number and Minor Channel Number (26 bits) + return params.length - offset >= 4; + } + } + } + return false; + } + /** * Check if the given value is a valid External Plug. A valid value is one which falls within * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) @@ -651,6 +744,30 @@ public class HdmiCecMessageValidator { } } + /** + * Check if the given Digital Timer message parameters are valid. Valid parameters should adhere + * to message description of Digital Timer defined in CEC 1.4 Specification : Message + * Descriptions for Timer Programming Feature (CEC Table 12) + */ + private class DigitalTimerValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 11) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode( + isValidDayOfMonth(params[0]) // Day of Month + && isValidMonthOfYear(params[1]) // Month of Year + && isValidHour(params[2]) // Start Time - Hour + && isValidMinute(params[3]) // Start Time - Minute + && isValidDurationHours(params[4]) // Duration - Duration Hours + && isValidMinute(params[5]) // Duration - Minute + && isValidRecordingSequence(params[6]) // Recording Sequence + && isValidDigitalServiceIdentification( + params, 7)); // Digital Service Identification + } + } + /** * Check if the given External Timer message parameters are valid. Valid parameters should * adhere to message description of External Timer defined in CEC 1.4 Specification : Message diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index 3d2e39d7e90af..fd355d359287e 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -227,6 +227,67 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("04:34:04:0C:16:0F:08:37: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); + // 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); + // 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); + // Service identified by Channel - 1 part channel number + assertMessageValidity("04:97:12:06:0C:2D:5A:19: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("4F:97:0C:08:15:05:04:1E: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("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") + .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); + // Out of range Start Time - Hour + assertMessageValidity("04:99:0C:08:20:05:04:1E: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") + .isEqualTo(ERROR_PARAMETER); + // Out of range Duration - Duration Hours + assertMessageValidity("04:99:1E:07:12:20:78:28: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") + .isEqualTo(ERROR_PARAMETER); + // Invalid Recording Sequence + assertMessageValidity("04:99:12:06:0C:2D:5A:19:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER); + // Invalid Recording Sequence + assertMessageValidity("04:97:0C:08:15:05:04:1E:21: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") + .isEqualTo(ERROR_PARAMETER); + // Invalid Digital Broadcast System + assertMessageValidity("04:97:05:0C:06:0A:19:3B: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") + .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); + // Insufficient data for DVB Broadcast system + assertMessageValidity("04:99:05:0C:06:0A:19:3B: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); + // Invalid Channel Number format + assertMessageValidity("04:99:12:06:0C:2D:5A:19: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); From 9bde85a14d514f6a208ad0bd8bd88e5690a7fe58 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Tue, 27 Oct 2020 16:10:09 +0530 Subject: [PATCH 3/3] CEC : Add validators for timer cleared status message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ia8944415eb25c9161f07fde8ec59246cfd8d082c --- .../server/hdmi/HdmiCecMessageValidator.java | 19 +++++++++++++++++++ .../hdmi/HdmiCecMessageValidatorTest.java | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 4ff67cdb92d39..f0fab26760c0f 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -137,6 +137,10 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_SET_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_SET_TIMER_PROGRAM_TITLE, new AsciiValidator(1, 14), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_TIMER_CLEARED_STATUS, + new TimerClearedStatusValidator(), + DEST_DIRECT); // Messages for the System Information. FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); @@ -790,4 +794,19 @@ public class HdmiCecMessageValidator { && isValidExternalSource(params, 7)); // External Source } } + + /** + * Check if the given timer cleared status parameter is valid. A valid parameter should lie + * within the range description defined in CEC 1.4 Specification : Operand Descriptions + * (Section 17) + */ + private class TimerClearedStatusValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 1) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isWithinRange(params[0], 0x00, 0x02) || (params[0] & 0xFF) == 0x80); + } + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index fd355d359287e..c84e10b44de87 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -318,6 +318,17 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_timerClearedStatus() { + assertMessageValidity("40:43:01:7E").isEqualTo(OK); + assertMessageValidity("40:43:80").isEqualTo(OK); + + assertMessageValidity("4F:43:01").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:43:80").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:43").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:43:03").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); }