#include "CECCommandHandler.h"
#include "../devices/CECBusDevice.h"
#include "../devices/CECAudioSystem.h"
+#include "../devices/CECPlaybackDevice.h"
#include "../CECProcessor.h"
using namespace CEC;
+using namespace std;
CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice)
{
bool bHandled(true);
CStdString strLog;
- strLog.Format(">> %x -> %x: %s (%2x)", command.initiator, command.destination, ToString(command.opcode), command.opcode);
+ strLog.Format(">> %s (%X) -> %s (%X): %s (%2X)", ToString(command.initiator), command.initiator, ToString(command.destination), command.destination, ToString(command.opcode), command.opcode);
m_busDevice->AddLog(CEC_LOG_NOTICE, strLog);
if (m_busDevice->MyLogicalAddressContains(command.destination))
break;
case CEC_OPCODE_SET_MENU_LANGUAGE:
HandleSetMenuLanguage(command);
+ /* pass to listeners */
m_busDevice->GetProcessor()->AddCommand(command);
break;
case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
break;
default:
UnhandledCommand(command);
+ /* pass to listeners */
m_busDevice->GetProcessor()->AddCommand(command);
bHandled = false;
break;
{
case CEC_OPCODE_SET_MENU_LANGUAGE:
HandleSetMenuLanguage(command);
+ /* pass to listeners */
m_busDevice->GetProcessor()->AddCommand(command);
break;
case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
break;
case CEC_OPCODE_SET_STREAM_PATH:
HandleSetStreamPath(command);
- m_busDevice->GetProcessor()->AddCommand(command);
break;
case CEC_OPCODE_ROUTING_CHANGE:
HandleRoutingChange(command);
- m_busDevice->GetProcessor()->AddCommand(command);
break;
case CEC_OPCODE_DEVICE_VENDOR_ID:
HandleDeviceVendorId(command);
case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
HandleDeviceVendorCommandWithId(command);
break;
+ case CEC_OPCODE_STANDBY:
+ HandleStandby(command);
+ /* pass to listeners */
+ m_busDevice->GetProcessor()->AddCommand(command);
+ break;
+ case CEC_OPCODE_ACTIVE_SOURCE:
+ HandleActiveSource(command);
+ /* pass to listeners */
+ m_busDevice->GetProcessor()->AddCommand(command);
+ break;
default:
UnhandledCommand(command);
+ /* pass to listeners */
m_busDevice->GetProcessor()->AddCommand(command);
bHandled = false;
break;
return bHandled;
}
+bool CCECCommandHandler::HandleActiveSource(const cec_command &command)
+{
+ if (command.parameters.size == 2)
+ {
+ uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
+ return m_busDevice->GetProcessor()->SetStreamPath(iAddress);
+ }
+
+ return true;
+}
+
bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command)
{
if (command.parameters.size == 1)
bool CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command)
{
CCECBusDevice *device = GetDevice(command.destination);
- if (device)
- return device->TransmitDeckStatus(command.initiator);
+ if (device && device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE)
+ return ((CCECPlaybackDevice *) device)->TransmitDeckStatus(command.initiator);
return false;
}
CStdString strLog;
strLog.Format(">> %i requests active source", (uint8_t) command.initiator);
m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
- CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetMyLogicalAddress()];
- if (device)
- return device->TransmitActiveSource();
- return false;
+
+ vector<CCECBusDevice *> devices;
+ for (int iDevicePtr = (int)GetMyDevices(devices)-1; iDevicePtr >=0; iDevicePtr--)
+ devices[iDevicePtr]->TransmitActiveSource();
+ return true;
}
bool CCECCommandHandler::HandleRoutingChange(const cec_command &command)
return true;
}
+bool CCECCommandHandler::HandleStandby(const cec_command &command)
+{
+ CCECBusDevice *device = GetDevice(command.initiator);
+ if (device)
+ device->SetPowerStatus(CEC_POWER_STATUS_STANDBY);
+ return true;
+}
+
bool CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &command)
{
CCECBusDevice *device = GetDevice(command.destination);
m_busDevice->AddLog(CEC_LOG_DEBUG, strLog);
}
+unsigned int CCECCommandHandler::GetMyDevices(vector<CCECBusDevice *> &devices) const
+{
+ unsigned int iReturn(0);
+
+ cec_logical_addresses addresses = m_busDevice->GetProcessor()->GetLogicalAddresses();
+ for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
+ {
+ if (addresses[iPtr])
+ {
+ devices.push_back(GetDevice((cec_logical_address) iPtr));
+ ++iReturn;
+ }
+ }
+
+ return iReturn;
+}
+
CCECBusDevice *CCECCommandHandler::GetDevice(cec_logical_address iLogicalAddress) const
{
CCECBusDevice *device = NULL;
CCECBusDevice *CCECCommandHandler::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress) const
{
- CCECBusDevice *device = NULL;
-
- for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
- {
- if (m_busDevice->GetProcessor()->m_busDevices[iPtr]->GetPhysicalAddress() == iPhysicalAddress)
- {
- device = m_busDevice->GetProcessor()->m_busDevices[iPtr];
- break;
- }
- }
-
- return device;
+ return m_busDevice->GetProcessor()->GetDeviceByPhysicalAddress(iPhysicalAddress);
}
void CCECCommandHandler::SetVendorId(const cec_command &command)
device->SetVendorId(iVendorId, command.parameters.size > 3 ? command.parameters[3] : 0);
}
+const char *CCECCommandHandler::ToString(const cec_logical_address address)
+{
+ switch(address)
+ {
+ case CECDEVICE_AUDIOSYSTEM:
+ return "Audio";
+ case CECDEVICE_BROADCAST:
+ return "Broadcast";
+ case CECDEVICE_FREEUSE:
+ return "Free use";
+ case CECDEVICE_PLAYBACKDEVICE1:
+ return "Playback 1";
+ case CECDEVICE_PLAYBACKDEVICE2:
+ return "Playback 2";
+ case CECDEVICE_PLAYBACKDEVICE3:
+ return "Playback 3";
+ case CECDEVICE_RECORDINGDEVICE1:
+ return "Recorder 1";
+ case CECDEVICE_RECORDINGDEVICE2:
+ return "Recorder 2";
+ case CECDEVICE_RECORDINGDEVICE3:
+ return "Recorder 3";
+ case CECDEVICE_RESERVED1:
+ return "Reserved 1";
+ case CECDEVICE_RESERVED2:
+ return "Reserved 2";
+ case CECDEVICE_TUNER1:
+ return "Tuner 1";
+ case CECDEVICE_TUNER2:
+ return "Tuner 2";
+ case CECDEVICE_TUNER3:
+ return "Tuner 3";
+ case CECDEVICE_TUNER4:
+ return "Tuner 4";
+ case CECDEVICE_TV:
+ return "TV";
+ default:
+ return "unknown";
+ }
+}
+
+const char *CCECCommandHandler::ToString(const cec_deck_info status)
+{
+ switch (status)
+ {
+ case CEC_DECK_INFO_PLAY:
+ return "play";
+ case CEC_DECK_INFO_RECORD:
+ return "record";
+ case CEC_DECK_INFO_PLAY_REVERSE:
+ return "play reverse";
+ case CEC_DECK_INFO_STILL:
+ return "still";
+ case CEC_DECK_INFO_SLOW:
+ return "slow";
+ case CEC_DECK_INFO_SLOW_REVERSE:
+ return "slow reverse";
+ case CEC_DECK_INFO_FAST_FORWARD:
+ return "fast forward";
+ case CEC_DECK_INFO_FAST_REVERSE:
+ return "fast reverse";
+ case CEC_DECK_INFO_NO_MEDIA:
+ return "no media";
+ case CEC_DECK_INFO_STOP:
+ return "stop";
+ case CEC_DECK_INFO_SKIP_FORWARD_WIND:
+ return "info skip forward wind";
+ case CEC_DECK_INFO_SKIP_REVERSE_REWIND:
+ return "info skip reverse rewind";
+ case CEC_DECK_INFO_INDEX_SEARCH_FORWARD:
+ return "info index search forward";
+ case CEC_DECK_INFO_INDEX_SEARCH_REVERSE:
+ return "info index search reverse";
+ case CEC_DECK_INFO_OTHER_STATUS:
+ return "other";
+ default:
+ return "unknown";
+ }
+}
+
const char *CCECCommandHandler::ToString(const cec_opcode opcode)
{
switch (opcode)