cec: fixed typo which prevented LG TVs from connecting sometimes
[deb_libcec.git] / src / lib / implementations / SLCommandHandler.cpp
index 7cf4399612f99c3b9a279869b7663a1413418e4c..c068540c486db3ce8bf92bc775ad3b9d8b6eb807 100644 (file)
@@ -43,7 +43,7 @@ using namespace CEC;
 #define SL_COMMAND_UNKNOWN_03           0x05
 
 #define SL_COMMAND_REQUEST_POWER_STATUS 0xa0
-#define SL_COMMAND_POWER_ON             0x0300
+#define SL_COMMAND_POWER_ON             0x03
 #define SL_COMMAND_CONNECT_REQUEST      0x04
 #define SL_COMMAND_CONNECT_ACCEPT       0x05
 
@@ -53,6 +53,8 @@ CSLCommandHandler::CSLCommandHandler(CCECBusDevice *busDevice) :
     m_bSLEnabled(false),
     m_bVendorIdSent(false)
 {
+  /* TODO set to powered off until we fixed the connect on start loop issue */
+  m_processor->GetPrimaryDevice()->m_powerStatus = CEC_POWER_STATUS_STANDBY;
 }
 
 bool CSLCommandHandler::HandleVendorCommand(const cec_command &command)
@@ -63,16 +65,22 @@ bool CSLCommandHandler::HandleVendorCommand(const cec_command &command)
     HandleVendorCommand01(command);
     return true;
   }
+  else if (command.parameters.size == 2 &&
+      command.parameters[0] == SL_COMMAND_POWER_ON)
+  {
+    HandleVendorCommandPowerOn(command);
+    return true;
+  }
   else if (command.parameters.size == 2 &&
       command.parameters[0] == SL_COMMAND_CONNECT_REQUEST)
   {
-    HandleVendorCommand04(command);
+    HandleVendorCommandSLConnect(command);
     return true;
   }
   else if (command.parameters.size == 1 &&
       command.parameters[0] == SL_COMMAND_REQUEST_POWER_STATUS)
   {
-    HandleVendorCommandA0(command);
+    HandleVendorCommandPowerOnStatus(command);
     return true;
   }
 
@@ -97,31 +105,53 @@ bool CSLCommandHandler::HandleGiveDeckStatus(const cec_command &command)
 }
 
 void CSLCommandHandler::HandleVendorCommand01(const cec_command &command)
+{
+  TransmitVendorCommand0205(command.destination, command.initiator);
+}
+
+void CSLCommandHandler::TransmitVendorCommand0205(const cec_logical_address iSource, const cec_logical_address iDestination)
 {
   cec_command response;
-  cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
+  cec_command::Format(response, iSource, iDestination, CEC_OPCODE_VENDOR_COMMAND);
   response.PushBack(SL_COMMAND_UNKNOWN_02);
   response.PushBack(SL_COMMAND_UNKNOWN_03);
 
   Transmit(response);
-
-  /* transmit power status */
-  if (command.destination != CECDEVICE_BROADCAST)
-    m_processor->m_busDevices[command.destination]->TransmitPowerState(command.initiator);
 }
 
-void CSLCommandHandler::HandleVendorCommand04(const cec_command &command)
+void CSLCommandHandler::TransmitVendorCommand05(const cec_logical_address iSource, const cec_logical_address iDestination)
 {
+  m_bSLEnabled = true;
   cec_command response;
-  cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
+  cec_command::Format(response, iSource, iDestination, CEC_OPCODE_VENDOR_COMMAND);
   response.PushBack(SL_COMMAND_CONNECT_ACCEPT);
-  response.PushBack((uint8_t)m_processor->GetLogicalAddresses().primary);
+  response.PushBack((uint8_t)iSource);
   Transmit(response);
+}
 
+void CSLCommandHandler::HandleVendorCommandPowerOn(const cec_command &command)
+{
+  CCECBusDevice *device = m_processor->GetPrimaryDevice();
+  if (device)
+  {
+    m_bSLEnabled = true;
+    device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
+    device->TransmitPowerState(command.initiator);
+    device->TransmitVendorID(command.initiator);
+    TransmitPowerOn(device->GetLogicalAddress(), command.initiator);
+  }
+}
+
+void CSLCommandHandler::HandleVendorCommandSLConnect(const cec_command &command)
+{
+  m_bSLEnabled = true;
+  m_processor->m_busDevices[command.initiator]->SetActiveSource();
+  m_processor->m_busDevices[command.destination]->TransmitActiveSource();
+  TransmitVendorCommand05(command.destination, command.initiator);
   TransmitDeckStatus(command.initiator);
 }
 
