m_powerStatus(CEC_POWER_STATUS_UNKNOWN),
m_processor(processor),
m_vendor(CEC_VENDOR_UNKNOWN),
+ m_bReplaceHandler(false),
m_menuState(CEC_MENU_STATE_ACTIVATED),
m_bActiveSource(false),
m_iLastActive(0),
m_cecVersion(CEC_VERSION_UNKNOWN),
- m_deviceStatus(CEC_DEVICE_STATUS_UNKNOWN)
+ m_deviceStatus(CEC_DEVICE_STATUS_UNKNOWN),
+ m_handlerMutex(false)
{
m_handler = new CCECCommandHandler(this);
strLog.Format("<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_DEBUG, strLog.c_str());
- if (m_handler->TransmitPowerOn(GetMyLogicalAddress(), m_iLogicalAddress))
+ if (m_handler->TransmitImageViewOn(GetMyLogicalAddress(), m_iLogicalAddress))
{
{
CLockObject lock(&m_mutex);
//@{
cec_version CCECBusDevice::GetCecVersion(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (bUpdate || m_cecVersion == CEC_VERSION_UNKNOWN))
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (bUpdate || m_cecVersion == CEC_VERSION_UNKNOWN));
+ }
+
+ if (bRequestUpdate)
RequestCecVersion();
+ CLockObject lock(&m_mutex);
return m_cecVersion;
}
bool CCECBusDevice::RequestCecVersion(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting CEC version of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestCecVersion(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
}
return bReturn;
}
cec_menu_language &CCECBusDevice::GetMenuLanguage(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (bUpdate || !strcmp(m_menuLanguage.language, "???")))
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (bUpdate || !strcmp(m_menuLanguage.language, "???")));
+ }
+
+ if (bRequestUpdate)
RequestMenuLanguage();
+ CLockObject lock(&m_mutex);
return m_menuLanguage;
}
bool CCECBusDevice::RequestMenuLanguage(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress) &&
!IsUnsupportedFeature(CEC_OPCODE_GET_MENU_LANGUAGE))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting menu language of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestMenuLanguage(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
}
return bReturn;
}
+cec_menu_state CCECBusDevice::GetMenuState(void)
+{
+ CLockObject lock(&m_mutex);
+ return m_menuState;
+}
+
cec_logical_address CCECBusDevice::GetMyLogicalAddress(void) const
{
return m_processor->GetLogicalAddress();
CStdString CCECBusDevice::GetOSDName(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (bUpdate || m_strDeviceName.Equals(ToString(m_iLogicalAddress))) &&
- m_type != CEC_DEVICE_TYPE_TV)
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (bUpdate || m_strDeviceName.Equals(ToString(m_iLogicalAddress))) &&
+ m_type != CEC_DEVICE_TYPE_TV);
+ }
+
+ if (bRequestUpdate)
RequestOSDName();
+ CLockObject lock(&m_mutex);
return m_strDeviceName;
}
bool CCECBusDevice::RequestOSDName(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress) &&
!IsUnsupportedFeature(CEC_OPCODE_GIVE_OSD_NAME))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting OSD name of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestOSDName(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
}
return bReturn;
}
uint16_t CCECBusDevice::GetPhysicalAddress(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (m_iPhysicalAddress == 0xFFFF || bUpdate))
+ bool bRequestUpdate(false);
{
- if (!RequestPhysicalAddress())
- AddLog(CEC_LOG_ERROR, "failed to request the physical address");
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (m_iPhysicalAddress == 0xFFFF || bUpdate));
}
+ if (bRequestUpdate && !RequestPhysicalAddress())
+ AddLog(CEC_LOG_ERROR, "failed to request the physical address (1)");
+
+ CLockObject lock(&m_mutex);
return m_iPhysicalAddress;
}
bool CCECBusDevice::RequestPhysicalAddress(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting physical address of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestPhysicalAddress(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
}
return bReturn;
}
cec_power_status CCECBusDevice::GetPowerStatus(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (bUpdate || m_powerStatus == CEC_POWER_STATUS_UNKNOWN))
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (bUpdate || m_powerStatus == CEC_POWER_STATUS_UNKNOWN ||
+ m_powerStatus == CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON));
+ }
+
+ if (bRequestUpdate)
RequestPowerStatus();
+ CLockObject lock(&m_mutex);
return m_powerStatus;
}
bool CCECBusDevice::RequestPowerStatus(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress) &&
!IsUnsupportedFeature(CEC_OPCODE_GIVE_DEVICE_POWER_STATUS))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting power status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestPowerStatus(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
}
return bReturn;
}
cec_vendor_id CCECBusDevice::GetVendorId(bool bUpdate /* = false */)
{
- CLockObject lock(&m_mutex);
- if (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
- (bUpdate || m_vendor == CEC_VENDOR_UNKNOWN))
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(&m_mutex);
+ bRequestUpdate = (GetStatus() == CEC_DEVICE_STATUS_PRESENT &&
+ (bUpdate || m_vendor == CEC_VENDOR_UNKNOWN));
+ }
+
+ if (bRequestUpdate)
RequestVendorId();
+ CLockObject lock(&m_mutex);
return m_vendor;
}
bool CCECBusDevice::RequestVendorId(void)
{
bool bReturn(false);
+
if (!MyLogicalAddressContains(m_iLogicalAddress))
{
+ m_handler->MarkBusy();
CStdString strLog;
strLog.Format("<< requesting vendor ID of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
AddLog(CEC_LOG_NOTICE, strLog);
bReturn = m_handler->TransmitRequestVendorId(GetMyLogicalAddress(), m_iLogicalAddress);
+ m_handler->MarkReady();
+
+ ReplaceHandler(true);
}
return bReturn;
}
void CCECBusDevice::SetActiveSource(void)
{
CLockObject lock(&m_mutex);
+ if (!m_bActiveSource)
+ {
+ CStdString strLog;
+ strLog.Format("making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
+ AddLog(CEC_LOG_DEBUG, strLog);
+ }
for (int iPtr = 0; iPtr < 16; iPtr++)
if (iPtr != m_iLogicalAddress)
}
}
-bool CCECBusDevice::SetVendorId(uint64_t iVendorId, bool bInitHandler /* = true */)
+bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
{
- bool bVendorChanged(false);
+ CLockObject lock(&m_mutex);
+ CLockObject handlerLock(&m_handlerMutex);
+ if (m_vendor != m_handler->GetVendorId())
{
- CLockObject lock(&m_mutex);
- bVendorChanged = (m_vendor != (cec_vendor_id)iVendorId);
- m_vendor = (cec_vendor_id)iVendorId;
+ if (CCECCommandHandler::HasSpecificHandler(m_vendor))
+ {
+ CStdString strLog;
+ if (m_handler->InUse())
+ {
+ strLog.Format("handler for device '%s' (%x) is being used. not replacing the command handler", GetLogicalAddressName(), GetLogicalAddress());
+ m_processor->AddLog(CEC_LOG_DEBUG, strLog);
+ return false;
+ }
- if (bVendorChanged)
+ strLog.Format("replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
+ m_processor->AddLog(CEC_LOG_DEBUG, strLog);
delete m_handler;
- switch (iVendorId)
- {
- case CEC_VENDOR_SAMSUNG:
- if (bVendorChanged)
+ switch (m_vendor)
+ {
+ case CEC_VENDOR_SAMSUNG:
m_handler = new CANCommandHandler(this);
- break;
- case CEC_VENDOR_LG:
- if (bVendorChanged)
+ break;
+ case CEC_VENDOR_LG:
m_handler = new CSLCommandHandler(this);
- break;
- case CEC_VENDOR_PANASONIC:
- if (bVendorChanged)
+ break;
+ case CEC_VENDOR_PANASONIC:
m_handler = new CVLCommandHandler(this);
- break;
- default:
- if (bVendorChanged)
+ break;
+ default:
m_handler = new CCECCommandHandler(this);
- break;
+ break;
+ }
+
+ m_handler->SetVendorId(m_vendor);
+ m_handler->InitHandler();
+
+ if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised() && IsActiveSource())
+ m_handler->ActivateSource();
}
}
- if (bVendorChanged && bInitHandler && m_handler->GetVendorId() != CEC_VENDOR_UNKNOWN)
- m_handler->InitHandler();
+ return true;
+}
+
+bool CCECBusDevice::SetVendorId(uint64_t iVendorId)
+{
+ bool bVendorChanged(false);
+
+ {
+ CLockObject lock(&m_mutex);
+ bVendorChanged = (m_vendor != (cec_vendor_id)iVendorId);
+ m_vendor = (cec_vendor_id)iVendorId;
+ }
CStdString strLog;
strLog.Format("%s (%X): vendor = %s (%06x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_vendor), m_vendor);
}
}
- return bSendActiveSource ? m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress) : false;
+ if (bSendActiveSource)
+ {
+ m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV);
+ m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress);
+ return true;
+ }
+
+ return false;
}
bool CCECBusDevice::TransmitCECVersion(cec_logical_address dest)
{
m_unsupportedFeatures.insert(opcode);
}
+
+bool CCECBusDevice::ActivateSource(void)
+{
+ CLockObject lock(&m_mutex);
+ return m_handler->ActivateSource();
+}
+
//@}