/*
* 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.
static_cast<CRPiCECAdapterCommunication *>(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<CRPiCECAdapterCommunication *>(callback_data)->OnTVServiceCallback(reason, p0, p1);
+}
+
CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
IAdapterCommunication(callback),
m_logicalAddress(CECDEVICE_UNKNOWN),
m_bLogicalAddressChanged(false),
- m_previousLogicalAddress(CECDEVICE_FREEUSE)
+ m_previousLogicalAddress(CECDEVICE_FREEUSE),
+ m_bLogicalAddressRegistered(false)
{
m_queue = new CRPiCECAdapterMessageQueue(this);
}
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);
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;
// 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();
else
return;
}
+ if (m_bInitialised)
+ vc_tv_unregister_callback(rpi_tv_callback);
+
UnregisterLogicalAddress();
// disable passive mode
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)
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();
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)