X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fimplementations%2FCECCommandHandler.cpp;h=122c4be1c51e2eaedbc681b9c5b2a163992e67c2;hb=181b347542a6ed9dc1f9ea7bca2051c72b49a9df;hp=951434722ca8d036c715b0dcdcbc4fb91bf98821;hpb=a04fbe344dee8f1ae56ad0a04d2f6ebab8f5ee24;p=deb_libcec.git diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 9514347..122c4be 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -31,7 +31,8 @@ */ #include "CECCommandHandler.h" -#include "../CECBusDevice.h" +#include "../devices/CECBusDevice.h" +#include "../devices/CECAudioSystem.h" #include "../CECProcessor.h" using namespace CEC; @@ -45,10 +46,20 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) { bool bHandled(true); - if (command.destination == m_busDevice->GetMyLogicalAddress()) + if (m_busDevice->MyLogicalAddressContains(command.destination)) { switch(command.opcode) { + case CEC_OPCODE_REPORT_POWER_STATUS: + HandleReportPowerStatus(command); + break; + case CEC_OPCODE_CEC_VERSION: + HandleDeviceCecVersion(command); + break; + case CEC_OPCODE_SET_MENU_LANGUAGE: + HandleSetMenuLanguage(command); + m_busDevice->GetProcessor()->AddCommand(command); + break; case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS: HandleGivePhysicalAddress(command); break; @@ -82,8 +93,18 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) case CEC_OPCODE_USER_CONTROL_RELEASE: HandleUserControlRelease(command); break; + case CEC_OPCODE_GIVE_AUDIO_STATUS: + HandleGiveAudioStatus(command); + break; + case CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS: + HandleGiveSystemAudioModeStatus(command); + break; + case CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST: + HandleSetSystemAudioModeRequest(command); + break; default: UnhandledCommand(command); + m_busDevice->GetProcessor()->AddCommand(command); bHandled = false; break; } @@ -93,14 +114,20 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) CStdString strLog; switch (command.opcode) { + case CEC_OPCODE_SET_MENU_LANGUAGE: + HandleSetMenuLanguage(command); + m_busDevice->GetProcessor()->AddCommand(command); + break; case CEC_OPCODE_REQUEST_ACTIVE_SOURCE: HandleRequestActiveSource(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); @@ -110,6 +137,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) break; default: UnhandledCommand(command); + m_busDevice->GetProcessor()->AddCommand(command); bHandled = false; break; } @@ -117,7 +145,7 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) else { CStdString strLog; - strLog.Format("ignoring frame: destination: %u != %u", command.destination, (uint8_t)m_busDevice->GetMyLogicalAddress()); + strLog.Format("ignoring frame: we're not at destination %x", command.destination); m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str()); bHandled = false; } @@ -125,59 +153,112 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) return bHandled; } +bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command) +{ + if (command.parameters.size == 1) + { + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + device->SetCecVersion((cec_version) command.parameters[0]); + } + + return true; +} + bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command) { - m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters); + SetVendorId(command); return true; } bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command) { - m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters); + SetVendorId(command); return true; } bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command) { - m_busDevice->GetProcessor()->ReportCECVersion(command.initiator); - return true; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitCECVersion(command.initiator); + + return false; +} + +bool CCECCommandHandler::HandleGiveAudioStatus(const cec_command &command) +{ + CCECBusDevice *device = GetDevice(command.destination); + if (device && device->GetType() == CEC_DEVICE_TYPE_AUDIO_SYSTEM) + return ((CCECAudioSystem *) device)->TransmitAudioStatus(command.initiator); + + return false; } 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; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitDeckStatus(command.initiator); + + return false; } bool CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) { - m_busDevice->GetProcessor()->ReportPowerState(command.initiator); - return true; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitPowerState(command.initiator); + + return false; } bool CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command) { - m_busDevice->GetProcessor()->ReportVendorID(command.initiator); - return true; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitVendorID(command.initiator); + + return false; } bool CCECCommandHandler::HandleGiveOSDName(const cec_command &command) { - m_busDevice->GetProcessor()->ReportOSDName(command.initiator); - return true; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitOSDName(command.initiator); + + return false; } bool CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command) { - m_busDevice->GetProcessor()->ReportPhysicalAddress(); - return true; + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitPhysicalAddress(); + + return false; } bool CCECCommandHandler::HandleMenuRequest(const cec_command &command) { if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY) - m_busDevice->GetProcessor()->ReportMenuState(command.initiator); + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitMenuState(command.initiator); + } + return false; +} + +bool CCECCommandHandler::HandleReportPowerStatus(const cec_command &command) +{ + if (command.parameters.size == 1) + { + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + device->SetPowerStatus((cec_power_status) command.parameters[0]); + } return true; } @@ -186,8 +267,10 @@ 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; + CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetMyLogicalAddress()]; + if (device) + return device->TransmitActiveSource(); + return false; } bool CCECCommandHandler::HandleRoutingChange(const cec_command &command) @@ -196,11 +279,28 @@ bool CCECCommandHandler::HandleRoutingChange(const cec_command &command) { 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); + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + device->SetStreamPath(iNewAddress, iOldAddress); + } + return true; +} + +bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command) +{ + if (command.parameters.size == 3) + { + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + { + cec_menu_language language; + language.device = command.initiator; + for (uint8_t iPtr = 0; iPtr < 4; iPtr++) + language.language[iPtr] = command.parameters[iPtr]; + language.language[3] = 0; + device->SetMenuLanguage(language); + } } return true; } @@ -213,12 +313,33 @@ bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command) 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(); + CCECBusDevice *device = GetDeviceByPhysicalAddress(streamaddr); + if (device) + return device->TransmitActiveSource(); } return true; } +bool CCECCommandHandler::HandleSetSystemAudioModeRequest(const cec_command &command) +{ + if (command.parameters.size >= 1) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device&& device->GetType() == CEC_DEVICE_TYPE_AUDIO_SYSTEM) + return ((CCECAudioSystem *) device)->SetSystemAudioMode(command); + } + return true; +} + +bool CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &command) +{ + CCECBusDevice *device = GetDevice(command.destination); + if (device && device->GetType() == CEC_DEVICE_TYPE_AUDIO_SYSTEM) + return ((CCECAudioSystem *) device)->TransmitSystemAudioModeStatus(command.initiator); + + return false; +} + bool CCECCommandHandler::HandleUserControlPressed(const cec_command &command) { if (command.parameters.size > 0) @@ -245,5 +366,51 @@ bool CCECCommandHandler::HandleUserControlRelease(const cec_command &command) void CCECCommandHandler::UnhandledCommand(const cec_command &command) { - m_busDevice->GetProcessor()->AddCommand(command);; + CStdString strLog; + strLog.Format("unhandled command with opcode %02x from address %d", command.opcode, command.initiator); + m_busDevice->AddLog(CEC_LOG_DEBUG, strLog); +} + +CCECBusDevice *CCECCommandHandler::GetDevice(cec_logical_address iLogicalAddress) const +{ + CCECBusDevice *device = NULL; + + if (iLogicalAddress >= CECDEVICE_TV && iLogicalAddress <= CECDEVICE_BROADCAST) + device = m_busDevice->GetProcessor()->m_busDevices[iLogicalAddress]; + + return device; +} + +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; +} + + +void CCECCommandHandler::SetVendorId(const cec_command &command) +{ + if (command.parameters.size < 3) + { + m_busDevice->AddLog(CEC_LOG_WARNING, "invalid vendor ID received"); + return; + } + + uint64_t iVendorId = ((uint64_t)command.parameters[0] << 3) + + ((uint64_t)command.parameters[1] << 2) + + (uint64_t)command.parameters[2]; + + CCECBusDevice *device = GetDevice((cec_logical_address) command.initiator); + if (device) + device->SetVendorId(iVendorId, iVendorId); }