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)
+{
+ 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;
+}
+
CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
IAdapterCommunication(callback),
m_logicalAddress(CECDEVICE_UNKNOWN),
- m_bLogicalAddressChanged(false)
+ m_bLogicalAddressChanged(false),
+ m_laLost(NULL)
{
m_queue = new CRPiCECAdapterMessageQueue(this);
}
CRPiCECAdapterCommunication::~CRPiCECAdapterCommunication(void)
{
+ if (m_laLost)
+ {
+ m_laLost->StopThread();
+ delete m_laLost;
+ m_laLost = NULL;
+ }
delete(m_queue);
Close();
}
}
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
m_logicalAddressCondition.Signal();
}
break;
+ case VC_CEC_LOGICAL_ADDR_LOST:
+ {
+ // the logical address was taken by another device
+ cec_logical_address previousAddress = 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();
+ }
+ 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);