X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fadapter%2FRPi%2FRPiCECAdapterCommunication.cpp;h=243223d3f67d0a149d5e37a85bc8daa4e065a0aa;hb=485660f88df81ef5e535a074b1385c49bc687489;hp=5d13368e50a3c569667ab0b812ed3d824b534c50;hpb=8b0462ea5e37459446a493c124e4c2d7a9e6b108;p=deb_libcec.git diff --git a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp index 5d13368..243223d 100644 --- a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp +++ b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp @@ -1,7 +1,7 @@ /* * This file is part of the libCEC(R) library. * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. * libCEC(R) is an original work, containing original code. * * libCEC(R) is a trademark of Pulse-Eight Limited. @@ -58,10 +58,19 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2 static_cast(callback_data)->OnDataReceived(p0, p1, p2, p3, p4); } +// callback for the TV service +void rpi_tv_callback(void *callback_data, uint32_t reason, uint32_t p0, uint32_t p1) +{ + if (callback_data) + static_cast(callback_data)->OnTVServiceCallback(reason, p0, p1); +} + CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) : IAdapterCommunication(callback), m_logicalAddress(CECDEVICE_UNKNOWN), - m_bLogicalAddressChanged(false) + m_bLogicalAddressChanged(false), + m_previousLogicalAddress(CECDEVICE_FREEUSE), + m_bLogicalAddressRegistered(false) { m_queue = new CRPiCECAdapterMessageQueue(this); } @@ -105,11 +114,35 @@ bool CRPiCECAdapterCommunication::IsInitialised(void) return m_bInitialised; } +void CRPiCECAdapterCommunication::OnTVServiceCallback(uint32_t reason, uint32_t UNUSED(p0), uint32_t UNUSED(p1)) +{ + switch(reason) + { + case VC_HDMI_ATTACHED: + { + uint16_t iNewAddress = GetPhysicalAddress(); + m_callback->HandlePhysicalAddressChanged(iNewAddress); + break; + } + case VC_HDMI_UNPLUGGED: + case VC_HDMI_DVI: + case VC_HDMI_HDMI: + case VC_HDMI_HDCP_UNAUTH: + case VC_HDMI_HDCP_AUTH: + case VC_HDMI_HDCP_KEY_DOWNLOAD: + case VC_HDMI_HDCP_SRM_DOWNLOAD: + default: + break; + } +} + void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) { VC_CEC_NOTIFY_T reason = (VC_CEC_NOTIFY_T)CEC_CB_REASON(header); +#ifdef CEC_DEBUGGING LIB_CEC->AddLog(CEC_LOG_DEBUG, "received data: header:%08X p0:%08X p1:%08X p2:%08X p3:%08X reason:%x", header, p0, p1, p2, p3, reason); +#endif switch (reason) { @@ -174,6 +207,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u case VC_CEC_LOGICAL_ADDR: { CLockObject lock(m_mutex); + m_previousLogicalAddress = m_logicalAddress; if (CEC_CB_RC(header) == VCHIQ_SUCCESS) { m_bLogicalAddressChanged = true; @@ -182,7 +216,7 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u } else { - m_logicalAddress = CECDEVICE_BROADCAST; + m_logicalAddress = CECDEVICE_FREEUSE; LIB_CEC->AddLog(CEC_LOG_DEBUG, "failed to change the logical address, reset to %s (%x)", LIB_CEC->ToString(m_logicalAddress), m_logicalAddress); } m_logicalAddressCondition.Signal(); @@ -191,11 +225,16 @@ void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, u case VC_CEC_LOGICAL_ADDR_LOST: { // the logical address was taken by another device - cec_logical_address previousAddress = m_logicalAddress; + cec_logical_address previousAddress = m_logicalAddress == CECDEVICE_BROADCAST ? m_previousLogicalAddress : m_logicalAddress; m_logicalAddress = CECDEVICE_UNKNOWN; // notify libCEC that we lost our LA when the connection was initialised - if (m_bInitialised) + bool bNotify(false); + { + CLockObject lock(m_mutex); + bNotify = m_bInitialised && m_bLogicalAddressRegistered; + } + if (bNotify) m_callback->HandleLogicalAddressLost(previousAddress); } break; @@ -262,8 +301,9 @@ bool CRPiCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN // enable passive mode vc_cec_set_passive(true); - // register the callback - vc_cec_register_callback(((CECSERVICE_CALLBACK_T)rpi_cec_callback), (void*)this); + // register the callbacks + vc_cec_register_callback(rpi_cec_callback, (void*)this); + vc_tv_register_callback(rpi_tv_callback, (void*)this); // release previous LA vc_cec_release_logical_address(); @@ -313,6 +353,9 @@ void CRPiCECAdapterCommunication::Close(void) else return; } + if (m_bInitialised) + vc_tv_unregister_callback(rpi_tv_callback); + UnregisterLogicalAddress(); // disable passive mode @@ -340,13 +383,18 @@ cec_adapter_message_state CRPiCECAdapterCommunication::Write(const cec_command & return (data.initiator == data.destination) ? ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED : ADAPTER_MESSAGE_STATE_ERROR; } - if (!data.opcode_set && data.initiator == data.destination) + if (!m_queue->Write(data, bIsReply)) { - // registration of the logical address would have failed - return ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED; + if (!data.opcode_set) + { + return ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED; + } + + return ADAPTER_MESSAGE_STATE_SENT; } - return m_queue->Write(data, bIsReply) ? ADAPTER_MESSAGE_STATE_SENT_ACKED : ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED; + return ADAPTER_MESSAGE_STATE_SENT_ACKED; + } uint16_t CRPiCECAdapterCommunication::GetFirmwareVersion(void) @@ -375,7 +423,11 @@ bool CRPiCECAdapterCommunication::UnregisterLogicalAddress(void) return true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - releasing previous logical address", __FUNCTION__); - m_bLogicalAddressChanged = false; + { + CLockObject lock(m_mutex); + m_bLogicalAddressRegistered = false; + m_bLogicalAddressChanged = false; + } vc_cec_release_logical_address(); @@ -407,7 +459,12 @@ bool CRPiCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_addre return false; } - return m_logicalAddressCondition.Wait(m_mutex, m_bLogicalAddressChanged); + if (m_logicalAddressCondition.Wait(m_mutex, m_bLogicalAddressChanged)) + { + m_bLogicalAddressRegistered = true; + return true; + } + return false; } cec_logical_addresses CRPiCECAdapterCommunication::GetLogicalAddresses(void)