X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fimplementations%2FCECCommandHandler.cpp;h=2db0c7232ba96301919baa8a675885753562ad77;hb=04437dcf953eb9bf3accaceb4dab0fe06d935264;hp=e30810c6671c7c564721c0906ed5db94630db0c1;hpb=e5e86c76b70975d8a8c03c58a230a70726399906;p=deb_libcec.git diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index e30810c..2db0c72 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) { @@ -46,6 +48,10 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) { bool bHandled(true); + CStdString strLog; + 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)) { switch(command.opcode) @@ -58,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: @@ -104,6 +111,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) break; default: UnhandledCommand(command); + /* pass to listeners */ m_busDevice->GetProcessor()->AddCommand(command); bHandled = false; break; @@ -116,6 +124,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: @@ -123,11 +132,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); @@ -135,8 +142,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; @@ -153,6 +171,17 @@ 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::HandleDeviceCecVersion(const cec_command &command) { if (command.parameters.size == 1) @@ -167,19 +196,13 @@ bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command) bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.initiator); - if (device) - device->SetVendorId(command.parameters); - + SetVendorId(command); return true; } bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.initiator); - if (device) - device->SetVendorId(command.parameters); - + SetVendorId(command); return true; } @@ -204,8 +227,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; } @@ -273,10 +296,11 @@ 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) @@ -288,7 +312,7 @@ bool CCECCommandHandler::HandleRoutingChange(const cec_command &command) CCECBusDevice *device = GetDevice(command.initiator); if (device) - device->SetPhysicalAddress(iNewAddress, iOldAddress); + device->SetStreamPath(iNewAddress, iOldAddress); } return true; } @@ -317,11 +341,10 @@ bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command) { 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); + strLog.Format(">> %i sets stream path to physical address %04x", command.initiator, streamaddr); m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str()); - CCECBusDevice *device = GetDeviceByPhysicalAddress(streamaddr); - if (device) - return device->TransmitActiveSource(); + + return m_busDevice->GetProcessor()->SetStreamPath(streamaddr); } return true; } @@ -337,6 +360,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); @@ -377,6 +408,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 (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; @@ -389,16 +437,235 @@ CCECBusDevice *CCECCommandHandler::GetDevice(cec_logical_address iLogicalAddress CCECBusDevice *CCECCommandHandler::GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress) const { - CCECBusDevice *device = NULL; + return m_busDevice->GetProcessor()->GetDeviceByPhysicalAddress(iPhysicalAddress); +} - for (unsigned int iPtr = 0; iPtr < 16; iPtr++) +void CCECCommandHandler::SetVendorId(const cec_command &command) +{ + if (command.parameters.size < 3) { - if (m_busDevice->GetProcessor()->m_busDevices[iPtr]->GetPhysicalAddress() == iPhysicalAddress) - { - device = m_busDevice->GetProcessor()->m_busDevices[iPtr]; - break; - } + m_busDevice->AddLog(CEC_LOG_WARNING, "invalid vendor ID received"); + return; } - return device; + 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); +} + +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) + { + case CEC_OPCODE_ACTIVE_SOURCE: + return "active source"; + case CEC_OPCODE_IMAGE_VIEW_ON: + return "image view on"; + case CEC_OPCODE_TEXT_VIEW_ON: + return "text view on"; + case CEC_OPCODE_INACTIVE_SOURCE: + return "inactive source"; + case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: + return "request active source"; + case CEC_OPCODE_ROUTING_CHANGE: + return "routing change"; + case CEC_OPCODE_ROUTING_INFORMATION: + return "routing information"; + case CEC_OPCODE_SET_STREAM_PATH: + return "set stream path"; + case CEC_OPCODE_STANDBY: + return "standby"; + case CEC_OPCODE_RECORD_OFF: + return "record off"; + case CEC_OPCODE_RECORD_ON: + return "record on"; + case CEC_OPCODE_RECORD_STATUS: + return "record status"; + case CEC_OPCODE_RECORD_TV_SCREEN: + return "record tv screen"; + case CEC_OPCODE_CLEAR_ANALOGUE_TIMER: + return "clear analogue timer"; + case CEC_OPCODE_CLEAR_DIGITAL_TIMER: + return "clear digital timer"; + case CEC_OPCODE_CLEAR_EXTERNAL_TIMER: + return "clear external timer"; + case CEC_OPCODE_SET_ANALOGUE_TIMER: + return "set analogue timer"; + case CEC_OPCODE_SET_DIGITAL_TIMER: + return "set digital timer"; + case CEC_OPCODE_SET_EXTERNAL_TIMER: + return "set external timer"; + case CEC_OPCODE_SET_TIMER_PROGRAM_TITLE: + return "set timer program title"; + case CEC_OPCODE_TIMER_CLEARED_STATUS: + return "timer cleared status"; + case CEC_OPCODE_TIMER_STATUS: + return "timer status"; + case CEC_OPCODE_CEC_VERSION: + return "cec version"; + case CEC_OPCODE_GET_CEC_VERSION: + return "get cec version"; + case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: + return "give physical address"; + case CEC_OPCODE_GET_MENU_LANGUAGE: + return "get menu language"; + case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS: + return "report physical address"; + case CEC_OPCODE_SET_MENU_LANGUAGE: + return "set menu language"; + case CEC_OPCODE_DECK_CONTROL: + return "deck control"; + case CEC_OPCODE_DECK_STATUS: + return "deck status"; + case CEC_OPCODE_GIVE_DECK_STATUS: + return "give deck status"; + case CEC_OPCODE_PLAY: + return "play"; + case CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS: + return "give tuner status"; + case CEC_OPCODE_SELECT_ANALOGUE_SERVICE: + return "select analogue service"; + case CEC_OPCODE_SELECT_DIGITAL_SERVICE: + return "set digital service"; + case CEC_OPCODE_TUNER_DEVICE_STATUS: + return "tuner device status"; + case CEC_OPCODE_TUNER_STEP_DECREMENT: + return "tuner step decrement"; + case CEC_OPCODE_TUNER_STEP_INCREMENT: + return "tuner step increment"; + case CEC_OPCODE_DEVICE_VENDOR_ID: + return "device vendor id"; + case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID: + return "give device vendor id"; + case CEC_OPCODE_VENDOR_COMMAND: + return "vendor command"; + case CEC_OPCODE_VENDOR_COMMAND_WITH_ID: + return "vendor command with id"; + case CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN: + return "vendor remote button down"; + case CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP: + return "vendor remote button up"; + case CEC_OPCODE_SET_OSD_STRING: + return "set osd string"; + case CEC_OPCODE_GIVE_OSD_NAME: + return "give osd name"; + case CEC_OPCODE_SET_OSD_NAME: + return "set osd name"; + case CEC_OPCODE_MENU_REQUEST: + return "menu request"; + case CEC_OPCODE_MENU_STATUS: + return "menu status"; + case CEC_OPCODE_USER_CONTROL_PRESSED: + return "user control pressed"; + case CEC_OPCODE_USER_CONTROL_RELEASE: + return "user control release"; + case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS: + return "give device power status"; + case CEC_OPCODE_REPORT_POWER_STATUS: + return "report power status"; + case CEC_OPCODE_FEATURE_ABORT: + return "feature abort"; + case CEC_OPCODE_ABORT: + return "abort"; + case CEC_OPCODE_GIVE_AUDIO_STATUS: + return "give audio status"; + case CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS: + return "give audio mode status"; + case CEC_OPCODE_REPORT_AUDIO_STATUS: + return "report audio status"; + case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE: + return "set system audio mode"; + case CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST: + return "system audio mode request"; + case CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS: + return "system audio mode status"; + case CEC_OPCODE_SET_AUDIO_RATE: + return "set audio rate"; + default: + return "UNKNOWN"; + } }