cec: refactor CEC command handling. split up standard and non-standard CEC implementa...
[deb_libcec.git] / src / lib / CECCommandHandler.cpp
CommitLineData
e9de9629
LOK
1#pragma once
2/*
3 * This file is part of the libCEC(R) library.
4 *
5 * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
6 * libCEC(R) is an original work, containing original code.
7 *
8 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 *
10 * This program is dual-licensed; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 *
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
27 *
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
32 */
33
34#include "CECCommandHandler.h"
35#include "CECBusDevice.h"
36#include "CECProcessor.h"
37
38using namespace CEC;
39
40CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice)
41{
42 m_busDevice = busDevice;
43}
44
45bool CCECCommandHandler::HandleCommand(const cec_command &command)
46{
47 bool bHandled(true);
48
49 if (command.destination == m_busDevice->GetMyLogicalAddress())
50 {
51 switch(command.opcode)
52 {
53 case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
54 HandleGivePhysicalAddress(command);
55 break;
56 case CEC_OPCODE_GIVE_OSD_NAME:
57 HandleGiveOSDName(command);
58 break;
59 case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
60 HandleGiveDeviceVendorId(command);
61 break;
62 case CEC_OPCODE_DEVICE_VENDOR_ID:
63 HandleDeviceVendorId(command);
64 break;
65 case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
66 HandleDeviceVendorCommandWithId(command);
67 break;
68 case CEC_OPCODE_GIVE_DECK_STATUS:
69 HandleGiveDeckStatus(command);
70 break;
71 case CEC_OPCODE_MENU_REQUEST:
72 HandleMenuRequest(command);
73 break;
74 case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
75 HandleGiveDevicePowerStatus(command);
76 break;
77 case CEC_OPCODE_GET_CEC_VERSION:
78 HandleGetCecVersion(command);
79 break;
80 case CEC_OPCODE_USER_CONTROL_PRESSED:
81 HandleUserControlPressed(command);
82 break;
83 case CEC_OPCODE_USER_CONTROL_RELEASE:
84 HandleUserControlRelease(command);
85 break;
86 default:
87 UnhandledCommand(command);
88 bHandled = false;
89 break;
90 }
91 }
92 else if (command.destination == CECDEVICE_BROADCAST)
93 {
94 CStdString strLog;
95 switch (command.opcode)
96 {
97 case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
98 HandleRequestActiveSource(command);
99 break;
100 case CEC_OPCODE_SET_STREAM_PATH:
101 HandleSetStreamPath(command);
102 break;
103 case CEC_OPCODE_ROUTING_CHANGE:
104 HandleRoutingChange(command);
105 break;
106 case CEC_OPCODE_DEVICE_VENDOR_ID:
107 HandleDeviceVendorId(command);
108 break;
109 case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
110 HandleDeviceVendorCommandWithId(command);
111 break;
112 default:
113 UnhandledCommand(command);
114 bHandled = false;
115 break;
116 }
117 }
118 else
119 {
120 CStdString strLog;
121 strLog.Format("ignoring frame: destination: %u != %u", command.destination, (uint8_t)m_busDevice->GetMyLogicalAddress());
122 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
123 bHandled = false;
124 }
125
126 return bHandled;
127}
128
129bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
130{
131 m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters);
132 return true;
133}
134
135bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command)
136{
137 m_busDevice->GetProcessor()->ParseVendorId(command.initiator, command.parameters);
138 return true;
139}
140
141bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command)
142{
143 m_busDevice->GetProcessor()->ReportCECVersion(command.initiator);
144 return true;
145}
146
147bool CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command)
148{
149 // need to support opcodes play and deck control before doing anything with this
150 m_busDevice->GetProcessor()->TransmitAbort(command.initiator, CEC_OPCODE_GIVE_DECK_STATUS);
151 return true;
152}
153
154bool CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command)
155{
156 m_busDevice->GetProcessor()->ReportPowerState(command.initiator);
157 return true;
158}
159
160bool CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command)
161{
162 m_busDevice->GetProcessor()->ReportVendorID(command.initiator);
163 return true;
164}
165
166bool CCECCommandHandler::HandleGiveOSDName(const cec_command &command)
167{
168 m_busDevice->GetProcessor()->ReportOSDName(command.initiator);
169 return true;
170}
171
172bool CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command)
173{
174 m_busDevice->GetProcessor()->ReportPhysicalAddress();
175 return true;
176}
177
178bool CCECCommandHandler::HandleMenuRequest(const cec_command &command)
179{
180 if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY)
181 m_busDevice->GetProcessor()->ReportMenuState(command.initiator);
182 return true;
183}
184
185bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command)
186{
187 CStdString strLog;
188 strLog.Format(">> %i requests active source", (uint8_t) command.initiator);
189 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
190 m_busDevice->GetProcessor()->BroadcastActiveSource();
191 return true;
192}
193
194bool CCECCommandHandler::HandleRoutingChange(const cec_command &command)
195{
196 if (command.parameters.size == 4)
197 {
198 uint16_t iOldAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
199 uint16_t iNewAddress = ((uint16_t)command.parameters[2] << 8) | ((uint16_t)command.parameters[3]);
200 CStdString strLog;
201 strLog.Format(">> %i changed physical address from %04x to %04x", command.initiator, iOldAddress, iNewAddress);
202 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
203
204 m_busDevice->GetProcessor()->AddCommand(command);
205 }
206 return true;
207}
208
209bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
210{
211 if (command.parameters.size >= 2)
212 {
213 int streamaddr = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
214 CStdString strLog;
215 strLog.Format(">> %i requests stream path from physical address %04x", command.initiator, streamaddr);
216 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
217 if (streamaddr == m_busDevice->GetMyPhysicalAddress())
218 m_busDevice->GetProcessor()->BroadcastActiveSource();
219 }
220 return true;
221}
222
223bool CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
224{
225 if (command.parameters.size > 0)
226 {
227 m_busDevice->GetProcessor()->AddKey();
228
229 if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX)
230 {
231 CStdString strLog;
232 strLog.Format("key pressed: %1x", command.parameters[0]);
233 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
234
235 m_busDevice->GetProcessor()->SetCurrentButton((cec_user_control_code) command.parameters[0]);
236 }
237 }
238 return true;
239}
240
241bool CCECCommandHandler::HandleUserControlRelease(const cec_command &command)
242{
243 m_busDevice->GetProcessor()->AddKey();
244 return true;
245}
246
247void CCECCommandHandler::UnhandledCommand(const cec_command &command)
248{
249 m_busDevice->GetProcessor()->AddCommand(command);;
250}