cec: don't respond with a feature abort to opcode play messages. bugzid: 873
[deb_libcec.git] / src / lib / implementations / VLCommandHandler.cpp
CommitLineData
bb5b4874
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
b492c10e 4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
bb5b4874
LOK
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
33#include "VLCommandHandler.h"
34#include "../devices/CECBusDevice.h"
3e61b350 35#include "../CECProcessor.h"
b78b4e33 36#include "../LibCEC.h"
004b8382 37#include "../CECClient.h"
b78b4e33
LOK
38
39#define VL_POWER_CHANGE 0x20
40#define VL_POWERED_UP 0x00
41#define VL_POWERED_DOWN 0x01
bb5b4874
LOK
42
43using namespace CEC;
b78b4e33 44using namespace PLATFORM;
bb5b4874 45
004b8382
LOK
46#define LIB_CEC m_busDevice->GetProcessor()->GetLib()
47#define ToString(p) LIB_CEC->ToString(p)
48
bb5b4874 49CVLCommandHandler::CVLCommandHandler(CCECBusDevice *busDevice) :
b78b4e33
LOK
50 CCECCommandHandler(busDevice),
51 m_bActiveSourcePending(false),
52 m_bPowerUpEventReceived(false)
bb5b4874 53{
cf4931be 54 m_vendorId = CEC_VENDOR_PANASONIC;
b47f66af
LOK
55
56 /* use the VL commandhandler for the primary device that is handled by libCEC */
57 if (busDevice->GetLogicalAddress() == CECDEVICE_TV)
58 {
59 CCECBusDevice *primary = m_processor->GetPrimaryDevice();
60 if (primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
61 {
62 primary->SetVendorId(CEC_VENDOR_PANASONIC);
63 primary->ReplaceHandler(false);
64 }
65 }
bb5b4874 66}
3e61b350
LOK
67
68bool CVLCommandHandler::InitHandler(void)
69{
70 CCECBusDevice *primary = m_processor->GetPrimaryDevice();
71 if (primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)
004b8382 72 return m_processor->GetPrimaryClient()->ChangeDeviceType(CEC_DEVICE_TYPE_RECORDING_DEVICE, CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
b78b4e33 73
3e61b350
LOK
74 return CCECCommandHandler::InitHandler();
75}
b78b4e33
LOK
76
77bool CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
78{
79 if (command.initiator == CECDEVICE_TV &&
80 command.destination == CECDEVICE_BROADCAST &&
81 command.parameters.At(3) == VL_POWER_CHANGE)
82 {
83 if (command.parameters.At(4) == VL_POWERED_UP)
84 {
004b8382 85 LIB_CEC->AddLog(CEC_LOG_DEBUG, "TV powered up");
b78b4e33
LOK
86 {
87 CLockObject lock(m_mutex);
88 m_bPowerUpEventReceived = true;
89 }
90 m_processor->TransmitPendingActiveSourceCommands();
91 }
92 else if (command.parameters.At(4) == VL_POWERED_DOWN)
004b8382 93 LIB_CEC->AddLog(CEC_LOG_DEBUG, "TV powered down");
b78b4e33 94 else if (command.parameters.At(4) == VL_POWERED_DOWN)
004b8382 95 LIB_CEC->AddLog(CEC_LOG_DEBUG, "unknown vendor command");
b78b4e33
LOK
96
97 return true;
98 }
99
100 return CCECCommandHandler::HandleDeviceVendorCommandWithId(command);
101}
102
103bool CVLCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress)
104{
105 bool bPowerUpEventReceived(false);
106
004b8382
LOK
107 CCECBusDevice *tv = m_processor->GetDevice(CECDEVICE_TV);
108 if (tv && tv->GetCurrentVendorId() == CEC_VENDOR_PANASONIC)
b78b4e33 109 {
b47f66af
LOK
110 CVLCommandHandler *handler = static_cast<CVLCommandHandler *>(tv->GetHandler());
111 bPowerUpEventReceived = handler ? handler->PowerUpEventReceived() : false;
b78b4e33
LOK
112 }
113
114 if (!bPowerUpEventReceived)
115 {
116 CLockObject lock(m_mutex);
117 // wait until we received the event
118 m_bActiveSourcePending = true;
119 return true;
120 }
121 else
122 {
123 // transmit standard active source message
6d7c0fa8
LOK
124 return CCECCommandHandler::TransmitActiveSource(iInitiator, iPhysicalAddress) &&
125 TransmitMenuState(iInitiator, CECDEVICE_TV, CEC_MENU_STATE_ACTIVATED);
b78b4e33
LOK
126 }
127}
128
129bool CVLCommandHandler::TransmitPendingActiveSourceCommands(void)
130{
131 bool bTransmitCommand(false);
132 {
133 CLockObject lock(m_mutex);
134 bTransmitCommand = m_bActiveSourcePending;
135 m_bActiveSourcePending = false;
136 }
137
138 if (bTransmitCommand)
139 {
004b8382 140 LIB_CEC->AddLog(CEC_LOG_DEBUG, "transmitting delayed activate source command");
6d7c0fa8
LOK
141 return CCECCommandHandler::TransmitActiveSource(m_busDevice->GetLogicalAddress(), m_busDevice->GetCurrentPhysicalAddress()) &&
142 TransmitMenuState(m_busDevice->GetLogicalAddress(), CECDEVICE_TV, CEC_MENU_STATE_ACTIVATED);
b78b4e33
LOK
143 }
144 return true;
145}
b47f66af
LOK
146
147bool CVLCommandHandler::PowerUpEventReceived(void)
148{
149 {
150 CLockObject lock(m_mutex);
151 if (m_bPowerUpEventReceived)
152 return true;
153 }
154
004b8382 155 cec_power_status powerStatus = m_busDevice->GetCurrentPowerStatus();
b47f66af
LOK
156
157 CLockObject lock(m_mutex);
158 m_bPowerUpEventReceived = (powerStatus == CEC_POWER_STATUS_ON);
159 return m_bPowerUpEventReceived;
160}