signal all waiting threads when receiving an active source message, cache the current...
authorLars Op den Kamp <lars@opdenkamp.eu>
Mon, 12 Nov 2012 16:42:20 +0000 (17:42 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Mon, 12 Nov 2012 16:44:17 +0000 (17:44 +0100)
src/lib/CECProcessor.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECDeviceMap.cpp
src/lib/devices/CECDeviceMap.h
src/lib/implementations/CECCommandHandler.cpp
src/testclient/main.cpp

index e432033961ab0a487cbeb4d4768d44455ac48824..399e065daa81f9872e4d95d3efb54e2773c49d05 100644 (file)
@@ -351,7 +351,7 @@ cec_logical_address CCECProcessor::GetActiveSource(bool bRequestActiveSource /*
   if (activeSource)
     return activeSource->GetLogicalAddress();
 
-  if (bRequestActiveSource)
+  if (bRequestActiveSource && m_busDevices->GetActiveSourceAddress() == CEC_INVALID_PHYSICAL_ADDRESS)
   {
     // request the active source from the bus
     CCECBusDevice *primary = GetPrimaryDevice();
index 3be7adf618786f2b08d68f71374b07d7d2b53c29..4234ec72254d0ee436e352588f3c6c5c1f797488 100644 (file)
@@ -532,6 +532,9 @@ bool CCECBusDevice::SetPhysicalAddress(uint16_t iNewAddress)
   {
     LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X): physical address changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, m_iPhysicalAddress, iNewAddress);
     m_iPhysicalAddress = iNewAddress;
+
+    if (m_processor->GetDevices()->GetActiveSourceAddress() == iNewAddress)
+      MarkAsActiveSource();
   }
   return true;
 }
@@ -966,7 +969,8 @@ void CCECBusDevice::MarkAsActiveSource(void)
 
   if (bWasActivated)
   {
-    m_processor->SetActiveSource(true, false);
+    if (IsHandledByLibCEC())
+      m_processor->SetActiveSource(true, false);
     CCECClient *client = GetClient();
     if (client)
       client->SourceActivated(m_iLogicalAddress);
@@ -988,7 +992,8 @@ void CCECBusDevice::MarkAsInactiveSource(bool bClientUnregistered /* = false */)
 
   if (bWasDeactivated)
   {
-    m_processor->SetActiveSource(false, bClientUnregistered);
+    if (IsHandledByLibCEC())
+      m_processor->SetActiveSource(false, bClientUnregistered);
     CCECClient *client = GetClient();
     if (client)
       client->SourceDeactivated(m_iLogicalAddress);
index 23e7a6fad980e89b60b357608a35adb280a6360a..1280de6e2f43eb4db87376e7529000b0c9a42bcd 100644 (file)
@@ -45,7 +45,8 @@ using namespace std;
 using namespace CEC;
 
 CCECDeviceMap::CCECDeviceMap(CCECProcessor *processor) :
-    m_processor(processor)
+    m_processor(processor),
+    m_iActiveSource(CEC_INVALID_PHYSICAL_ADDRESS)
 {
   for (uint8_t iPtr = CECDEVICE_TV; iPtr <= CECDEVICE_BROADCAST; iPtr++)
   {
@@ -206,6 +207,9 @@ CCECBusDevice *CCECDeviceMap::GetActiveSource(void) const
 {
   for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
   {
+    if (m_iActiveSource != CEC_INVALID_PHYSICAL_ADDRESS && !it->second->IsActiveSource() &&
+        m_iActiveSource == it->second->GetCurrentPhysicalAddress())
+      it->second->MarkAsActiveSource();
     if (it->second->IsActiveSource())
       return it->second;
   }
@@ -283,3 +287,19 @@ void CCECDeviceMap::GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device)
       devices.push_back(it->second);
   }
 }
+
+void CCECDeviceMap::SetActiveSource(uint16_t iPhysicalAddress)
+{
+  m_iActiveSource = iPhysicalAddress;
+}
+
+uint16_t CCECDeviceMap::GetActiveSourceAddress(void) const
+{
+  return m_iActiveSource;
+}
+
+void CCECDeviceMap::SignalAll(cec_opcode opcode)
+{
+  for (CECDEVICEMAP::iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
+    it->second->SignalOpcode(opcode);
+}
index c27a2dd57e533df3e631fa3b1e4c0b67b18c57c1..50271dc04d61576f8827b3cd3f7390dc11a7112c 100644 (file)
@@ -63,6 +63,9 @@ namespace CEC
     void GetActive(CECDEVICEVEC &devices) const;
     void GetByType(const cec_device_type type, CECDEVICEVEC &devices) const;
     void GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const;
+    void SetActiveSource(uint16_t iPhysicalAddress);
+    uint16_t GetActiveSourceAddress(void) const;
+    void SignalAll(cec_opcode opcode);
 
     void GetPowerOffDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const;
     void GetWakeDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const;
@@ -79,5 +82,6 @@ namespace CEC
 
     CECDEVICEMAP   m_busDevices;
     CCECProcessor *m_processor;
+    uint16_t       m_iActiveSource;
   };
 }
index 3b0187a1c3edbc1ef6560143bc2cd652470d5b84..5a2afb17143d9d95314de110a2068f1f95cc7ba1 100644 (file)
@@ -209,12 +209,13 @@ int CCECCommandHandler::HandleActiveSource(const cec_command &command)
   if (command.parameters.size == 2)
   {
     uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
+    m_processor->GetDevices()->SetActiveSource(iAddress);
     CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iAddress);
     if (device)
-    {
       device->MarkAsActiveSource();
-      return COMMAND_HANDLED;
-    }
+
+    m_processor->GetDevices()->SignalAll(command.opcode);
+    return COMMAND_HANDLED;
   }
 
   return CEC_ABORT_REASON_INVALID_OPERAND;
index a1f319039a3dc7d8b6c908d7a69aacabc97c65e5..945935afc86d9946feb9ff36f1ebc039fc3efbf3 100644 (file)
@@ -864,8 +864,8 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string & UNU
       if (addresses[iPtr])
       {
         uint64_t iVendorId        = parser->GetDeviceVendorId((cec_logical_address)iPtr);
-        bool     bActive          = parser->IsActiveSource((cec_logical_address)iPtr);
         uint16_t iPhysicalAddress = parser->GetDevicePhysicalAddress((cec_logical_address)iPtr);
+        bool     bActive          = parser->IsActiveSource((cec_logical_address)iPtr);
         cec_version iCecVersion   = parser->GetDeviceCecVersion((cec_logical_address)iPtr);
         cec_power_status power    = parser->GetDevicePowerStatus((cec_logical_address)iPtr);
         cec_osd_name osdName      = parser->GetDeviceOSDName((cec_logical_address)iPtr);
@@ -888,6 +888,7 @@ bool ProcessCommandSCAN(ICECAdapter *parser, const string &command, string & UNU
       }
     }
 
+    activeSource = parser->GetActiveSource();
     strLog.AppendFormat("currently active source: %s (%d)", parser->ToString(activeSource), (int)activeSource);
 
     PrintToStdOut(strLog);