X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fimplementations%2FCECCommandHandler.cpp;h=3c3d84146cf96fc56b48da7c5b2e913542b0d6cd;hb=305500533ee1524692ceaf3cb5f38d24225c5920;hp=fd7d003cd09cbc34bc6967cacc2ac41bc09f1fc1;hpb=5e822b09216e0d3c070d01b83015265129cc8c89;p=deb_libcec.git diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index fd7d003..3c3d841 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -33,9 +33,11 @@ #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) { @@ -47,7 +49,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) 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)) @@ -62,6 +64,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) break; case CEC_OPCODE_SET_MENU_LANGUAGE: HandleSetMenuLanguage(command); + /* pass to listeners */ m_busDevice->GetProcessor()->AddCommand(command); break; case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: @@ -82,6 +85,11 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) case CEC_OPCODE_GIVE_DECK_STATUS: HandleGiveDeckStatus(command); break; + case CEC_OPCODE_DECK_CONTROL: + HandleDeckControl(command); + /* pass to listeners */ + m_busDevice->GetProcessor()->AddCommand(command); + break; case CEC_OPCODE_MENU_REQUEST: HandleMenuRequest(command); break; @@ -108,6 +116,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) break; default: UnhandledCommand(command); + /* pass to listeners */ m_busDevice->GetProcessor()->AddCommand(command); bHandled = false; break; @@ -120,6 +129,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) { case CEC_OPCODE_SET_MENU_LANGUAGE: HandleSetMenuLanguage(command); + /* pass to listeners */ m_busDevice->GetProcessor()->AddCommand(command); break; case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: @@ -127,11 +137,9 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) 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); @@ -139,8 +147,19 @@ bool CCECCommandHandler::HandleCommand(const cec_command &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; @@ -157,6 +176,29 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) 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::HandleDeckControl(const cec_command &command) +{ + CCECBusDevice *device = GetDevice(command.destination); + if (device && device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE && command.parameters.size > 0) + { + ((CCECPlaybackDevice *) device)->SetDeckControlMode((cec_deck_control_mode) command.parameters[0]); + return true; + } + + return false; +} + bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command) { if (command.parameters.size == 1) @@ -172,6 +214,7 @@ bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command) bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command) { SetVendorId(command); + m_busDevice->GetProcessor()->TransmitAbort(command.initiator, command.opcode, CEC_ABORT_REASON_REFUSED); return true; } @@ -202,8 +245,8 @@ bool CCECCommandHandler::HandleGiveAudioStatus(const cec_command &command) 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; } @@ -271,10 +314,12 @@ 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()); - CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetMyLogicalAddress()]; - if (device) - return device->TransmitActiveSource(); - return false; + + vector devices; + for (int iDevicePtr = (int)GetMyDevices(devices)-1; iDevicePtr >=0; iDevicePtr--) + devices[iDevicePtr]->TransmitActiveSource(); + + return true; } bool CCECCommandHandler::HandleRoutingChange(const cec_command &command) @@ -313,13 +358,21 @@ 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]); + uint16_t iStreamAddress = ((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); + strLog.Format(">> %i sets stream path to physical address %04x", command.initiator, iStreamAddress); m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str()); - CCECBusDevice *device = GetDeviceByPhysicalAddress(streamaddr); - if (device) - return device->TransmitActiveSource(); + + if (m_busDevice->GetProcessor()->SetStreamPath(iStreamAddress)) + { + CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamAddress); + if (device) + { + return device->TransmitActiveSource() && + device->TransmitMenuState(command.initiator); + } + } + return false; } return true; } @@ -335,6 +388,14 @@ bool CCECCommandHandler::HandleSetSystemAudioModeRequest(const cec_command &comm 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); @@ -353,9 +414,17 @@ bool CCECCommandHandler::HandleUserControlPressed(const cec_command &command) if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX) { CStdString strLog; - strLog.Format("key pressed: %1x", command.parameters[0]); + strLog.Format("key pressed: %x", command.parameters[0]); m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str()); + if (command.parameters[0] == CEC_USER_CONTROL_CODE_POWER || + command.parameters[0] == CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + device->SetPowerStatus(CEC_POWER_STATUS_ON); + } + m_busDevice->GetProcessor()->SetCurrentButton((cec_user_control_code) command.parameters[0]); } } @@ -375,6 +444,23 @@ void CCECCommandHandler::UnhandledCommand(const cec_command &command) m_busDevice->AddLog(CEC_LOG_DEBUG, strLog); } +unsigned int CCECCommandHandler::GetMyDevices(vector &devices) const +{ + unsigned int iReturn(0); + + cec_logical_addresses addresses = m_busDevice->GetProcessor()->GetLogicalAddresses(); + for (uint8_t 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; @@ -387,18 +473,12 @@ CCECBusDevice *CCECCommandHandler::GetDevice(cec_logical_address iLogicalAddress 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 m_busDevice->GetProcessor()->GetDeviceByPhysicalAddress(iPhysicalAddress); +} - return device; +CCECBusDevice *CCECCommandHandler::GetDeviceByType(cec_device_type type) const +{ + return m_busDevice->GetProcessor()->GetDeviceByType(type); } void CCECCommandHandler::SetVendorId(const cec_command &command) @@ -409,13 +489,159 @@ void CCECCommandHandler::SetVendorId(const cec_command &command) return; } - uint64_t iVendorId = ((uint64_t)command.parameters[0] << 3) + - ((uint64_t)command.parameters[1] << 2) + + uint64_t iVendorId = ((uint64_t)command.parameters[0] << 16) + + ((uint64_t)command.parameters[1] << 8) + (uint64_t)command.parameters[2]; CCECBusDevice *device = GetDevice((cec_logical_address) command.initiator); if (device) - device->SetVendorId(iVendorId, command.parameters.size > 3 ? command.parameters[3] : 0); + device->SetVendorId(iVendorId); +} + +const char *CCECCommandHandler::ToString(const cec_menu_state state) +{ + switch (state) + { + case CEC_MENU_STATE_ACTIVATED: + return "activated"; + case CEC_MENU_STATE_DEACTIVATED: + return "deactivated"; + default: + return "unknown"; + } +} + +const char *CCECCommandHandler::ToString(const cec_version version) +{ + switch (version) + { + case CEC_VERSION_1_2: + return "1.2"; + case CEC_VERSION_1_2A: + return "1.2a"; + case CEC_VERSION_1_3: + return "1.3"; + case CEC_VERSION_1_3A: + return "1.3a"; + case CEC_VERSION_1_4: + return "1.4"; + default: + return "unknown"; + } +} + +const char *CCECCommandHandler::ToString(const cec_power_status status) +{ + switch (status) + { + case CEC_POWER_STATUS_ON: + return "on"; + case CEC_POWER_STATUS_STANDBY: + return "standby"; + case CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY: + return "in transition from on to standby"; + case CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON: + return "in transition from standby to on"; + default: + return "unknown"; + } +} + +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_control_mode mode) +{ + switch (mode) + { + case CEC_DECK_CONTROL_MODE_SKIP_FORWARD_WIND: + return "skip forward wind"; + case CEC_DECK_CONTROL_MODE_EJECT: + return "eject"; + case CEC_DECK_CONTROL_MODE_SKIP_REVERSE_REWIND: + return "reverse rewind"; + case CEC_DECK_CONTROL_MODE_STOP: + return "stop"; + 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) @@ -550,3 +776,39 @@ const char *CCECCommandHandler::ToString(const cec_opcode opcode) return "UNKNOWN"; } } + +const char *CCECCommandHandler::ToString(const cec_system_audio_status mode) +{ + switch(mode) + { + case CEC_SYSTEM_AUDIO_STATUS_ON: + return "on"; + case CEC_SYSTEM_AUDIO_STATUS_OFF: + return "off"; + default: + return "unknown"; + } +} + +const char *CCECCommandHandler::ToString(const cec_audio_status status) +{ + // TODO this is a mask + return "TODO"; +} + +const char *CCECCommandHandler::ToString(const cec_vendor_id vendor) +{ + switch (vendor) + { + case CEC_VENDOR_SAMSUNG: + return "Samsung"; + case CEC_VENDOR_LG: + return "LG"; + case CEC_VENDOR_PANASONIC: + return "Panasonic"; + case CEC_VENDOR_PIONEER: + return "Pioneer"; + default: + return "Unknown"; + } +}