#define ToString(p) m_processor->ToString(p)
-CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress) :
+CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */) :
m_type (CEC_DEVICE_TYPE_RESERVED),
m_iPhysicalAddress (iPhysicalAddress),
- m_iStreamPath (0),
+ m_iStreamPath (CEC_INVALID_PHYSICAL_ADDRESS),
m_iLogicalAddress (iLogicalAddress),
m_powerStatus (CEC_POWER_STATUS_UNKNOWN),
m_processor (processor),
return m_cecVersion;
}
+bool CCECBusDevice::RequestActiveSource(bool bWaitForResponse /* = true */)
+{
+ bool bReturn(false);
+
+ if (MyLogicalAddressContains(m_iLogicalAddress))
+ {
+ MarkBusy();
+ CLibCEC::AddLog(CEC_LOG_NOTICE, "<< requesting active source");
+
+ bReturn = m_handler->TransmitRequestActiveSource(GetMyLogicalAddress(), bWaitForResponse);
+ MarkReady();
+ }
+ return bReturn;
+}
+
bool CCECBusDevice::RequestCecVersion(bool bWaitForResponse /* = true */)
{
bool bReturn(false);
return bReturn;
}
-uint16_t CCECBusDevice::GetPhysicalAddress(bool bUpdate /* = false */, bool bSuppressPoll /* = false */)
+uint16_t CCECBusDevice::GetPhysicalAddress(bool bSuppressUpdate /* = true */)
{
- bool bIsPresent(GetStatus(false, bSuppressPoll) == CEC_DEVICE_STATUS_PRESENT);
- bool bRequestUpdate(false);
+ if (!bSuppressUpdate)
{
- CLockObject lock(m_mutex);
- bRequestUpdate = bIsPresent &&
- (m_iPhysicalAddress == 0xFFFF || bUpdate);
- }
+ bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(m_mutex);
+ bRequestUpdate = bIsPresent && m_iPhysicalAddress == CEC_INVALID_PHYSICAL_ADDRESS;
+ }
- if (bRequestUpdate)
- {
- CheckVendorIdRequested();
- if (!RequestPhysicalAddress())
- CLibCEC::AddLog(CEC_LOG_ERROR, "failed to request the physical address");
+ if (bRequestUpdate)
+ {
+ CheckVendorIdRequested();
+ if (!RequestPhysicalAddress())
+ CLibCEC::AddLog(CEC_LOG_ERROR, "failed to request the physical address");
+ }
}
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "marking %s (%X) as inactive source", GetLogicalAddressName(), m_iLogicalAddress);
m_bActiveSource = false;
}
-
- if (MyLogicalAddressContains(m_iLogicalAddress))
- SetPowerStatus(CEC_POWER_STATUS_STANDBY);
}
void CCECBusDevice::SetActiveSource(void)
CLockObject lock(m_mutex);
if (!m_bActiveSource)
CLibCEC::AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
+ else
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress);
for (int iPtr = 0; iPtr < 16; iPtr++)
if (iPtr != m_iLogicalAddress)
SetVendorId (CEC_VENDOR_UNKNOWN);
SetMenuState (CEC_MENU_STATE_ACTIVATED);
SetCecVersion (CEC_VERSION_UNKNOWN);
- SetStreamPath (0);
+ SetStreamPath (CEC_INVALID_PHYSICAL_ADDRESS);
SetOSDName (ToString(m_iLogicalAddress));
SetInactiveSource();
m_iLastActive = 0;
+ m_unsupportedFeatures.clear();
}
void CCECBusDevice::SetDeviceStatus(const cec_bus_device_status newStatus)
SetVendorId (CEC_VENDOR_UNKNOWN);
SetMenuState (CEC_MENU_STATE_ACTIVATED);
SetCecVersion (CEC_VERSION_1_3A);
- SetStreamPath (0);
+ SetStreamPath (CEC_INVALID_PHYSICAL_ADDRESS);
SetInactiveSource();
m_iLastActive = 0;
m_deviceStatus = newStatus;
}
}
-void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = 0 */)
+void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */)
{
CLockObject lock(m_mutex);
- if (iNewAddress > 0)
+ if (iNewAddress != m_iStreamPath)
{
CLibCEC::AddLog(CEC_LOG_DEBUG, ">> %s (%X): stream path changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, iOldAddress == 0 ? m_iStreamPath : iOldAddress, iNewAddress);
m_iStreamPath = iNewAddress;
+ }
- // suppress polls when searching for a device
- CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iNewAddress, false, true);
+ CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iNewAddress);
+ if (device)
+ {
+ // if a device is found with the new physical address, mark it as active, which will automatically mark all other devices as inactive
+ device->SetActiveSource();
+ }
+ else
+ {
+ // try to find the device with the old address, and mark it as inactive when found
+ device = m_processor->GetDeviceByPhysicalAddress(iOldAddress);
if (device)
- {
- // if a device is found with the new physical address, mark it as active, which will automatically mark all other devices as inactive
- device->SetActiveSource();
- }
- else
- {
- // try to find the device with the old address, and mark it as inactive when found
- device = m_processor->GetDeviceByPhysicalAddress(iOldAddress, false, true);
- if (device)
- device->SetInactiveSource();
- }
-
- if (iNewAddress > 0)
- {
- lock.Unlock();
- SetPowerStatus(CEC_POWER_STATUS_ON);
- }
+ device->SetInactiveSource();
}
}
cec_device_type type;
{
CLockObject lock(m_mutex);
- if (m_iPhysicalAddress == 0xffff)
+ if (m_iPhysicalAddress == CEC_INVALID_PHYSICAL_ADDRESS)
return false;
CLibCEC::AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): physical adddress %4x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress);
CLockObject lock(m_mutex);
bool bUnsupported = (m_unsupportedFeatures.find(opcode) != m_unsupportedFeatures.end());
if (bUnsupported)
- CLibCEC::AddLog(CEC_LOG_NOTICE, "'%s' is marked as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "'%s' is marked as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
return bUnsupported;
}
void CCECBusDevice::SetUnsupportedFeature(cec_opcode opcode)
{
- CLockObject lock(m_mutex);
- CLibCEC::AddLog(CEC_LOG_DEBUG, "marking opcode '%s' as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
- m_unsupportedFeatures.insert(opcode);
+ // some commands should never be marked as unsupported
+ if (opcode == CEC_OPCODE_VENDOR_COMMAND ||
+ opcode == CEC_OPCODE_VENDOR_COMMAND_WITH_ID ||
+ opcode == CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN ||
+ opcode == CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP ||
+ opcode == CEC_OPCODE_ABORT ||
+ opcode == CEC_OPCODE_FEATURE_ABORT ||
+ opcode == CEC_OPCODE_NONE)
+ return;
+
+ {
+ CLockObject lock(m_mutex);
+ if (m_unsupportedFeatures.find(opcode) == m_unsupportedFeatures.end())
+ {
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "marking opcode '%s' as unsupported feature for device '%s'", ToString(opcode), GetLogicalAddressName());
+ m_unsupportedFeatures.insert(opcode);
+ }
+ }
+
+ // signal threads that are waiting for a reponse
+ MarkBusy();
+ m_handler->SignalOpcode(cec_command::GetResponseOpcode(opcode));
+ MarkReady();
}
bool CCECBusDevice::ActivateSource(void)