cec: moved CEC handlers to implementations/
[deb_libcec.git] / src / lib / CECProcessor.cpp
CommitLineData
abbca718
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
2abe74eb 33#include "CECProcessor.h"
abbca718 34
2abe74eb 35#include "AdapterCommunication.h"
e9de9629 36#include "CECBusDevice.h"
2abe74eb 37#include "LibCEC.h"
abbca718 38#include "util/StdString.h"
b9187cc6 39#include "platform/timeutils.h"
abbca718
LOK
40
41using namespace CEC;
42using namespace std;
43
2b4d8297 44CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) :
2492216a 45 m_iPhysicalAddress(iPhysicalAddress),
df7339c6 46 m_iLogicalAddress(iLogicalAddress),
2abe74eb
LOK
47 m_strDeviceName(strDeviceName),
48 m_communication(serComm),
8b7e5ff6
LOK
49 m_controller(controller),
50 m_bMonitor(false)
abbca718 51{
e9de9629
LOK
52 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
53 m_busDevices[iPtr] = new CCECBusDevice(this, (cec_logical_address) iPtr, 0);
abbca718
LOK
54}
55
2abe74eb 56CCECProcessor::~CCECProcessor(void)
abbca718 57{
2abe74eb
LOK
58 StopThread();
59 m_communication = NULL;
60 m_controller = NULL;
d1998c7b
LOK
61 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
62 delete m_busDevices[iPtr];
abbca718
LOK
63}
64
2abe74eb 65bool CCECProcessor::Start(void)
abbca718 66{
2abe74eb 67 if (!m_communication || !m_communication->IsOpen())
13fd6a66
LOK
68 {
69 m_controller->AddLog(CEC_LOG_ERROR, "connection is closed");
a8f0bd18 70 return false;
13fd6a66 71 }
abbca718 72
a8f0bd18 73 if (!SetLogicalAddress(m_iLogicalAddress))
abbca718 74 {
2abe74eb 75 m_controller->AddLog(CEC_LOG_ERROR, "could not set the logical address");
a8f0bd18 76 return false;
abbca718
LOK
77 }
78
60fa4578 79 if (CreateThread())
a8f0bd18 80 return true;
a8f0bd18 81 else
2abe74eb 82 m_controller->AddLog(CEC_LOG_ERROR, "could not create a processor thread");
abbca718 83
a8f0bd18 84 return false;
abbca718
LOK
85}
86
2abe74eb 87void *CCECProcessor::Process(void)
f99bc831 88{
2abe74eb 89 m_controller->AddLog(CEC_LOG_DEBUG, "processor thread started");
abbca718 90
9dee1670
LOK
91 cec_command command;
92 cec_adapter_message msg;
93
13fd6a66 94 while (!IsStopped())
abbca718 95 {
60fa4578 96 bool bParseFrame(false);
78e8010a
LOK
97 bool bError(false);
98 bool bTransmitSucceeded(false);
9dee1670 99 command.clear();
76321de4
LOK
100 msg.clear();
101
60fa4578
LOK
102 {
103 CLockObject lock(&m_mutex);
76321de4 104 if (m_communication->IsOpen() && m_communication->Read(msg, 50))
78e8010a 105 ParseMessage(msg, &bError, &bTransmitSucceeded, &bParseFrame);
76321de4 106
78e8010a 107 bParseFrame &= !IsStopped();
76321de4 108 if (bParseFrame)
9dee1670 109 command = m_currentframe;
60fa4578
LOK
110 }
111
13fd6a66 112 if (bParseFrame)
9dee1670 113 ParseCommand(command);
abbca718 114
13fd6a66
LOK
115 m_controller->CheckKeypressTimeout();
116
117 if (!IsStopped())
d5bffd3c 118 Sleep(5);
abbca718
LOK
119 }
120
60fa4578 121 return NULL;
abbca718
LOK
122}
123
2abe74eb 124bool CCECProcessor::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */)
abbca718 125{
60fa4578 126 if (!IsRunning())
f99bc831
LOK
127 return false;
128
abbca718 129 CStdString strLog;
88f45c9b 130 strLog.Format("<< powering on device with logical address %d", (int8_t)address);
2abe74eb 131 m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
25701fa6 132
06a1f7ce
LOK
133 cec_command command;
134 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_IMAGE_VIEW_ON);
135
136 return Transmit(command);
abbca718
LOK
137}
138
2abe74eb 139bool CCECProcessor::StandbyDevices(cec_logical_address address /* = CECDEVICE_BROADCAST */)
abbca718 140{
60fa4578 141 if (!IsRunning())
f99bc831
LOK
142 return false;
143
abbca718 144 CStdString strLog;
88f45c9b 145 strLog.Format("<< putting device with logical address %d in standby mode", (int8_t)address);
2abe74eb 146 m_controller->AddLog(CEC_LOG_DEBUG, strLog.c_str());
25701fa6 147
06a1f7ce
LOK
148 cec_command command;
149 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_STANDBY);
150
151 return Transmit(command);
abbca718
LOK
152}
153
2abe74eb 154bool CCECProcessor::SetActiveView(void)
abbca718 155{
60fa4578 156 if (!IsRunning())
f99bc831
LOK
157 return false;
158
88f45c9b 159 m_controller->AddLog(CEC_LOG_DEBUG, "<< setting active view");
9dee1670 160
06a1f7ce
LOK
161 cec_command command;
162 cec_command::format(command, m_iLogicalAddress, CECDEVICE_BROADCAST, CEC_OPCODE_ACTIVE_SOURCE);
2492216a
LOK
163 command.parameters.push_back((m_iPhysicalAddress >> 8) & 0xFF);
164 command.parameters.push_back(m_iPhysicalAddress & 0xFF);
9dee1670
LOK
165
166 return Transmit(command);
abbca718
LOK
167}
168
2abe74eb 169bool CCECProcessor::SetInactiveView(void)
abbca718 170{
60fa4578 171 if (!IsRunning())
f99bc831
LOK
172 return false;
173
88f45c9b 174 m_controller->AddLog(CEC_LOG_DEBUG, "<< setting inactive view");
9dee1670 175
06a1f7ce
LOK
176 cec_command command;
177 cec_command::format(command, m_iLogicalAddress, CECDEVICE_BROADCAST, CEC_OPCODE_INACTIVE_SOURCE);
2492216a
LOK
178 command.parameters.push_back((m_iPhysicalAddress >> 8) & 0xFF);
179 command.parameters.push_back(m_iPhysicalAddress & 0xFF);
9dee1670
LOK
180
181 return Transmit(command);
abbca718
LOK
182}
183
9dee1670 184void CCECProcessor::LogOutput(const cec_command &data)
abbca718 185{
2abe74eb 186 CStdString txStr = "transmit ";
9dee1670 187 txStr.AppendFormat(" %02x", ((uint8_t)data.initiator << 4) + (uint8_t)data.destination);
2b885768 188 txStr.AppendFormat(":%02x", (uint8_t)data.opcode);
9dee1670 189
06a1f7ce 190 for (uint8_t iPtr = 0; iPtr < data.parameters.size; iPtr++)
2b885768 191 txStr.AppendFormat(":%02x", data.parameters[iPtr]);
2abe74eb 192 m_controller->AddLog(CEC_LOG_DEBUG, txStr.c_str());
9dee1670 193}
2abe74eb 194
9dee1670
LOK
195bool CCECProcessor::Transmit(const cec_command &data, bool bWaitForAck /* = true */)
196{
197 LogOutput(data);
2abe74eb 198
9dee1670 199 cec_adapter_message output;
25701fa6 200 output.clear();
9dee1670 201 CAdapterCommunication::FormatAdapterMessage(data, output);
2abe74eb
LOK
202
203 return TransmitFormatted(output, bWaitForAck);
abbca718
LOK
204}
205
2abe74eb 206bool CCECProcessor::SetLogicalAddress(cec_logical_address iLogicalAddress)
abbca718 207{
2abe74eb 208 CStdString strLog;
2492216a 209 strLog.Format("<< setting logical address to %1x", iLogicalAddress);
2abe74eb
LOK
210 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
211
212 m_iLogicalAddress = iLogicalAddress;
213 return m_communication && m_communication->SetAckMask(0x1 << (uint8_t)m_iLogicalAddress);
abbca718 214}
825ddb96 215
2492216a
LOK
216bool CCECProcessor::SetPhysicalAddress(uint16_t iPhysicalAddress)
217{
218 CStdString strLog;
219 strLog.Format("<< setting physical address to %2x", iPhysicalAddress);
220 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
221
222 m_iPhysicalAddress = iPhysicalAddress;
223 return SetActiveView();
224}
225
1969b140
LOK
226bool CCECProcessor::SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage)
227{
228 CStdString strLog;
229 strLog.Format("<< display message '%s'", strMessage);
230 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
231
232 cec_command command;
233 cec_command::format(command, m_iLogicalAddress, iLogicalAddress, CEC_OPCODE_SET_OSD_STRING);
234 command.parameters.push_back((uint8_t)duration);
235
236 for (unsigned int iPtr = 0; iPtr < strlen(strMessage); iPtr++)
237 command.parameters.push_back(strMessage[iPtr]);
238
239 return Transmit(command);
240}
241
8b7e5ff6
LOK
242bool CCECProcessor::SwitchMonitoring(bool bEnable)
243{
244 CStdString strLog;
245 strLog.Format("== %s monitoring mode ==", bEnable ? "enabling" : "disabling");
246 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
247
248 m_bMonitor = bEnable;
249 if (bEnable)
250 return m_communication && m_communication->SetAckMask(0);
251 else
252 return m_communication && m_communication->SetAckMask(0x1 << (uint8_t)m_iLogicalAddress);
253}
254
9dee1670 255bool CCECProcessor::TransmitFormatted(const cec_adapter_message &data, bool bWaitForAck /* = true */)
825ddb96 256{
2abe74eb
LOK
257 CLockObject lock(&m_mutex);
258 if (!m_communication || !m_communication->Write(data))
259 return false;
260
050df0f9 261 if (bWaitForAck)
2abe74eb 262 {
050df0f9
LOK
263 uint64_t now = GetTimeMs();
264 uint64_t target = now + 1000;
265 bool bError(false);
266 bool bGotAck(false);
267
268 while (!bGotAck && now < target)
269 {
06a1f7ce 270 bGotAck = WaitForAck(&bError, (uint32_t) (target - now));
050df0f9
LOK
271 now = GetTimeMs();
272
273 if (bError && now < target)
274 {
275 m_controller->AddLog(CEC_LOG_ERROR, "retransmitting previous frame");
276 if (!m_communication->Write(data))
277 return false;
278 }
279 }
2abe74eb
LOK
280 }
281
282 return true;
825ddb96 283}
abbca718 284
2abe74eb 285void CCECProcessor::TransmitAbort(cec_logical_address address, cec_opcode opcode, ECecAbortReason reason /* = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE */)
abbca718 286{
9dee1670
LOK
287 m_controller->AddLog(CEC_LOG_DEBUG, "<< transmitting abort message");
288
06a1f7ce
LOK
289 cec_command command;
290 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_FEATURE_ABORT);
9dee1670
LOK
291 command.parameters.push_back((uint8_t)opcode);
292 command.parameters.push_back((uint8_t)reason);
293
294 Transmit(command);
abbca718
LOK
295}
296
2abe74eb 297void CCECProcessor::ReportCECVersion(cec_logical_address address /* = CECDEVICE_TV */)
abbca718 298{
88f45c9b 299 m_controller->AddLog(CEC_LOG_NOTICE, "<< reporting CEC version as 1.3a");
9dee1670 300
06a1f7ce
LOK
301 cec_command command;
302 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_CEC_VERSION);
9dee1670
LOK
303 command.parameters.push_back(CEC_VERSION_1_3A);
304
305 Transmit(command);
abbca718
LOK
306}
307
2abe74eb 308void CCECProcessor::ReportPowerState(cec_logical_address address /*= CECDEVICE_TV */, bool bOn /* = true */)
abbca718 309{
abbca718 310 if (bOn)
88f45c9b 311 m_controller->AddLog(CEC_LOG_NOTICE, "<< reporting \"On\" power status");
abbca718 312 else
88f45c9b 313 m_controller->AddLog(CEC_LOG_NOTICE, "<< reporting \"Off\" power status");
abbca718 314
06a1f7ce
LOK
315 cec_command command;
316 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_REPORT_POWER_STATUS);
9dee1670
LOK
317 command.parameters.push_back(bOn ? (uint8_t) CEC_POWER_STATUS_ON : (uint8_t) CEC_POWER_STATUS_STANDBY);
318
319 Transmit(command);
abbca718
LOK
320}
321
2abe74eb 322void CCECProcessor::ReportMenuState(cec_logical_address address /* = CECDEVICE_TV */, bool bActive /* = true */)
abbca718 323{
abbca718 324 if (bActive)
88f45c9b 325 m_controller->AddLog(CEC_LOG_NOTICE, "<< reporting menu state as active");
abbca718 326 else
88f45c9b 327 m_controller->AddLog(CEC_LOG_NOTICE, "<< reporting menu state as inactive");
abbca718 328
06a1f7ce
LOK
329 cec_command command;
330 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_MENU_STATUS);
9dee1670
LOK
331 command.parameters.push_back(bActive ? (uint8_t) CEC_MENU_STATE_ACTIVATED : (uint8_t) CEC_MENU_STATE_DEACTIVATED);
332
333 Transmit(command);
abbca718
LOK
334}
335
2abe74eb 336void CCECProcessor::ReportVendorID(cec_logical_address address /* = CECDEVICE_TV */)
abbca718 337{
88f45c9b 338 m_controller->AddLog(CEC_LOG_NOTICE, "<< vendor ID requested, feature abort");
abbca718
LOK
339 TransmitAbort(address, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID);
340}
341
2abe74eb 342void CCECProcessor::ReportOSDName(cec_logical_address address /* = CECDEVICE_TV */)
abbca718 343{
abbca718
LOK
344 const char *osdname = m_strDeviceName.c_str();
345 CStdString strLog;
88f45c9b 346 strLog.Format("<< reporting OSD name as %s", osdname);
2abe74eb 347 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
abbca718 348
06a1f7ce
LOK
349 cec_command command;
350 cec_command::format(command, m_iLogicalAddress, address, CEC_OPCODE_SET_OSD_NAME);
9dee1670
LOK
351 for (unsigned int iPtr = 0; iPtr < strlen(osdname); iPtr++)
352 command.parameters.push_back(osdname[iPtr]);
abbca718 353
9dee1670 354 Transmit(command);
abbca718
LOK
355}
356
2abe74eb 357void CCECProcessor::ReportPhysicalAddress(void)
abbca718 358{
abbca718 359 CStdString strLog;
2492216a 360 strLog.Format("<< reporting physical address as %04x", m_iPhysicalAddress);
2abe74eb 361 m_controller->AddLog(CEC_LOG_NOTICE, strLog.c_str());
9dee1670 362
06a1f7ce
LOK
363 cec_command command;
364 cec_command::format(command, m_iLogicalAddress, CECDEVICE_BROADCAST, CEC_OPCODE_REPORT_PHYSICAL_ADDRESS);
2492216a
LOK
365 command.parameters.push_back((uint8_t) ((m_iPhysicalAddress >> 8) & 0xFF));
366 command.parameters.push_back((uint8_t) (m_iPhysicalAddress & 0xFF));
4a75b661 367 command.parameters.push_back((uint8_t) (CEC_DEVICE_TYPE_PLAYBACK_DEVICE));
9dee1670
LOK
368
369 Transmit(command);
abbca718
LOK
370}
371
2abe74eb 372void CCECProcessor::BroadcastActiveSource(void)
abbca718 373{
a6d4fc28 374 m_controller->AddLog(CEC_LOG_NOTICE, "<< broadcasting active source");
abbca718 375
06a1f7ce
LOK
376 cec_command command;
377 cec_command::format(command, m_iLogicalAddress, CECDEVICE_BROADCAST, CEC_OPCODE_ACTIVE_SOURCE);
2492216a
LOK
378 command.parameters.push_back((uint8_t) ((m_iPhysicalAddress >> 8) & 0xFF));
379 command.parameters.push_back((uint8_t) (m_iPhysicalAddress & 0xFF));
9dee1670
LOK
380
381 Transmit(command);
abbca718
LOK
382}
383
050df0f9 384bool CCECProcessor::WaitForAck(bool *bError, uint32_t iTimeout /* = 1000 */)
abbca718 385{
78e8010a 386 bool bTransmitSucceeded = false, bEom = false;
050df0f9 387 *bError = false;
abbca718
LOK
388
389 int64_t iNow = GetTimeMs();
25701fa6 390 int64_t iTargetTime = iNow + (uint64_t) iTimeout;
abbca718 391
78e8010a 392 while (!bTransmitSucceeded && !*bError && (iTimeout == 0 || iNow < iTargetTime))
abbca718 393 {
9dee1670 394 cec_adapter_message msg;
25701fa6
LOK
395 msg.clear();
396
06a1f7ce 397 if (!m_communication->Read(msg, iTimeout > 0 ? (int32_t)(iTargetTime - iNow) : 1000))
abbca718 398 {
abbca718 399 iNow = GetTimeMs();
5d38b0b6
LOK
400 continue;
401 }
402
78e8010a 403 ParseMessage(msg, bError, &bTransmitSucceeded, &bEom, false);
5d38b0b6 404 iNow = GetTimeMs();
abbca718
LOK
405 }
406
78e8010a 407 return bTransmitSucceeded && !*bError;
abbca718
LOK
408}
409
78e8010a 410void CCECProcessor::ParseMessage(cec_adapter_message &msg, bool *bError, bool *bTransmitSucceeded, bool *bEom, bool bProcessMessages /* = true */)
abbca718 411{
78e8010a
LOK
412 *bError = false;
413 *bTransmitSucceeded = false;
414 *bEom = false;
60fa4578 415
a6b6469c 416 if (msg.empty())
78e8010a 417 return;
abbca718
LOK
418
419 CStdString logStr;
abbca718 420
a6b6469c 421 switch(msg.message())
abbca718
LOK
422 {
423 case MSGCODE_NOTHING:
2abe74eb 424 m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_NOTHING");
abbca718
LOK
425 break;
426 case MSGCODE_TIMEOUT_ERROR:
427 case MSGCODE_HIGH_ERROR:
428 case MSGCODE_LOW_ERROR:
429 {
a6b6469c 430 if (msg.message() == MSGCODE_TIMEOUT_ERROR)
abbca718 431 logStr = "MSGCODE_TIMEOUT";
a6b6469c 432 else if (msg.message() == MSGCODE_HIGH_ERROR)
abbca718
LOK
433 logStr = "MSGCODE_HIGH_ERROR";
434 else
435 logStr = "MSGCODE_LOW_ERROR";
436
a6b6469c
LOK
437 int iLine = (msg.size() >= 3) ? (msg[1] << 8) | (msg[2]) : 0;
438 uint32_t iTime = (msg.size() >= 7) ? (msg[3] << 24) | (msg[4] << 16) | (msg[5] << 8) | (msg[6]) : 0;
abbca718
LOK
439 logStr.AppendFormat(" line:%i", iLine);
440 logStr.AppendFormat(" time:%u", iTime);
2abe74eb 441 m_controller->AddLog(CEC_LOG_WARNING, logStr.c_str());
78e8010a 442 *bError = true;
abbca718
LOK
443 }
444 break;
445 case MSGCODE_FRAME_START:
446 {
78e8010a 447 if (bProcessMessages)
abbca718 448 {
78e8010a
LOK
449 logStr = "MSGCODE_FRAME_START";
450 m_currentframe.clear();
451 if (msg.size() >= 2)
452 {
453 logStr.AppendFormat(" initiator:%u destination:%u ack:%s %s", msg.initiator(), msg.destination(), msg.ack() ? "high" : "low", msg.eom() ? "eom" : "");
454 m_currentframe.initiator = msg.initiator();
455 m_currentframe.destination = msg.destination();
456 m_currentframe.ack = msg.ack();
457 m_currentframe.eom = msg.eom();
458 }
459 m_controller->AddLog(CEC_LOG_DEBUG, logStr.c_str());
460 }
461 else
462 {
463 m_frameBuffer.Push(msg);
abbca718 464 }
abbca718
LOK
465 }
466 break;
467 case MSGCODE_FRAME_DATA:
468 {
78e8010a
LOK
469 if (bProcessMessages)
470 {
471 logStr = "MSGCODE_FRAME_DATA";
472 if (msg.size() >= 2)
473 {
474 uint8_t iData = msg[1];
475 logStr.AppendFormat(" %02x", iData);
476 m_currentframe.push_back(iData);
477 m_currentframe.eom = msg.eom();
478 }
479 m_controller->AddLog(CEC_LOG_DEBUG, logStr.c_str());
480 }
481 else
abbca718 482 {
78e8010a 483 m_frameBuffer.Push(msg);
abbca718 484 }
78e8010a
LOK
485
486 *bEom = msg.eom();
abbca718 487 }
78e8010a
LOK
488 break;
489 case MSGCODE_COMMAND_ACCEPTED:
490 m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_COMMAND_ACCEPTED");
491 break;
492 case MSGCODE_TRANSMIT_SUCCEEDED:
493 m_controller->AddLog(CEC_LOG_DEBUG, "MSGCODE_TRANSMIT_SUCCEEDED");
494 *bTransmitSucceeded = true;
495 break;
496 case MSGCODE_RECEIVE_FAILED:
497 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_RECEIVE_FAILED");
498 *bError = true;
499 break;
500 case MSGCODE_COMMAND_REJECTED:
501 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_COMMAND_REJECTED");
502 *bError = true;
503 break;
504 case MSGCODE_TRANSMIT_FAILED_LINE:
505 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_LINE");
506 *bError = true;
507 break;
508 case MSGCODE_TRANSMIT_FAILED_ACK:
509 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_ACK");
510 *bError = true;
511 break;
512 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
513 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA");
514 *bError = true;
515 break;
516 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
517 m_controller->AddLog(CEC_LOG_WARNING, "MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE");
518 *bError = true;
abbca718
LOK
519 break;
520 default:
521 break;
522 }
523}
524
9dee1670 525void CCECProcessor::ParseVendorId(cec_logical_address device, const cec_datapacket &data)
5f150ee2 526{
9dee1670 527 if (data.size < 3)
5f150ee2
LOK
528 {
529 m_controller->AddLog(CEC_LOG_WARNING, "invalid vendor ID received");
530 return;
531 }
532
a6b6469c
LOK
533 uint64_t iVendorId = ((uint64_t)data[0] << 3) +
534 ((uint64_t)data[1] << 2) +
535 (uint64_t)data[2];
5f150ee2 536
e9de9629 537 m_busDevices[(uint8_t)device]->SetVendorId(iVendorId, data.size >= 4 ? data[3] : 0);
5f150ee2
LOK
538}
539
e9de9629 540void CCECProcessor::ParseCommand(cec_command &command)
abbca718 541{
e9de9629
LOK
542 CStdString dataStr;
543 dataStr.Format(">> received frame: %1x%1x:%02x", command.initiator, command.destination, command.opcode);
544 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
545 dataStr.AppendFormat(":%02x", (unsigned int)command.parameters[iPtr]);
546 m_controller->AddLog(CEC_LOG_DEBUG, dataStr.c_str());
dc113aca 547
e9de9629
LOK
548 if (!m_bMonitor)
549 m_busDevices[(uint8_t)command.initiator]->HandleCommand(command);
dc113aca
LOK
550}
551
e9de9629 552void CCECProcessor::SetCurrentButton(cec_user_control_code iButtonCode)
dc113aca 553{
e9de9629 554 m_controller->SetCurrentButton(iButtonCode);
dc113aca
LOK
555}
556
e9de9629 557void CCECProcessor::AddCommand(const cec_command &command)
dc113aca 558{
e9de9629 559 m_controller->AddCommand(command);
dc113aca
LOK
560}
561
e9de9629 562void CCECProcessor::AddKey(void)
dc113aca 563{
e9de9629 564 m_controller->AddKey();
abbca718 565}
acec5f48 566
e9de9629 567void CCECProcessor::AddLog(cec_log_level level, const CStdString &strMessage)
acec5f48 568{
e9de9629 569 m_controller->AddLog(level, strMessage);
acec5f48 570}