cec: send deck status 0x20 when an LG tv is found, so keypresses will be routed to...
authorLars Op den Kamp <lars@opdenkamp.eu>
Sun, 4 Dec 2011 01:55:21 +0000 (02:55 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sun, 4 Dec 2011 02:28:27 +0000 (03:28 +0100)
include/cectypes.h
src/lib/AdapterCommunication.cpp
src/lib/CECProcessor.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/implementations/CECCommandHandler.h
src/lib/implementations/SLCommandHandler.cpp
src/lib/implementations/SLCommandHandler.h

index 467f15049a422f8e9945130ab0a7d8706029a65d..c13f3491367dfa223b0dc7ea34c681ed5986b0f2 100644 (file)
@@ -154,7 +154,8 @@ typedef enum cec_deck_info
   CEC_DECK_INFO_SKIP_REVERSE_REWIND  = 0x1C,
   CEC_DECK_INFO_INDEX_SEARCH_FORWARD = 0x1D,
   CEC_DECK_INFO_INDEX_SEARCH_REVERSE = 0x1E,
-  CEC_DECK_INFO_OTHER_STATUS         = 0x1F
+  CEC_DECK_INFO_OTHER_STATUS         = 0x1F,
+  CEC_DECK_INFO_OTHER_STATUS_LG      = 0x20
 } cec_deck_info;
 
 typedef enum cec_device_type
index 7f801b62d2bf8162b652f39d25621f9f99631d7c..caa8442c1b59185dbf37e6ab52eb0c946ca38517 100644 (file)
@@ -290,7 +290,7 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
 
   //clear any input bytes
   uint8_t buff[1024];
-  while (m_port->Read(buff, sizeof(buff), 500) > 0) {}
+  while (m_port->Read(buff, sizeof(buff), 1000) > 0) {}
 
   if (CreateThread())
   {
index d1d7c6d472c6d56d1fa626c17ddfbc1439f145a8..6791d514401b41d3f356a01037e2e87161535710 100644 (file)
@@ -315,8 +315,17 @@ bool CCECProcessor::SetActiveSource(cec_device_type type /* = CEC_DEVICE_TYPE_RE
     }
   }
 
-  return SetStreamPath(m_busDevices[addr]->GetPhysicalAddress(false)) &&
-      m_busDevices[addr]->TransmitActiveSource();
+  bReturn = m_busDevices[CECDEVICE_TV]->PowerOn() &&
+      m_busDevices[addr]->TransmitActiveSource() &&
+      SetStreamPath(m_busDevices[addr]->GetPhysicalAddress(false));
+
+  if (bReturn && (m_busDevices[addr]->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE ||
+      m_busDevices[addr]->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE))
+  {
+    bReturn = ((CCECPlaybackDevice *)m_busDevices[addr])->TransmitDeckStatus(CECDEVICE_TV);
+  }
+
+  return bReturn;
 }
 
 bool CCECProcessor::SetActiveSource(cec_logical_address iAddress)
index c06a8b8e777c057eac616cdadfc3fe79cb9b2fe4..5cfca5914c10bb890b07cf0a2a7f0cce80c69b1b 100644 (file)
@@ -84,7 +84,15 @@ bool CCECBusDevice::HandleCommand(const cec_command &command)
   m_iLastActive = GetTimeMs();
   m_handler->HandleCommand(command);
   if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
+  {
+    if (m_deviceStatus != CEC_DEVICE_STATUS_PRESENT)
+    {
+      CStdString strLog;
+      strLog.Format("device %s (%x) status changed to present after command %s", GetLogicalAddressName(), (uint8_t)GetLogicalAddress(), ToString(command.opcode));
+      AddLog(CEC_LOG_DEBUG, strLog);
+    }
     m_deviceStatus = CEC_DEVICE_STATUS_PRESENT;
+  }
   m_condition.Signal();
   return true;
 }
@@ -595,6 +603,8 @@ void CCECBusDevice::SetVendorId(uint64_t iVendorId)
     }
   }
 
+  m_handler->InitHandler();
+
   CStdString strLog;
   strLog.Format("%s (%X): vendor = %s (%06x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(m_vendor), m_vendor);
   m_processor->AddLog(CEC_LOG_DEBUG, strLog.c_str());
index 8c6d0c10506149e5faff24e997b3c1c06b4ab296..383a38613b036311951ad744fc6062f0a9980c6b 100644 (file)
@@ -50,6 +50,8 @@ namespace CEC
     virtual void HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination);
     virtual bool HandleReceiveFailed(void);
 
+    virtual bool InitHandler(void) { return true; }
+
   protected:
     virtual bool HandleActiveSource(const cec_command &command);
     virtual bool HandleDeckControl(const cec_command &command);
index c6affec4330c3977c9fa6fb734af6b852a133e91..d442eaf44a09fd6650832309044518baac45533f 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "SLCommandHandler.h"
 #include "../devices/CECBusDevice.h"
+#include "../devices/CECPlaybackDevice.h"
 #include "../CECProcessor.h"
 
 using namespace CEC;
@@ -53,35 +54,42 @@ bool CSLCommandHandler::HandleVendorCommand(const cec_command &command)
     response.PushBack(0x02);
     response.PushBack(0x05);
 
-    return m_busDevice->GetProcessor()->Transmit(response);
+    m_busDevice->GetProcessor()->Transmit(response);
+    TransmitLGVendorId(command.destination, command.initiator);
+    return true;
   }
   else if (command.parameters.size >= 1 &&
       command.parameters[0] == 0x04)
   {
-    /* enable SL */
-    cec_command response;
-    cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
-    response.PushBack(0x05);
-    response.PushBack(0x04);
-
-    return m_busDevice->GetProcessor()->Transmit(response);
+    CCECBusDevice *primary = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetProcessor()->GetLogicalAddresses().primary];
+    if (primary->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE || primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)
+    {
+      ((CCECPlaybackDevice *)primary)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
+      ((CCECPlaybackDevice *)primary)->TransmitDeckStatus(command.initiator);
+    }
+    return true;
   }
   else if (command.parameters.size == 1 &&
       command.parameters[0] == 0xa0)
   {
-    /* enable SL */
-    cec_command response;
-    cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
-    response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 16) & 0xFF));
-    response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 8) & 0xFF));
-    response.parameters.PushBack((uint8_t) ((uint64_t)CEC_VENDOR_LG & 0xFF));
-
-    return m_busDevice->GetProcessor()->Transmit(response);
+    TransmitLGVendorId(command.destination, command.initiator);
+    return true;
   }
 
   return false;
 }
 
