diff --git a/ccec/src/Bus.cpp b/ccec/src/Bus.cpp index adc4af07..288402af 100644 --- a/ccec/src/Bus.cpp +++ b/ccec/src/Bus.cpp @@ -70,8 +70,8 @@ Bus & Bus::getInstance(void) Bus::Bus(void) : reader(*this), writer(*this), started(false) { CCEC_LOG( LOG_DEBUG, "Bus Instance Created\r\n"); - Thread(this->reader).start(); - Thread(this->writer).start(); + /* Reader and Writer threads start via Bus::start() to prevent 100% CPU on HALs without CEC; + launched from LibCCEC::init() after driver validation. */ CCEC_LOG( LOG_DEBUG, "Bus Instance DONE\r\n"); } @@ -93,7 +93,6 @@ void Bus::start(void) Thread(writer).start(); } - Driver::getInstance().open(); started = true; } @@ -116,7 +115,6 @@ CCEC_LOG( LOG_INFO, "Bus::stop is called\r\n"); writer.stop(true); } - Driver::getInstance().close(); CCEC_LOG( LOG_INFO, "Bus::stop is called reader isstop :%d writer isstop :%d \r\n",reader.isStopped(),writer.isStopped()); } @@ -404,7 +402,7 @@ void Bus::sendAsync(const CECFrame &frame) } /** - * @brief This function is used to poll the logical address + * @brief This function is used to poll the logical address * and returns the ACK or NACK received from other devices. * If NACK then the device can use this logical address. * @@ -431,7 +429,7 @@ void Bus::poll(const LogicalAddress &from, const LogicalAddress &to) } /** - * @brief This function is used to ping devices, to know whether it present + * @brief This function is used to ping devices, to know whether it present * and returns the ACK or NACK received from other devices. * If ACK is received, then the device is present. * diff --git a/ccec/src/DriverImpl.cpp b/ccec/src/DriverImpl.cpp index 13b90f44..90ec5401 100644 --- a/ccec/src/DriverImpl.cpp +++ b/ccec/src/DriverImpl.cpp @@ -117,8 +117,23 @@ void DriverImpl::open(void) noexcept(false) } int err = HdmiCecOpen(&nativeHandle); - if (err != HDMI_CEC_IO_SUCCESS) { - throw IOException(); + if (HDMI_CEC_IO_SUCCESS != err) { + CCEC_LOG( LOG_EXP, "DriverImpl::open HdmiCecOpen failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + break; + case HDMI_CEC_IO_ALREADY_OPEN: + throw InvalidStateException(); + break; + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + break; + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } } HdmiCecSetRxCallback(nativeHandle, DriverReceiveCallback, 0); @@ -145,7 +160,19 @@ void DriverImpl::close(void) noexcept(false) int err = HdmiCecClose(nativeHandle); if (err != HDMI_CEC_IO_SUCCESS) { - throw IOException(); + CCEC_LOG( LOG_EXP, "DriverImpl::close HdmiCecClose failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + break; + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + break; + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + break; + } } status = CLOSED; @@ -195,7 +222,6 @@ void DriverImpl::read(CECFrame &frame) noexcept(false) */ void DriverImpl::writeAsync(const CECFrame &frame) noexcept(false) { - const uint8_t *buf = NULL; size_t length = 0; @@ -219,7 +245,20 @@ void DriverImpl::writeAsync(const CECFrame &frame) noexcept(false) CCEC_LOG( LOG_DEBUG, "DriverImpl:: call HdmiCecTxAsync %x\r\n", err); if (err != HDMI_CEC_IO_SUCCESS) { - throw IOException(); + CCEC_LOG(LOG_EXP, "DriverImpl::write HdmiCecTxAsync failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + break; + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + break; + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + break; + } } } @@ -233,7 +272,6 @@ void DriverImpl::writeAsync(const CECFrame &frame) noexcept(false) */ void DriverImpl::write(const CECFrame &frame) noexcept(false) { - const uint8_t *buf = NULL; size_t length = 0; @@ -258,14 +296,24 @@ void DriverImpl::write(const CECFrame &frame) noexcept(false) CCEC_LOG( LOG_DEBUG, "DriverImpl:: call HdmiCecTx DONE %x, result %x\r\n", err, sendResult); if (err != HDMI_CEC_IO_SUCCESS) { - throw IOException(); + CCEC_LOG(LOG_EXP, "DriverImpl::write HdmiCecTx failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } } if (sendResult != HDMI_CEC_IO_SUCCESS) { if ((sendResult == HDMI_CEC_IO_INVALID_HANDLE) || - (sendResult == HDMI_CEC_IO_INVALID_ARGUMENT) || - (sendResult == HDMI_CEC_IO_LOGICALADDRESS_UNAVAILABLE) || - (sendResult == HDMI_CEC_IO_SENT_FAILED) || + (sendResult == HDMI_CEC_IO_INVALID_ARGUMENT) || + (sendResult == HDMI_CEC_IO_LOGICALADDRESS_UNAVAILABLE) || + (sendResult == HDMI_CEC_IO_SENT_FAILED) || (sendResult == HDMI_CEC_IO_GENERAL_ERROR) ) { throw IOException(); @@ -278,7 +326,6 @@ void DriverImpl::write(const CECFrame &frame) noexcept(false) /* CEC CTS 9-3-3 -Ensure that the DUT will accept a negatively for broadcat report physical address msg and retry atleast once */ else if (((frame.at(0) & 0x0F) == 0x0F) && (length > 1) && ((frame.at(1) & 0xFF) == REPORT_PHYSICAL_ADDRESS ) && (sendResult == HDMI_CEC_IO_SENT_BUT_NOT_ACKD)) { - throw CECNoAckException(); } } @@ -292,7 +339,20 @@ int DriverImpl::getLogicalAddress(int devType) int logicalAddress = 0; CCEC_LOG( LOG_DEBUG, "DriverImpl::getLogicalAddress called for devType : %d \r\n", devType); - HdmiCecGetLogicalAddress(nativeHandle, &logicalAddress); + int err = HdmiCecGetLogicalAddress(nativeHandle, &logicalAddress); + if (err != HDMI_CEC_IO_SUCCESS) { + CCEC_LOG(LOG_EXP, "DriverImpl::getLogicalAddress HdmiCecGetLogicalAddress failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } + } CCEC_LOG( LOG_DEBUG, "DriverImpl::getLogicalAddress got logical Address : %d \r\n", logicalAddress); return logicalAddress; @@ -304,7 +364,20 @@ void DriverImpl::getPhysicalAddress(unsigned int *physicalAddress) {AutoLock lock_(mutex); CCEC_LOG( LOG_DEBUG, "DriverImpl::getPhysicalAddress called \r\n"); - HdmiCecGetPhysicalAddress(nativeHandle,physicalAddress); + int err = HdmiCecGetPhysicalAddress(nativeHandle,physicalAddress); + if (err != HDMI_CEC_IO_SUCCESS) { + CCEC_LOG(LOG_EXP, "DriverImpl::getPhysicalAddress HdmiCecGetPhysicalAddress failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } + } CCEC_LOG( LOG_DEBUG, "DriverImpl::getPhysicalAddress got physical Address : %x \r\n", *physicalAddress); return ; @@ -321,7 +394,20 @@ void DriverImpl::removeLogicalAddress(const LogicalAddress &source) } logicalAddresses.remove(source); - HdmiCecRemoveLogicalAddress(nativeHandle, source.toInt()); + int err = HdmiCecRemoveLogicalAddress(nativeHandle, source.toInt()); + if (err != HDMI_CEC_IO_SUCCESS) { + CCEC_LOG(LOG_EXP, "DriverImpl::removeLogicalAddress HdmiCecRemoveLogicalAddress failed with error %d\r\n", err); + switch (err) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } + } } } @@ -334,14 +420,21 @@ bool DriverImpl::addLogicalAddress(const LogicalAddress &source) } int retErr = HdmiCecAddLogicalAddress(nativeHandle, source.toInt()); - - if (retErr == HDMI_CEC_IO_LOGICALADDRESS_UNAVAILABLE) { - throw AddressNotAvailableException(); - } - else if (retErr == HDMI_CEC_IO_GENERAL_ERROR) { - throw IOException(); - } - else { + if (retErr != HDMI_CEC_IO_SUCCESS) { + CCEC_LOG(LOG_EXP, "DriverImpl::addLogicalAddress HdmiCecAddLogicalAddress failed with error %d\r\n", retErr); + switch (retErr) { + case HDMI_CEC_IO_INVALID_ARGUMENT: + case HDMI_CEC_IO_INVALID_HANDLE: + throw InvalidParamException(); + case HDMI_CEC_IO_OPERATION_NOT_SUPPORTED: + throw OperationNotSupportedException(); + case HDMI_CEC_IO_LOGICALADDRESS_UNAVAILABLE: + throw AddressNotAvailableException(); + case HDMI_CEC_IO_GENERAL_ERROR: + default: + throw IOException(); + } + } else { logicalAddresses.push_back(source); } } @@ -374,7 +467,7 @@ void DriverImpl::poll(const LogicalAddress &from, const LogicalAddress &to) frame.append(firstByte); write(frame); } - + #if 0 { /* Send a Poll so indicate there is a device present */ diff --git a/ccec/src/LibCCEC.cpp b/ccec/src/LibCCEC.cpp index f8856bd3..69ac7358 100644 --- a/ccec/src/LibCCEC.cpp +++ b/ccec/src/LibCCEC.cpp @@ -99,10 +99,23 @@ void LibCCEC::init(const char *name) check_cec_log_status(); - /* Add Host-specific Initialization*/ - Driver::getInstance().open(); + /* Add Host-specific Initialization */ + // Do not start the threads in Bus constructor if HAL does not support CEC to prevent 100% CPU usage issue. + // throw exceptions and prevent starting the worker threads if driver open fails. + try { + Driver::getInstance().open(); + } catch (OperationNotSupportedException &e) { + CCEC_LOG( LOG_EXP, "LibCCEC::init Caught OperationNotSupportedException during host-specific initialization: %s\r\n", e.what()); + throw; + } catch (Exception &e) { + CCEC_LOG( LOG_EXP, "LibCCEC::init Caught Exception during host-specific initialization: %s\r\n", e.what()); + throw; + } catch (...) { + CCEC_LOG( LOG_EXP, "LibCCEC::init Caught Unknown Exception during host-specific initialization\r\n"); + throw; + } Bus::getInstance().start(); - t2_init(const_cast("hdmicec")); + t2_init(const_cast("hdmicec")); initialized = true; } diff --git a/ccec/src/Util.cpp b/ccec/src/Util.cpp index f096bf04..2e837c08 100644 --- a/ccec/src/Util.cpp +++ b/ccec/src/Util.cpp @@ -81,7 +81,7 @@ void check_cec_log_status(void) memset(&st,0,sizeof(st)); if((fp = fopen("/tmp/cec_log_enabled","r")) == NULL) { - printf("Error in opening cec_log_enabled filee \n"); + printf("Error in opening cec_log_enabled file.\n"); return; } if ((fgets(cecBuffer,buffer_length,fp)) != NULL) @@ -96,7 +96,7 @@ void check_cec_log_status(void) } } fclose(fp); - + return; }