-void CSLCommandHandler::HandleVendorCommandA0(const cec_command &command)
+void CSLCommandHandler::HandleVendorCommandPowerOnStatus(const cec_command &command)
 {
   if (command.destination != CECDEVICE_BROADCAST)
   {
@@ -135,7 +165,7 @@ void CSLCommandHandler::HandleVendorCommandA0(const cec_command &command)
 void CSLCommandHandler::TransmitDeckStatus(const cec_logical_address iDestination)
 {
   /* set deck status for the playback device */
-  CCECBusDevice *primary = m_processor->m_busDevices[m_processor->GetLogicalAddresses().primary];
+  CCECBusDevice *primary = m_processor->GetPrimaryDevice();
   if (primary->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE || primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)
   {
     ((CCECPlaybackDevice *)primary)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
@@ -169,8 +199,8 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
 {
   bool bHandled(false);
 
-  if (m_processor->IsStarted() && m_busDevice->MyLogicalAddressContains(command.destination) ||
-      command.destination == CECDEVICE_BROADCAST)
+  if (m_processor->IsStarted() && (m_busDevice->MyLogicalAddressContains(command.destination) ||
+      command.destination == CECDEVICE_BROADCAST))
   {
     switch(command.opcode)
     {
@@ -184,7 +214,6 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
           m_bVendorIdSent = true;
           TransmitLGVendorId(m_processor->GetLogicalAddresses().primary, CECDEVICE_BROADCAST);
         }
-        m_bSLEnabled = false;
       }
       bHandled = true;
     default:
@@ -217,9 +246,9 @@ bool CSLCommandHandler::HandleReceiveFailed(void)
 
 bool CSLCommandHandler::InitHandler(void)
 {
-  if (m_bSLEnabled)
+  if (m_bHandlerInited)
     return true;
-  m_bSLEnabled = true;
+  m_bHandlerInited = true;
 
   m_processor->SetStandardLineTimeout(3);
   m_processor->SetRetryLineTimeout(3);
@@ -229,15 +258,15 @@ bool CSLCommandHandler::InitHandler(void)
   m_iTransmitRetries = 4;
   m_iTransmitTimeout = 500;
 
-  CCECBusDevice *primary = m_processor->m_busDevices[m_processor->GetLogicalAddresses().primary];
+  CCECBusDevice *primary = m_processor->GetPrimaryDevice();
   if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
+  {
     primary->SetVendorId(CEC_VENDOR_LG, false);
+    primary->TransmitVendorID(CECDEVICE_TV, false);
+  }
 
   if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV)
   {
-    primary->TransmitVendorID(CECDEVICE_TV);
-    primary->TransmitPhysicalAddress();
-
     /* LG TVs don't always reply to CEC version requests, so just set it to 1.3a */
     m_busDevice->SetCecVersion(CEC_VERSION_1_3A);
   }
@@ -250,7 +279,8 @@ bool CSLCommandHandler::InitHandler(void)
 
   if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV)
   {
-    m_processor->SetActiveSource(m_processor->GetLogicalAddresses().primary);
+    m_processor->SetActiveSource();
+
     /* LG TVs only route keypresses when the deck status is set to 0x20 */
     cec_logical_addresses addr = m_processor->GetLogicalAddresses();
     for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
@@ -263,7 +293,7 @@ bool CSLCommandHandler::InitHandler(void)
                        device->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE))
         {
           ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
-          TransmitDeckStatus(CECDEVICE_TV);
+          ((CCECPlaybackDevice *)device)->TransmitDeckStatus(CECDEVICE_TV);
         }
       }
     }
@@ -275,14 +305,16 @@ bool CSLCommandHandler::InitHandler(void)
 bool CSLCommandHandler::TransmitPowerOn(const cec_logical_address iInitiator, const cec_logical_address iDestination)
 {
   if (iDestination != CECDEVICE_BROADCAST &&
-      m_processor->m_busDevices[iDestination]->GetVendorId(false) == CEC_VENDOR_LG);
+      iInitiator != CECDEVICE_TV &&
+      m_processor->m_busDevices[iDestination]->GetVendorId(false) == CEC_VENDOR_LG)
   {
     cec_command command;
     cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_VENDOR_COMMAND);
-    command.parameters.PushBack((uint8_t) (((uint16_t)SL_COMMAND_POWER_ON >> 8) & 0xFF));
-    command.parameters.PushBack((uint8_t) ((uint16_t)SL_COMMAND_POWER_ON & 0xFF));
+    command.parameters.PushBack((uint8_t)SL_COMMAND_POWER_ON);
+    command.parameters.PushBack(0x00);
     return Transmit(command);
   }
 
   return CCECCommandHandler::TransmitPowerOn(iInitiator, iDestination);
 }
+