bool CCECClient::SetStreamPath(const uint16_t iPhysicalAddress) { bool bReturn(false); CCECBusDevice *device = GetDeviceByType(CEC_DEVICE_TYPE_TV); if (device) { device->SetStreamPath(iPhysicalAddress); bReturn = device->GetHandler()->TransmitSetStreamPath(iPhysicalAddress, false); device->MarkHandlerReady(); } else { LIB_CEC->AddLog(CEC_LOG_ERROR, "only the TV is allowed to send CEC_OPCODE_SET_STREAM_PATH"); } return bReturn; }
bool CVLCommandHandler::PowerUpEventReceived(void) { bool bPowerUpEventReceived(true); if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV) { CCECBusDevice* tv = m_processor->GetTV(); if (tv && tv->GetStatus() != CEC_DEVICE_STATUS_PRESENT) return true; // get the status from the TV if (tv && tv->GetCurrentVendorId() == CEC_VENDOR_PANASONIC) { CVLCommandHandler *handler = static_cast<CVLCommandHandler *>(tv->GetHandler()); bPowerUpEventReceived = handler ? handler->PowerUpEventReceived() : false; tv->MarkHandlerReady(); } } else { // get the current status { CLockObject lock(m_mutex); bPowerUpEventReceived = m_iPowerUpEventReceived > 0 && GetTimeMs() - m_iPowerUpEventReceived > SOURCE_SWITCH_DELAY_MS; } // if we didn't receive the event, check if the TV is already marked as powered on if (!bPowerUpEventReceived && m_busDevice->GetCurrentPowerStatus() == CEC_POWER_STATUS_ON) { CLockObject lock(m_mutex); m_iPowerUpEventReceived = GetTimeMs(); bPowerUpEventReceived = true; } } return bPowerUpEventReceived; }
bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) { cec_command transmitData(data); uint8_t iMaxTries(0); bool bRetry(true); uint8_t iTries(0); // get the current timeout setting uint8_t iLineTimeout(GetStandardLineTimeout()); // reset the state of this message to 'unknown' cec_adapter_message_state adapterState = ADAPTER_MESSAGE_STATE_UNKNOWN; CLockObject lock(m_mutex); if (!m_communication) return false; if (!m_communication->SupportsSourceLogicalAddress(transmitData.initiator)) { if (transmitData.initiator == CECDEVICE_UNREGISTERED && m_communication->SupportsSourceLogicalAddress(CECDEVICE_FREEUSE)) { m_libcec->AddLog(CEC_LOG_DEBUG, "initiator '%s' is not supported by the CEC adapter. using '%s' instead", ToString(transmitData.initiator), ToString(CECDEVICE_FREEUSE)); transmitData.initiator = CECDEVICE_FREEUSE; } else { m_libcec->AddLog(CEC_LOG_DEBUG, "initiator '%s' is not supported by the CEC adapter", ToString(transmitData.initiator)); return false; } } LogOutput(transmitData); // find the initiator device CCECBusDevice *initiator = m_busDevices->At(transmitData.initiator); if (!initiator) { m_libcec->AddLog(CEC_LOG_WARNING, "invalid initiator"); return false; } // find the destination device, if it's not the broadcast address if (transmitData.destination != CECDEVICE_BROADCAST) { // check if the device is marked as handled by libCEC CCECBusDevice *destination = m_busDevices->At(transmitData.destination); if (destination && destination->IsHandledByLibCEC()) { // and reject the command if it's trying to send data to a device that is handled by libCEC m_libcec->AddLog(CEC_LOG_WARNING, "not sending data to myself!"); return false; } } // wait until we finished allocating a new LA if it got lost lock.Unlock(); while (m_bStallCommunication) Sleep(5); lock.Lock(); m_iLastTransmission = GetTimeMs(); // set the number of tries iMaxTries = initiator->GetHandler()->GetTransmitRetries() + 1; initiator->MarkHandlerReady(); // and try to send the command while (bRetry && ++iTries < iMaxTries) { if (initiator->IsUnsupportedFeature(transmitData.opcode)) return false; adapterState = !IsStopped() && m_communication && m_communication->IsOpen() ? m_communication->Write(transmitData, bRetry, iLineTimeout, bIsReply) : ADAPTER_MESSAGE_STATE_ERROR; iLineTimeout = m_iRetryLineTimeout; } return bIsReply ? adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED || adapterState == ADAPTER_MESSAGE_STATE_SENT || adapterState == ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT : adapterState == ADAPTER_MESSAGE_STATE_SENT_ACKED; }