static_cast<CRPiCECAdapterCommunication *>(callback_data)->OnDataReceived(p0, p1, p2, p3, p4);
}
-CRPiCECAdapterFindNewLogicalAddress::CRPiCECAdapterFindNewLogicalAddress(CRPiCECAdapterCommunication* communication, const cec_logical_address address) :
- m_communication(communication),
- m_address(address) { }
-
-void *CRPiCECAdapterFindNewLogicalAddress::Process(void)
+// callback for the TV service
+void rpi_tv_callback(void *callback_data, uint32_t reason, uint32_t p0, uint32_t p1)
{
- cec_logical_address newAddress(CECDEVICE_UNKNOWN);
- for (unsigned int iLA = CECDEVICE_RECORDINGDEVICE1; newAddress == CECDEVICE_UNKNOWN && iLA < CECDEVICE_BROADCAST; iLA++)
- {
- if (CCECTypeUtils::GetType((cec_logical_address)iLA) == CCECTypeUtils::GetType(m_address) &&
- m_communication->SupportsSourceLogicalAddress((cec_logical_address)iLA) &&
- m_communication->RegisterLogicalAddress((cec_logical_address)iLA))
- newAddress = (cec_logical_address)iLA;
- }
-
- m_communication->m_callback->HandleLogicalAddressLost(m_address, newAddress);
- return NULL;
+ 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_laLost(NULL)
+ m_previousLogicalAddress(CECDEVICE_FREEUSE),
+ m_bLogicalAddressRegistered(false)
{
m_queue = new CRPiCECAdapterMessageQueue(this);
}
CRPiCECAdapterCommunication::~CRPiCECAdapterCommunication(void)
{
- if (m_laLost)
- {
- m_laLost->StopThread();
- delete m_laLost;
- m_laLost = NULL;
- }
delete(m_queue);
Close();
}
return m_bInitialised;
}
+void CRPiCECAdapterCommunication::OnTVServiceCallback(uint32_t reason, uint32_t UNUSED(p0), uint32_t UNUSED(p1))
+{
+ switch(reason)
+ {
+ case VC_HDMI_UNPLUGGED:
+ {
+ m_callback->HandlePhysicalAddressChanged(0x1000);
+ break;
+ }
+ case VC_HDMI_ATTACHED:
+ {
+ uint16_t iNewAddress = GetPhysicalAddress();
+ m_callback->HandlePhysicalAddressChanged(iNewAddress);
+ break;
+ }
+ 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)
{
}
break;
case VC_CEC_BUTTON_PRESSED:
+ case VC_CEC_REMOTE_PRESSED:
{
// translate into a cec_command
cec_command command;
- cec_command::Format(command, (cec_logical_address)CEC_CB_INITIATOR(p0), (cec_logical_address)CEC_CB_FOLLOWER(p0), CEC_OPCODE_USER_CONTROL_PRESSED);
+ cec_command::Format(command,
+ (cec_logical_address)CEC_CB_INITIATOR(p0),
+ (cec_logical_address)CEC_CB_FOLLOWER(p0),
+ reason == VC_CEC_BUTTON_PRESSED ? CEC_OPCODE_USER_CONTROL_PRESSED : CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN);
command.parameters.PushBack((uint8_t)CEC_CB_OPERAND1(p0));
// send to libCEC
}
break;
case VC_CEC_BUTTON_RELEASE:
+ case VC_CEC_REMOTE_RELEASE:
{
// translate into a cec_command
cec_command command;
- cec_command::Format(command, (cec_logical_address)CEC_CB_INITIATOR(p0), (cec_logical_address)CEC_CB_FOLLOWER(p0), CEC_OPCODE_USER_CONTROL_RELEASE);
+ cec_command::Format(command,
+ (cec_logical_address)CEC_CB_INITIATOR(p0),
+ (cec_logical_address)CEC_CB_FOLLOWER(p0),
+ reason == VC_CEC_BUTTON_PRESSED ? CEC_OPCODE_USER_CONTROL_RELEASE : CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP);
command.parameters.PushBack((uint8_t)CEC_CB_OPERAND1(p0));
// send to libCEC
case VC_CEC_LOGICAL_ADDR:
{
CLockObject lock(m_mutex);
+ m_previousLogicalAddress = m_logicalAddress;
if (CEC_CB_RC(header) == VCHIQ_SUCCESS)
{
m_bLogicalAddressChanged = true;
}
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();
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;
- if (m_laLost && !m_laLost->IsRunning())
- delete m_laLost;
- m_laLost = new CRPiCECAdapterFindNewLogicalAddress(this, previousAddress);
- if (m_laLost)
- m_laLost->CreateThread();
+ // notify libCEC that we lost our LA when the connection was initialised
+ bool bNotify(false);
+ {
+ CLockObject lock(m_mutex);
+ bNotify = m_bInitialised && m_bLogicalAddressRegistered;
+ }
+ if (bNotify)
+ m_callback->HandleLogicalAddressLost(previousAddress);
}
break;
case VC_CEC_TOPOLOGY:
- case VC_CEC_REMOTE_PRESSED:
- case VC_CEC_REMOTE_RELEASE:
break;
default:
LIB_CEC->AddLog(CEC_LOG_DEBUG, "ignoring unknown reason %x", reason);
// 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;
}
+ vc_tv_unregister_callback(rpi_tv_callback);
+
UnregisterLogicalAddress();
// disable passive mode
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)