X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2FCECProcessor.cpp;h=557b76d904e15cf48d0ff291cf4db0e7dd61f839;hb=bb6138eabba9a42f85c3167c0a8aefbd77ff95b8;hp=6749170cda71cd8310c859d54ae037e628f5a2d6;hpb=dad75c6cfa3c1a1c12eeca10190f14831c435325;p=deb_libcec.git diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 6749170..557b76d 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -57,6 +57,34 @@ using namespace PLATFORM; #define ToString(x) CCECTypeUtils::ToString(x) +CCECStandbyProtection::CCECStandbyProtection(CCECProcessor* processor) : + m_processor(processor) {} +CCECStandbyProtection::~CCECStandbyProtection(void) {} + +void* CCECStandbyProtection::Process(void) +{ + int64_t last = GetTimeMs(); + int64_t next; + while (!IsStopped()) + { + PLATFORM::CEvent::Sleep(1000); + + next = GetTimeMs(); + + // reset the connection if the clock changed + if (next < last || next - last > 10000) + { + libcec_parameter param; + param.paramData = NULL; param.paramType = CEC_PARAMETER_TYPE_UNKOWN; + m_processor->GetLib()->Alert(CEC_ALERT_CONNECTION_LOST, param); + break; + } + + last = next; + } + return NULL; +} + CCECProcessor::CCECProcessor(CLibCEC *libcec) : m_bInitialised(false), m_communication(NULL), @@ -66,7 +94,8 @@ CCECProcessor::CCECProcessor(CLibCEC *libcec) : m_iLastTransmission(0), m_bMonitor(true), m_addrAllocator(NULL), - m_bStallCommunication(false) + m_bStallCommunication(false), + m_connCheck(NULL) { m_busDevices = new CCECDeviceMap(this); } @@ -105,11 +134,13 @@ void CCECProcessor::Close(void) SetCECInitialised(false); // stop the processor + DELETE_AND_NULL(m_connCheck); StopThread(-1); m_inBuffer.Broadcast(); StopThread(); // close the connection + CLockObject lock(m_mutex); DELETE_AND_NULL(m_communication); } @@ -215,6 +246,10 @@ void *CCECProcessor::Process(void) { m_libcec->AddLog(CEC_LOG_DEBUG, "processor thread started"); + if (!m_connCheck) + m_connCheck = new CCECStandbyProtection(this); + m_connCheck->CreateThread(); + cec_command command; command.Clear(); CTimeout activeSourceCheck(ACTIVE_SOURCE_CHECK_INTERVAL); CTimeout tvPresentCheck(TV_PRESENT_CHECK_INTERVAL); @@ -405,6 +440,10 @@ bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) // 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)) @@ -443,15 +482,14 @@ bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) } // wait until we finished allocating a new LA if it got lost + lock.Unlock(); while (m_bStallCommunication) Sleep(5); + lock.Lock(); - { - CLockObject lock(m_mutex); - m_iLastTransmission = GetTimeMs(); - // set the number of tries - iMaxTries = initiator->GetHandler()->GetTransmitRetries() + 1; - initiator->MarkHandlerReady(); - } + 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) @@ -859,7 +897,7 @@ bool CCECProcessor::RegisterClient(CCECClient *client) client->GetPrimaryDevice()->TransmitOSDName(CECDEVICE_TV, false); // request the power status of the TV - tv->RequestPowerStatus(sourceAddress, true); + tv->RequestPowerStatus(sourceAddress, true, true); return bReturn; }