diff --git a/Makefile b/Makefile index 3bf2882..4b2fd2e 100644 --- a/Makefile +++ b/Makefile @@ -81,9 +81,9 @@ export HAL_LIB_DIR build: $(SETUP_SKELETON_LIBS) echo "SETUP_SKELETON_LIBS $(SETUP_SKELETON_LIBS)" @echo UT [$@] - make -C ./ut-core framework - make -C ./ut-core test - + make -C ./ut-core TARGET=${TARGET} + rm -rf $(BIN_DIR)/lib$(HAL_LIB).so + rm -rf $(ROOT_DIR)/libs/lib$(HAL_LIB).so #Build against the real library leads to the SOC library dependency also.SOC lib dependency cannot be specified in the ut Makefile, since it is supposed to be common across may platforms. So in order to over come this situation, creating a template skelton library with empty templates so that the template library wont have any other Soc dependency. And in the real platform mount copy bind with the actual library will work fine. skeleton: echo $(CC) diff --git a/host/tests/classes/hdmiCEC.py b/host/tests/classes/hdmiCEC.py index 9a1ecfb..a7c3ab4 100644 --- a/host/tests/classes/hdmiCEC.py +++ b/host/tests/classes/hdmiCEC.py @@ -55,7 +55,7 @@ def __init__(self, moduleConfigProfileFile :str, session=None, targetWorkspace=" Returns: None """ - self.moduleName = "hdmiCEC" + self.moduleName = "hdmicec" self.testConfigFile = os.path.join(dir_path, "hdmiCEC_testConfig.yml") self.testSuite = "L3 HDMICEC Sink Functions" @@ -105,7 +105,7 @@ def initialise(self): Returns: None """ - result = self.utMenu.select( self.testSuite, "L3_Init_HdmiCec") + result = self.utMenu.select( self.testSuite, "Init HDMI CEC") def terminate(self): """ @@ -117,7 +117,7 @@ def terminate(self): Returns: None """ - result = self.utMenu.select(self.testSuite, "L3_Close_HdmiCec_Sink") + result = self.utMenu.select(self.testSuite, "Close HDMI CEC") def addLogicalAddress(self, logicalAddress:int): """ @@ -137,11 +137,9 @@ def addLogicalAddress(self, logicalAddress:int): "input": str(logicalAddress) } ] + result = self.utMenu.select(self.testSuite, "Add Logical Address", promptWithAnswers) - - result = self.utMenu.select(self.testSuite, "L3_AddLogicalAddress", promptWithAnswers) - - def removeLogicalAddress(self, logicalAddress:int): + def removeLogicalAddress(self): """ Remove logical address. @@ -151,17 +149,7 @@ def removeLogicalAddress(self, logicalAddress:int): Returns: None """ - promptWithAnswers = [ - { - "query_type": "direct", - "query": "Enter Logical Address to Remove:", - "input": str(logicalAddress) - } - ] - - result = self.utMenu.select(self.testSuite, "L3_RemoveLogicalAddressHdmiCec_Sink", promptWithAnswers) - - + result = self.utMenu.select(self.testSuite, "Remove Logical Address") def getLogicalAddress(self): """ @@ -173,13 +161,12 @@ def getLogicalAddress(self): Returns: int: Logical address of the device. """ - result = self.utMenu.select( self.testSuite, "L3_GetLogicalAddress") - connectionStatusPattern = r"HdmiCecGetLogicalAddress\(IN: handle: [.*\], OUT: logicalAddress: [.*\]), status: [.*\])" + result = self.utMenu.select( self.testSuite, "Get Logical Address") + connectionStatusPattern = r"Result HdmiCecGetLogicalAddress\(IN:handle:[.*\], OUT:logicalAddress:[.*\]) HDMI_CEC_STATUS:[.*\])" logicalAddress = self.searchPattern(result, connectionStatusPattern) return logicalAddress - def getPhysicalAddress(self): """ Retrieve the Physical Address of the DUT. @@ -190,13 +177,13 @@ def getPhysicalAddress(self): Returns: int: Physical Address of the DUT. """ - result = self.utMenu.select( self.testSuite, "L3_GetPhyiscalAddress") - typeStatusPattern = r"HdmiCecGetPhysicalAddress\(IN: handle: [.*\], physicalAddress: [.*\]), status:[.*\]" + result = self.utMenu.select( self.testSuite, "Get Phyiscal Address") + typeStatusPattern = r"Result HdmiCecGetPhysicalAddress\(IN:handle:[.*\], OUT:physicalAddress:[.*\]) HDMI_CEC_STATUS:[.*\]" physicalAddress = self.searchPattern(result, typeStatusPattern) return physicalAddress - def cecTransmitCmd(self, sourceLogicalAddress:int, destLogicalAddress:int, cecCommand:int, cecData:list=None): + def cecTransmitCmd(self, destLogicalAddress:int, cecCommand:int, cecData:list=None): """ Transmit/Broadcast the CEC command and data to the respective destination. @@ -208,11 +195,6 @@ def cecTransmitCmd(self, sourceLogicalAddress:int, destLogicalAddress:int, cecCo """ promptWithAnswers = [ - { - "query_type": "direct", - "query": "Enter a valid Source Logical Address:", - "input": str(sourceLogicalAddress) - }, { "query_type": "direct", "query": "Enter a valid Destination Logical Address:", @@ -220,7 +202,7 @@ def cecTransmitCmd(self, sourceLogicalAddress:int, destLogicalAddress:int, cecCo }, { "query_type": "direct", - "query": "Enter CEC Command:", + "query": "Enter CEC Command (in hex):", "input": str(cecCommand) }, ] @@ -234,8 +216,7 @@ def cecTransmitCmd(self, sourceLogicalAddress:int, destLogicalAddress:int, cecCo "input": str(byte) }) - result = self.utMenu.select( self.testSuite, "L3_TransmitCecCommand",promptWithAnswers) - + result = self.utMenu.select( self.testSuite, "Transmit CEC Command",promptWithAnswers) def __del__(self): """ diff --git a/host/tests/classes/hdmiCEC_testConfig.yml b/host/tests/classes/hdmiCEC_testConfig.yml index baa8d23..40ac032 100644 --- a/host/tests/classes/hdmiCEC_testConfig.yml +++ b/host/tests/classes/hdmiCEC_testConfig.yml @@ -19,7 +19,7 @@ # * limitations under the License. # * #* ****************************************************************************** -hdmiCEC: +hdmicec: description: "hdmi CEC testing profile / menu system for UT" test: artifacts: @@ -56,11 +56,10 @@ hdmiCEC: 2: name: "L3 hdmicec - Sink" tests: - - "L3_Init_HdmiCec" - - "L3_AddLogicalAddress" - - "L3_GetLogicalAddress" - - "L3_TransmitCecCommand" - - "L3_ReceiveCecCommand" - - "L3_GetPhyiscalAddress" - - "L3_RemoveLogicalAddressHdmiCec_Sink" - - "L3_Close_HdmiCec_Sink" + - "Init HDMI CEC" + - "Add Logical Address" + - "Get Logical Address" + - "Transmit CEC Command" + - "Get Phyiscal Address" + - "Remove Logical Address" + - "Close HDMI CEC" diff --git a/host/tests/hdmiCEC_L3_Tests/hdmiCECHelperClass.py b/host/tests/hdmiCEC_L3_Tests/hdmiCECHelperClass.py index dcabad0..478f421 100755 --- a/host/tests/hdmiCEC_L3_Tests/hdmiCECHelperClass.py +++ b/host/tests/hdmiCEC_L3_Tests/hdmiCECHelperClass.py @@ -47,7 +47,7 @@ def __init__(self, testName:str, qcId:str, log:logModule=None ): """ self.testName = "" self.testSetupPath = os.path.join(dir_path, "hdmiCEC_L3_testSetup.yml") - self.moduleName = "hdmiCEC" + self.moduleName = "hdmicec" self.rackDevice = "dut" super().__init__(testName, qcId, log) diff --git a/host/tests/hdmiCEC_L3_Tests/hdmiCECTestCommands.yml b/host/tests/hdmiCEC_L3_Tests/hdmiCECTestCommands.yml index e3ae591..ecf469e 100644 --- a/host/tests/hdmiCEC_L3_Tests/hdmiCECTestCommands.yml +++ b/host/tests/hdmiCEC_L3_Tests/hdmiCECTestCommands.yml @@ -1,14 +1,15 @@ hdmiCEC: - test01_TransmitSingleStandbyCommandandValidateAck: + test01_TransmitCECCommands: + - command: "0x04" # Image View on + payload: + responses: - command: "0x36" # Standby + payload: responses: - - type: "power_status" - loop_devices: true # Apply this response to all devices in the device map - payload: "[:sender]:90:[:power_status]" # Response pattern with placeholders - description: "Devices report their power status" - - command: "0x8F" # Request Power Status + - command: "0x9F" # Get CEC version + payload: responses: - - type: "power_status_response" - loop_devices: true # Apply this response to all devices in the device map - payload: "[:sender]:90:[:power_status]" # Response pattern with placeholders - description: "Devices respond with their current power status" \ No newline at end of file + - type: "Get CEC Version" + loop_devices: false # Apply this response to all devices in the device map + payload: "" # Response pattern with placeholders + description: "Device request for CEC version" \ No newline at end of file diff --git a/host/tests/hdmiCEC_L3_Tests/hdmiCEC_L3_testSetup.yml b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_L3_testSetup.yml index 9abc501..fcddfe7 100755 --- a/host/tests/hdmiCEC_L3_Tests/hdmiCEC_L3_testSetup.yml +++ b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_L3_testSetup.yml @@ -21,7 +21,7 @@ #* ****************************************************************************** -hdmiCEC: # Prefix must always exist +hdmicec: # Prefix must always exist description: "hdmiCEC test setup" assets: device: diff --git a/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitSingleStandbyCommandandValidateAck.py b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitCECCommands.py similarity index 57% rename from host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitSingleStandbyCommandandValidateAck.py rename to host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitCECCommands.py index bd21665..fb4c648 100755 --- a/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitSingleStandbyCommandandValidateAck.py +++ b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test01_TransmitCECCommands.py @@ -32,7 +32,7 @@ from raft.framework.core.logModule import logModule from raft.framework.plugins.ut_raft.configRead import ConfigRead -class hdmiCEC_test01_TransmitSingleStandbyCommandandValidateAck(hdmiCECHelperClass): +class hdmiCEC_test01_TransmitCECCommands(hdmiCECHelperClass): """ Test class to enable, disable, and verify the status of audio ports on a device. @@ -48,39 +48,15 @@ def __init__(self, log:logModule=None): None """ # Class variables - self.testName = "test01_TransmitSingleStanbyCommandandValidateAck" + self.testName = "test01_TransmitCECCommands" self.qcID = '1' + self.sourceLogicalAddress = 0 self.testCECCommands = os.path.join(dir_path, "hdmiCECTestCommands.yml") hdmicec = ConfigRead(self.testCECCommands, "hdmiCEC") - self.cecCommands = hdmicec.fields.get("test01_TransmitSingleStandbyCommandandValidateAck") - for command in self.cecCommands: - cec = command.get("command") - payload = command.get("payload") - print(cec, payload) - super().__init__(self.testName, self.qcID, log) - - #TODO: Current version supports only manual verification. - def testVerifyStanbyStatus(self, ack, manual=False): - """ - Verifies the CEC Transmit Status through the result and also through the manual input. - - For manual verification, it prompts the user to confirm if CEC data is received by the destination - device and the action has been performed. - - Args: - ack(str): Ack result as printed on the test. Need to check that proper ACK is received. - (bool, optional): Flag to indicate if manual verification should be used. - Defaults to False for automation, True for manual. + self.cecCommands = hdmicec.fields.get(self.testName) - Returns: - bool: True if ACK verification succeeds, False otherwise.Also True if Manual test is Y and Flase if N - """ - if manual == True: - return self.testUserResponse.getUserYN(f"Is Stanby Command honored? (Y/N):") - else : - #TODO: Add automation verification methods - return False + super().__init__(self.testName, self.qcID, log) def testFunction(self): """ @@ -97,44 +73,41 @@ def testFunction(self): # Initialize the hdmiCEC module self.testhdmiCEC.initialise() - # Add the logical Address. For now 0 only. - self.testhdmiCEC.addLogicalAddress(0) + # Add the logical Address. + self.testhdmiCEC.addLogicalAddress(self.sourceLogicalAddress) - self.cecDevices = [1,2,3]#self.cecAdapter.listDevices() + self.cecDevices = self.cecAdapter.listDevices() for device in self.cecDevices: - logicalAddress = 1#int(device["address"].split('.')[0]) + logicalAddress = device["logical address"] # To bypass sending the message to TV if logicalAddress == 0 or logicalAddress == 14: continue - # self.log.stepStart(f'HdmiCecTx(IN: handle: [0x%0X], IN: length: [%d], result: [%d], status:[%d]') - for command in self.cecCommands: cec = command.get("command") payload = command.get("payload") - #result = self.cecAdapter.startMonitoring() - #print(result) + # Transmit Standby command to a specific destination address - self.testhdmiCEC.cecTransmitCmd(0, logicalAddress,cec,payload) - #self.cecAdapter.stopMonitoring() + self.testhdmiCEC.cecTransmitCmd(logicalAddress, cec, payload) + + self.log.stepStart(f'HdmiCecTx Source: {self.sourceLogicalAddress} Destination: {logicalAddress} CEC OPCode: {cec} Payload: {payload}') - #Verify the test result - result = self.testVerifyStanbyStatus(logicalAddress, True) + result = self.cecAdapter.checkTransmitStatus(self.sourceLogicalAddress, logicalAddress, cec, payload) - self.log.stepResult() + self.log.stepResult(result, f'HdmiCecTx Source: {self.sourceLogicalAddress} Destination: {logicalAddress} CEC OPCode: {cec} Payload: {payload}') - # Remove the Logical Address - self.testhdmiCEC.removeLogicalAddress(0) + # Remove the Logical Address + self.testhdmiCEC.removeLogicalAddress() # Terminate dsAudio Module - self.testdsAudio.terminate() + self.testhdmiCEC.terminate() return result if __name__ == '__main__': summerLogName = os.path.splitext(os.path.basename(__file__))[0] + "_summery" summeryLog = logModule(summerLogName, level=logModule.INFO) - test = hdmiCEC_test01_TransmitSingleStandbyCommandandValidateAck(summeryLog) + test = hdmiCEC_test01_TransmitCECCommands(summeryLog) test.run(False) diff --git a/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test02_ReceiveCECCommands.py b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test02_ReceiveCECCommands.py new file mode 100644 index 0000000..cec862b --- /dev/null +++ b/host/tests/hdmiCEC_L3_Tests/hdmiCEC_test02_ReceiveCECCommands.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2024 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** + +import os +import sys + +dir_path = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(dir_path)) +sys.path.append(os.path.join(dir_path, "../")) + +from hdmiCECHelperClass import hdmiCECHelperClass +from raft.framework.core.logModule import logModule +from raft.framework.plugins.ut_raft.configRead import ConfigRead + +class hdmiCEC_test02_ReceiveCECCommands(hdmiCECHelperClass): + """ + Test class to enable, disable, and verify the status of audio ports on a device. + + This class uses the `dsAudioClass` to interact with the device's audio ports, + downloading necessary test assets, playing audio streams, enabling and disabling + audio ports, and performing verification of audio output. + """ + def __init__(self, log:logModule=None): + """ + Initializes the test class with test name, setup configuration, and sessions for the device. + + Args: + None + """ + # Class variables + self.testName = "test02_ReceiveCECCommands" + self.qcID = '2' + self.sourceLogicalAddress = 0 + + self.testCECCommands = os.path.join(dir_path, "hdmiCECTestCommands.yml") + hdmicec = ConfigRead(self.testCECCommands, "hdmiCEC") + self.cecCommands = hdmicec.fields.get(self.testName) + + super().__init__(self.testName, self.qcID, log) + + def testFunction(self): + """ + The main test function that Transmits the Stanby Command and checks the ACK and validates it. + + This function: + - Send a standby command to a device that is connected on the CEC network and get the ack. + - User to confirm whether the targetted device had recieved this command or not. + + Returns: + bool: Final result of the test. + """ + + # Initialize the hdmiCEC module + self.testhdmiCEC.initialise() + + # Add the logical Address. + self.testhdmiCEC.addLogicalAddress(self.sourceLogicalAddress) + + self.cecDevices = self.cecAdapter.listDevices() + + for device in self.cecDevices: + logicalAddress = device["logical address"] + + # To bypass sending the message to TV + if logicalAddress == 0 or logicalAddress == 14: + continue + + for command in self.cecCommands: + cec = command.get("command") + payload = command.get("payload") + + # Transmit Standby command to a specific destination address + self.testhdmiCEC.cecTransmitCmd(logicalAddress, cec, payload) + + self.log.stepStart(f'HdmiCecTx Source: {self.sourceLogicalAddress} Destination: {logicalAddress} CEC OPCode: {cec} Payload: {payload}') + + result = self.cecAdapter.checkTransmitStatus(self.sourceLogicalAddress, logicalAddress, cec, payload) + + self.log.stepResult(result, f'HdmiCecTx Source: {self.sourceLogicalAddress} Destination: {logicalAddress} CEC OPCode: {cec} Payload: {payload}') + + # Remove the Logical Address + self.testhdmiCEC.removeLogicalAddress() + + # Terminate dsAudio Module + self.testhdmiCEC.terminate() + + return result + +if __name__ == '__main__': + summerLogName = os.path.splitext(os.path.basename(__file__))[0] + "_summery" + summeryLog = logModule(summerLogName, level=logModule.INFO) + test = hdmiCEC_test02_ReceiveCECCommands(summeryLog) + test.run(False) diff --git a/src/test_l3_hdmi_cec_sink_driver.c b/src/test_l3_hdmi_cec_sink_driver.c index 50ee614..799dcf4 100644 --- a/src/test_l3_hdmi_cec_sink_driver.c +++ b/src/test_l3_hdmi_cec_sink_driver.c @@ -15,26 +15,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * @addtogroup HPK Hardware Porting Kit * @{ * */ - /** * @addtogroup HDMI_CEC HDMI CEC Module * @{ * */ - /** * @defgroup HDMI_CEC_HALTESTS HDMI CEC HAL Tests * @{ * */ - /** * @defgroup HDMI_CEC_HALTESTS_L3 HDMI CEC HAL Tests L2 File * @{ @@ -60,6 +56,7 @@ * */ +#include #include #include #include @@ -69,21 +66,21 @@ #define TIMEOUT 5 #define REPLY_TIMEOUT 5 -#define UT_LOG_MENU_INFO UT_LOG_INFO +#define HDMI_CEC_MAX_PAYLOAD 128 +#define HDMI_CEC_MAX_OSDNAME 15 -static int gTestGroup = 3; -static int gTestID = 1; -static int gHandle = 0; -static int cbFlag = 0; +#define UT_LOG_MENU_INFO UT_LOG_INFO // CEC command map table and supporting function -typedef struct { - unsigned char cecCommand; // CEC command code +typedef struct +{ + uint8_t cecCommand; // CEC command code const char* commandName; // Human-readable command name - int dataLength; // Number of data bytes required for the command + int32_t dataLength; // Number of data bytes required for the command } CecCommandMap; -CecCommandMap cecCommandTable[] = { +CecCommandMap cecCommandTable[] = +{ {0x00, "Feature Abort", 2}, {0x04, "Image View On", 0}, {0x0D, "Text View On", 0}, @@ -119,8 +116,66 @@ CecCommandMap cecCommandTable[] = { // Add more commands as needed }; +typedef enum HDMI_CEC_DEVICE_TYPE_T +{ + HDMI_CEC_RECORDER = 1, + HDMI_CEC_AMPLIFIER, + HDMI_CEC_TUNER, + HDMI_CEC_PLAYBACK, + HDMI_CEC_AUDIO, + HDMI_CEC_TV, + HDMI_CEC_RESERVED +} HDMI_CEC_DEVICE_TYPE; + +const static ut_control_keyStringMapping_t cecDeviceType_mapTable[] = +{ + {"Recorder", (int32_t)HDMI_CEC_RECORDER}, + {"Amplifier", (int32_t)HDMI_CEC_AMPLIFIER}, + {"Tuner", (int32_t)HDMI_CEC_TUNER}, + {"Playback Device", (int32_t)HDMI_CEC_PLAYBACK}, + {"Audio System", (int32_t)HDMI_CEC_AUDIO}, + {"TV", (int32_t)HDMI_CEC_TV}, + {"Reserved", (int32_t)HDMI_CEC_RESERVED} +}; + +typedef enum HDMI_CEC_POWER_STATUS_T +{ + HDMI_CEC_ON = 0, + HDMI_CEC_STANDBY, + HDMI_CEC_TRANSIT_STANDBY, + HDMI_CEC_TRANSIT_ON +} HDMI_CEC_POWER_STATUS; + +const static ut_control_keyStringMapping_t cecPowerStatus_mapTable[] = +{ + {"On", (int32_t)HDMI_CEC_ON}, + {"Standby", (int32_t)HDMI_CEC_STANDBY}, + {"Transition to Standby", (int32_t)HDMI_CEC_TRANSIT_STANDBY}, + {"Transition to On", (int32_t)HDMI_CEC_TRANSIT_ON} +}; + +typedef enum HDMI_CEC_FEATURE_ABORT_REASON_T +{ + HDMI_CEC_UNRECOGNIZE = 0, + HDMI_CEC_NOTCORRECTMODE, + HDMI_CEC_CANNOTPROVIDE, + HDMI_CEC_INVALID, + HDMI_CEC_REFUSED, + HDMI_CEC_UNABLE +} HDMI_CEC_FEATURE_ABORT_REASON; + +const static ut_control_keyStringMapping_t cecFeatureAbortReason_mapTable[] = +{ + {"Unrecognized opcode", (int32_t)HDMI_CEC_UNRECOGNIZE}, + {"Not in Correct mode to respond", (int32_t)HDMI_CEC_NOTCORRECTMODE}, + {"Cannot provide source", (int32_t)HDMI_CEC_CANNOTPROVIDE}, + {"Invalid operand", (int32_t)HDMI_CEC_INVALID}, + {"Refused", (int32_t)HDMI_CEC_REFUSED}, + {"Unable to determine", (int32_t)HDMI_CEC_UNABLE} +}; /* cecError_t */ -const static ut_control_keyStringMapping_t cecError_mapTable [] = { +const static ut_control_keyStringMapping_t cecError_mapTable [] = +{ {"HDMI_CEC_IO_SUCCESS", (int32_t)HDMI_CEC_IO_SUCCESS}, {"HDMI_CEC_IO_SENT_AND_ACKD", (int32_t)HDMI_CEC_IO_SENT_AND_ACKD}, {"HDMI_CEC_IO_SENT_BUT_NOT_ACKD", (int32_t)HDMI_CEC_IO_SENT_BUT_NOT_ACKD}, @@ -139,6 +194,24 @@ const static ut_control_keyStringMapping_t cecError_mapTable [] = { { NULL, -1 } }; +static int32_t gTestGroup = 3; +static int32_t gTestID = 1; +static int32_t gHandle = 0; +static int32_t gLogicalAddress = -1; +static uint32_t gPhysicalAddress = -1; +static uint8_t *gPhysicalAddressBytes; +static HDMI_CEC_DEVICE_TYPE gDeviceType = HDMI_CEC_TV; +static HDMI_CEC_POWER_STATUS gPowerStatus = HDMI_CEC_ON; +static uint8_t gDeviceVendorID[] = {0x00, 0x00, 0x01}; // Example Vendor ID: 0x000001 +static uint8_t gCECVersion = 0x05; // CEC Version: 1.4 (0x05) +static uint8_t gAudioDelay = (100/2) + 1; //100msec audio delay ((number of milliseconds/2) + 1) +static uint8_t gVideoDelay = (200/2) + 1; //100msec video delay ((number of milliseconds/2) + 1) +static uint8_t gBroadcastAddress = 0xF; + +//(Bits 1-0) : Audio Ouput Compensated (0 - N/A, 1 - TV audio output is delay compensated, 2 - TV audio output is NOT delay compensated, 3 - TV audio output is Par delay compensated) +//(Bit 2) : 0 - normal latency, 1 - low latency +//Bit(7-3) : Reserved +uint8_t gLatencyFlag = 0x00; /** * @brief CEC Command with data size mapping function. @@ -146,17 +219,17 @@ const static ut_control_keyStringMapping_t cecError_mapTable [] = { * This function maps the provided CEC command with the data length required for the CEC Command. * This will help the test to consider the correct size of the data required for the CEC Command. * -* **Test Group ID:** 03@n -* **Test Case ID:** 000@n -* */ -int getCecCommandInfo(unsigned char cecCommand, const char** commandName, int* dataLength) { +static int32_t getCecCommandInfo(uint8_t cecCommand, const char** commandName, int32_t* dataLength) +{ UT_LOG_INFO("In %s(IN: cecCommand: [0x%02X])\n", __FUNCTION__, cecCommand); - int tableSize = sizeof(cecCommandTable) / sizeof(CecCommandMap); + int32_t tableSize = sizeof(cecCommandTable) / sizeof(CecCommandMap); - for (int i = 0; i < tableSize; i++) { - if (cecCommandTable[i].cecCommand == cecCommand) { + for (int32_t i = 0; i < tableSize; i++) + { + if (cecCommandTable[i].cecCommand == cecCommand) + { *commandName = cecCommandTable[i].commandName; *dataLength = cecCommandTable[i].dataLength; UT_LOG_INFO("Out %s(OUT: commandName: [%s], OUT: dataLength: [%d])\n", __FUNCTION__, *commandName, *dataLength); @@ -168,170 +241,222 @@ int getCecCommandInfo(unsigned char cecCommand, const char** commandName, int* d return -1; // Command not found } -/** -* @brief Rx Callback function -* -* This function is a Receive Call back function called when data is received from a connected device. -* This function should be registered through HdmiCecSetRxCallback(). -* -* **Test Group ID:** 03@n -* **Test Case ID:** 000@n -* -*/ - -/* Callback function */ -#if 0 -void onRxDataReceived(int handle, void *callbackData, unsigned char *buf, int len) { - UT_LOG_INFO("In %s(IN: handle: [%d], IN: callbackData: [%p], IN: buf: [%p], IN: len: [%d])\n", __FUNCTION__, handle, callbackData, buf, len); - - if ((handle != 0) && (callbackData != NULL) && (len > 0)) { - UT_LOG_INFO("CEC Data Received\n"); - - // Log each byte received in the buffer - for (int index = 0; index < len; index++) { - UT_LOG_INFO("Buffer at index [%d]: [0x%02X]\n", index, buf[index]); - } - - // Clear the buffer after processing - memset(buf, 0, len); - UT_LOG_INFO("Buffer cleared after processing.\n"); - - } else { - // Log specific errors based on failed conditions - if (handle == 0) { - UT_LOG_ERROR("Error: Invalid handle.\n"); - } - if (callbackData == NULL) { - UT_LOG_ERROR("Error: Null callback data.\n"); - } - if (len <= 0) { - UT_LOG_ERROR("Error: Invalid length.\n"); - } - } - - cbFlag = 1; - UT_LOG_INFO("Out %s(OUT: cbFlag set to [1])\n", __FUNCTION__); -} -#endif - -void displayOsdMessage(const char *message) { - UT_LOG_INFO("Displaying OSD message: \"%s\" on the device.\n", message); - - // Implement device-specific logic here, e.g., - // - Update a graphical display - // - Notify the user via LEDs or indicators - // - Trigger an external display mechanism - - // For example: - printf("OSD Message: %s\n", message); - - UT_LOG_INFO("OSD message display completed.\n"); -} - -void handleImageViewOn(int handle, unsigned char initiator, unsigned char destination) { +static void handleImageViewOn() +{ UT_LOG_INFO("Image View On command received.\n"); // Perform any device-specific action for "Image View On" if needed. UT_LOG_INFO("Image View On processed.\n"); } -void handleActiveSource(int handle, unsigned char initiator, unsigned char destination, unsigned char *buf, int len) { - if (len >= 4) { - unsigned short physicalAddress = (buf[2] << 8) | buf[3]; // Combine bytes to form the physical address +static void handleActiveSource(uint8_t *buf, int32_t len) +{ + if (len >= 4) + { + uint16_t physicalAddress = (buf[2] << 8) | buf[3]; // Combine bytes to form the physical address UT_LOG_INFO("Active Source command received. Physical Address: [0x%04X]\n", physicalAddress); - // Process Active Source as needed. - } else { + } + else + { UT_LOG_ERROR("Active Source command received with insufficient data.\n"); } } -void handleGivePhysicalAddress(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[5] = { (destination << 4) | initiator, 0x84, 0x10, 0x00, 0x02 }; // Physical Address = 1.0.0.0, Device Type = TV - int result; +static void handleGivePhysicalAddress(int32_t handle, uint8_t initiator, uint8_t destination, uint8_t *pPhysicalAddress, HDMI_CEC_DEVICE_TYPE deviceType) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x84, (pPhysicalAddress[3] << 4) | pPhysicalAddress[2], (pPhysicalAddress[1] << 4 ) | pPhysicalAddress[0], deviceType}; + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); UT_LOG_INFO("Reported Physical Address response sent with result: %d\n", result); } -void handleDeviceVendorID(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[4] = { (destination << 4) | initiator, 0x87, 0x00, 0x00, 0x01 }; // Example Vendor ID: 0x000001 - int result; - HdmiCecTx(handle, response, sizeof(response), &result); - UT_LOG_INFO("Device Vendor ID response sent with result: %d\n", result); +static void handleReportPhysicalAddress(uint8_t *buf, int32_t len) +{ + if (len >= 5) + UT_LOG_INFO("Reported Physical Address: 0x%02X:0x%02X:0x%02X:0x%02X, Type: %s\n", (buf[2] >> 4) & 0x0F, buf[2] & 0x0F, (buf[3] >> 4) & 0x0F, buf[3] & 0x0F, UT_Control_GetMapString(cecDeviceType_mapTable, buf[4])); + else + UT_LOG_ERROR("Reported Physical command received with insufficient data.\n"); } -void handleReportPhysicalAddress(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[5] = { (destination << 4) | initiator, 0x84, 0x10, 0x00, 0x02 }; // Physical Address = 1.0.0.0, Device Type = TV - int result; +static void handleGetCECVersion(int32_t handle, uint8_t initiator, uint8_t destination, uint8_t version) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x9E, version }; + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); - UT_LOG_INFO("Reported Physical Address response sent with result: %d\n", result); + UT_LOG_INFO("CEC Version response sent with result: %d\n", result); } -void handleReportPowerStatus(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[3] = { (destination << 4) | initiator, 0x90, 0x00 }; // Power Status: On (0x00) - int result; - HdmiCecTx(handle, response, sizeof(response), &result); - UT_LOG_INFO("Reported Power Status response sent with result: %d\n", result); +static void handleCECVersion(uint8_t *buf, int32_t len) +{ + if (len >= 3) + UT_LOG_INFO("Received CEC Version: %x\n", buf[2]); + else + UT_LOG_ERROR("CEC Version command received with insufficient data.\n"); } -void handleGiveCECVersion(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[3] = { (destination << 4) | initiator, 0x9E, 0x05 }; // CEC Version: 1.4 (0x05) - int result; +static void handleGiveDeviceVendorID(int32_t handle, uint8_t initiator, uint8_t destination, uint8_t *pDeviceVendorId) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x87, pDeviceVendorId[0], pDeviceVendorId[1], pDeviceVendorId[2]}; + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); - UT_LOG_INFO("CEC Version response sent with result: %d\n", result); + UT_LOG_INFO("Device Vendor ID response sent with result: %d\n", result); } -void handleGiveDeviceVendorID(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[4] = { (destination << 4) | initiator, 0x87, 0x00, 0x00, 0x01 }; // Vendor ID: 0x000001 - int result; - HdmiCecTx(handle, response, sizeof(response), &result); - UT_LOG_INFO("Device Vendor ID response sent with result: %d\n", result); +static void handleDeviceVendorID(uint8_t *buf, int32_t len) +{ + if (len >= 5) + UT_LOG_INFO("Received Device Vendor ID: %x%x%x\n", buf[2], buf[3], buf[4]); + else + UT_LOG_ERROR("Give Device vendor ID command received with insufficient data.\n"); } -void handleStandby(int handle) { +static void handleStandby() +{ UT_LOG_INFO("Standby command received. Initiating standby actions.\n"); // Implement device-specific standby actions here, such as turning off the display. } -void handleGiveDeviceInfo(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[12] = { (destination << 4) | initiator, 0xA1, 'V', 'T', 'S', ' ', 'D', 'e', 'v', 'i', 'c', 'e' }; // Device Info: "VTS Device" - int result; +static void handleGiveDeviceInfo(int32_t handle, uint8_t initiator, uint8_t destination) +{ + uint8_t response[] = { (destination << 4) | initiator, 0xA1, 'V', 'T', 'S', ' ', 'D', 'e', 'v', 'i', 'c', 'e' }; // Device Info: "VTS Device" + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); UT_LOG_INFO("Device Info response sent with result: %d\n", result); } -void handleOsdDisplay(int handle, unsigned char initiator, unsigned char destination, unsigned char *buf, int len) { - if (len > 2) { - UT_LOG_INFO("OSD Display message received: "); - for (int i = 2; i < len; i++) { - UT_LOG_INFO("%c", buf[i]); +static void handleOsdDisplay(uint8_t *buf, int32_t len) +{ + if (len > 3) + { + uint8_t buffer[HDMI_CEC_MAX_OSDNAME] = {0}; + uint8_t *temp = buffer; + UT_LOG_INFO("OSD Display Control: %d", buf[2]); + for (int32_t i = 3; i < len; i++) + { + int32_t len = 0; + len = snprintf(temp, HDMI_CEC_MAX_OSDNAME, "%c", buf[i]); + temp += len; } - UT_LOG_INFO("\n"); - } else { + UT_LOG_INFO("OSD Display message received: %s", buffer); + } + else + { UT_LOG_ERROR("OSD Display message received with insufficient data.\n"); } } -void handleGetOsdName(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[11] = { (destination << 4) | initiator, 0x47, 'V', 'T', 'S', ' ', 'D', 'e', 'v', 'i', 'c', 'e' }; // OSD Name: "VTS Device" - int result; +static void handleGiveOSDName(int32_t handle, uint8_t initiator, uint8_t destination) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x47, 'V', 'T', 'S', ' ', 'D', 'e', 'v', 'i', 'c', 'e' }; // OSD Name: "VTS Device" + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); UT_LOG_INFO("OSD Name response sent with result: %d sourc/destination:0x%2x\n", result,response[0]); } -void handleGetPowerStatus(int handle, unsigned char initiator, unsigned char destination) { - unsigned char response[3] = { (destination << 4) | initiator, 0x90, 0x00 }; // Power Status: On (0x00) - int result; +static void handleSetOSDName(uint8_t *buf, int32_t len) +{ + if (len > 2) + { + uint8_t buffer[HDMI_CEC_MAX_OSDNAME] = {0}; + uint8_t *temp = buffer; + for (int32_t i = 2; i < len; i++) + { + int32_t len = 0; + len = snprintf(temp, HDMI_CEC_MAX_OSDNAME, "%c", buf[i]); + temp += len; + } + UT_LOG_INFO("OSD Name received: %s", buffer); + } + else + { + UT_LOG_ERROR("OSD Name message received with insufficient data.\n"); + } +} + +static void handleGivePowerStatus(int32_t handle, uint8_t initiator, uint8_t destination, HDMI_CEC_POWER_STATUS powerStatus) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x90, powerStatus }; + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); UT_LOG_INFO("Power Status response sent with result: %d\n", result); } -void handleFeatureAbort(int handle, unsigned char initiator, unsigned char destination, unsigned char opcode, unsigned char reason) { - unsigned char response[4] = { (destination << 4) | initiator, 0x00, opcode, reason }; // Abort with reason - int result; +static void handleReportPowerStatus(uint8_t *buf, int32_t len) +{ + if (len >= 3) + { + UT_LOG_INFO("Power Status: %s\n", UT_Control_GetMapString(cecPowerStatus_mapTable, buf[2])); + } + else + { + UT_LOG_ERROR("Power Status received with insufficient data.\n"); + } +} + +static void handleFeatureAbort(uint8_t *buf, int32_t len) +{ + if (len >= 4) + { + UT_LOG_INFO("Feature Abort: Opcode: 0x%02X, Reason: %s\n", buf[2], UT_Control_GetMapString(cecFeatureAbortReason_mapTable, buf[3])); + } + else + { + UT_LOG_ERROR("Feature Abort received with insufficient data.\n"); + } +} + +static void sendFeatureAbort(int32_t handle, uint8_t initiator, uint8_t destination, uint8_t opcode, uint8_t reason) +{ + uint8_t response[] = { (destination << 4) | initiator, 0x00, opcode, reason }; // Abort with reason + int32_t result; HdmiCecTx(handle, response, sizeof(response), &result); UT_LOG_WARNING("Feature Abort sent for opcode: 0x%02X with reason: 0x%02X, result: %d\n", opcode, reason, result); } +static void handleSetMenuLanguage(uint8_t *buf, int32_t len) +{ + if (len >= 5) + { + UT_LOG_INFO("OSD Menu Language received: %c%c%c", buf[2], buf[2], buf[3]); + } + else + { + UT_LOG_ERROR("OSD Menu Language received with insufficient data"); + } +} + +static void handleCurrentLatency(int32_t handle, uint8_t *buf, int32_t len, uint8_t *pPhysicalAddress, uint8_t videoDelay, uint8_t audioDelay, uint8_t latency) +{ + uint8_t response[] = {(gLogicalAddress << 4) | gBroadcastAddress, 0xA8, buf[2], buf[3], videoDelay, latency, audioDelay}; + + int32_t result; + + if (len >= 4) + { + if (buf[2] == (pPhysicalAddress[3] << 4) | pPhysicalAddress[2] && + buf[3] == (pPhysicalAddress[1] << 4) | pPhysicalAddress[0]) + { + response[4] = videoDelay; + response[5] = latency; + response[6] = audioDelay; + + HdmiCecTx(handle, response, sizeof(response), &result); + } + + } + else + { + UT_LOG_ERROR("Latency query received with insufficient data.\n"); + } +} + +static void handleRequestActiveSource(int32_t handle, uint8_t *pPhysicalAddress) +{ + uint8_t response[] = { (gLogicalAddress << 4) | gBroadcastAddress, 0x82, (pPhysicalAddress[3] << 4) | pPhysicalAddress[2], (pPhysicalAddress[1] << 4 ) | pPhysicalAddress[0]}; + int32_t result; + HdmiCecTx(handle, response, sizeof(response), &result); + UT_LOG_INFO("Requested Active Sources response sent with result: %d\n", result); +} /** * @brief This function clears the stdin buffer. @@ -340,7 +465,7 @@ void handleFeatureAbort(int handle, unsigned char initiator, unsigned char desti */ static void readAndDiscardRestOfLine(FILE *in) { - int c; + int32_t c; while ((c = fgetc(in)) != EOF && c != '\n'); } @@ -355,69 +480,97 @@ static void readHex(int32_t *value) scanf("%x", value); readAndDiscardRestOfLine(stdin); } -void onRxDataReceived(int handle, void *callbackData, unsigned char *buf, int len) { - UT_LOG_INFO("In %s(IN: handle: [%d], IN: callbackData: [%p], IN: buf: [%p], IN: len: [%d])\n", __FUNCTION__, handle, callbackData, buf, len); - - if ((handle != 0) && (callbackData != NULL) && (len > 0)) { - UT_LOG_INFO("CEC Data Received\n"); - // Log each byte received in the buffer - for (int index = 0; index < len; index++) { - UT_LOG_INFO("Buffer at index [%d]: [0x%02X]\n", index, buf[index]); - } +static void onRxDataReceived(int32_t handle, void *callbackData, uint8_t *buf, int32_t len) +{ + UT_LOG_INFO("In %s(IN: handle: [%p], IN: callbackData: [%p], IN: buf: [%p], IN: len: [%d])\n", __FUNCTION__, handle, callbackData, buf, len); + if ((handle != 0) && (callbackData != NULL) && (len > 0)) + { // Parse the command - unsigned char initiator = (buf[0] >> 4) & 0xF; // Extract initiator address - unsigned char destination = buf[0] & 0xF; // Extract destination address - unsigned char opcode = buf[1]; // Command opcode + uint8_t initiator = (buf[0] >> 4) & 0xF; // Extract initiator address + uint8_t destination = buf[0] & 0xF; // Extract destination address + uint8_t opcode; // Command opcode + if( len == 1) + { + UT_LOG_INFO("Received Ping message Initiator: [0x%02X], Destination: [0x%02X]", initiator, destination); + UT_LOG_INFO("Out %s\n", __FUNCTION__); + return; + } - UT_LOG_INFO("Initiator: [0x%X], Destination: [0x%X], Opcode: [0x%02X]\n", initiator, destination, opcode); + opcode = buf[1]; + + UT_LOG_INFO("Initiator: [0x%02X], Destination: [0x%02X], Opcode: [0x%02X]", initiator, destination, opcode); + if (len > 2) + { + char buffer[HDMI_CEC_MAX_PAYLOAD] = {0}; + uint8_t *temp = buffer; + // Log each byte received in the buffer + for (int32_t index = 2; index < len; index++) + { + int32_t len = 0; + len = snprintf(temp, HDMI_CEC_MAX_PAYLOAD, "0x%02X, ", buf[index]); + temp += len; + } + buffer[strlen(buffer)-2] = '\0'; + UT_LOG_INFO("Payload: [%s]", buffer); + } // Handle each opcode with its corresponding function - switch (opcode) { - case 0x04: handleImageViewOn(handle, initiator, destination); break; - case 0x82: handleActiveSource(handle, initiator, destination, buf, len); break; - case 0x8E: handleGivePhysicalAddress(handle, initiator, destination); break; - case 0x87: handleDeviceVendorID(handle, initiator, destination); break; - case 0x84: handleReportPhysicalAddress(handle, initiator, destination); break; - case 0x90: handleReportPowerStatus(handle, initiator, destination); break; - case 0x9F: handleGiveCECVersion(handle, initiator, destination); break; - case 0x8C: handleGiveDeviceVendorID(handle, initiator, destination); break; - case 0x36: handleStandby(handle); break; - case 0xA0: handleGiveDeviceInfo(handle, initiator, destination); break; - case 0x64: handleOsdDisplay(handle, initiator, destination, buf, len); break; - case 0x46: handleGetOsdName(handle, initiator, destination); break; - case 0x8F: handleGetPowerStatus(handle, initiator, destination); break; - case 0x00: handleFeatureAbort(handle, initiator, destination, opcode, 0x04); break; + switch (opcode) + { + // CEC Commands no response sent + case 0x00: handleFeatureAbort(buf, len); break; + case 0x04: handleImageViewOn(); break; + case 0x32: handleSetMenuLanguage(buf, len); break; + case 0x82: handleActiveSource(buf, len); break; + case 0x84: handleReportPhysicalAddress(buf, len); break; + case 0x87: handleDeviceVendorID(buf, len); break; + case 0x36: handleStandby(); break; + case 0x64: handleOsdDisplay(buf, len); break; + case 0x90: handleReportPowerStatus(buf, len); break; + case 0x9E: handleCECVersion(buf, len); break; + case 0x47: handleSetOSDName(buf, len); break; + + // CEC commands with response + case 0x83: handleGivePhysicalAddress(handle, initiator, destination, gPhysicalAddressBytes, gDeviceType); break; + case 0x8F: handleGivePowerStatus(handle, initiator, destination, gPowerStatus); break; + case 0x8C: handleGiveDeviceVendorID(handle, initiator, destination, gDeviceVendorID); break; + case 0x9F: handleGetCECVersion(handle, initiator, destination, gCECVersion); break; + case 0x46: handleGiveOSDName(handle, initiator, destination); break; + + // Broadcasting CEC commands with response + case 0x85: handleRequestActiveSource(handle, gPhysicalAddressBytes); break; + case 0xA7: handleCurrentLatency(handle, buf, len, gPhysicalAddressBytes, gVideoDelay, gAudioDelay, gLatencyFlag); break; default: UT_LOG_WARNING("Unhandled opcode: [0x%02X]\n", opcode); - //handleFeatureAbort(handle, initiator, destination, opcode, 0x04); // Feature Abort: Unrecognized opcode + sendFeatureAbort(handle, initiator, destination, opcode, 0x04); // Feature Abort: Unrecognized opcode break; } // Clear the buffer after processing memset(buf, 0, len); - UT_LOG_INFO("Buffer cleared after processing.\n"); - - } else { + } + else + { // Log specific errors based on failed conditions - if (handle == 0) { + if (handle == 0) + { UT_LOG_ERROR("Error: Invalid handle.\n"); } - if (callbackData == NULL) { + if (callbackData == NULL) + { UT_LOG_ERROR("Error: Null callback data.\n"); } - if (len <= 0) { + if (len <= 0) + { UT_LOG_ERROR("Error: Invalid length.\n"); } } - cbFlag = 1; - UT_LOG_INFO("Out %s(OUT: cbFlag set to [1])\n", __FUNCTION__); + UT_LOG_INFO("Out %s\n", __FUNCTION__); } - - /** * @brief Initialization of the HAL CEC Module * @@ -436,27 +589,34 @@ void onRxDataReceived(int handle, void *callbackData, unsigned char *buf, int le * User or Automation tool should select the Test 1 to before running any test. * */ - void test_l3_hdmi_cec_sink_hal_Init(void) { - gTestID = 1; - HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; + gTestID = 1; + HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; - UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); + UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); - // Step 1: Call HdmiCecOpen() - UT_LOG_INFO("Calling HdmiCecOpen(IN:gHandle[0x%0X])",&gHandle); - status = HdmiCecOpen(&gHandle); - UT_LOG_INFO("Result HdmiCecSetRxCallback() cecError:[%s]",UT_Control_GetMapString(cecError_mapTable,status)); - assert(status == HDMI_CEC_IO_SUCCESS); + // Step 1: Call HdmiCecOpen() + UT_LOG_INFO("Calling HdmiCecOpen(OUT:handle:[])"); + status = HdmiCecOpen(&gHandle); + UT_LOG_INFO("Result HdmiCecOpen(OUT:handle:[0x%0X]) HDMI_CEC_STATUS:[%s]",gHandle, UT_Control_GetMapString(cecError_mapTable,status)); + assert(status == HDMI_CEC_IO_SUCCESS); + assert(gHandle != 0); - // Step 2: Register the call back - UT_LOG_INFO("Calling HdmiCecSetRxCallback(IN:handle[0x%0X],IN:cbfunc[0x%0X]",gHandle,onRxDataReceived); - status = HdmiCecSetRxCallback(gHandle, onRxDataReceived,(void*)0xABABABAB); - UT_LOG_INFO("Result HdmiCecSetRxCallback() cecError:[%s]",UT_Control_GetMapString(cecError_mapTable,status)); - assert(status == HDMI_CEC_IO_SUCCESS); + // Step 2: Register the call back + UT_LOG_INFO("Calling HdmiCecSetRxCallback(IN:handle:[0x%0X], IN:cbfunc:[0x%0X])",gHandle, onRxDataReceived); + status = HdmiCecSetRxCallback(gHandle, onRxDataReceived,(void*)0xABABABAB); + UT_LOG_INFO("Result HdmiCecSetRxCallback(IN:handle:[0x%0X], IN:cbfunc:[0x%0X]) HDMI_CEC_STATUS:[%s]",gHandle,onRxDataReceived, UT_Control_GetMapString(cecError_mapTable,status)); + assert(status == HDMI_CEC_IO_SUCCESS); + + UT_LOG_INFO("Calling HdmiCecGetPhysicalAddress(IN:handle:[0x%0X], OUT:physicalAddress:[])", gHandle); + status = HdmiCecGetPhysicalAddress(gHandle, &gPhysicalAddress); + UT_LOG_INFO("Result HdmiCecGetPhysicalAddress(IN:handle:[0x%0X], OUT:physicalAddress:[%d]) HDMI_CEC_STATUS:[%s]", gHandle, gPhysicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); + assert(status == HDMI_CEC_IO_SUCCESS); - UT_LOG_INFO("Out %s\n", __FUNCTION__); + gPhysicalAddressBytes = (uint8_t*)&gPhysicalAddress; + + UT_LOG_INFO("Out %s\n", __FUNCTION__); } /** @@ -489,23 +649,29 @@ void test_l3_hdmi_cec_sink_hal_AddLogicalAddress(void) HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; - int logicalAddress = -1; + int32_t logicalAddress = -1; + int32_t getLogicalAddress = -1; - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tEnter Logical Address: "); - readHex(&logicalAddress;) - UT_LOG_MENU_INFO("----------------------------------------------------------"); + UT_LOG_MENU_INFO("Enter Logical Address:"); + readInt(&logicalAddress); /* Check that logical address should be valid one */ - UT_LOG_INFO("Calling HdmiCecAddLogicalAddress(IN:handle:[0x%0X], IN:logicalAddress:[%d]",gHandle,logicalAddress); - status = HdmiCecAddLogicalAddress(gHandle,logicalAddress ); - UT_LOG_INFO("HdmiCecAddLogicalAddress (IN:handle:[0x%0X], IN:logicalAddress:[%d]), status[%d]",gHandle,logicalAddress,UT_Control_GetMapString(cecError_mapTable,status)); + UT_LOG_INFO("Calling HdmiCecAddLogicalAddress(IN:handle:[0x%0X], IN:logicalAddress:[%d]", gHandle, logicalAddress); + status = HdmiCecAddLogicalAddress(gHandle, logicalAddress); + UT_LOG_INFO("Result HdmiCecAddLogicalAddress (IN:handle:[0x%0X], IN:logicalAddress:[%d]) HDMI_CEC_STATUS[%s]",gHandle,logicalAddress,UT_Control_GetMapString(cecError_mapTable,status)); + assert(status == HDMI_CEC_IO_SUCCESS); + + UT_LOG_INFO("Calling HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[])", gHandle); + status = HdmiCecGetLogicalAddress(gHandle, &getLogicalAddress); + UT_LOG_INFO("Result HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[%d]) HDMI_CEC_STATUS:[%s])", gHandle, getLogicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); assert(status == HDMI_CEC_IO_SUCCESS); + assert(logicalAddress == getLogicalAddress); + + gLogicalAddress = getLogicalAddress; UT_LOG_INFO("Out %s\n", __FUNCTION__); } - /** * @brief Test to get the logical address * @@ -531,18 +697,16 @@ void test_l3_hdmi_cec_sink_hal_GetLogicalAddress(void) UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; - int logicalAddress = -1; + int32_t logicalAddress = -1; - UT_LOG_INFO("Calling HdmiCecGetLogicalAddress(IN: handle: [0x%0X], OUT: logicalAddress: [])", gHandle); + UT_LOG_INFO("Calling HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[])", gHandle); status = HdmiCecGetLogicalAddress(gHandle, &logicalAddress); - - UT_LOG_INFO("HdmiCecGetLogicalAddress(IN: handle: [0x%0X], OUT: logicalAddress: [%d]), status: [%d])", gHandle, logicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); + UT_LOG_INFO("Result HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[%d]) HDMI_CEC_STATUS:[%s])", gHandle, logicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); assert(status == HDMI_CEC_IO_SUCCESS); + UT_LOG_INFO("Out %s\n", __FUNCTION__); } - - /** * @brief Test provides a scope to Transmit the CEC Command * @@ -559,7 +723,7 @@ void test_l3_hdmi_cec_sink_hal_GetLogicalAddress(void) * **Dependencies:** None@n * * **User Interaction:** @n -* User or Automation tool should select the Test 4 and shall provide the necessary source and destination logical address, +* User or Automation tool should select the Test 4 and shall provide the necessary source and destination logical address, * CEC command, data lenght and data. * */ @@ -567,123 +731,63 @@ void test_l3_hdmi_cec_sink_hal_TransmitHdmiCecCommand(void) { gTestID = 4; UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); - int sourceLogicalAddress = -1; - int destinationLogicalAddress = -1; - unsigned char buf[16] = {0}; - int len = 0, cecCommand = 0; - int result; + int32_t sourceLogicalAddress = gLogicalAddress; + int32_t destinationLogicalAddress = -1; + uint8_t buf[16] = {0}; + int32_t len = 0, cecCommand = 0; + int32_t result; const char* commandName; - int expectedDataLength; + int32_t expectedDataLength; - // Reading inputs from the user or test framework - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tEnter a valid Source Logical Address:"); - readHex(&sourceLogicalAddress); - UT_LOG_MENU_INFO("----------------------------------------------------------"); - - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tEnter a valid Destination Logical Address: "); - readHex(&destinationLogicalAddress); - UT_LOG_MENU_INFO("----------------------------------------------------------"); + assert(sourceLogicalAddress != -1); + // Reading inputs from the user or test framework + UT_LOG_MENU_INFO("Enter a valid Destination Logical Address: "); + readInt(&destinationLogicalAddress); - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tEnter CEC Command (in hex): "); + UT_LOG_MENU_INFO("Enter CEC Command (in hex): "); readHex(&cecCommand); - UT_LOG_MENU_INFO("----------------------------------------------------------"); // Validate the CEC command and get the expected data length - if (getCecCommandInfo(cecCommand, &commandName, &expectedDataLength) != 0) { + if (getCecCommandInfo(cecCommand, &commandName, &expectedDataLength) != 0) + { // Command not found in the map, prompt the user for additional information UT_LOG_WARNING("CEC command 0x%02X is not recognized. It might be a vendor-specific command.", cecCommand); - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tPlease enter the number of data bytes for the CEC command: "); + UT_LOG_MENU_INFO("Enter the number of data bytes for the CEC command:"); readInt(&expectedDataLength); - UT_LOG_MENU_INFO("----------------------------------------------------------"); commandName = "Vendor Specific Command"; - } else { + } + else + { UT_LOG_INFO("CEC Command: %s (0x%02X), expects %d data byte(s)", commandName, cecCommand, expectedDataLength); } // If the command has data bytes, prompt for them - if (expectedDataLength > 0) { - for (int i = 0; i < expectedDataLength; i++) { - UT_LOG_MENU_INFO("\t \tEnter Databyte[%d] (in hex):", i); - readHex(&buf[i + 2]); // +2 to account for the first two bytes + if (expectedDataLength > 0) + { + for (int32_t i = 0; i < expectedDataLength; i++) + { + int32_t byte_data; + UT_LOG_MENU_INFO("Enter Databyte[%d] (in hex):", i); + readHex(&byte_data); + buf[i + 2] = (uint8_t)byte_data; // +2 to account for the first two bytes } } // Building the CEC message - buf[0] = (unsigned char)((sourceLogicalAddress << 4) | (destinationLogicalAddress & 0x0F)); - buf[1] = (unsigned char)cecCommand; + buf[0] = (uint8_t)((sourceLogicalAddress << 4) | (destinationLogicalAddress & 0x0F)); + buf[1] = (uint8_t)cecCommand; len = expectedDataLength + 2; // 1 byte for logical addresses, 1 byte for CEC Command // Logging the transmission attempt - UT_LOG_INFO("Calling HdmiCecTx(IN: handle: [0x%0X], IN: message length: [%d], IN: message data: [", gHandle, len); - for (int i = 0; i < len; i++) { - printf(" %02X", buf[i]); - } - printf(" ])"); - - // Assume HdmiCecTx is a function to send the CEC command - int status = HdmiCecTx(gHandle, buf, len, &result); - UT_LOG_INFO("HdmiCecTx(IN: handle: [0x%0X], IN: length: [%d], result: [%d], status:[%d])", gHandle, len, result, UT_Control_GetMapString(cecError_mapTable,status)); - - //assert((result == HDMI_CEC_IO_SENT_BUT_NOT_ACKD) && (status == HDMI_CEC_IO_SUCCESS)); - - // Optional delay after sending the command - sleep(5); - - UT_LOG_INFO("Out %s\n", __FUNCTION__); -} - -/** -* @brief Test to Receive the CEC Command -* -* This test provides an interface to check whether the CEC has received any frames or not. -* -* **Test Group ID:** 02@n -* -* **Test Case ID:** 005@n -* -* **Pre-Conditions:** @n -* HDMI-CEC Module should be intialized through Test 1 before calling this test. -* -* **Dependencies:** @n -* Depends on the external device to send a CEC Frames with necessary command and data. -* -* **User Interaction:** @n -* User or Automation tool should select the Test 5 and make sure that the CEC Frames has been sent from an external -* device connected in the network. -* -*/ -void test_l3_hdmi_cec_sink_hal_ReceiveHdmiCecCommand(void) -{ - gTestID = 5; - UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); - - UT_LOG_INFO("Waiting for HDMI CEC command (timeout: %d seconds)", REPLY_TIMEOUT); - - sleep(REPLY_TIMEOUT); // Wait for a reply - - if (cbFlag != 1) - { - UT_LOG_ERROR("HdmiCecRx failed to receive data (IN: expected callback flag: [1], OUT: actual callback flag: [%d])", cbFlag); - assert(cbFlag == 1); - } - else - { - UT_LOG_INFO("HdmiCecRx successfully received data (OUT: callback flag: [%d])", cbFlag); - } - - // Resetting callback flag for future tests - cbFlag = 0; + UT_LOG_INFO("Calling HdmiCecTx(IN:handle:[0x%0X], IN:buf:[%p], IN:len:[%d], OUT:result:[])", gHandle, buf, len); + int32_t status = HdmiCecTx(gHandle, buf, len, &result); + UT_LOG_INFO("Result HdmiCecTx(IN:handle:[0x%0X], IN:buf:[%p], IN:len:[%d], OUT:result:[%d]) HDMI_CEC_STATUS:[%s]", gHandle, buf, len, result, UT_Control_GetMapString(cecError_mapTable,status)); UT_LOG_INFO("Out %s\n", __FUNCTION__); } - /** * @brief Test to get the physical address * @@ -699,7 +803,7 @@ void test_l3_hdmi_cec_sink_hal_ReceiveHdmiCecCommand(void) * **Dependencies:** None@n * * **User Interaction:** @n -* User or Automation tool should select the Test 6 to read the physical address of the device +* User or Automation tool should select the Test 6 to read the physical address of the device * device connected in the network. * */ @@ -709,22 +813,20 @@ void test_l3_hdmi_cec_sink_hal_GetPhysicalAddress(void) UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; - int physicalAddress = -1; - - UT_LOG_INFO("Calling HdmiCecGetPhysicalAddress(IN: handle: [0x%0X], OUT: physicalAddress: [uninitialized])", gHandle); + uint32_t physicalAddress = -1; + UT_LOG_INFO("Calling HdmiCecGetPhysicalAddress(IN:handle:[0x%0X], OUT:physicalAddress:[])", gHandle); status = HdmiCecGetPhysicalAddress(gHandle, &physicalAddress); - UT_LOG_INFO("HdmiCecGetPhysicalAddress(IN: handle: [0x%0X], physicalAddress: [%d]), status:[%d]", gHandle, physicalAddress,UT_Control_GetMapString(cecError_mapTable,status)); + UT_LOG_INFO("Result HdmiCecGetPhysicalAddress(IN:handle:[0x%0X], OUT:physicalAddress:[%d]) HDMI_CEC_STATUS:[%s]", gHandle, physicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); assert(status == HDMI_CEC_IO_SUCCESS); UT_LOG_INFO("Out %s\n", __FUNCTION__); } - /** * @brief Test to Remove logical address * -* This test provides a scope to remove the logical address of the device. HAL API to set +* This test provides a scope to remove the logical address of the device. HAL API to set * to default logical addres 0xF once the logical address is removed. * * **Test Group ID:** 02@n @@ -746,20 +848,24 @@ void test_l3_hdmi_cec_sink_hal_RemoveLogicalAddress(void) UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); HDMI_CEC_STATUS status = HDMI_CEC_IO_SUCCESS; - int logicalAddress = -1; + int32_t logicalAddress = gLogicalAddress; + int32_t getLogicalAddress = 0; - UT_LOG_MENU_INFO("----------------------------------------------------------"); - UT_LOG_MENU_INFO("\t \tEnter Logical Address to Remove: "); - readHex(&logicalAddress); - UT_LOG_MENU_INFO("----------------------------------------------------------"); + assert(logicalAddress != -1); - UT_LOG_INFO("Calling HdmiCecRemoveLogicalAddress(IN: handle: [0x%0X], IN: logicalAddress: [%d])", gHandle, logicalAddress); - - // Invoke the API HdmiCecRemoveLogicalAddress + UT_LOG_INFO("Calling HdmiCecRemoveLogicalAddress(IN:handle:[0x%0X], IN:logicalAddress:[%d])", gHandle, logicalAddress); status = HdmiCecRemoveLogicalAddress(gHandle, logicalAddress); - UT_LOG_INFO("HdmiCecRemoveLogicalAddress(IN: handle: [0x%0X], IN: logicalAddress: [%d], OUT: status: [%d])", gHandle, logicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); + UT_LOG_INFO("Result HdmiCecRemoveLogicalAddress(IN:handle:[0x%0X], IN:logicalAddress:[%d]) HDMI_CEC_STATUS:[%s])", gHandle, logicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); + assert(status == HDMI_CEC_IO_SUCCESS); + + UT_LOG_INFO("Calling HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[])", gHandle); + status = HdmiCecGetLogicalAddress(gHandle, &getLogicalAddress); + UT_LOG_INFO("Result HdmiCecGetLogicalAddress(IN:handle:[0x%0X], OUT:logicalAddress:[%d]) HDMI_CEC_STATUS:[%s])", gHandle, getLogicalAddress, UT_Control_GetMapString(cecError_mapTable,status)); assert(status == HDMI_CEC_IO_SUCCESS); - + assert(getLogicalAddress == -1); + + gLogicalAddress = -1; + UT_LOG_INFO("Out %s\n", __FUNCTION__); } /** @@ -780,22 +886,19 @@ void test_l3_hdmi_cec_sink_hal_RemoveLogicalAddress(void) * User or Automation tool should select the Test 8 to close the created HDMI CEC handle. * */ -void test_l2_hdmi_cec_sink_hal_Close(void) +void test_l3_hdmi_cec_sink_hal_Close(void) { gTestID = 8; HDMI_CEC_STATUS status; UT_LOG_INFO("In %s [%02d%03d]\n", __FUNCTION__, gTestGroup, gTestID); - // Step 1: Log the pre-requisite action - UT_LOG_INFO("Calling HdmiCecClose(IN: handle: [0x%0X])", gHandle); - - // Step 2: Call the API to close the HDMI CEC handle + UT_LOG_INFO("Calling HdmiCecClose(IN:handle:[0x%0X])", gHandle); status = HdmiCecClose(gHandle); - UT_LOG_INFO("HdmiCecClose(IN: handle: [0x%0X]) status: [%d]", gHandle, status); + UT_LOG_INFO("Result HdmiCecClose(IN:handle:[0x%0X]) HDMI_CEC_STATUS:[%s]", gHandle, UT_Control_GetMapString(cecError_mapTable,status)); assert(status == HDMI_CEC_IO_SUCCESS); + gHandle = 0; - // Step 4: Log the end of the function UT_LOG_INFO("Out %s\n", __FUNCTION__); } @@ -804,9 +907,9 @@ static UT_test_suite_t * pSuite = NULL; /** * @brief Register the main tests for this module * - * @return int - 0 on success, otherwise failure + * @return int32_t - 0 on success, otherwise failure */ -int test_register_hdmicec_hal_sink_l3_tests(void) +int32_t test_register_hdmicec_hal_sink_l3_tests(void) { // Create the test suite pSuite = UT_add_suite("[L3 HDMICEC Sink Functions] ", NULL, NULL); @@ -816,14 +919,13 @@ int test_register_hdmicec_hal_sink_l3_tests(void) } // List of test function names and strings - UT_add_test( pSuite, "L3_Init_HdmiCec", test_l3_hdmi_cec_sink_hal_Init); - UT_add_test( pSuite, "L3_AddLogicalAddress", test_l3_hdmi_cec_sink_hal_AddLogicalAddress); - UT_add_test( pSuite, "L3_GetLogicalAddress", test_l3_hdmi_cec_sink_hal_GetLogicalAddress); - UT_add_test( pSuite, "L3_TransmitCecCommand", test_l3_hdmi_cec_sink_hal_TransmitHdmiCecCommand); - UT_add_test( pSuite, "L3_ReceiveCecCommand", test_l3_hdmi_cec_sink_hal_ReceiveHdmiCecCommand); - UT_add_test( pSuite, "L3_GetPhyiscalAddress", test_l3_hdmi_cec_sink_hal_GetPhysicalAddress); - UT_add_test( pSuite, "L3_RemoveLogicalAddressHdmiCec_Sink", test_l3_hdmi_cec_sink_hal_RemoveLogicalAddress); - UT_add_test( pSuite, "L3_Close_HdmiCec_Sink", test_l2_hdmi_cec_sink_hal_Close); + UT_add_test( pSuite, "Init HDMI CEC", test_l3_hdmi_cec_sink_hal_Init); + UT_add_test( pSuite, "Add Logical Address", test_l3_hdmi_cec_sink_hal_AddLogicalAddress); + UT_add_test( pSuite, "Get Logical Address", test_l3_hdmi_cec_sink_hal_GetLogicalAddress); + UT_add_test( pSuite, "Transmit CEC Command", test_l3_hdmi_cec_sink_hal_TransmitHdmiCecCommand); + UT_add_test( pSuite, "Get Phyiscal Address", test_l3_hdmi_cec_sink_hal_GetPhysicalAddress); + UT_add_test( pSuite, "Remove Logical Address", test_l3_hdmi_cec_sink_hal_RemoveLogicalAddress); + UT_add_test( pSuite, "Close HDMI CEC", test_l3_hdmi_cec_sink_hal_Close); return 0; }