+bool CSLCommandHandler::TransmitLGVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination)
+{
+  cec_command response;
+  cec_command::Format(response, iInitiator, iDestination, CEC_OPCODE_VENDOR_COMMAND);
+  response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 16) & 0xFF));
+  response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 8) & 0xFF));
+  response.parameters.PushBack((uint8_t) ((uint64_t)CEC_VENDOR_LG & 0xFF));
+
+  return m_busDevice->GetProcessor()->Transmit(response);
+}
+
 bool CSLCommandHandler::HandleGiveDeviceVendorId(const cec_command &command)
 {
   /* imitate LG devices */
@@ -102,6 +110,15 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
     case CEC_OPCODE_VENDOR_COMMAND:
       bHandled = HandleVendorCommand(command);
       break;
+    case CEC_OPCODE_DEVICE_VENDOR_ID:
+      {
+        if (command.initiator == m_busDevice->GetLogicalAddress())
+        {
+          TransmitLGVendorId(m_busDevice->GetProcessor()->GetLogicalAddresses().primary, command.initiator);
+          bHandled = true;
+        }
+      }
+      break;
     default:
       break;
     }
@@ -113,7 +130,6 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
   return bHandled;
 }
 
-
 void CSLCommandHandler::HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination)
 {
   CCECCommandHandler::HandlePoll(iInitiator, iDestination);
@@ -130,3 +146,26 @@ bool CSLCommandHandler::HandleReceiveFailed(void)
 
   return true;
 }
+
+bool CSLCommandHandler::InitHandler(void)
+{
+  if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV)
+    return true;
+
+  /* LG TVs only route keypresses when the deck status is set to 0x20 */
+  cec_logical_addresses addr = m_busDevice->GetProcessor()->GetLogicalAddresses();
+  for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
+  {
+    if (addr[iPtr])
+    {
+      CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[iPtr];
+      if (device && (device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE ||
+                     device->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE))
+      {
+        ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
+        ((CCECPlaybackDevice *)device)->TransmitDeckStatus(CECDEVICE_TV);
+      }
+    }
+  }
+  return true;
+}
index 7566fb795d773fd13e8a78cb8352f723829d5bb6..9d3ba013bf27669a193b181a41f41d34ec3e9ba1 100644 (file)
@@ -45,6 +45,8 @@ namespace CEC
     virtual bool HandleCommand(const cec_command &command);
     virtual void HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination);
     virtual bool HandleReceiveFailed(void);
+    virtual bool InitHandler(void);
+    virtual bool TransmitLGVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination);
 
   protected:
     virtual bool HandleGiveDeviceVendorId(const cec_command &command);