+libcec (2.0.2-2) unstable; urgency=medium
+
+ * fixed:
+ * updating the device status after a poll was broken and could reset the
+ status of devices that were marked as handled by libCEC to 'not
+ present'
+ * don't keep spamming the bus with a vendor command when an active source
+ switch is pending for panasonic, but only send it when needed
+ * reset CVLCommandHandler::m_bCapabilitiesSent when the TV goes to standby
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com> Mon, 15 Oct 2012 13:52:00 +0100
+
libcec (2.0.2-1) unstable; urgency=low
* changed/added:
AC_SEARCH_LIBS([dlopen], [dl],
[test "$ac_cv_search_dlopen" = "none required" || LIBS_DL=$ac_cv_search_dlopen],
AC_MSG_ERROR($msg_dl_missing))
-AC_CHECK_FUNCS([dlopen dlcose dlsym])
+AC_CHECK_FUNCS([dlopen dlclose dlsym])
## platform specific libs, required by all targets
case "${host}" in
+libcec (2.0.2-2) unstable; urgency=medium
+
+ * fixed:
+ * updating the device status after a poll was broken and could reset the
+ status of devices that were marked as handled by libCEC to 'not
+ present'
+ * don't keep spamming the bus with a vendor command when an active source
+ switch is pending for panasonic, but only send it when needed
+ * reset CVLCommandHandler::m_bCapabilitiesSent when the TV goes to standby
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com> Mon, 15 Oct 2012 13:52:00 +0100
+
libcec (2.0.2-1) unstable; urgency=low
* changed/added:
#include "cectypes.h"
-#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_2_0_1
+#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_2_0_2
namespace CEC
{
CEC_CLIENT_VERSION_1_99_0 = 0x1990,
CEC_CLIENT_VERSION_2_0_0 = 0x2000,
CEC_CLIENT_VERSION_2_0_1 = 0x2001,
+ CEC_CLIENT_VERSION_2_0_2 = 0x2002,
} cec_client_version;
typedef enum cec_server_version
CEC_SERVER_VERSION_1_99_0 = 0x1990,
CEC_SERVER_VERSION_2_0_0 = 0x2000,
CEC_SERVER_VERSION_2_0_1 = 0x2001,
+ CEC_SERVER_VERSION_2_0_2 = 0x2002,
} cec_server_version;
struct libcec_configuration
!include "LogicLib.nsh"
!include "x64.nsh"
-Name "Pulse-Eight libCEC version 2.0.0"
+Name "Pulse-Eight libCEC version 2.0.2"
OutFile "..\build\libCEC-installer.exe"
XPStyle on
Config = new LibCECConfiguration();
Config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
Config.DeviceName = "CEC Tester";
- Config.ClientVersion = CecClientVersion.Version2_0_0;
+ Config.ClientVersion = CecClientVersion.Version2_0_2;
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.1.0")]
-[assembly: AssemblyFileVersion("2.0.1.0")]
+[assembly: AssemblyVersion("2.0.2.0")]
+[assembly: AssemblyFileVersion("2.0.2.0")]
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
-[assembly:AssemblyVersionAttribute("2.0.1.0")];
+[assembly:AssemblyVersionAttribute("2.0.2.0")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
/// <summary>
/// v2.0.1
/// </summary>
- Version2_0_1 = 0x2001
+ Version2_0_1 = 0x2001,
+ /// <summary>
+ /// v2.0.2
+ /// </summary>
+ Version2_0_2 = 0x2002
};
/// <summary>
/// <summary>
/// v2.0.1
/// </summary>
- Version2_0_1 = 0x2001
+ Version2_0_1 = 0x2001,
+ /// <summary>
+ /// v2.0.2
+ /// </summary>
+ Version2_0_2 = 0x2002
};
/// <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.1.0")]
-[assembly: AssemblyFileVersion("2.0.1.0")]
+[assembly: AssemblyVersion("2.0.2.0")]
+[assembly: AssemblyFileVersion("2.0.2.0")]
{
if (_config == null)
{
- _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_0 };
+ _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_2 };
_config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
_config.SetCallbacks(this);
g_config.Clear();
snprintf(g_config.strDeviceName, 13, "CEC-config");
g_config.callbackParam = NULL;
- g_config.clientVersion = (uint32_t)CEC_CLIENT_VERSION_2_0_0;
+ g_config.clientVersion = (uint32_t)CEC_CLIENT_VERSION_2_0_2;
g_callbacks.CBCecLogMessage = &CecLogMessage;
g_callbacks.CBCecKeyPress = &CecKeyPress;
g_callbacks.CBCecCommand = &CecCommand;
CCECBusDevice *primary = GetPrimaryDevice();
// poll the destination, with the primary as source
if (primary)
- return primary->TransmitPoll(iAddress, false);
+ return primary->TransmitPoll(iAddress, true);
return m_processor ? m_processor->PollDevice(iAddress) : false;
}
CCECBusDevice *primary = GetPrimaryDevice();
// poll the destination, with the primary as source
if (primary)
- return primary->TransmitPoll(iAddress, false);
+ return primary->TransmitPoll(iAddress, true);
CCECBusDevice *device = m_busDevices->At(CECDEVICE_UNREGISTERED);
if (device)
- return device->TransmitPoll(iAddress, false);
+ return device->TransmitPoll(iAddress, true);
return false;
}
return "2.0.0";
case CEC_CLIENT_VERSION_2_0_1:
return "2.0.1";
+ case CEC_CLIENT_VERSION_2_0_2:
+ return "2.0.2";
default:
return "Unknown";
}
return "1.9.0";
case CEC_SERVER_VERSION_1_99_0:
return "2.0.0-pre";
- case CEC_CLIENT_VERSION_2_0_0:
+ case CEC_SERVER_VERSION_2_0_0:
return "2.0.0";
- case CEC_CLIENT_VERSION_2_0_1:
+ case CEC_SERVER_VERSION_2_0_1:
return "2.0.1";
+ case CEC_SERVER_VERSION_2_0_2:
+ return "2.0.2";
default:
return "Unknown";
}
while (m_persistedConfiguration.iFirmwareVersion == CEC_FW_VERSION_UNKNOWN && iFwVersionTry++ < 3)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting the firmware version");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_FIRMWARE_VERSION);
if (response.size == 2)
m_persistedConfiguration.iFirmwareVersion = (response[0] << 8 | response[1]);
bool CUSBCECAdapterCommands::RequestSettingAutoEnabled(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting autonomous mode setting");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_AUTO_ENABLED);
if (response.size == 1)
bool CUSBCECAdapterCommands::RequestSettingCECVersion(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting CEC version setting");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_HDMI_VERSION);
if (response.size == 1)
{
if (m_adapterType == P8_ADAPTERTYPE_UNKNOWN)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting adapter type");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_ADAPTER_TYPE);
if (response.size == 1)
{
if (m_iBuildDate == CEC_FW_BUILD_UNKNOWN)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting firmware build date");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_BUILDDATE);
if (response.size == 4)
bool CUSBCECAdapterCommands::RequestSettingDefaultLogicalAddress(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting default logical address setting");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS);
if (response.size == 1)
bool CUSBCECAdapterCommands::RequestSettingDeviceType(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting device type setting");
+#endif
m_persistedConfiguration.deviceTypes.Clear();
cec_datapacket response = RequestSetting(MSGCODE_GET_DEVICE_TYPE);
bool CUSBCECAdapterCommands::RequestSettingLogicalAddressMask(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting logical address mask setting");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_LOGICAL_ADDRESS_MASK);
if (response.size == 2)
bool CUSBCECAdapterCommands::RequestSettingOSDName(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting OSD name setting");
+#endif
memset(m_persistedConfiguration.strDeviceName, 0, 13);
cec_datapacket response = RequestSetting(MSGCODE_GET_OSD_NAME);
bool CUSBCECAdapterCommands::RequestSettingPhysicalAddress(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting physical address setting");
+#endif
cec_datapacket response = RequestSetting(MSGCODE_GET_PHYSICAL_ADDRESS);
if (response.size == 2)
bool CUSBCECAdapterCommands::PingAdapter(void)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending ping");
+#endif
CCECAdapterMessage params;
CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_PING, params);
{
VC_CEC_NOTIFY_T reason = (VC_CEC_NOTIFY_T)CEC_CB_REASON(header);
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "received data: header:%08X p0:%08X p1:%08X p2:%08X p3:%08X reason:%x", header, p0, p1, p2, p3, reason);
+#endif
switch (reason)
{
message.payload[iPtr + 1] = command.parameters.At(iPtr);
}
+#ifdef CEC_DEBUGGING
CStdString strDump;
strDump.Format("len = %d, payload = %X%X", message.length, (int)message.initiator, (int)message.follower);
for (uint8_t iPtr = 0; iPtr < message.length - 1; iPtr++)
strDump.AppendFormat(":%02X", message.payload[iPtr]);
LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending data: %s", strDump.c_str());
+#endif
int iReturn = vc_cec_send_message2(&message);
#else
payload[iPtr + 1] = command.parameters.At(iPtr);
}
+#ifdef CEC_DEBUGGING
CStdString strDump;
strDump.Format("len = %d, payload = %X%X", iLength, (int)command.initiator, (int)command.destination);
for (uint8_t iPtr = 0; iPtr < iLength; iPtr++)
strDump.AppendFormat(":%02X", payload[iPtr]);
LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending data: %s", strDump.c_str());
+#endif
int iReturn = vc_cec_send_message((uint32_t)command.destination, (uint8_t*)&payload, iLength, bIsReply);
#endif
!IsUnsupportedFeature(CEC_OPCODE_GIVE_DEVICE_POWER_STATUS))
{
MarkBusy();
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting power status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
bReturn = m_handler->TransmitRequestPowerStatus(initiator, m_iLogicalAddress, bWaitForResponse);
MarkReady();
}
CLockObject lock(m_mutex);
status = m_deviceStatus;
bNeedsPoll = !bSuppressPoll &&
- (bForcePoll || m_deviceStatus == CEC_DEVICE_STATUS_UNKNOWN);
+ (bForcePoll || m_deviceStatus == CEC_DEVICE_STATUS_UNKNOWN) &&
+ m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC;
}
if (bNeedsPoll)
if (m_deviceStatus != newStatus)
LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X): device status changed into 'present'", GetLogicalAddressName(), m_iLogicalAddress);
m_deviceStatus = newStatus;
+ m_iLastActive = GetTimeMs();
break;
case CEC_DEVICE_STATUS_NOT_PRESENT:
if (m_deviceStatus != newStatus)
m_deviceStatus = CEC_DEVICE_STATUS_UNKNOWN;
}
-bool CCECBusDevice::TransmitPoll(const cec_logical_address dest, bool bIsReply)
+bool CCECBusDevice::TransmitPoll(const cec_logical_address dest, bool bUpdateDeviceStatus)
{
bool bReturn(false);
cec_logical_address destination(dest);
MarkBusy();
LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest);
- bReturn = m_handler->TransmitPoll(m_iLogicalAddress, destination, bIsReply);
+ bReturn = m_handler->TransmitPoll(m_iLogicalAddress, destination, false);
LIB_CEC->AddLog(CEC_LOG_DEBUG, bReturn ? ">> POLL sent" : ">> POLL not sent");
- CLockObject lock(m_mutex);
- if (bReturn)
- {
- m_iLastActive = GetTimeMs();
- SetDeviceStatus(CEC_DEVICE_STATUS_PRESENT);
- }
- else
- SetDeviceStatus(CEC_DEVICE_STATUS_NOT_PRESENT);
+ if (bUpdateDeviceStatus)
+ destDevice->SetDeviceStatus(bReturn ? CEC_DEVICE_STATUS_PRESENT : CEC_DEVICE_STATUS_NOT_PRESENT);
MarkReady();
return bReturn;
virtual cec_bus_device_status GetStatus(bool bForcePoll = false, bool bSuppressPoll = false);
virtual void SetDeviceStatus(const cec_bus_device_status newStatus, cec_version libCECSpecVersion = CEC_VERSION_1_4);
virtual void ResetDeviceStatus(void);
- virtual bool TransmitPoll(const cec_logical_address destination, bool bIsReply);
+ virtual bool TransmitPoll(const cec_logical_address destination, bool bUpdateDeviceStatus);
virtual void HandlePoll(const cec_logical_address destination);
virtual void HandlePollFrom(const cec_logical_address initiator);
virtual bool HandleReceiveFailed(void);
#define LIB_CEC m_busDevice->GetProcessor()->GetLib()
#define ToString(p) CCECTypeUtils::ToString(p)
+#define REQUEST_POWER_STATUS_TIMEOUT 5000
CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice,
int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */,
m_bHandlerInited(false),
m_bOPTSendDeckStatusUpdateOnActiveSource(false),
m_vendorId(CEC_VENDOR_UNKNOWN),
- m_iActiveSourcePending(iActiveSourcePending)
+ m_iActiveSourcePending(iActiveSourcePending),
+ m_iPowerStatusRequested(0)
{
}
cec_command command;
cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_IMAGE_VIEW_ON);
- return Transmit(command, false, false);
+ if (Transmit(command, false, false))
+ {
+ CCECBusDevice* dest = m_processor->GetDevice(iDestination);
+ if (dest && dest->GetCurrentPowerStatus() != CEC_POWER_STATUS_ON)
+ dest->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON);
+ return true;
+ }
+ return false;
}
bool CCECCommandHandler::TransmitStandby(const cec_logical_address iInitiator, const cec_logical_address iDestination)
bool CCECCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
{
+ if (iDestination == CECDEVICE_TV)
+ {
+ int64_t now(GetTimeMs());
+ if (now - m_iPowerStatusRequested < REQUEST_POWER_STATUS_TIMEOUT)
+ return true;
+ m_iPowerStatusRequested = now;
+ }
+
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting power status of '%s' (%X)", m_busDevice->GetLogicalAddressName(), iDestination);
+
cec_command command;
cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_POWER_STATUS);
{
if ((bReturn = m_processor->Transmit(command, bIsReply)) == true)
{
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "command transmitted");
+#endif
if (bExpectResponse)
{
bReturn = m_busDevice->WaitForOpcode(expectedResponse);
if (m_iActiveSourcePending == 0 || GetTimeMs() < m_iActiveSourcePending)
return false;
+#ifdef CEC_DEBUGGING
LIB_CEC->AddLog(CEC_LOG_DEBUG, "transmitting delayed activate source command");
+#endif
}
}
virtual bool SourceSwitchAllowed(void) { return true; }
- CCECBusDevice * m_busDevice;
- CCECProcessor * m_processor;
- int32_t m_iTransmitTimeout;
- int32_t m_iTransmitWait;
- int8_t m_iTransmitRetries;
- bool m_bHandlerInited;
- bool m_bOPTSendDeckStatusUpdateOnActiveSource;
- cec_vendor_id m_vendorId;
- int64_t m_iActiveSourcePending;
- PLATFORM::CMutex m_mutex;
+ CCECBusDevice * m_busDevice;
+ CCECProcessor * m_processor;
+ int32_t m_iTransmitTimeout;
+ int32_t m_iTransmitWait;
+ int8_t m_iTransmitRetries;
+ bool m_bHandlerInited;
+ bool m_bOPTSendDeckStatusUpdateOnActiveSource;
+ cec_vendor_id m_vendorId;
+ int64_t m_iActiveSourcePending;
+ PLATFORM::CMutex m_mutex;
+ int64_t m_iPowerStatusRequested;
};
};
#define VL_POWERED_DOWN 0x01
#define VL_UNKNOWN1 0x06
-#define VL_REQUEST_POWER_STATUS_TIMEOUT 5000
-
using namespace CEC;
using namespace PLATFORM;
int64_t iActiveSourcePending /* = 0 */) :
CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending),
m_iPowerUpEventReceived(0),
- m_bCapabilitiesSent(false),
- m_iPowerStatusRequested(0)
+ m_bCapabilitiesSent(false)
{
m_vendorId = CEC_VENDOR_PANASONIC;
}
{
CLockObject lock(m_mutex);
m_iPowerUpEventReceived = 0;
+ m_bCapabilitiesSent = false;
}
return CCECCommandHandler::HandleStandby(command);
void CVLCommandHandler::SendVendorCommandCapabilities(const cec_logical_address initiator, const cec_logical_address destination)
{
- cec_command response;
- cec_command::Format(response, initiator, destination, CEC_OPCODE_VENDOR_COMMAND);
- uint8_t iResponseData[] = {0x10, 0x02, 0xFF, 0xFF, 0x00, 0x05, 0x05, 0x45, 0x55, 0x5c, 0x58, 0x32};
- response.PushArray(12, iResponseData);
-
- if (Transmit(response, false, true))
+ if (PowerUpEventReceived())
{
- if (PowerUpEventReceived())
+ cec_command response;
+ cec_command::Format(response, initiator, destination, CEC_OPCODE_VENDOR_COMMAND);
+ uint8_t iResponseData[] = {0x10, 0x02, 0xFF, 0xFF, 0x00, 0x05, 0x05, 0x45, 0x55, 0x5c, 0x58, 0x32};
+ response.PushArray(12, iResponseData);
+
+ if (Transmit(response, false, true))
{
CLockObject lock(m_mutex);
m_bCapabilitiesSent = true;
return CEC_ABORT_REASON_INVALID_OPERAND;
}
-bool CVLCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
-{
- m_iPowerStatusRequested = GetTimeMs();
- return CCECCommandHandler::TransmitRequestPowerStatus(iInitiator, iDestination, bWaitForResponse);
-}
-
bool CVLCommandHandler::SourceSwitchAllowed(void)
{
- int64_t now(GetTimeMs());
- if (!PowerUpEventReceived() && now - m_iPowerStatusRequested > VL_REQUEST_POWER_STATUS_TIMEOUT)
+ if (!PowerUpEventReceived())
TransmitRequestPowerStatus(m_processor->GetPrimaryDevice()->GetLogicalAddress(), CECDEVICE_TV, false);
return PowerUpEventReceived();
bool PowerUpEventReceived(void);
bool SupportsDeviceType(const cec_device_type type) const { return type != CEC_DEVICE_TYPE_RECORDING_DEVICE; };
cec_device_type GetReplacementDeviceType(const cec_device_type type) const { return type == CEC_DEVICE_TYPE_RECORDING_DEVICE ? CEC_DEVICE_TYPE_PLAYBACK_DEVICE : type; }
- bool TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
bool SourceSwitchAllowed(void);
PLATFORM::CMutex m_mutex;
uint64_t m_iPowerUpEventReceived;
bool m_bCapabilitiesSent;
- int64_t m_iPowerStatusRequested;
};
};
using namespace std;
using namespace PLATFORM;
-#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_2_0_1;
+#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_2_0_2;
#include "../../include/cecloader.h"