From f42d3e0fb1f63456b87232019d9cce731acad640 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 6 Feb 2012 12:47:34 +0100 Subject: [PATCH] cec: added SetStreamPath()/cec_set_stream_path_logical()/cec_set_stream_path_physical() to the interface, to send a "set stream path" command over the CEC bus, used to activate another source. --- include/cec.h | 14 +++++++ include/cecc.h | 8 ++++ src/lib/CECProcessor.cpp | 6 +++ src/lib/CECProcessor.h | 1 + src/lib/LibCEC.cpp | 13 ++++++ src/lib/LibCEC.h | 2 + src/lib/LibCECC.cpp | 10 +++++ src/lib/implementations/CECCommandHandler.cpp | 10 +++++ src/lib/implementations/CECCommandHandler.h | 1 + src/testclient/main.cpp | 42 ++++++++++++++++++- 10 files changed, 106 insertions(+), 1 deletion(-) diff --git a/include/cec.h b/include/cec.h index c083777..97e75a4 100644 --- a/include/cec.h +++ b/include/cec.h @@ -350,6 +350,20 @@ namespace CEC */ virtual bool IsActiveSource(cec_logical_address iAddress) = 0; + /*! + * @brief Sets the stream path to the device on the given logical address. + * @param iAddress The address to activate. + * @return True when the command was sent, false otherwise. + */ + virtual bool SetStreamPath(cec_logical_address iAddress) = 0; + + /*! + * @brief Sets the stream path to the device on the given logical address. + * @param iPhysicalAddress The address to activate. + * @return True when the command was sent, false otherwise. + */ + virtual bool SetStreamPath(uint16_t iPhysicalAddress) = 0; + virtual const char *ToString(const cec_menu_state state) = 0; virtual const char *ToString(const cec_version version) = 0; virtual const char *ToString(const cec_power_status status) = 0; diff --git a/include/cecc.h b/include/cecc.h index 5a49b09..dc4b795 100644 --- a/include/cecc.h +++ b/include/cecc.h @@ -259,6 +259,14 @@ extern DECLSPEC cec_osd_name cec_get_device_osd_name(cec_logical_address iAddres extern DECLSPEC int cec_enable_physical_address_detection(void); +#ifdef __cplusplus +extern DECLSPEC int cec_set_stream_path_logical(CEC::cec_logical_address iAddress); +#else +extern DECLSPEC int cec_set_stream_path_logical(cec_logical_address iAddress); +#endif + +extern DECLSPEC int cec_set_stream_path_physical(uint16_t iPhysicalAddress); + #ifdef __cplusplus }; #endif diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index e45eda0..78d2436 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -1332,3 +1332,9 @@ bool CCECProcessor::HandleReceiveFailed(cec_logical_address initiator) { return !m_busDevices[initiator]->HandleReceiveFailed(); } + +bool CCECProcessor::SetStreamPath(uint16_t iPhysicalAddress) +{ + // stream path changes are sent by the TV + return m_busDevices[CECDEVICE_TV]->GetHandler()->TransmitSetStreamPath(iPhysicalAddress); +} diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 0d2446a..c21110d 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -77,6 +77,7 @@ namespace CEC virtual cec_logical_address GetActiveSource(void); virtual bool IsActiveSource(cec_logical_address iAddress); virtual bool IsInitialised(void); + virtual bool SetStreamPath(uint16_t iPhysicalAddress); virtual bool SetActiveView(void); virtual bool SetActiveSource(cec_device_type type = CEC_DEVICE_TYPE_RESERVED); diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index 2562cfd..7022def 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -435,6 +435,19 @@ void CLibCEC::CheckKeypressTimeout(void) } } +bool CLibCEC::SetStreamPath(cec_logical_address iAddress) +{ + uint16_t iPhysicalAddress = GetDevicePhysicalAddress(iAddress); + if (iPhysicalAddress != 0xFFFF) + return SetStreamPath(iPhysicalAddress); + return false; +} + +bool CLibCEC::SetStreamPath(uint16_t iPhysicalAddress) +{ + return m_cec->SetStreamPath(iPhysicalAddress); +} + static CLibCEC *g_libCEC_instance(NULL); CLibCEC *CLibCEC::GetInstance(void) { diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index a0cc254..6cc2514 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -99,6 +99,8 @@ namespace CEC virtual bool EnablePhysicalAddressDetection(void); virtual cec_logical_address GetActiveSource(void); virtual bool IsActiveSource(cec_logical_address iAddress); + virtual bool SetStreamPath(cec_logical_address iAddress); + virtual bool SetStreamPath(uint16_t iPhysicalAddress); const char *ToString(const cec_menu_state state); const char *ToString(const cec_version version); diff --git a/src/lib/LibCECC.cpp b/src/lib/LibCECC.cpp index edc30d2..3711686 100644 --- a/src/lib/LibCECC.cpp +++ b/src/lib/LibCECC.cpp @@ -371,4 +371,14 @@ int cec_enable_physical_address_detection(void) return cec_parser ? (cec_parser->EnablePhysicalAddressDetection() ? 1 : 0) : -1; } +int cec_set_stream_path_logical(CEC::cec_logical_address iAddress) +{ + return cec_parser ? (cec_parser->SetStreamPath(iAddress) ? 1 : 0) : -1; +} + +int cec_set_stream_path_physical(uint16_t iPhysicalAddress) +{ + return cec_parser ? (cec_parser->SetStreamPath(iPhysicalAddress) ? 1 : 0) : -1; +} + //@} diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 7be147d..0f00627 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -899,6 +899,16 @@ bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iI return Transmit(command, false); } +bool CCECCommandHandler::TransmitSetStreamPath(uint16_t iStreamPath) +{ + cec_command command; + cec_command::Format(command, m_busDevice->GetLogicalAddress(), CECDEVICE_BROADCAST, CEC_OPCODE_SET_STREAM_PATH); + command.parameters.PushBack((uint8_t) ((iStreamPath >> 8) & 0xFF)); + command.parameters.PushBack((uint8_t) (iStreamPath & 0xFF)); + + return Transmit(command, false); +} + bool CCECCommandHandler::TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state) { cec_command command; diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index 409591b..e265302 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -80,6 +80,7 @@ namespace CEC virtual bool TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state); virtual bool TransmitKeypress(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_user_control_code key, bool bWait = true); virtual bool TransmitKeyRelease(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWait = true); + virtual bool TransmitSetStreamPath(uint16_t iStreamPath); virtual void MarkBusy(void); virtual bool MarkReady(void); diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index cbdeddf..c8e6819 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -273,6 +273,8 @@ void ShowHelpConsole(void) "[lad] lists active devices on the bus" << endl << "[ad] {addr} checks whether the specified device is active." << endl << "[at] {type} checks whether the specified device type is active." << endl << + "[sp] {addr} makes the specified physical address active." << endl << + "[spl] {addr} makes the specified logical address active." << endl << "[volup] send a volume up command to the amp if present" << endl << "[voldown] send a volume down command to the amp if present" << endl << "[mute] send a mute/unmute command to the amp if present" << endl << @@ -289,6 +291,42 @@ void ShowHelpConsole(void) "================================================================================" << endl; } +bool ProcessCommandSP(ICECAdapter *parser, const string &command, string &arguments) +{ + if (command == "sp") + { + string strAddress; + int iAddress; + if (GetWord(arguments, strAddress)) + { + sscanf(strAddress.c_str(), "%x", &iAddress); + if (iAddress >= 0 && iAddress <= 0xFFFF) + parser->SetStreamPath((uint16_t)iAddress); + return true; + } + } + + return false; +} + +bool ProcessCommandSPL(ICECAdapter *parser, const string &command, string &arguments) +{ + if (command == "spl") + { + string strAddress; + cec_logical_address iAddress; + if (GetWord(arguments, strAddress)) + { + iAddress = (cec_logical_address)atoi(strAddress.c_str()); + if (iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST) + parser->SetStreamPath(iAddress); + return true; + } + } + + return false; +} + bool ProcessCommandTX(ICECAdapter *parser, const string &command, string &arguments) { if (command == "tx" || command == "txn") @@ -828,7 +866,9 @@ bool ProcessConsoleCommand(ICECAdapter *parser, string &input) ProcessCommandR(parser, command, input) || ProcessCommandH(parser, command, input) || ProcessCommandLOG(parser, command, input) || - ProcessCommandSCAN(parser, command, input); + ProcessCommandSCAN(parser, command, input) || + ProcessCommandSP(parser, command, input) || + ProcessCommandSPL(parser, command, input); } } return true; -- 2.34.1