Merge branch 'master' into release
authorLars Op den Kamp <lars@opdenkamp.eu>
Wed, 31 Oct 2012 14:58:41 +0000 (15:58 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Wed, 31 Oct 2012 14:58:41 +0000 (15:58 +0100)
37 files changed:
ChangeLog
README
bootstrap [new file with mode: 0755]
configure.ac
debian/changelog
include/cec.h
include/cectypes.h
project/cec-config.rc
project/libcec.rc
project/testclient.rc
src/CecSharpTester/CecSharpClient.cs
src/CecSharpTester/Properties/AssemblyInfo.cs
src/LibCecSharp/AssemblyInfo.cpp
src/LibCecSharp/CecSharpTypes.h
src/LibCecTray/Properties/AssemblyInfo.cs
src/LibCecTray/controller/CECController.cs
src/lib/CECClient.cpp
src/lib/CECTypeUtils.h
src/lib/Makefile.am
src/lib/adapter/AdapterFactory.cpp
src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.cpp
src/lib/adapter/RPi/RPiCECAdapterMessageQueue.cpp
src/lib/adapter/TDA995x/AdapterMessageQueue.h [moved from src/lib/adapter/CuBox/AdapterMessageQueue.h with 100% similarity]
src/lib/adapter/TDA995x/TDA995xCECAdapterCommunication.cpp [moved from src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp with 89% similarity]
src/lib/adapter/TDA995x/TDA995xCECAdapterCommunication.h [moved from src/lib/adapter/CuBox/NxpCECAdapterCommunication.h with 88% similarity]
src/lib/adapter/TDA995x/TDA995xCECAdapterDetection.cpp [moved from src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp with 94% similarity]
src/lib/adapter/TDA995x/TDA995xCECAdapterDetection.h [moved from src/lib/adapter/CuBox/NxpCECAdapterDetection.h with 97% similarity]
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h
src/lib/devices/CECDeviceMap.cpp
src/lib/devices/CECDeviceMap.h
src/lib/implementations/ANCommandHandler.cpp
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/CECCommandHandler.h
src/lib/implementations/SLCommandHandler.cpp
src/lib/implementations/SLCommandHandler.h
src/testclient/main.cpp

index 983d0060874144630a92c40773ef24ccc03e2ffe..9b0d274dd1aedac09a04760b2c1eabde7091ce6b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+libcec (2.0.3-1) unstable; urgency=low
+
+  * changed:
+    * log unhandled vendor remote keycodes in the log, so they get logged
+      without debugging enabled
+    * double tap timeout increased from 200ms to 250ms
+    * CuBox/NXP* renamed to TDA995x*
+  * fixed:
+    * handling of active route changes. github issue #56 and issue #58
+    * new combo key handling broke samsung's vendor specific remote buttons.
+      github issue #54
+    * don't try to set controlled mode when using firmware version 1 and crash.
+      github issue #76
+    * fix for LG models that send a vendor key up after a normal key down.
+      github issue #71
+    * some TVs send keypresses to us without making us the active source. mark
+      us as active source when this happens. github issue #71
+    * LG doesn't send routing changes, and marks the TV as active source when
+      switching to another source that's not been selected in the simplink menu
+      instead. this change keeps libCEC marked as powered on and keep the deck
+      state set to CEC_DECK_INFO_OTHER_STATUS_LG. fixes keypresses not working
+      after switching to another source and back to libCEC's hdmi port via the
+      source select menu instead of the simplink menu. github issue #71
+    * don't respond with an abort message when receiving a vendor remote button
+      command
+    * respond with CEC_ABORT_REASON_INVALID_OPERAND when receiving a keypress
+      without a parameter
+    * typo in stop+pause combo key that prevented one of the keys from working
+    * rpi: log what data we received exactly when we receive an response from
+      the pi's firmware that doesn't match any command that we sent. issue #77
+    * cubox: added adapter ID interface
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Wed, 31 Oct 2012 15:57:00 +0100
+
 libcec (2.0.2-2) unstable; urgency=medium
 
   * fixed:
diff --git a/README b/README
index 9bf87861cffd4ba81ac7e702b8b81a90ecb437fa..f25c53946cbc5d64fd1772c48977a9fa3f0f191d 100644 (file)
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ You can find a list of frequently asked questions on the following page:
                     http://libcec.pulse-eight.com/faq
 
 ===============================================================================
-                                === Linux ===
+                             === Linux & BSD ===
 ===============================================================================
 
 libCEC needs the following dependencies in order to work correctly:
@@ -25,7 +25,7 @@ be auto-detected.
 * udev development headers v151 or later
 
 To compile, execute the following commands:
-# autoreconf -vif
+# ./bootstrap 
 # ./configure
 # make
 # sudo make install
@@ -40,8 +40,8 @@ To compile libCEC on OS-X, you'll need the following dependencies:
 * pkg-config
 * xcode 3.2.6 or later
 
-To compile, execute the following commands (TODO: please verify):
-# autoreconf -vif
+To compile, execute the following command:
+# ./bootstrap 
 # ./configure
 # make
 # sudo make install
@@ -100,15 +100,15 @@ for 'configure':
 --with-rpi-lib-path="/path/to/libbcm_host.so"
 
 ===============================================================================
-                           === CuBox ===
+                           === CuBox / TDA995x ===
 ===============================================================================
 
 Solid-Run's CuBox uses a combined HDMI tranceiver / CEC controller by NXP. The
 device driver for it is based on an SDK by the chip vendor and is compiled into
 the Linux kernel. The following options for 'configure' have been introduced:
 
-To enable support for the CuBox:
---enable-cubox
+To enable support for the CuBox / TDA995x:
+--enable-tda995x
 
 To specify the path to the SDK part of the kernel driver:
 --with-tda995x-toolkit-path='path/to/linux/drivers/video/dovefb/nxp_hdmi'
@@ -120,6 +120,10 @@ If the toolkit path is not specified, it is assumed that a directory named
                             === Debugging / Testing ===
 ===============================================================================
 
+To compile libCEC with extensive debugging output, pass the following argument
+to configure on Linux/OS-X/BSD:
+--enable-debug
+
 We provide a test client, named cec-client, to debug the device.
 To check whether the device can be detected, execute the following command:
 * cec-client -l
diff --git a/bootstrap b/bootstrap
new file mode 100755 (executable)
index 0000000..b80eba2
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+autoreconf -vif
+
index df63c2d3f86e7df4b1aee298020fff1c4d98f378..45d969b7aba2e56e259b53fc90cf468312d9f434 100644 (file)
@@ -43,10 +43,10 @@ AC_ARG_ENABLE([optimisation],
   [use_optimisation=$enableval],
   [use_optimisation=yes])
 
-## CuBox support
+## TDA995x support
 AC_ARG_ENABLE([cubox],
-  [AS_HELP_STRING([--enable-cubox],
-  [enable support for the CuBox (default is no)])],
+  [AS_HELP_STRING([--enable-tda995x],
+  [enable support for the TDA995x (default is no)])],
   [use_tda995x=$enableval],
   [use_tda995x=no])
 
@@ -250,16 +250,16 @@ else
   features="$features\n  Raspberry Pi support :\t\tno"
 fi
 
-## mark CuBox support as available
+## mark TDA995x support as available
 if test "x$use_tda995x" != "xno"; then
   AC_DEFINE([HAVE_TDA995X_API],[1],[Define to 1 to include CuBox support])
   AM_CONDITIONAL(USE_TDA995X_API, true)
-  features="$features\n  CuBox support :\t\t\tyes"
-  LIB_INFO="$LIB_INFO 'CuBox'"
+  features="$features\n  TDA995x support :\t\t\tyes"
+  LIB_INFO="$LIB_INFO 'TDA995x'"
   CPPFLAGS="$CPPFLAGS $TDA995X_CFLAGS"
 else
   AM_CONDITIONAL(USE_TDA995X_API, false)
-  features="$features\n  CuBox support :\t\t\tno"
+  features="$features\n  TDA995x support :\t\t\tno"
 fi
 
 ## check if our build system is complete
index 983d0060874144630a92c40773ef24ccc03e2ffe..9b0d274dd1aedac09a04760b2c1eabde7091ce6b 100644 (file)
@@ -1,3 +1,37 @@
+libcec (2.0.3-1) unstable; urgency=low
+
+  * changed:
+    * log unhandled vendor remote keycodes in the log, so they get logged
+      without debugging enabled
+    * double tap timeout increased from 200ms to 250ms
+    * CuBox/NXP* renamed to TDA995x*
+  * fixed:
+    * handling of active route changes. github issue #56 and issue #58
+    * new combo key handling broke samsung's vendor specific remote buttons.
+      github issue #54
+    * don't try to set controlled mode when using firmware version 1 and crash.
+      github issue #76
+    * fix for LG models that send a vendor key up after a normal key down.
+      github issue #71
+    * some TVs send keypresses to us without making us the active source. mark
+      us as active source when this happens. github issue #71
+    * LG doesn't send routing changes, and marks the TV as active source when
+      switching to another source that's not been selected in the simplink menu
+      instead. this change keeps libCEC marked as powered on and keep the deck
+      state set to CEC_DECK_INFO_OTHER_STATUS_LG. fixes keypresses not working
+      after switching to another source and back to libCEC's hdmi port via the
+      source select menu instead of the simplink menu. github issue #71
+    * don't respond with an abort message when receiving a vendor remote button
+      command
+    * respond with CEC_ABORT_REASON_INVALID_OPERAND when receiving a keypress
+      without a parameter
+    * typo in stop+pause combo key that prevented one of the keys from working
+    * rpi: log what data we received exactly when we receive an response from
+      the pi's firmware that doesn't match any command that we sent. issue #77
+    * cubox: added adapter ID interface
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Wed, 31 Oct 2012 15:57:00 +0100
+
 libcec (2.0.2-2) unstable; urgency=medium
 
   * fixed:
index ba12a879c66b61e5db6153a8f8f4d8cea7f33562..7d14a47366d74cbdecb3f213164df6e3a2ecd7eb 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "cectypes.h"
 
-#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_2_0_2
+#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_2_0_3
 
 namespace CEC
 {
index 6b7f73cbaa149a81549fd8b8be3330d7994d808f..48d1ab8f7b840a5c41b965235903acf43b18f53b 100644 (file)
@@ -82,7 +82,7 @@ namespace CEC {
 /*!
  * don't send the same key twice within this timeout in milliseconds
  */
-#define CEC_DOUBLE_TAP_TIMEOUT_MS    200
+#define CEC_DOUBLE_TAP_TIMEOUT_MS    250
 
 /*!
  * don't query the power state for the same device within this timeout in milliseconds
@@ -1376,6 +1376,7 @@ typedef enum cec_client_version
   CEC_CLIENT_VERSION_2_0_0   = 0x2000,
   CEC_CLIENT_VERSION_2_0_1   = 0x2001,
   CEC_CLIENT_VERSION_2_0_2   = 0x2002,
+  CEC_CLIENT_VERSION_2_0_3   = 0x2003,
 } cec_client_version;
 
 typedef enum cec_server_version
@@ -1400,6 +1401,7 @@ typedef enum cec_server_version
   CEC_SERVER_VERSION_2_0_0   = 0x2000,
   CEC_SERVER_VERSION_2_0_1   = 0x2001,
   CEC_SERVER_VERSION_2_0_2   = 0x2002,
+  CEC_SERVER_VERSION_2_0_3   = 0x2003,
 } cec_server_version;
 
 struct libcec_configuration
index 7a9da22b6c09b69028e223b21d4a2bc581028c0a..def8b1f69a03934bb26d7195c4d6be8b6b983fdf 100644 (file)
Binary files a/project/cec-config.rc and b/project/cec-config.rc differ
index b925f41863ef6df3b77fdee35a383ed680d5422c..c92cadcf2585e555af850ca68c5241992a5f1a5c 100644 (file)
Binary files a/project/libcec.rc and b/project/libcec.rc differ
index abb8ee4b4e592f709bed20989f032dc76a324f85..0da16c66d9248a654b58bccc7715febf413ddac1 100644 (file)
Binary files a/project/testclient.rc and b/project/testclient.rc differ
index cd9b0e975f5fd9354c63905d3c3c6691eb94c464..63a2e23788430aa3b6ca20a57275b3d87873135b 100644 (file)
@@ -43,7 +43,7 @@ namespace CecSharpClient
       Config = new LibCECConfiguration();
       Config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
       Config.DeviceName = "CEC Tester";
-      Config.ClientVersion = CecClientVersion.Version2_0_2;
+      Config.ClientVersion = CecClientVersion.Version2_0_3;
       Config.SetCallbacks(this);
       LogLevel = (int)CecLogLevel.All;
 
index 23128fc429bbfcb2e0aaed934528faf4e61e7004..ad7143fcdc84d78a85373476346c7cf745b24f47 100644 (file)
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.2.0")]
-[assembly: AssemblyFileVersion("2.0.2.0")]
+[assembly: AssemblyVersion("2.0.3.0")]
+[assembly: AssemblyFileVersion("2.0.3.0")]
index fe944b5d7826d71beebdfaf7b7d92cf7d0be4e29..fa6b40ba3b03fd6754774611612c1ee20e8ca658 100644 (file)
@@ -13,7 +13,7 @@ using namespace System::Security::Permissions;
 [assembly:AssemblyTrademarkAttribute("")];
 [assembly:AssemblyCultureAttribute("")];
 
-[assembly:AssemblyVersionAttribute("2.0.2.0")];
+[assembly:AssemblyVersionAttribute("2.0.3.0")];
 
 [assembly:ComVisible(false)];
 [assembly:CLSCompliantAttribute(true)];
index e183be36d5275091347d3f1202fe99face7bf23c..bf429965ede5ec10ab5cca8f5eae0e693e6a9bbd 100644 (file)
@@ -1171,7 +1171,11 @@ namespace CecSharp
     /// <summary>
     /// v2.0.2
     /// </summary>
-    Version2_0_2   = 0x2002
+    Version2_0_2   = 0x2002,
+    /// <summary>
+    /// v2.0.3
+    /// </summary>
+    Version2_0_3   = 0x2003
   };
 
   /// <summary>
@@ -1258,7 +1262,11 @@ namespace CecSharp
     /// <summary>
     /// v2.0.2
     /// </summary>
-    Version2_0_2   = 0x2002
+    Version2_0_2   = 0x2002,
+    /// <summary>
+    /// v2.0.3
+    /// </summary>
+    Version2_0_3   = 0x2003
   };
 
   /// <summary>
index aad28dde6e8a8a833de0ede860435fd8c2043356..8bc224582a0145a2c12aabba06b5700e7eb8cfa7 100644 (file)
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.2.0")]
-[assembly: AssemblyFileVersion("2.0.2.0")]
+[assembly: AssemblyVersion("2.0.3.0")]
+[assembly: AssemblyFileVersion("2.0.3.0")]
index ebce4baecc4ce5bc416bd7927eb5f7f459bde275..f4dc434b18bf4dcb6921dc981c07e683ec8689e6 100644 (file)
@@ -438,7 +438,7 @@ namespace LibCECTray.controller
       {
         if (_config == null)
         {
-          _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_2 };
+          _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_3 };
           _config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
           _config.SetCallbacks(this);
 
index a5a960ea36b00e4c804c3362b088e855550fdde3..004d741379b27e97eb287112c641838d7fe9b23e 100644 (file)
@@ -940,21 +940,21 @@ void CCECClient::AddKey(const cec_keypress &key)
   // send back the previous key if there is one
   AddKey();
 
+  if (key.keycode > CEC_USER_CONTROL_CODE_MAX &&
+      key.keycode < CEC_USER_CONTROL_CODE_SELECT)
+    return;
+
   cec_keypress transmitKey(key);
 
   {
     CLockObject lock(m_mutex);
-    if (key.duration > 0 || key.keycode > CEC_USER_CONTROL_CODE_MAX)
-    {
-      transmitKey.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
-    }
-    else if (m_iCurrentButton == COMBO_KEY)
+    if (m_iCurrentButton == COMBO_KEY && key.duration == 0)
     {
       // stop + ok -> exit
       if (key.keycode == CEC_USER_CONTROL_CODE_SELECT)
         transmitKey.keycode = CEC_USER_CONTROL_CODE_EXIT;
       // stop + pause -> root menu
-      else if (key.keycode == CEC_USER_CONTROL_CODE_ROOT_MENU)
+      else if (key.keycode == CEC_USER_CONTROL_CODE_PAUSE)
         transmitKey.keycode = CEC_USER_CONTROL_CODE_ROOT_MENU;
       // stop + play -> dot (which is handled as context menu in xbmc)
       else if (key.keycode == CEC_USER_CONTROL_CODE_PLAY)
@@ -968,8 +968,11 @@ void CCECClient::AddKey(const cec_keypress &key)
     m_buttontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
   }
 
-  LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
-  CallbackAddKey(transmitKey);
+  if (key.keycode != COMBO_KEY || key.duration > 0)
+  {
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
+    CallbackAddKey(transmitKey);
+  }
 }
 
 void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode)
index 21a651d59fe259fbcabcbb5683aacc3a761143c9..ee3ddb30bb80396f43cac879fce3aac2cd261d54 100644 (file)
@@ -561,6 +561,8 @@ namespace CEC
         return "2.0.1";
       case CEC_CLIENT_VERSION_2_0_2:
         return "2.0.2";
+      case CEC_CLIENT_VERSION_2_0_3:
+        return "2.0.3";
       default:
         return "Unknown";
       }
@@ -610,6 +612,8 @@ namespace CEC
         return "2.0.1";
       case CEC_SERVER_VERSION_2_0_2:
         return "2.0.2";
+      case CEC_SERVER_VERSION_2_0_3:
+        return "2.0.3";
       default:
         return "Unknown";
       }
@@ -819,5 +823,16 @@ namespace CEC
         return "unknown";
       }
     }
+
+    static bool PhysicalAddressIsIncluded(uint16_t iParent, uint16_t iChild)
+    {
+      for (int iPtr = 3; iPtr >= 0; iPtr--)
+      {
+        if (((iParent >> 4*iPtr) & 0xF) > 0 &&
+            ((iParent >> 4*iPtr) & 0xF) != ((iChild >> 4*iPtr) & 0xF))
+          return false;
+      }
+      return true;
+    }
   };
 }
index b88b02baf1ac1be7f3389fc07ada17d64ee0274c..ab00f1bb04d4ab1c0df120d10e19016d2aed0de9 100644 (file)
@@ -52,8 +52,8 @@ endif
 
 ## CuBox (NXP) support
 if USE_TDA995X_API
-libcec_la_SOURCES += adapter/CuBox/NxpCECAdapterDetection.cpp \
-                     adapter/CuBox/NxpCECAdapterCommunication.cpp
+libcec_la_SOURCES += adapter/TDA995x/TDA995xCECAdapterDetection.cpp \
+                     adapter/TDA995x/TDA995xCECAdapterCommunication.cpp
 endif
 
 
index d1dae84ac69b0de80e7f0ceebcbaeefe272277ab..02b6200e1616674964f34af5459cc9955ffe6a22 100644 (file)
@@ -48,8 +48,8 @@
 #endif
 
 #if defined(HAVE_TDA995X_API)
-#include "CuBox/NxpCECAdapterDetection.h"
-#include "CuBox/NxpCECAdapterCommunication.h"
+#include "TDA995x/TDA995xCECAdapterDetection.h"
+#include "TDA995x/TDA995xCECAdapterCommunication.h"
 #endif
 
 using namespace std;
@@ -81,7 +81,7 @@ int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize,
 #endif
 
 #if defined(HAVE_TDA995X_API)
-  if (iAdaptersFound < iBufSize && CNxpCECAdapterDetection::FindAdapter() &&
+  if (iAdaptersFound < iBufSize && CTDA995xCECAdapterDetection::FindAdapter() &&
       (!strDevicePath || !strcmp(strDevicePath, CEC_TDA995x_VIRTUAL_COM)))
   {
     snprintf(deviceList[iAdaptersFound].path, 1024, CEC_TDA995x_PATH);
@@ -100,7 +100,7 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_
 {
 #if defined(HAVE_TDA995X_API)
   if (!strcmp(strPort, CEC_TDA995x_VIRTUAL_COM))
-    return new CNxpCECAdapterCommunication(m_lib->m_cec);
+    return new CTDA995xCECAdapterCommunication(m_lib->m_cec);
 #endif
 
 #if defined(HAVE_RPI_API)
index 717e7d3f3e7be4225051e9ef12d4e903be5ffe55..944806828ea5553c95d6549c8f006ee22cd00f58 100644 (file)
@@ -104,6 +104,10 @@ uint16_t CUSBCECAdapterCommands::RequestFirmwareVersion(void)
     m_persistedConfiguration.iFirmwareVersion = 1;
   }
 
+  // firmware versions < 2 don't have an autonomous mode
+  if (m_persistedConfiguration.iFirmwareVersion < 2)
+    m_bControlledMode = true;
+
   return m_persistedConfiguration.iFirmwareVersion;
 }
 
index 656a25d0a2d54243983a7b813007481cc4ea18ba..625b2e9e5ab4102b5906baadd43fe5f0c9c807c6 100644 (file)
@@ -121,7 +121,7 @@ void CRPiCECAdapterMessageQueue::MessageReceived(cec_opcode opcode, cec_logical_
     bHandled = it->second->MessageReceived(opcode, initiator, destination, response);
 
   if (!bHandled)
-    LIB_CEC->AddLog(CEC_LOG_WARNING, "unhandled response received");
+    LIB_CEC->AddLog(CEC_LOG_WARNING, "unhandled response received: opcode=%x initiator=%x destination=%x response=%x", (int)opcode, (int)initiator, (int)destination, response);
 }
 
 bool CRPiCECAdapterMessageQueue::Write(const cec_command &command, bool bIsReply)
similarity index 89%
rename from src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp
rename to src/lib/adapter/TDA995x/TDA995xCECAdapterCommunication.cpp
index e46f94e63055f24f322e75f6b14a0866311600a7..83df1199b26a9fe0a801c1cb02b01761eac6c5e1 100644 (file)
@@ -33,7 +33,7 @@
 #include "env.h"
 
 #if defined(HAVE_TDA995X_API)
-#include "NxpCECAdapterCommunication.h"
+#include "TDA995xCECAdapterCommunication.h"
 
 #include "lib/CECTypeUtils.h"
 #include "lib/LibCEC.h"
@@ -66,7 +66,7 @@ using namespace PLATFORM;
 #define CEC_MSG_FAIL_DATA_NOT_ACK       0x86   /*Message transmisson failed: Databyte not acknowledged*/
 
 
-CNxpCECAdapterCommunication::CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
+CTDA995xCECAdapterCommunication::CTDA995xCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
     IAdapterCommunication(callback),
     m_bLogicalAddressChanged(false)
 { 
@@ -78,7 +78,7 @@ CNxpCECAdapterCommunication::CNxpCECAdapterCommunication(IAdapterCommunicationCa
 }
 
 
-CNxpCECAdapterCommunication::~CNxpCECAdapterCommunication(void)
+CTDA995xCECAdapterCommunication::~CTDA995xCECAdapterCommunication(void)
 {
   Close();
 
@@ -88,13 +88,13 @@ CNxpCECAdapterCommunication::~CNxpCECAdapterCommunication(void)
 }
 
 
-bool CNxpCECAdapterCommunication::IsOpen(void)
+bool CTDA995xCECAdapterCommunication::IsOpen(void)
 {
   return IsInitialised() && m_dev->IsOpen();
 }
 
     
-bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening)
+bool CTDA995xCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening)
 {
   if (m_dev->Open(iTimeoutMs))
   {
@@ -129,7 +129,7 @@ bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChe
 }
 
 
-void CNxpCECAdapterCommunication::Close(void)
+void CTDA995xCECAdapterCommunication::Close(void)
 {
   StopThread(0);
 
@@ -140,14 +140,14 @@ void CNxpCECAdapterCommunication::Close(void)
 }
 
 
-std::string CNxpCECAdapterCommunication::GetError(void) const
+std::string CTDA995xCECAdapterCommunication::GetError(void) const
 {
   std::string strError(m_strError);
   return strError;
 }
 
 
-cec_adapter_message_state CNxpCECAdapterCommunication::Write(
+cec_adapter_message_state CTDA995xCECAdapterCommunication::Write(
   const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply))
 {
   cec_frame frame;
@@ -211,7 +211,7 @@ cec_adapter_message_state CNxpCECAdapterCommunication::Write(
 }
 
 
-uint16_t CNxpCECAdapterCommunication::GetFirmwareVersion(void)
+uint16_t CTDA995xCECAdapterCommunication::GetFirmwareVersion(void)
 {
   cec_sw_version  vers = { 0 };
 
@@ -221,7 +221,7 @@ uint16_t CNxpCECAdapterCommunication::GetFirmwareVersion(void)
 }
 
 
-cec_vendor_id CNxpCECAdapterCommunication::GetVendorId(void)
+cec_vendor_id CTDA995xCECAdapterCommunication::GetVendorId(void)
 {
   cec_raw_info info;
  
@@ -235,7 +235,7 @@ cec_vendor_id CNxpCECAdapterCommunication::GetVendorId(void)
 }
 
 
-uint16_t CNxpCECAdapterCommunication::GetPhysicalAddress(void)
+uint16_t CTDA995xCECAdapterCommunication::GetPhysicalAddress(void)
 {
   cec_raw_info info;
  
@@ -249,7 +249,7 @@ uint16_t CNxpCECAdapterCommunication::GetPhysicalAddress(void)
 }
 
 
-cec_logical_addresses CNxpCECAdapterCommunication::GetLogicalAddresses(void)
+cec_logical_addresses CTDA995xCECAdapterCommunication::GetLogicalAddresses(void)
 {
   CLockObject lock(m_mutex);
 
@@ -280,7 +280,7 @@ cec_logical_addresses CNxpCECAdapterCommunication::GetLogicalAddresses(void)
 }
 
 
-bool CNxpCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
+bool CTDA995xCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
 {
   unsigned char log_addr = addresses.primary;
   
@@ -308,7 +308,7 @@ bool CNxpCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresse
 }
 
 
-void CNxpCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
+void CTDA995xCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
 {
   unsigned char log_addr = CECDEVICE_BROADCAST;
 
@@ -319,7 +319,7 @@ void CNxpCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address U
 }
 
 
-void *CNxpCECAdapterCommunication::Process(void)
+void *CTDA995xCECAdapterCommunication::Process(void)
 {
   bool bHandled;
   cec_frame frame;
similarity index 88%
rename from src/lib/adapter/CuBox/NxpCECAdapterCommunication.h
rename to src/lib/adapter/TDA995x/TDA995xCECAdapterCommunication.h
index 066c03248cf4d5c0407807121a68c30eeebf1350..9476383d2edf7bb9b63f3ea48a993ca37bdc4d93 100644 (file)
@@ -39,6 +39,8 @@
 #include "lib/adapter/AdapterCommunication.h"
 #include <map>
 
+#define TDA995X_ADAPTER_VID 0x0471
+#define TDA995X_ADAPTER_PID 0x1001
 
 namespace PLATFORM
 {
@@ -50,15 +52,15 @@ namespace CEC
 {
   class CAdapterMessageQueueEntry;
 
-  class CNxpCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread
+  class CTDA995xCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread
   {
   public:
     /*!
      * @brief Create a new USB-CEC communication handler.
      * @param callback The callback to use for incoming CEC commands.
      */
-    CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback);
-    virtual ~CNxpCECAdapterCommunication(void);
+    CTDA995xCECAdapterCommunication(IAdapterCommunicationCallback *callback);
+    virtual ~CTDA995xCECAdapterCommunication(void);
 
     /** @name IAdapterCommunication implementation */
     ///{
@@ -78,12 +80,14 @@ namespace CEC
     bool IsRunningLatestFirmware(void) { return true; }
     bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; }
     bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; }
-    std::string GetPortName(void) { return std::string("NXP"); }
+    std::string GetPortName(void) { return std::string("TDA995X"); }
     uint16_t GetPhysicalAddress(void);
     bool SetControlledMode(bool UNUSED(controlled)) { return true; }
     cec_vendor_id GetVendorId(void);
     bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; }
     cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_TDA995x; }
+    uint16_t GetAdapterVendorId(void) const { return TDA995X_ADAPTER_VID; }
+    uint16_t GetAdapterProductId(void) const { return TDA995X_ADAPTER_PID; }
     void HandleLogicalAddressLost(cec_logical_address oldAddress);
     ///}
 
similarity index 94%
rename from src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp
rename to src/lib/adapter/TDA995x/TDA995xCECAdapterDetection.cpp
index b4b7495a908f8efecc55a961032b934d313a8def..a355f78b99d4d558b040bb9a2c144976c5eab89c 100644 (file)
@@ -34,7 +34,7 @@
 #include <stdio.h>
 
 #if defined(HAVE_TDA995X_API)
-#include "NxpCECAdapterDetection.h"
+#include "TDA995xCECAdapterDetection.h"
 
 extern "C" {
 #define __cec_h__
@@ -44,7 +44,7 @@ extern "C" {
 
 using namespace CEC;
 
-bool CNxpCECAdapterDetection::FindAdapter(void)
+bool CTDA995xCECAdapterDetection::FindAdapter(void)
 {
   return access(CEC_TDA995x_PATH, 0) == 0;
 }
similarity index 97%
rename from src/lib/adapter/CuBox/NxpCECAdapterDetection.h
rename to src/lib/adapter/TDA995x/TDA995xCECAdapterDetection.h
index dde82a239713af2aeaa18d8e618571d263f8420a..5380663fd8bf1db967bd2dabd6cb7c92c758a7fb 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace CEC
 {
-  class CNxpCECAdapterDetection
+  class CTDA995xCECAdapterDetection
   {
   public:
     static bool FindAdapter(void);
index 5137cfbc00ad08ce7bf7940cd9fde57e30586484..5fe6d4dd26ee0060267dfd90880b2ad123a00947 100644 (file)
@@ -1066,6 +1066,26 @@ bool CCECBusDevice::TransmitPendingActiveSourceCommands(void)
   return bReturn;
 }
 
+void CCECBusDevice::SetActiveRoute(uint16_t iRoute)
+{
+  CCECDeviceMap* map = m_processor->GetDevices();
+  if (!map)
+    return;
+
+  CCECBusDevice* previouslyActive = map->GetActiveSource();
+  if (!previouslyActive)
+    return;
+
+  CECDEVICEVEC devices;
+  m_processor->GetDevices()->GetChildrenOf(devices, this);
+
+  for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++)
+  {
+    if (!CCECTypeUtils::PhysicalAddressIsIncluded(iRoute, (*it)->GetCurrentPhysicalAddress()))
+      (*it)->MarkAsInactiveSource();
+  }
+}
+
 void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */)
 {
   CLockObject lock(m_mutex);
index fad7191e6be216ac2bd83c7898681acb5e8892c0..6cba39f864f9adc4105b2bf639dbd964644bb25c 100644 (file)
@@ -224,6 +224,7 @@ namespace CEC
     virtual bool                  TransmitImageViewOn(void);
     virtual bool                  TransmitInactiveSource(void);
     virtual bool                  TransmitPendingActiveSourceCommands(void);
+    virtual void                  SetActiveRoute(uint16_t iRoute);
     virtual void                  SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress = CEC_INVALID_PHYSICAL_ADDRESS);
 
     virtual bool                  PowerOn(const cec_logical_address initiator);
index a21b2b43254149cf51408d43c90365a81bbe6a4a..23e7a6fad980e89b60b357608a35adb280a6360a 100644 (file)
@@ -39,6 +39,7 @@
 #include "CECTuner.h"
 #include "CECTV.h"
 #include "lib/CECProcessor.h"
+#include "lib/CECTypeUtils.h"
 
 using namespace std;
 using namespace CEC;
@@ -266,3 +267,19 @@ cec_logical_addresses CCECDeviceMap::ToLogicalAddresses(const CECDEVICEVEC &devi
     addresses.Set((*it)->GetLogicalAddress());
   return addresses;
 }
+
+void CCECDeviceMap::GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const
+{
+  devices.clear();
+  if (!device)
+    return;
+
+  uint16_t iPA = device->GetCurrentPhysicalAddress();
+
+  for (CECDEVICEMAP::const_iterator it = m_busDevices.begin(); it != m_busDevices.end(); it++)
+  {
+    uint16_t iCurrentPA = it->second->GetCurrentPhysicalAddress();
+    if (CCECTypeUtils::PhysicalAddressIsIncluded(iPA, iCurrentPA))
+      devices.push_back(it->second);
+  }
+}
index d4af816a076dad44c85eac3d582f9f42de490b44..c27a2dd57e533df3e631fa3b1e4c0b67b18c57c1 100644 (file)
@@ -62,6 +62,7 @@ namespace CEC
     void GetByLogicalAddresses(CECDEVICEVEC &devices, const cec_logical_addresses &addresses);
     void GetActive(CECDEVICEVEC &devices) const;
     void GetByType(const cec_device_type type, CECDEVICEVEC &devices) const;
+    void GetChildrenOf(CECDEVICEVEC& devices, CCECBusDevice* device) const;
 
     void GetPowerOffDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const;
     void GetWakeDevices(const libcec_configuration &configuration, CECDEVICEVEC &devices) const;
index 648f4a0de21501cefd521eedb94aed67a955a91c..92b4464b2fe82dd06325d0c8f723ec9e41b4b547 100644 (file)
@@ -68,23 +68,9 @@ int CANCommandHandler::HandleVendorRemoteButtonDown(const cec_command &command)
 
   cec_keypress key;
   key.duration = CEC_BUTTON_TIMEOUT;
-  key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
+  key.keycode = (cec_user_control_code)command.parameters[0];
 
-  switch (command.parameters[0])
-  {
-  case CEC_USER_CONTROL_CODE_AN_RETURN:
-    key.keycode = client && client->GetClientVersion() >= CEC_CLIENT_VERSION_1_5_0 ?
-      CEC_USER_CONTROL_CODE_AN_RETURN :
-      CEC_USER_CONTROL_CODE_EXIT;
-    break;
-  case CEC_USER_CONTROL_CODE_AN_CHANNELS_LIST:
-    key.keycode = CEC_USER_CONTROL_CODE_AN_CHANNELS_LIST;
-    break;
-  default:
-    break;
-  }
-
-  if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN && client)
+  if (client)
     client->AddKey(key);
 
   return COMMAND_HANDLED;
index 5398513ab52fa8a5d20ed949d041bcb882091422..3b0187a1c3edbc1ef6560143bc2cd652470d5b84 100644 (file)
@@ -488,13 +488,11 @@ int CCECCommandHandler::HandleRoutingChange(const cec_command &command)
 {
   if (command.parameters.size == 4)
   {
-    uint16_t iOldAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
-    uint16_t iNewAddress = ((uint16_t)command.parameters[2] << 8) | ((uint16_t)command.parameters[3]);
-
     CCECBusDevice *device = GetDevice(command.initiator);
     if (device)
     {
-      device->SetStreamPath(iNewAddress, iOldAddress);
+      uint16_t iNewAddress = ((uint16_t)command.parameters[2] << 8) | ((uint16_t)command.parameters[3]);
+      device->SetActiveRoute(iNewAddress);
       return COMMAND_HANDLED;
     }
   }
@@ -506,11 +504,11 @@ int CCECCommandHandler::HandleRoutingInformation(const cec_command &command)
 {
   if (command.parameters.size == 2)
   {
-    uint16_t iNewAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
-    CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iNewAddress);
+    CCECBusDevice *device = GetDevice(command.initiator);
     if (device)
     {
-      device->MarkAsActiveSource();
+      uint16_t iNewAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
+      device->SetActiveRoute(iNewAddress);
       return COMMAND_HANDLED;
     }
   }
@@ -570,9 +568,6 @@ int CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
     uint16_t iStreamAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
     LIB_CEC->AddLog(CEC_LOG_DEBUG, ">> %s (%x) sets stream path to physical address %04x", ToString(command.initiator), command.initiator, iStreamAddress);
 
-    // a device will only change the stream path when it's powered on
-    m_busDevice->SetPowerStatus(CEC_POWER_STATUS_ON);
-
     /* one of the device handled by libCEC has been made active */
     CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamAddress);
     if (device && device->IsHandledByLibCEC())
@@ -678,13 +673,15 @@ int CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
     client->SetCurrentButton((cec_user_control_code) command.parameters[0]);
 
   if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER ||
-      command.parameters[0] == CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION)
+      command.parameters[0] == CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION||
+      command.parameters[0] == CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION)
   {
     bool bPowerOn(true);
 
-    // CEC_USER_CONTROL_CODE_POWER operates as a toggle
+    // CEC_USER_CONTROL_CODE_POWER and CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION operate as a toggle
     // assume CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION does not
-    if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER)
+    if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER ||
+        command.parameters[0] == CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION)
     {
       cec_power_status status = device->GetCurrentPowerStatus();
       bPowerOn = !(status == CEC_POWER_STATUS_ON || status == CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
@@ -701,6 +698,12 @@ int CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
       device->SetMenuState(CEC_MENU_STATE_DEACTIVATED);
     }
   }
