From e8543c290e1907699b659e5488c535ac0493e020 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Thu, 1 Oct 2020 10:46:33 +0530 Subject: CEC: Add Analogue Timer validator Used to validate and message parameters Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: I7f45d9555f7300fbb8f160f83f2b0c0563192607 --- .../server/hdmi/HdmiCecMessageValidator.java | 66 ++++++++++++++++++++++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 34 +++++++++++ 2 files changed, 100 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index e65614307368..b0a147a3f04d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -123,6 +123,10 @@ public class HdmiCecMessageValidator { new RecordStatusInfoValidator(), DEST_DIRECT); // TODO: Handle messages for the Timer Programming. + addValidationInfo( + Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SET_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); // Messages for the System Information. FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); @@ -415,6 +419,42 @@ public class HdmiCecMessageValidator { return (Integer.bitCount(value) <= 1); } + /** + * Check if the given value is a valid analogue broadcast type. A valid value is one which falls + * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section + * 17) + * + * @param value analogue broadcast type + * @return true if the analogue broadcast type is valid + */ + private boolean isValidAnalogueBroadcastType(int value) { + return isWithinRange(value, 0x00, 0x02); + } + + /** + * Check if the given value is a valid analogue frequency. A valid value is one which falls + * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section + * 17) + * + * @param value analogue frequency + * @return true if the analogue frequency is valid + */ + private boolean isValidAnalogueFrequency(int value) { + value = value & 0xFFFF; + return (value != 0x000 && value != 0xFFFF); + } + + /** + * Check if the given value is a valid 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 broadcast system + * @return true if the broadcast system is valid + */ + private boolean isValidBroadcastSystem(int value) { + return isWithinRange(value, 0, 31); + } + private class PhysicalAddressValidator implements ParameterValidator { @Override public int isValid(byte[] params) { @@ -544,4 +584,30 @@ public class HdmiCecMessageValidator { return toErrorCode(isWithinRange(params[0], mMinValue, mMaxValue)); } } + + /** + * Check if the given Analogue Timer message parameters are valid. Valid parameters should + * adhere to message description of Analogue Timer defined in CEC 1.4 Specification : Message + * Descriptions for Timer Programming Feature (CEC Table 12) + */ + private class AnalogueTimerValidator 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 + && isValidAnalogueBroadcastType(params[7]) // Analogue Broadcast Type + && isValidAnalogueFrequency( + HdmiUtils.twoBytesToInt(params, 8)) // Analogue Frequency + && isValidBroadcastSystem(params[10])); // Broadcast System + } + } } 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 470294073535..530f388d68e0 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -182,6 +182,40 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:0A:30").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_setAnalogueTimer_clearAnalogueTimer() { + assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:13:AD:06").isEqualTo(OK); + assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:03:34").isEqualTo(OK); + + assertMessageValidity("0F:33:0C:08:10:1E:04:30:08:00:13:AD:06") + .isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:34:04:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_SOURCE); + 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); + // Out of range Month of Year + assertMessageValidity("04:33:0C:00:10:1E:04:30: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); + // Out of range Start Time - Minute + assertMessageValidity("04:33:0C:08:10:50:04:30: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); + // Out of range Duration - Minute + assertMessageValidity("04:33:0C:08:10:1E:04:64: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); + // Invalid Recording Sequence + assertMessageValidity("04:33:0C:08:10:1E:04:30: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); + // Out of range Analogue Frequency + assertMessageValidity("04:33:0C:08:10:1E:04:30: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); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } -- cgit v1.2.3-59-g8ed1b From bcae9da108097a8ac57ec092a11d7d229723b246 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 12 Oct 2020 15:35:59 +0530 Subject: CEC: Add External Timer validator Used to validate and message parameters Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: I49a33e91937907fe5a5828c1cdf31d0004a01d46 --- .../server/hdmi/HdmiCecMessageValidator.java | 61 ++++++++++++++++++++++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 30 +++++++++++ 2 files changed, 91 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index b0a147a3f04d..66d9f607d5d4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -125,8 +125,12 @@ public class HdmiCecMessageValidator { // TODO: Handle messages for the Timer Programming. addValidationInfo( Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), 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_EXTERNAL_TIMER, new ExternalTimerValidator(), DEST_DIRECT); // Messages for the System Information. FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); @@ -455,6 +459,40 @@ public class HdmiCecMessageValidator { return isWithinRange(value, 0, 31); } + /** + * 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) + * + * @param value External Plug + * @return true if the External Plug is valid + */ + private boolean isValidExternalPlug(int value) { + return isWithinRange(value, 1, 255); + } + + /** + * Check if the given value is a valid External Source. A valid value is one which falls within + * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value External Source Specifier + * @return true if the External Source is valid + */ + private boolean isValidExternalSource(byte[] params, int offset) { + int externalSourceSpecifier = params[offset]; + offset = offset + 1; + if (externalSourceSpecifier == 0x04) { + // External Plug + return isValidExternalPlug(params[offset]); + } else if (externalSourceSpecifier == 0x05) { + // External Physical Address + // Validate it contains 2 bytes Physical Address + if (params.length - offset >= 2) { + return isValidPhysicalAddress(params, offset); + } + } + return false; + } + private class PhysicalAddressValidator implements ParameterValidator { @Override public int isValid(byte[] params) { @@ -610,4 +648,27 @@ public class HdmiCecMessageValidator { && isValidBroadcastSystem(params[10])); // Broadcast System } } + + /** + * 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 + * Descriptions for Timer Programming Feature (CEC Table 12) + */ + private class ExternalTimerValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 9) { + 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 + && isValidExternalSource(params, 7)); // External Source + } + } } 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 530f388d68e0..a034643233e2 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -216,6 +216,36 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").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("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); + // Out of range Day of Month + assertMessageValidity("40:A2:28:09:12:28:4B:19: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); + // Out of range Start Time - Hour + assertMessageValidity("40:A2:14:09:1A:28:4B:19: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); + // Out of range Duration - Duration Hours + assertMessageValidity("40:A2:14:09:12:28:66:19: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); + // Invalid Recording Sequence + assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER); + // Invalid Recording Sequence + assertMessageValidity("40:A1:0C:08:15:05:04:1E:14: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); + // Invalid External PLug + assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } -- cgit v1.2.3-59-g8ed1b