+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:
http://libcec.pulse-eight.com/faq
===============================================================================
- === Linux ===
+ === Linux & BSD ===
===============================================================================
libCEC needs the following dependencies in order to work correctly:
* udev development headers v151 or later
To compile, execute the following commands:
-# autoreconf -vif
+# ./bootstrap
# ./configure
# make
# sudo make install
* 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
--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'
=== 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
--- /dev/null
+#!/bin/sh
+
+autoreconf -vif
+
[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])
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
+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:
#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
{
/*!
* 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
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
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
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;
// 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")]
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
-[assembly:AssemblyVersionAttribute("2.0.2.0")];
+[assembly:AssemblyVersionAttribute("2.0.3.0")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
/// <summary>
/// v2.0.2
/// </summary>
- Version2_0_2 = 0x2002
+ Version2_0_2 = 0x2002,
+ /// <summary>
+ /// v2.0.3
+ /// </summary>
+ Version2_0_3 = 0x2003
};
/// <summary>
/// <summary>
/// v2.0.2
/// </summary>
- Version2_0_2 = 0x2002
+ Version2_0_2 = 0x2002,
+ /// <summary>
+ /// v2.0.3
+ /// </summary>
+ Version2_0_3 = 0x2003
};
/// <summary>
// 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")]
{
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);
// 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)
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)
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";
}
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";
}
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;
+ }
};
}
## 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
#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;
#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);
{
#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)
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;
}
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)
#include "env.h"
#if defined(HAVE_TDA995X_API)
-#include "NxpCECAdapterCommunication.h"
+#include "TDA995xCECAdapterCommunication.h"
#include "lib/CECTypeUtils.h"
#include "lib/LibCEC.h"
#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)
{
}
-CNxpCECAdapterCommunication::~CNxpCECAdapterCommunication(void)
+CTDA995xCECAdapterCommunication::~CTDA995xCECAdapterCommunication(void)
{
Close();
}
-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))
{
}
-void CNxpCECAdapterCommunication::Close(void)
+void CTDA995xCECAdapterCommunication::Close(void)
{
StopThread(0);
}
-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;
}
-uint16_t CNxpCECAdapterCommunication::GetFirmwareVersion(void)
+uint16_t CTDA995xCECAdapterCommunication::GetFirmwareVersion(void)
{
cec_sw_version vers = { 0 };
}
-cec_vendor_id CNxpCECAdapterCommunication::GetVendorId(void)
+cec_vendor_id CTDA995xCECAdapterCommunication::GetVendorId(void)
{
cec_raw_info info;
}
-uint16_t CNxpCECAdapterCommunication::GetPhysicalAddress(void)
+uint16_t CTDA995xCECAdapterCommunication::GetPhysicalAddress(void)
{
cec_raw_info info;
}
-cec_logical_addresses CNxpCECAdapterCommunication::GetLogicalAddresses(void)
+cec_logical_addresses CTDA995xCECAdapterCommunication::GetLogicalAddresses(void)
{
CLockObject lock(m_mutex);
}
-bool CNxpCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
+bool CTDA995xCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
{
unsigned char log_addr = addresses.primary;
}
-void CNxpCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
+void CTDA995xCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
{
unsigned char log_addr = CECDEVICE_BROADCAST;
}
-void *CNxpCECAdapterCommunication::Process(void)
+void *CTDA995xCECAdapterCommunication::Process(void)
{
bool bHandled;
cec_frame frame;
#include "lib/adapter/AdapterCommunication.h"
#include <map>
+#define TDA995X_ADAPTER_VID 0x0471
+#define TDA995X_ADAPTER_PID 0x1001
namespace PLATFORM
{
{
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 */
///{
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);
///}
#include <stdio.h>
#if defined(HAVE_TDA995X_API)
-#include "NxpCECAdapterDetection.h"
+#include "TDA995xCECAdapterDetection.h"
extern "C" {
#define __cec_h__
using namespace CEC;
-bool CNxpCECAdapterDetection::FindAdapter(void)
+bool CTDA995xCECAdapterDetection::FindAdapter(void)
{
return access(CEC_TDA995x_PATH, 0) == 0;
}
namespace CEC
{
- class CNxpCECAdapterDetection
+ class CTDA995xCECAdapterDetection
{
public:
static bool FindAdapter(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);
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);
#include "CECTuner.h"
#include "CECTV.h"
#include "lib/CECProcessor.h"
+#include "lib/CECTypeUtils.h"
using namespace std;
using namespace CEC;
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);
+ }
+}
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;
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;
{
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;
}
}
{
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;
}
}
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())
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);
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;
}
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))
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) {};
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;
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);
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);
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"