-AC_INIT([libcec], 0:7:0)
+AC_INIT([libcec], 0:8:0)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
AC_PROG_CXX
if (!g_libCEC)
{
#if defined(__APPLE__)
- cout << "cannot find " << (strLib ? strLib : "libcec.dylib") << endl;
+ cout << "cannot find " << (strLib ? strLib : "libcec.dylib") << dlerror() << endl;
#else
- cout << "cannot find " << (strLib ? strLib : "libcec.so") << endl;
+ cout << "cannot find " << (strLib ? strLib : "libcec.so") << dlerror() << endl;
#endif
return NULL;
}
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "ANCommandHandler.h"
+#include "CECBusDevice.h"
+#include "CECProcessor.h"
+#include "util/StdString.h"
+
+using namespace CEC;
+
+CANCommandHandler::CANCommandHandler(CCECBusDevice *busDevice) :
+ CCECCommandHandler(busDevice)
+{
+}
+
+bool CANCommandHandler::HandleVendorRemoteButtonDown(const cec_command &command)
+{
+ if (command.parameters.size > 0)
+ {
+ m_busDevice->GetProcessor()->AddKey();
+
+ uint8_t iButton = 0;
+ switch (command.parameters[0])
+ {
+ case CEC_AN_USER_CONTROL_CODE_RETURN:
+ iButton = CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL;
+ break;
+ default:
+ break;
+ }
+
+ if (iButton > 0 && iButton <= CEC_USER_CONTROL_CODE_MAX)
+ {
+ CStdString strLog;
+ strLog.Format("key pressed: %1x", iButton);
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog);
+
+ m_busDevice->GetProcessor()->SetCurrentButton((cec_user_control_code) command.parameters[0]);
+ }
+ }
+
+ return true;
+}
+
+bool CANCommandHandler::HandleCommand(const cec_command &command)
+{
+ bool bHandled(true);
+ if (command.destination == m_busDevice->GetMyLogicalAddress())
+ {
+ switch(command.opcode)
+ {
+ case CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
+ HandleVendorRemoteButtonDown(command);
+ break;
+ case CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP:
+ HandleUserControlRelease(command);
+ break;
+ default:
+ bHandled = false;
+ break;
+ }
+ }
+ else if (command.destination == CECDEVICE_BROADCAST)
+ {
+ switch(command.opcode)
+ {
+ // TODO
+ default:
+ bHandled = false;
+ break;
+ }
+ }
+
+ if (!bHandled)
+ bHandled = CCECCommandHandler::HandleCommand(command);
+
+ return bHandled;
+}
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "CECCommandHandler.h"
+
+namespace CEC
+{
+ class CANCommandHandler : public CCECCommandHandler
+ {
+ public:
+ CANCommandHandler(CCECBusDevice *busDevice);
+ virtual ~CANCommandHandler(void) {};
+
+ virtual bool HandleCommand(const cec_command &command);
+
+ protected:
+ virtual bool HandleVendorRemoteButtonDown(const cec_command &command);
+ };
+};
--- /dev/null
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "CECBusDevice.h"
+#include "CECProcessor.h"
+#include "ANCommandHandler.h"
+#include "SLCommandHandler.h"
+
+using namespace CEC;
+
+CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogicalAddress, uint16_t iPhysicalAddress) :
+ m_iPhysicalAddress(iPhysicalAddress),
+ m_iLogicalAddress(iLogicalAddress),
+ m_processor(processor),
+ m_iVendorId(0),
+ m_iVendorClass(0)
+{
+ m_handler = new CCECCommandHandler(this);
+}
+
+CCECBusDevice::~CCECBusDevice(void)
+{
+ delete m_handler;
+}
+
+cec_logical_address CCECBusDevice::GetMyLogicalAddress(void) const
+{
+ return m_processor->GetLogicalAddress();
+}
+
+uint16_t CCECBusDevice::GetMyPhysicalAddress(void) const
+{
+ return m_processor->GetPhysicalAddress();
+}
+
+void CCECBusDevice::AddLog(cec_log_level level, const CStdString &strMessage)
+{
+ m_processor->AddLog(level, strMessage);
+}
+
+void CCECBusDevice::SetVendorId(uint16_t iVendorId, uint8_t iVendorClass /* = 0 */)
+{
+ delete m_handler;
+ m_iVendorId = iVendorId;
+ m_iVendorClass = iVendorClass;
+
+ switch (iVendorId)
+ {
+ case CEC_VENDOR_SAMSUNG:
+ m_handler = new CANCommandHandler(this);
+ break;
+ case CEC_VENDOR_LG:
+ m_handler = new CSLCommandHandler(this);
+ break;
+ default:
+ m_handler = new CCECCommandHandler(this);
+ break;
+ }
+
+ CStdString strLog;
+ strLog.Format("device %d: vendor = %s (%04x) class = %2x", m_iLogicalAddress, CECVendorIdToString(iVendorId), iVendorId, iVendorClass);
+ m_processor->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+}
+
+bool CCECBusDevice::HandleCommand(const cec_command &command)
+{
+ CLockObject lock(&m_mutex);
+ m_handler->HandleCommand(command);
+ return true;
+}
+
+const char *CCECBusDevice::CECVendorIdToString(const uint64_t iVendorId)
+{
+ switch (iVendorId)
+ {
+ case CEC_VENDOR_SAMSUNG:
+ return "Samsung";
+ case CEC_VENDOR_LG:
+ return "LG";
+ default:
+ return "Unknown";
+ }
+}
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "CECCommandHandler.h"
+#include "platform/threads.h"
+#include "util/StdString.h"
+
+namespace CEC
+{
+ class CCECProcessor;
+
+ class CCECBusDevice
+ {
+ public:
+ CCECBusDevice(CCECProcessor *processor, cec_logical_address address, uint16_t iPhysicalAddress = 0);
+ virtual ~CCECBusDevice(void);
+
+ virtual cec_logical_address GetLogicalAddress(void) const { return m_iLogicalAddress; }
+ virtual uint16_t GetPhysicalAddress(void) const { return m_iPhysicalAddress; }
+
+ virtual cec_logical_address GetMyLogicalAddress(void) const;
+ virtual uint16_t GetMyPhysicalAddress(void) const;
+
+ virtual void SetVendorId(uint16_t iVendorId, uint8_t iVendorClass = 0);
+ virtual bool HandleCommand(const cec_command &command);
+
+ virtual void AddLog(cec_log_level level, const CStdString &strMessage);
+ virtual CCECProcessor *GetProcessor() const { return m_processor; }
+ virtual CCECCommandHandler *GetHandler(void) const { return m_handler; };
+
+ static const char *CECVendorIdToString(const uint64_t iVendorId);
+
+ protected:
+ uint16_t m_iPhysicalAddress;
+ cec_logical_address m_iLogicalAddress;
+ CCECProcessor *m_processor;
+ CCECCommandHandler *m_handler;
+ uint64_t m_iVendorId;
+ uint8_t m_iVendorClass;
+ CMutex m_mutex;
+ };
+};
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "CECCommandHandler.h"
+#include "CECBusDevice.h"
+#include "CECProcessor.h"
+
+using namespace CEC;
+
+CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice)
+{
+ m_busDevice = busDevice;
+}
+
+bool CCECCommandHandler::HandleCommand(const cec_command &command)
+{
+ bool bHandled(true);
+
+ if (command.destination == m_busDevice->GetMyLogicalAddress())
+ {
+ switch(command.opcode)
+ {
+ case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
+ HandleGivePhysicalAddress(command);
+ break;
+ case CEC_OPCODE_GIVE_OSD_NAME:
+ HandleGiveOSDName(command);
+ break;
+ case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
+ HandleGiveDeviceVendorId(command);
+ break;
+ case CEC_OPCODE_DEVICE_VENDOR_ID:
+ HandleDeviceVendorId(command);
+ break;
+ case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
+ HandleDeviceVendorCommandWithId(command);
+ break;
+ case CEC_OPCODE_GIVE_DECK_STATUS:
+ HandleGiveDeckStatus(command);
+ break;
+ case CEC_OPCODE_MENU_REQUEST:
+ HandleMenuRequest(command);
+ break;
+ case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
+ HandleGiveDevicePowerStatus(command);
+ break;
+ case CEC_OPCODE_GET_CEC_VERSION:
+ HandleGetCecVersion(command);
+ break;
+ case CEC_OPCODE_USER_CONTROL_PRESSED:
+ HandleUserControlPressed(command);
+ break;
+ case CEC_OPCODE_USER_CONTROL_RELEASE:
+ HandleUserControlRelease(command);
+ break;
+ default:
+ UnhandledCommand(command);
+ bHandled = false;
+ break;
+ }
+ }
+ else if (command.destination == CECDEVICE_BROADCAST)
+ {
+ CStdString strLog;
+ switch (command.opcode)
+ {
+ case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
+ HandleRequestActiveSource(command);
+ break;
+ case CEC_OPCODE_SET_STREAM_PATH:
+ HandleSetStreamPath(command);
+ break;
+ case CEC_OPCODE_ROUTING_CHANGE:
+ HandleRoutingChange(command);
+ break;
+ case CEC_OPCODE_DEVICE_VENDOR_ID:
+ HandleDeviceVendorId(command);
+ break;
+ case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
+ HandleDeviceVendorCommandWithId(command);
+ break;
+ default:
+ UnhandledCommand(command);
+ bHandled = false;
+ break;
+ }
+ }
+ else
+ {
+ CStdString strLog;
+ strLog.Format("ignoring frame: destination: %u != %u", command.destination, (uint8_t)m_busDevice->GetMyLogicalAddress());
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+ bHandled = false;
+ }
+
+ return bHandled;
+}
+
+bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters);
+ return true;
+}
+
+bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ReportCECVersion(command.initiator);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command)
+{
+ // need to support opcodes play and deck control before doing anything with this
+ m_busDevice->GetProcessor()->TransmitAbort(command.initiator, CEC_OPCODE_GIVE_DECK_STATUS);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ReportPowerState(command.initiator);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ReportVendorID(command.initiator);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGiveOSDName(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ReportOSDName(command.initiator);
+ return true;
+}
+
+bool CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->ReportPhysicalAddress();
+ return true;
+}
+
+bool CCECCommandHandler::HandleMenuRequest(const cec_command &command)
+{
+ if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY)
+ m_busDevice->GetProcessor()->ReportMenuState(command.initiator);
+ return true;
+}
+
+bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command)
+{
+ CStdString strLog;
+ strLog.Format(">> %i requests active source", (uint8_t) command.initiator);
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+ m_busDevice->GetProcessor()->BroadcastActiveSource();
+ return true;
+}
+
+bool 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]);
+ CStdString strLog;
+ strLog.Format(">> %i changed physical address from %04x to %04x", command.initiator, iOldAddress, iNewAddress);
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+
+ m_busDevice->GetProcessor()->AddCommand(command);
+ }
+ return true;
+}
+
+bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
+{
+ if (command.parameters.size >= 2)
+ {
+ int streamaddr = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
+ CStdString strLog;
+ strLog.Format(">> %i requests stream path from physical address %04x", command.initiator, streamaddr);
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+ if (streamaddr == m_busDevice->GetMyPhysicalAddress())
+ m_busDevice->GetProcessor()->BroadcastActiveSource();
+ }
+ return true;
+}
+
+bool CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
+{
+ if (command.parameters.size > 0)
+ {
+ m_busDevice->GetProcessor()->AddKey();
+
+ if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX)
+ {
+ CStdString strLog;
+ strLog.Format("key pressed: %1x", command.parameters[0]);
+ m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+
+ m_busDevice->GetProcessor()->SetCurrentButton((cec_user_control_code) command.parameters[0]);
+ }
+ }
+ return true;
+}
+
+bool CCECCommandHandler::HandleUserControlRelease(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->AddKey();
+ return true;
+}
+
+void CCECCommandHandler::UnhandledCommand(const cec_command &command)
+{
+ m_busDevice->GetProcessor()->AddCommand(command);;
+}
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include <cectypes.h>
+
+namespace CEC
+{
+ class CCECBusDevice;
+
+ class CCECCommandHandler
+ {
+ public:
+ CCECCommandHandler(CCECBusDevice *busDevice);
+ virtual ~CCECCommandHandler(void) {};
+
+ virtual bool HandleCommand(const cec_command &command);
+
+ protected:
+ bool HandleDeviceVendorCommandWithId(const cec_command &command);
+ bool HandleDeviceVendorId(const cec_command &command);
+ bool HandleGetCecVersion(const cec_command &command);
+ bool HandleGiveDeckStatus(const cec_command &command);
+ bool HandleGiveDevicePowerStatus(const cec_command &command);
+ bool HandleGiveDeviceVendorId(const cec_command &command);
+ bool HandleGiveOSDName(const cec_command &command);
+ bool HandleGivePhysicalAddress(const cec_command &command);
+ bool HandleMenuRequest(const cec_command &command);
+ bool HandleRequestActiveSource(const cec_command &command);
+ bool HandleRoutingChange(const cec_command &command);
+ bool HandleSetStreamPath(const cec_command &command);
+ bool HandleUserControlPressed(const cec_command &command);
+ bool HandleUserControlRelease(const cec_command &command);
+ void UnhandledCommand(const cec_command &command);
+
+ CCECBusDevice *m_busDevice;
+ };
+};
#include "CECProcessor.h"
#include "AdapterCommunication.h"
+#include "CECBusDevice.h"
#include "LibCEC.h"
#include "util/StdString.h"
#include "platform/timeutils.h"
m_controller(controller),
m_bMonitor(false)
{
- for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
- m_vendorIds[iPtr] = CEC_VENDOR_UNKNOWN;
- for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
- m_vendorClasses[iPtr] = (uint8_t) 0;
+ for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+ m_busDevices[iPtr] = new CCECBusDevice(this, (cec_logical_address) iPtr, 0);
}
CCECProcessor::~CCECProcessor(void)
StopThread();
m_communication = NULL;
m_controller = NULL;
+ delete[] m_busDevices;
}
bool CCECProcessor::Start(void)
((uint64_t)data[1] << 2) +
(uint64_t)data[2];
- m_vendorIds[(uint8_t)device] = iVendorId;
- m_vendorClasses[(uint8_t)device] = data.size >= 4 ? data[3] : 0;
-
- CStdString strLog;
- strLog.Format("device %d: vendor = %s (%04x) class = %2x", (uint8_t)device, CECVendorIdToString(m_vendorIds[(uint8_t)device]), iVendorId, m_vendorClasses[(uint8_t)device]);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
+ m_busDevices[(uint8_t)device]->SetVendorId(iVendorId, data.size >= 4 ? data[3] : 0);
}
-bool CCECProcessor::HandleANCommand(cec_command &command)
+void CCECProcessor::ParseCommand(cec_command &command)
{
- bool bHandled(true);
- if (command.destination == m_iLogicalAddress)
- {
- switch(command.opcode)
- {
- case CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
- if (command.parameters.size > 0)
- {
- m_controller->AddKey();
-
- uint8_t iButton = 0;
- switch (command.parameters[0])
- {
- case CEC_AN_USER_CONTROL_CODE_RETURN:
- iButton = CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL;
- break;
- default:
- break;
- }
-
- if (iButton > 0 && iButton <= CEC_USER_CONTROL_CODE_MAX)
- {
- CStdString strLog;
- strLog.Format("key pressed: %1x", iButton);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
-
- m_controller->SetCurrentButton((cec_user_control_code) command.parameters[0]);
- }
- }
- break;
- case CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP:
- m_controller->AddKey();
- break;
- default:
- bHandled = false;
- break;
- }
- }
- else if (command.destination == CECDEVICE_BROADCAST)
- {
- switch(command.opcode)
- {
- // TODO
- default:
- bHandled = false;
- break;
- }
- }
-
- if (!bHandled)
- bHandled = HandleCecCommand(command);
+ CStdString dataStr;
+ dataStr.Format(">> received frame: %1x%1x:%02x", command.initiator, command.destination, command.opcode);
+ for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
+ dataStr.AppendFormat(":%02x", (unsigned int)command.parameters[iPtr]);
+ m_controller->AddLog(CEC_LOG_DEBUG, dataStr.c_str());
- return bHandled;
+ if (!m_bMonitor)
+ m_busDevices[(uint8_t)command.initiator]->HandleCommand(command);
}
-bool CCECProcessor::HandleSLCommand(cec_command &command)
+void CCECProcessor::SetCurrentButton(cec_user_control_code iButtonCode)
{
- bool bHandled(true);
- if (command.destination == m_iLogicalAddress)
- {
- switch(command.opcode)
- {
- // TODO
- default:
- bHandled = false;
- break;
- }
- }
- else if (command.destination == CECDEVICE_BROADCAST)
- {
- switch(command.opcode)
- {
- // TODO
- default:
- bHandled = false;
- break;
- }
- }
-
- if (!bHandled)
- bHandled = HandleCecCommand(command);
-
- return bHandled;
+ m_controller->SetCurrentButton(iButtonCode);
}
-bool CCECProcessor::HandleCecCommand(cec_command &command)
+void CCECProcessor::AddCommand(const cec_command &command)
{
- bool bHandled(true);
-
- if (command.destination == m_iLogicalAddress)
- {
- switch(command.opcode)
- {
- case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
- ReportPhysicalAddress();
- break;
- case CEC_OPCODE_GIVE_OSD_NAME:
- ReportOSDName(command.initiator);
- break;
- case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
- ReportVendorID(command.initiator);
- break;
- case CEC_OPCODE_DEVICE_VENDOR_ID:
- case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
- ParseVendorId(command.initiator, command.parameters);
- break;
- case CEC_OPCODE_GIVE_DECK_STATUS:
- // need to support opcodes play and deck control before doing anything with this
- TransmitAbort(command.initiator, CEC_OPCODE_GIVE_DECK_STATUS);
- break;
- case CEC_OPCODE_MENU_REQUEST:
- if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY)
- ReportMenuState(command.initiator);
- break;
- case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
- ReportPowerState(command.initiator);
- break;
- case CEC_OPCODE_GET_CEC_VERSION:
- ReportCECVersion(command.initiator);
- break;
- case CEC_OPCODE_USER_CONTROL_PRESSED:
- if (command.parameters.size > 0)
- {
- m_controller->AddKey();
-
- if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX)
- {
- CStdString strLog;
- strLog.Format("key pressed: %1x", command.parameters[0]);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
-
- m_controller->SetCurrentButton((cec_user_control_code) command.parameters[0]);
- }
- }
- break;
- case CEC_OPCODE_USER_CONTROL_RELEASE:
- m_controller->AddKey();
- break;
- default:
- m_controller->AddCommand(command);
- bHandled = false;
- break;
- }
- }
- else if (command.destination == CECDEVICE_BROADCAST)
- {
- CStdString strLog;
- switch (command.opcode)
- {
- case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
- strLog.Format(">> %i requests active source", (uint8_t) command.initiator);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
- BroadcastActiveSource();
- break;
- case CEC_OPCODE_SET_STREAM_PATH:
- if (command.parameters.size >= 2)
- {
- int streamaddr = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
- strLog.Format(">> %i requests stream path from physical address %04x", command.initiator, streamaddr);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
- if (streamaddr == m_iPhysicalAddress)
- BroadcastActiveSource();
- }
- break;
- case CEC_OPCODE_ROUTING_CHANGE:
- 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]);
- strLog.Format(">> %i changed physical address from %04x to %04x", command.initiator, iOldAddress, iNewAddress);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
-
- m_controller->AddCommand(command);
- }
- break;
- case CEC_OPCODE_DEVICE_VENDOR_ID:
- case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
- ParseVendorId(command.initiator, command.parameters);
- break;
- default:
- m_controller->AddCommand(command);
- bHandled = false;
- break;
- }
- }
- else
- {
- CStdString strLog;
- strLog.Format("ignoring frame: destination: %u != %u", command.destination, (uint8_t)m_iLogicalAddress);
- m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
- bHandled = false;
- }
-
- return bHandled;
+ m_controller->AddCommand(command);
}
-void CCECProcessor::ParseCommand(cec_command &command)
+void CCECProcessor::AddKey(void)
{
- CStdString dataStr;
- dataStr.Format(">> received frame: %1x%1x:%02x", command.initiator, command.destination, command.opcode);
- for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
- dataStr.AppendFormat(":%02x", (unsigned int)command.parameters[iPtr]);
- m_controller->AddLog(CEC_LOG_DEBUG, dataStr.c_str());
-
- if (!m_bMonitor)
- {
- switch(m_vendorIds[command.initiator])
- {
- case CEC_VENDOR_LG:
- HandleSLCommand(command);
- break;
- case CEC_VENDOR_SAMSUNG:
- HandleANCommand(command);
- break;
- default:
- HandleCecCommand(command);
- break;
- }
- }
+ m_controller->AddKey();
}
-const char *CCECProcessor::CECVendorIdToString(const uint64_t iVendorId)
+void CCECProcessor::AddLog(cec_log_level level, const CStdString &strMessage)
{
- switch (iVendorId)
- {
- case CEC_VENDOR_SAMSUNG:
- return "Samsung";
- case CEC_VENDOR_LG:
- return "LG";
- default:
- return "Unknown";
- }
+ m_controller->AddLog(level, strMessage);
}
#include <cectypes.h>
#include "platform/threads.h"
#include "util/buffer.h"
+#include "util/StdString.h"
class CSerialPort;
{
class CLibCEC;
class CAdapterCommunication;
+ class CCECBusDevice;
class CCECProcessor : public CThread
{
virtual bool SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage);
virtual bool SwitchMonitoring(bool bEnable);
- static const char *CECVendorIdToString(const uint64_t iVendorId);
+ virtual cec_logical_address GetLogicalAddress(void) const { return m_iLogicalAddress; }
+ virtual uint16_t GetPhysicalAddress(void) const { return m_iPhysicalAddress; }
+
+ virtual void SetCurrentButton(cec_user_control_code iButtonCode);
+ virtual void AddCommand(const cec_command &command);
+ virtual void AddKey(void);
+ virtual void AddLog(cec_log_level level, const CStdString &strMessage);
- protected:
virtual bool TransmitFormatted(const cec_adapter_message &data, bool bWaitForAck = true);
virtual void TransmitAbort(cec_logical_address address, cec_opcode opcode, ECecAbortReason reason = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE);
virtual void ReportCECVersion(cec_logical_address address = CECDEVICE_TV);
virtual void ReportOSDName(cec_logical_address address = CECDEVICE_TV);
virtual void ReportPhysicalAddress(void);
virtual void BroadcastActiveSource(void);
- virtual bool HandleANCommand(cec_command &command);
- virtual bool HandleSLCommand(cec_command &command);
- virtual bool HandleCecCommand(cec_command &command);
+ virtual void ParseVendorId(cec_logical_address device, const cec_datapacket &data);
private:
void LogOutput(const cec_command &data);
bool WaitForAck(bool *bError, uint32_t iTimeout = 1000);
void ParseMessage(cec_adapter_message &msg, bool *bError, bool *bTransmitSucceeded, bool *bEom, bool bProcessMessages = true);
void ParseCommand(cec_command &command);
- void ParseVendorId(cec_logical_address device, const cec_datapacket &data);
cec_command m_currentframe;
uint16_t m_iPhysicalAddress;
CMutex m_mutex;
CAdapterCommunication *m_communication;
CLibCEC *m_controller;
- uint64_t m_vendorIds[16];
- uint8_t m_vendorClasses[16];
+ CCECBusDevice *m_busDevices[16];
bool m_bMonitor;
};
};
}
}
-void CLibCEC::AddCommand(cec_command &command)
+void CLibCEC::AddCommand(const cec_command &command)
{
if (m_commandBuffer.Push(command))
{
virtual void AddLog(cec_log_level level, const std::string &strMessage);
virtual void AddKey(void);
- virtual void AddCommand(cec_command &command);
+ virtual void AddCommand(const cec_command &command);
virtual void CheckKeypressTimeout(void);
virtual void SetCurrentButton(cec_user_control_code iButtonCode);
AdapterCommunication.h \
AdapterDetection.cpp \
AdapterDetection.h \
+ ANCommandHandler.cpp \
+ ANCommandHandler.h \
+ CECBusDevice.cpp \
+ CECBusDevice.h \
+ CECCommandHandler.cpp \
+ CECCommandHandler.h \
CECProcessor.cpp \
CECProcessor.h \
LibCEC.cpp \
LibCEC.h \
LibCECC.cpp \
+ SLCommandHandler.cpp \
+ SLCommandHandler.h \
util/StdString.h \
platform/timeutils.h \
platform/baudrate.h \
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "SLCommandHandler.h"
+
+using namespace CEC;
+
+CSLCommandHandler::CSLCommandHandler(CCECBusDevice *busDevice) :
+ CCECCommandHandler(busDevice)
+{
+}
--- /dev/null
+#pragma once
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing <license@pulse-eight.com>
+ * http://www.pulse-eight.com/
+ * http://www.pulse-eight.net/
+ */
+
+#include "CECCommandHandler.h"
+
+namespace CEC
+{
+ class CSLCommandHandler : public CCECCommandHandler
+ {
+ public:
+ CSLCommandHandler(CCECBusDevice *busDevice);
+ virtual ~CSLCommandHandler(void) {};
+ };
+};