X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fimplementations%2FCECCommandHandler.cpp;h=333b71b1ab12817d6927ff1ffbc4eae252717fd2;hb=678e227c17d6d0f015402dd53cc191570158395c;hp=2db0c7232ba96301919baa8a675885753562ad77;hpb=04437dcf953eb9bf3accaceb4dab0fe06d935264;p=deb_libcec.git diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 2db0c72..333b71b 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -52,122 +52,101 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command) 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) - { - 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); - /* pass to listeners */ - m_busDevice->GetProcessor()->AddCommand(command); - break; - 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; - 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); - /* pass to listeners */ - m_busDevice->GetProcessor()->AddCommand(command); - bHandled = false; - break; - } - } - else if (command.destination == CECDEVICE_BROADCAST) + switch(command.opcode) { - CStdString strLog; - switch (command.opcode) - { - case CEC_OPCODE_SET_MENU_LANGUAGE: - HandleSetMenuLanguage(command); - /* pass to listeners */ - m_busDevice->GetProcessor()->AddCommand(command); - break; - 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; - 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; - } - } - else - { - CStdString strLog; - strLog.Format("ignoring frame: we're not at destination %x", command.destination); - m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str()); + 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); + break; + 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_DECK_CONTROL: + HandleDeckControl(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; + 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; + 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_ROUTING_INFORMATION: + HandleRoutingInformation(command); + break; + case CEC_OPCODE_STANDBY: + HandleStandby(command); + break; + case CEC_OPCODE_ACTIVE_SOURCE: + HandleActiveSource(command); + break; + case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS: + HandleReportPhysicalAddress(command); + break; + case CEC_OPCODE_REPORT_AUDIO_STATUS: + HandleReportAudioStatus(command); + break; + case CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS: + HandleSystemAudioStatus(command); + break; + case CEC_OPCODE_SET_OSD_NAME: + HandleSetOSDName(command); + break; + default: + UnhandledCommand(command); bHandled = false; + break; } + if (command.destination == CECDEVICE_BROADCAST || m_busDevice->MyLogicalAddressContains(command.destination)) + m_busDevice->GetProcessor()->AddCommand(command); + return bHandled; } @@ -182,6 +161,18 @@ bool CCECCommandHandler::HandleActiveSource(const cec_command &command) return true; } +bool CCECCommandHandler::HandleDeckControl(const cec_command &command) +{ + CCECBusDevice *device = GetDevice(command.destination); + if (device && (device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE || device->GetType() == CEC_DEVICE_TYPE_RECORDING_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) @@ -196,7 +187,9 @@ bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command) bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command) { - SetVendorId(command); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + m_busDevice->GetProcessor()->TransmitAbort(command.initiator, command.opcode, CEC_ABORT_REASON_REFUSED); + return true; } @@ -208,78 +201,131 @@ bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command) bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitCECVersion(command.initiator); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + 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); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + 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) { - CCECBusDevice *device = GetDevice(command.destination); - if (device && device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE) - return ((CCECPlaybackDevice *) device)->TransmitDeckStatus(command.initiator); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device && (device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE || device->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)) + return ((CCECPlaybackDevice *) device)->TransmitDeckStatus(command.initiator); + } return false; } bool CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitPowerState(command.initiator); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitPowerState(command.initiator); + } return false; } bool CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitVendorID(command.initiator); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitVendorID(command.initiator); + } return false; } bool CCECCommandHandler::HandleGiveOSDName(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitOSDName(command.initiator); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitOSDName(command.initiator); + } return false; } bool CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitPhysicalAddress(); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + 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) + if (m_busDevice->MyLogicalAddressContains(command.destination)) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitMenuState(command.initiator); + if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY) + { + CCECBusDevice *device = GetDevice(command.destination); + if (device) + return device->TransmitMenuState(command.initiator); + } + } + + return false; +} + +bool CCECCommandHandler::HandleReportAudioStatus(const cec_command &command) +{ + if (command.parameters.size == 1) + { + CCECBusDevice *device = GetDevice(command.initiator); + if (device && device->GetType() == CEC_DEVICE_TYPE_AUDIO_SYSTEM) + { + ((CCECAudioSystem *)device)->SetAudioStatus(command.parameters[0]); + return true; + } } return false; } +bool CCECCommandHandler::HandleReportPhysicalAddress(const cec_command &command) +{ + if (command.parameters.size == 3) + { + uint16_t iNewAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]); + cec_device_type type = (cec_device_type)command.parameters[2]; + + CCECBusDevice *device = GetDevice(command.initiator); + if (device && device->GetType() == type) + device->SetPhysicalAddress(iNewAddress); + } + return true; +} + bool CCECCommandHandler::HandleReportPowerStatus(const cec_command &command) { if (command.parameters.size == 1) @@ -300,6 +346,7 @@ bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command) vector devices; for (int iDevicePtr = (int)GetMyDevices(devices)-1; iDevicePtr >=0; iDevicePtr--) devices[iDevicePtr]->TransmitActiveSource(); + return true; } @@ -317,6 +364,23 @@ bool CCECCommandHandler::HandleRoutingChange(const cec_command &command) return true; } +bool CCECCommandHandler::HandleRoutingInformation(const cec_command &command) +{ + if (command.parameters.size == 2) + { + uint16_t iNewAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]); + + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + { + device->SetPhysicalAddress(iNewAddress); + return true; + } + } + + return false; +} + bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command) { if (command.parameters.size == 3) @@ -330,34 +394,64 @@ bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command) language.language[iPtr] = command.parameters[iPtr]; language.language[3] = 0; device->SetMenuLanguage(language); + return true; } } - return true; + return false; +} + +bool CCECCommandHandler::HandleSetOSDName(const cec_command &command) +{ + if (command.parameters.size > 0) + { + CCECBusDevice *device = GetDevice(command.initiator); + if (device) + { + char buf[1024]; + for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++) + buf[iPtr] = (char)command.parameters[iPtr]; + buf[command.parameters.size] = 0; + + CStdString strName(buf); + device->SetOSDName(strName); + + return true; + } + } + return false; } 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 sets stream path to 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()); - return m_busDevice->GetProcessor()->SetStreamPath(streamaddr); + if (m_busDevice->GetProcessor()->SetStreamPath(iStreamAddress)) + { + CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamAddress); + if (device) + { + return device->TransmitActiveSource() && + device->TransmitMenuState(command.initiator); + } + } } - return true; + return false; } bool CCECCommandHandler::HandleSetSystemAudioModeRequest(const cec_command &command) { - if (command.parameters.size >= 1) + if (m_busDevice->MyLogicalAddressContains(command.destination) && 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; + return false; } bool CCECCommandHandler::HandleStandby(const cec_command &command) @@ -365,39 +459,66 @@ 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) +bool CCECCommandHandler::HandleSystemAudioStatus(const cec_command &command) { - CCECBusDevice *device = GetDevice(command.destination); + CCECBusDevice *device = GetDevice(command.initiator); if (device && device->GetType() == CEC_DEVICE_TYPE_AUDIO_SYSTEM) - return ((CCECAudioSystem *) device)->TransmitSystemAudioModeStatus(command.initiator); + { + ((CCECAudioSystem *)device)->SetSystemAudioMode(command); + return true; + } + + return false; +} + +bool CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &command) +{ + if (m_busDevice->MyLogicalAddressContains(command.destination)) + { + 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) + if (m_busDevice->MyLogicalAddressContains(command.destination) && 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]); + 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]); + return true; } } - return true; + return false; } bool CCECCommandHandler::HandleUserControlRelease(const cec_command &command) { - m_busDevice->GetProcessor()->AddKey(); + if (m_busDevice->MyLogicalAddressContains(command.destination)) + m_busDevice->GetProcessor()->AddKey(); + return true; } @@ -413,7 +534,7 @@ unsigned int CCECCommandHandler::GetMyDevices(vector &devices) unsigned int iReturn(0); cec_logical_addresses addresses = m_busDevice->GetProcessor()->GetLogicalAddresses(); - for (unsigned int iPtr = 0; iPtr < 16; iPtr++) + for (uint8_t iPtr = 0; iPtr < 16; iPtr++) { if (addresses[iPtr]) { @@ -440,6 +561,11 @@ CCECBusDevice *CCECCommandHandler::GetDeviceByPhysicalAddress(uint16_t iPhysical return m_busDevice->GetProcessor()->GetDeviceByPhysicalAddress(iPhysicalAddress); } +CCECBusDevice *CCECCommandHandler::GetDeviceByType(cec_device_type type) const +{ + return m_busDevice->GetProcessor()->GetDeviceByType(type); +} + void CCECCommandHandler::SetVendorId(const cec_command &command) { if (command.parameters.size < 3) @@ -454,7 +580,56 @@ void CCECCommandHandler::SetVendorId(const cec_command &command) 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) @@ -498,6 +673,23 @@ const char *CCECCommandHandler::ToString(const cec_logical_address address) } } +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) @@ -669,3 +861,41 @@ 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"; + case CEC_VENDOR_ONKYO: + return "Onkyo"; + default: + return "Unknown"; + } +}