+  else if (command.parameters[0] != CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION)
+  {
+    // we're not marked as active source, but the tv sends keypresses to us, so assume it forgot to activate us
+    if (!device->IsActiveSource() && command.initiator == CECDEVICE_TV)
+      device->ActivateSource();
+  }
 
   return COMMAND_HANDLED;
 }
@@ -723,6 +726,15 @@ int CCECCommandHandler::HandleVendorCommand(const cec_command & UNUSED(command))
   return CEC_ABORT_REASON_INVALID_OPERAND;
 }
 
+int CCECCommandHandler::HandleVendorRemoteButtonDown(const cec_command& command)
+{
+  if (command.parameters.size == 0)
+    return CEC_ABORT_REASON_INVALID_OPERAND;
+
+  LIB_CEC->AddLog(CEC_LOG_NOTICE, "unhandled vendor remote button received with keycode %x", command.parameters[0]);
+  return COMMAND_HANDLED;
+}
+
 void CCECCommandHandler::UnhandledCommand(const cec_command &command, const cec_abort_reason reason)
 {
   if (m_processor->IsHandledByLibCEC(command.destination))
index 1a6cd567c264881e2a50f9f2ff27f05cf4429f19..b09f9b3ecbf3b9b657caa33d283232c9138dff97 100644 (file)
@@ -135,8 +135,8 @@ namespace CEC
     virtual int HandleUserControlPressed(const cec_command &command);
     virtual int HandleUserControlRelease(const cec_command &command);
     virtual int HandleVendorCommand(const cec_command &command);
-    virtual int HandleVendorRemoteButtonDown(const cec_command & UNUSED(command)) { return CEC_ABORT_REASON_REFUSED; }
-    virtual int HandleVendorRemoteButtonUp(const cec_command & UNUSED(command)) { return CEC_ABORT_REASON_REFUSED; }
+    virtual int HandleVendorRemoteButtonDown(const cec_command& command);
+    virtual int HandleVendorRemoteButtonUp(const cec_command & UNUSED(command)) { return COMMAND_HANDLED; }
     virtual void UnhandledCommand(const cec_command &command, const cec_abort_reason reason);
 
     virtual void VendorPreActivateSourceHook(void) {};
index f495b8b8643d756a62d0d3215a9f219c2638631e..7c9579d8ea6b24254af43679ef656562f04d89c9 100644 (file)
@@ -115,19 +115,13 @@ int CSLCommandHandler::HandleActiveSource(const cec_command &command)
   if (command.parameters.size == 2)
   {
     uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
-    CCECBusDevice *primary = m_processor->GetPrimaryDevice();
-    bool bSendPowerOffState(iAddress != primary->GetCurrentPhysicalAddress() && primary->IsActiveSource());
-
     CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iAddress);
     if (device)
       device->MarkAsActiveSource();
-    if (bSendPowerOffState)
+
     {
-      {
-        CLockObject lock(m_SLMutex);
-        m_bActiveSourceSent = false;
-      }
-      primary->TransmitPowerState(CECDEVICE_TV, false);
+      CLockObject lock(m_SLMutex);
+      m_bActiveSourceSent = false;
     }
 
     return COMMAND_HANDLED;
@@ -273,7 +267,7 @@ int CSLCommandHandler::HandleGiveDeckStatus(const cec_command &command)
   if (!device || command.parameters.size == 0)
     return CEC_ABORT_REASON_INVALID_OPERAND;
 
-  device->SetDeckStatus(!device->IsActiveSource() ? CEC_DECK_INFO_OTHER_STATUS : CEC_DECK_INFO_OTHER_STATUS_LG);
+  device->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
   if (command.parameters[0] == CEC_STATUS_REQUEST_ON)
   {
     device->TransmitDeckStatus(command.initiator, true);
index 2cbef7b4b17f93faae0022e4592a61466da25a12..ec2a4ae5ee8da337baab00a77fce9fe17c151cdf 100644 (file)
@@ -68,6 +68,7 @@ namespace CEC
     int HandleStandby(const cec_command &command);
     bool TransmitMenuState(const cec_logical_address UNUSED(iInitiator), const cec_logical_address UNUSED(iDestination), cec_menu_state UNUSED(menuState), bool UNUSED(bIsReply)) { return true; }
     bool PowerOn(const cec_logical_address iInitiator, const cec_logical_address iDestination);
+    int HandleVendorRemoteButtonUp(const cec_command& command) { return HandleUserControlRelease(command); }
 
     void ResetSLState(void);
     bool SLInitialised(void);
index 2050ee91000873ed899cdc16f97e2390aeb50aba..d73d4cbe1a2b478cdaf20efc8c3042d69a9022a9 100644 (file)
@@ -48,7 +48,7 @@ using namespace CEC;
 using namespace std;
 using namespace PLATFORM;
 
-#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_2_0_2;
+#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_2_0_3;
 
 #include "../../include/cecloader.h"