cec: log string cosmetics in CCECBusDevice. log a source for each packet
[deb_libcec.git] / src / lib / implementations / CECCommandHandler.cpp
CommitLineData
e9de9629
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
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 "CECCommandHandler.h"
eafa9d46 34#include "../devices/CECBusDevice.h"
387b6f6f 35#include "../CECProcessor.h"
e9de9629
LOK
36
37using namespace CEC;
38
39CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice)
40{
41 m_busDevice = busDevice;
42}
43
44bool CCECCommandHandler::HandleCommand(const cec_command &command)
45{
46 bool bHandled(true);
47
f8513317 48 if (m_busDevice->MyLogicalAddressContains(command.destination))
e9de9629
LOK
49 {
50 switch(command.opcode)
51 {
e55f3f70
LOK
52 case CEC_OPCODE_REPORT_POWER_STATUS:
53 HandleReportPowerStatus(command);
54 break;
6a1c0009
LOK
55 case CEC_OPCODE_CEC_VERSION:
56 HandleDeviceCecVersion(command);
57 break;
a3269a0a
LOK
58 case CEC_OPCODE_SET_MENU_LANGUAGE:
59 HandleSetMenuLanguage(command);
a9e03a86 60 m_busDevice->GetProcessor()->AddCommand(command);
a3269a0a 61 break;
e9de9629
LOK
62 case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
63 HandleGivePhysicalAddress(command);
64 break;
65 case CEC_OPCODE_GIVE_OSD_NAME:
66 HandleGiveOSDName(command);
67 break;
68 case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
69 HandleGiveDeviceVendorId(command);
70 break;
71 case CEC_OPCODE_DEVICE_VENDOR_ID:
72 HandleDeviceVendorId(command);
73 break;
74 case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
75 HandleDeviceVendorCommandWithId(command);
76 break;
77 case CEC_OPCODE_GIVE_DECK_STATUS:
78 HandleGiveDeckStatus(command);
79 break;
80 case CEC_OPCODE_MENU_REQUEST:
81 HandleMenuRequest(command);
82 break;
83 case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
84 HandleGiveDevicePowerStatus(command);
85 break;
86 case CEC_OPCODE_GET_CEC_VERSION:
87 HandleGetCecVersion(command);
88 break;
89 case CEC_OPCODE_USER_CONTROL_PRESSED:
90 HandleUserControlPressed(command);
91 break;
92 case CEC_OPCODE_USER_CONTROL_RELEASE:
93 HandleUserControlRelease(command);
94 break;
95 default:
96 UnhandledCommand(command);
a9e03a86 97 m_busDevice->GetProcessor()->AddCommand(command);
e9de9629
LOK
98 bHandled = false;
99 break;
100 }
101 }
102 else if (command.destination == CECDEVICE_BROADCAST)
103 {
104 CStdString strLog;
105 switch (command.opcode)
106 {
a3269a0a
LOK
107 case CEC_OPCODE_SET_MENU_LANGUAGE:
108 HandleSetMenuLanguage(command);
a9e03a86 109 m_busDevice->GetProcessor()->AddCommand(command);
a3269a0a 110 break;
e9de9629
LOK
111 case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
112 HandleRequestActiveSource(command);
113 break;
114 case CEC_OPCODE_SET_STREAM_PATH:
115 HandleSetStreamPath(command);
a9e03a86 116 m_busDevice->GetProcessor()->AddCommand(command);
e9de9629
LOK
117 break;
118 case CEC_OPCODE_ROUTING_CHANGE:
119 HandleRoutingChange(command);
a9e03a86 120 m_busDevice->GetProcessor()->AddCommand(command);
e9de9629
LOK
121 break;
122 case CEC_OPCODE_DEVICE_VENDOR_ID:
123 HandleDeviceVendorId(command);
124 break;
125 case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
126 HandleDeviceVendorCommandWithId(command);
127 break;
128 default:
129 UnhandledCommand(command);
a9e03a86 130 m_busDevice->GetProcessor()->AddCommand(command);
e9de9629
LOK
131 bHandled = false;
132 break;
133 }
134 }
135 else
136 {
137 CStdString strLog;
f8513317 138 strLog.Format("ignoring frame: we're not at destination %x", command.destination);
e9de9629
LOK
139 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
140 bHandled = false;
141 }
142
143 return bHandled;
144}
145
6a1c0009
LOK
146bool CCECCommandHandler::HandleDeviceCecVersion(const cec_command &command)
147{
148 if (command.parameters.size == 1)
149 {
150 CCECBusDevice *device = GetDevice(command.initiator);
151 if (device)
152 device->SetCecVersion((cec_version) command.parameters[0]);
153 }
154
155 return true;
156}
157
e9de9629
LOK
158bool CCECCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
159{
0f23c85c
LOK
160 CCECBusDevice *device = GetDevice(command.initiator);
161 if (device)
162 device->SetVendorId(command.parameters);
163
6a1c0009 164 return true;
e9de9629
LOK
165}
166
167bool CCECCommandHandler::HandleDeviceVendorId(const cec_command &command)
168{
0f23c85c
LOK
169 CCECBusDevice *device = GetDevice(command.initiator);
170 if (device)
171 device->SetVendorId(command.parameters);
172
6a1c0009 173 return true;
e9de9629
LOK
174}
175
176bool CCECCommandHandler::HandleGetCecVersion(const cec_command &command)
177{
f8513317 178 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 179 if (device)
29912296 180 return device->TransmitCECVersion(command.initiator);
0f23c85c
LOK
181
182 return false;
e9de9629
LOK
183}
184
185bool CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command)
186{
f8513317 187 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 188 if (device)
29912296 189 return device->TransmitDeckStatus(command.initiator);
0f23c85c
LOK
190
191 return false;
e9de9629
LOK
192}
193
194bool CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command)
195{
f8513317 196 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 197 if (device)
29912296 198 return device->TransmitPowerState(command.initiator);
0f23c85c
LOK
199
200 return false;
e9de9629
LOK
201}
202
203bool CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command)
204{
f8513317 205 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 206 if (device)
29912296 207 return device->TransmitVendorID(command.initiator);
0f23c85c
LOK
208
209 return false;
e9de9629
LOK
210}
211
212bool CCECCommandHandler::HandleGiveOSDName(const cec_command &command)
213{
f8513317 214 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 215 if (device)
29912296 216 return device->TransmitOSDName(command.initiator);
0f23c85c
LOK
217
218 return false;
e9de9629
LOK
219}
220
221bool CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command)
222{
f8513317 223 CCECBusDevice *device = GetDevice(command.destination);
09c10b66 224 if (device)
29912296 225 return device->TransmitPhysicalAddress();
09c10b66
LOK
226
227 return false;
e9de9629
LOK
228}
229
230bool CCECCommandHandler::HandleMenuRequest(const cec_command &command)
231{
232 if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY)
0f23c85c 233 {
f8513317 234 CCECBusDevice *device = GetDevice(command.destination);
0f23c85c 235 if (device)
29912296 236 return device->TransmitMenuState(command.initiator);
0f23c85c
LOK
237 }
238 return false;
e9de9629
LOK
239}
240
e55f3f70
LOK
241bool CCECCommandHandler::HandleReportPowerStatus(const cec_command &command)
242{
243 if (command.parameters.size == 1)
244 {
245 CCECBusDevice *device = GetDevice(command.initiator);
246 if (device)
247 device->SetPowerStatus((cec_power_status) command.parameters[0]);
248 }
249 return true;
250}
251
e9de9629
LOK
252bool CCECCommandHandler::HandleRequestActiveSource(const cec_command &command)
253{
254 CStdString strLog;
255 strLog.Format(">> %i requests active source", (uint8_t) command.initiator);
256 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
f8513317 257 CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetMyLogicalAddress()];
09c10b66 258 if (device)
29912296 259 return device->TransmitActiveSource();
09c10b66 260 return false;
e9de9629
LOK
261}
262
263bool CCECCommandHandler::HandleRoutingChange(const cec_command &command)
264{
265 if (command.parameters.size == 4)
266 {
267 uint16_t iOldAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
268 uint16_t iNewAddress = ((uint16_t)command.parameters[2] << 8) | ((uint16_t)command.parameters[3]);
e9de9629 269
0f23c85c
LOK
270 CCECBusDevice *device = GetDevice(command.initiator);
271 if (device)
272 device->SetPhysicalAddress(iNewAddress, iOldAddress);
e9de9629
LOK
273 }
274 return true;
275}
276
a3269a0a
LOK
277bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command)
278{
279 if (command.parameters.size == 3)
280 {
281 CCECBusDevice *device = GetDevice(command.initiator);
282 if (device)
283 {
284 cec_menu_language language;
285 language.device = command.initiator;
56701628 286 for (uint8_t iPtr = 0; iPtr < 4; iPtr++)
a3269a0a
LOK
287 language.language[iPtr] = command.parameters[iPtr];
288 language.language[3] = 0;
289 device->SetMenuLanguage(language);
290 }
291 }
292 return true;
293}
294
e9de9629
LOK
295bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
296{
297 if (command.parameters.size >= 2)
298 {
299 int streamaddr = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
300 CStdString strLog;
301 strLog.Format(">> %i requests stream path from physical address %04x", command.initiator, streamaddr);
302 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
303 if (streamaddr == m_busDevice->GetMyPhysicalAddress())
09c10b66 304 {
f8513317 305 CCECBusDevice *device = GetDevice(command.destination);
09c10b66 306 if (device)
29912296 307 return device->TransmitActiveSource();
09c10b66
LOK
308 return false;
309 }
e9de9629
LOK
310 }
311 return true;
312}
313
314bool CCECCommandHandler::HandleUserControlPressed(const cec_command &command)
315{
316 if (command.parameters.size > 0)
317 {
318 m_busDevice->GetProcessor()->AddKey();
319
320 if (command.parameters[0] <= CEC_USER_CONTROL_CODE_MAX)
321 {
322 CStdString strLog;
323 strLog.Format("key pressed: %1x", command.parameters[0]);
324 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog.c_str());
325
326 m_busDevice->GetProcessor()->SetCurrentButton((cec_user_control_code) command.parameters[0]);
327 }
328 }
329 return true;
330}
331
332bool CCECCommandHandler::HandleUserControlRelease(const cec_command &command)
333{
334 m_busDevice->GetProcessor()->AddKey();
335 return true;
336}
337
338void CCECCommandHandler::UnhandledCommand(const cec_command &command)
339{
b5b53c7d
LOK
340 CStdString strLog;
341 strLog.Format("unhandled command with opcode %02x from address %d", command.opcode, command.initiator);
342 m_busDevice->AddLog(CEC_LOG_DEBUG, strLog);
0f23c85c
LOK
343}
344
345CCECBusDevice *CCECCommandHandler::GetDevice(cec_logical_address iLogicalAddress) const
346{
347 CCECBusDevice *device = NULL;
348
349 if (iLogicalAddress >= CECDEVICE_TV && iLogicalAddress <= CECDEVICE_BROADCAST)
350 device = m_busDevice->GetProcessor()->m_busDevices[iLogicalAddress];
351
352 return device;
e9de9629 353}