Commit | Line | Data |
---|---|---|
a75e3a5a LOK |
1 | /* |
2 | * This file is part of the libCEC(R) library. | |
3 | * | |
4 | * libCEC(R) is Copyright (C) 2011-2012 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 | ||
2b44051c | 33 | #include "env.h" |
a75e3a5a | 34 | #include "USBCECAdapterCommands.h" |
2b44051c LOK |
35 | |
36 | #include "USBCECAdapterMessage.h" | |
37 | #include "USBCECAdapterCommunication.h" | |
38 | #include "lib/LibCEC.h" | |
39 | #include "lib/CECProcessor.h" | |
40 | #include "lib/CECTypeUtils.h" | |
41 | #include <stdio.h> | |
a75e3a5a LOK |
42 | |
43 | using namespace CEC; | |
44 | using namespace PLATFORM; | |
45 | ||
004b8382 | 46 | #define LIB_CEC m_comm->m_callback->GetLib() |
0d800fe5 | 47 | #define ToString(p) CCECTypeUtils::ToString(p) |
004b8382 | 48 | |
7c5c5bf4 LOK |
49 | CUSBCECAdapterCommands::CUSBCECAdapterCommands(CUSBCECAdapterCommunication *comm) : |
50 | m_comm(comm), | |
51 | m_bSettingsRetrieved(false), | |
52 | m_bSettingAutoEnabled(false), | |
53 | m_settingCecVersion(CEC_VERSION_UNKNOWN), | |
54 | m_iSettingLAMask(0), | |
b2f56d35 | 55 | m_bNeedsWrite(false), |
d2d1660c | 56 | m_iBuildDate(CEC_FW_BUILD_UNKNOWN) |
7c5c5bf4 LOK |
57 | { |
58 | m_persistedConfiguration.Clear(); | |
59 | } | |
60 | ||
a75e3a5a LOK |
61 | cec_datapacket CUSBCECAdapterCommands::RequestSetting(cec_adapter_messagecode msgCode) |
62 | { | |
63 | cec_datapacket retVal; | |
64 | retVal.Clear(); | |
65 | ||
66 | CCECAdapterMessage params; | |
67 | CCECAdapterMessage *message = m_comm->SendCommand(msgCode, params); | |
68 | if (message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED) | |
69 | { | |
70 | retVal = message->response; | |
71 | retVal.Shift(2); // shift out start and msgcode | |
72 | retVal.size -= 1; // remove end | |
73 | } | |
c9d15485 | 74 | |
a75e3a5a LOK |
75 | delete message; |
76 | return retVal; | |
77 | } | |
78 | ||
79 | uint16_t CUSBCECAdapterCommands::RequestFirmwareVersion(void) | |
80 | { | |
7c5c5bf4 | 81 | m_persistedConfiguration.iFirmwareVersion = CEC_FW_VERSION_UNKNOWN; |
a75e3a5a LOK |
82 | unsigned int iFwVersionTry(0); |
83 | ||
7c5c5bf4 | 84 | while (m_persistedConfiguration.iFirmwareVersion == CEC_FW_VERSION_UNKNOWN && iFwVersionTry++ < 3) |
a75e3a5a | 85 | { |
004b8382 | 86 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting the firmware version"); |
a75e3a5a LOK |
87 | cec_datapacket response = RequestSetting(MSGCODE_FIRMWARE_VERSION); |
88 | if (response.size == 2) | |
7c5c5bf4 | 89 | m_persistedConfiguration.iFirmwareVersion = (response[0] << 8 | response[1]); |
a75e3a5a LOK |
90 | else |
91 | { | |
004b8382 | 92 | LIB_CEC->AddLog(CEC_LOG_WARNING, "the adapter did not respond with a correct firmware version (try %d)", iFwVersionTry); |
a75e3a5a LOK |
93 | CEvent::Sleep(500); |
94 | } | |
95 | } | |
96 | ||
7c5c5bf4 | 97 | if (m_persistedConfiguration.iFirmwareVersion == CEC_FW_VERSION_UNKNOWN) |
a75e3a5a | 98 | { |
004b8382 | 99 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "defaulting to firmware version 1"); |
7c5c5bf4 | 100 | m_persistedConfiguration.iFirmwareVersion = 1; |
a75e3a5a LOK |
101 | } |
102 | ||
7c5c5bf4 | 103 | return m_persistedConfiguration.iFirmwareVersion; |
a75e3a5a LOK |
104 | } |
105 | ||
7c5c5bf4 | 106 | bool CUSBCECAdapterCommands::RequestSettingAutoEnabled(void) |
a75e3a5a | 107 | { |
004b8382 | 108 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting autonomous mode setting"); |
a75e3a5a LOK |
109 | |
110 | cec_datapacket response = RequestSetting(MSGCODE_GET_AUTO_ENABLED); | |
111 | if (response.size == 1) | |
112 | { | |
7c5c5bf4 | 113 | m_bSettingAutoEnabled = response[0] == 1; |
004b8382 | 114 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted autonomous mode setting: '%s'", m_bSettingAutoEnabled ? "enabled" : "disabled"); |
a75e3a5a LOK |
115 | return true; |
116 | } | |
117 | return false; | |
118 | } | |
119 | ||
7c5c5bf4 | 120 | bool CUSBCECAdapterCommands::RequestSettingCECVersion(void) |
a75e3a5a | 121 | { |
004b8382 | 122 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting CEC version setting"); |
a75e3a5a LOK |
123 | |
124 | cec_datapacket response = RequestSetting(MSGCODE_GET_HDMI_VERSION); | |
125 | if (response.size == 1) | |
126 | { | |
7c5c5bf4 | 127 | m_settingCecVersion = (cec_version)response[0]; |
004b8382 | 128 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted CEC version setting: '%s'", ToString(m_settingCecVersion)); |
a75e3a5a LOK |
129 | return true; |
130 | } | |
131 | return false; | |
132 | } | |
133 | ||
b2f56d35 LOK |
134 | uint32_t CUSBCECAdapterCommands::RequestBuildDate(void) |
135 | { | |
d2d1660c | 136 | if (m_iBuildDate == CEC_FW_BUILD_UNKNOWN) |
c37545cf | 137 | { |
004b8382 | 138 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting firmware build date"); |
b2f56d35 | 139 | |
c37545cf LOK |
140 | cec_datapacket response = RequestSetting(MSGCODE_GET_BUILDDATE); |
141 | if (response.size == 4) | |
142 | m_iBuildDate = (uint32_t)response[0] << 24 | (uint32_t)response[1] << 16 | (uint32_t)response[2] << 8 | (uint32_t)response[3]; | |
143 | } | |
144 | return m_iBuildDate; | |
b2f56d35 LOK |
145 | } |
146 | ||
7c5c5bf4 | 147 | bool CUSBCECAdapterCommands::RequestSettingDefaultLogicalAddress(void) |
a75e3a5a | 148 | { |
004b8382 | 149 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting default logical address setting"); |
a75e3a5a LOK |
150 | |
151 | cec_datapacket response = RequestSetting(MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS); | |
152 | if (response.size == 1) | |
153 | { | |
7c5c5bf4 | 154 | m_persistedConfiguration.logicalAddresses.primary = (cec_logical_address)response[0]; |
004b8382 | 155 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted logical address setting: '%s'", ToString(m_persistedConfiguration.logicalAddresses.primary)); |
a75e3a5a LOK |
156 | return true; |
157 | } | |
158 | return false; | |
159 | } | |
160 | ||
7c5c5bf4 | 161 | bool CUSBCECAdapterCommands::RequestSettingDeviceType(void) |
a75e3a5a | 162 | { |
004b8382 | 163 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting device type setting"); |
7c5c5bf4 | 164 | m_persistedConfiguration.deviceTypes.Clear(); |
a75e3a5a LOK |
165 | |
166 | cec_datapacket response = RequestSetting(MSGCODE_GET_DEVICE_TYPE); | |
167 | if (response.size == 1) | |
168 | { | |
7c5c5bf4 | 169 | m_persistedConfiguration.deviceTypes.Add((cec_device_type)response[0]); |
004b8382 | 170 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted device type setting: '%s'", ToString((cec_device_type)response[0])); |
a75e3a5a LOK |
171 | return true; |
172 | } | |
004b8382 | 173 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "no persisted device type setting"); |
a75e3a5a LOK |
174 | return false; |
175 | } | |
176 | ||
7c5c5bf4 | 177 | bool CUSBCECAdapterCommands::RequestSettingLogicalAddressMask(void) |
a75e3a5a | 178 | { |
004b8382 | 179 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting logical address mask setting"); |
a75e3a5a LOK |
180 | |
181 | cec_datapacket response = RequestSetting(MSGCODE_GET_LOGICAL_ADDRESS_MASK); | |
182 | if (response.size == 2) | |
183 | { | |
7c5c5bf4 | 184 | m_iSettingLAMask = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); |
004b8382 | 185 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted logical address mask setting: '%x'", m_iSettingLAMask); |
a75e3a5a LOK |
186 | return true; |
187 | } | |
188 | return false; | |
189 | } | |
190 | ||
7c5c5bf4 | 191 | bool CUSBCECAdapterCommands::RequestSettingOSDName(void) |
a75e3a5a | 192 | { |
004b8382 | 193 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting OSD name setting"); |
a75e3a5a | 194 | |
7c5c5bf4 | 195 | memset(m_persistedConfiguration.strDeviceName, 0, 13); |
a75e3a5a LOK |
196 | cec_datapacket response = RequestSetting(MSGCODE_GET_OSD_NAME); |
197 | if (response.size == 0) | |
7c5c5bf4 | 198 | { |
004b8382 | 199 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "no persisted device name setting"); |
a75e3a5a | 200 | return false; |
7c5c5bf4 | 201 | } |
a75e3a5a LOK |
202 | |
203 | char buf[14]; | |
204 | for (uint8_t iPtr = 0; iPtr < response.size && iPtr < 13; iPtr++) | |
205 | buf[iPtr] = (char)response[iPtr]; | |
206 | buf[response.size] = 0; | |
207 | ||
7c5c5bf4 | 208 | snprintf(m_persistedConfiguration.strDeviceName, 13, "%s", buf); |
004b8382 | 209 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted device name setting: '%s'", buf); |
a75e3a5a LOK |
210 | return true; |
211 | } | |
212 | ||
7c5c5bf4 | 213 | bool CUSBCECAdapterCommands::RequestSettingPhysicalAddress(void) |
a75e3a5a | 214 | { |
004b8382 | 215 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "requesting physical address setting"); |
a75e3a5a LOK |
216 | |
217 | cec_datapacket response = RequestSetting(MSGCODE_GET_PHYSICAL_ADDRESS); | |
218 | if (response.size == 2) | |
219 | { | |
7c5c5bf4 | 220 | m_persistedConfiguration.iPhysicalAddress = ((uint16_t)response[0] << 8) | ((uint16_t)response[1]); |
004b8382 | 221 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "using persisted physical address setting: '%4x'", m_persistedConfiguration.iPhysicalAddress); |
a75e3a5a LOK |
222 | return true; |
223 | } | |
004b8382 | 224 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "no persisted physical address setting"); |
a75e3a5a LOK |
225 | return false; |
226 | } | |
227 | ||
228 | bool CUSBCECAdapterCommands::SetSettingAutoEnabled(bool enabled) | |
229 | { | |
2b44051c | 230 | bool bReturn(false); |
7c5c5bf4 LOK |
231 | |
232 | /* check whether this value was changed */ | |
c8b0c13a LOK |
233 | { |
234 | CLockObject lock(m_mutex); | |
235 | if (m_bSettingAutoEnabled == enabled) | |
236 | return bReturn; | |
237 | m_bNeedsWrite = true; | |
238 | } | |
7c5c5bf4 | 239 | |
004b8382 | 240 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "turning autonomous mode %s", enabled ? "on" : "off"); |
a75e3a5a LOK |
241 | |
242 | CCECAdapterMessage params; | |
243 | params.PushEscaped(enabled ? 1 : 0); | |
244 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_AUTO_ENABLED, params); | |
7c5c5bf4 | 245 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 246 | delete message; |
7c5c5bf4 LOK |
247 | |
248 | if (bReturn) | |
c8b0c13a LOK |
249 | { |
250 | CLockObject lock(m_mutex); | |
7c5c5bf4 | 251 | m_bSettingAutoEnabled = enabled; |
c8b0c13a | 252 | } |
7c5c5bf4 | 253 | |
a75e3a5a LOK |
254 | return bReturn; |
255 | } | |
256 | ||
257 | bool CUSBCECAdapterCommands::SetSettingDeviceType(cec_device_type type) | |
258 | { | |
2b44051c | 259 | bool bReturn(false); |
7c5c5bf4 LOK |
260 | |
261 | /* check whether this value was changed */ | |
c8b0c13a LOK |
262 | { |
263 | CLockObject lock(m_mutex); | |
264 | if (m_persistedConfiguration.deviceTypes.types[0] == type) | |
265 | return bReturn; | |
266 | m_bNeedsWrite = true; | |
267 | } | |
7c5c5bf4 | 268 | |
004b8382 | 269 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the device type to %X (previous: %X)", (uint8_t)type, (uint8_t)m_persistedConfiguration.deviceTypes.types[0]); |
a75e3a5a LOK |
270 | |
271 | CCECAdapterMessage params; | |
272 | params.PushEscaped((uint8_t)type); | |
273 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_DEVICE_TYPE, params); | |
7c5c5bf4 | 274 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 275 | delete message; |
7c5c5bf4 | 276 | |
c8b0c13a LOK |
277 | if (bReturn) |
278 | { | |
279 | CLockObject lock(m_mutex); | |
280 | m_persistedConfiguration.deviceTypes.types[0] = type; | |
281 | } | |
282 | ||
a75e3a5a LOK |
283 | return bReturn; |
284 | } | |
285 | ||
286 | bool CUSBCECAdapterCommands::SetSettingDefaultLogicalAddress(cec_logical_address address) | |
287 | { | |
2b44051c | 288 | bool bReturn(false); |
7c5c5bf4 LOK |
289 | |
290 | /* check whether this value was changed */ | |
c8b0c13a LOK |
291 | { |
292 | CLockObject lock(m_mutex); | |
293 | if (m_persistedConfiguration.logicalAddresses.primary == address) | |
294 | return bReturn; | |
295 | m_bNeedsWrite = true; | |
296 | } | |
7c5c5bf4 | 297 | |
004b8382 | 298 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the default logical address to %X (previous: %X)", (uint8_t)address, (uint8_t)m_persistedConfiguration.logicalAddresses.primary); |
a75e3a5a LOK |
299 | |
300 | CCECAdapterMessage params; | |
301 | params.PushEscaped((uint8_t)address); | |
302 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, params); | |
7c5c5bf4 | 303 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 304 | delete message; |
7c5c5bf4 LOK |
305 | |
306 | if (bReturn) | |
c8b0c13a LOK |
307 | { |
308 | CLockObject lock(m_mutex); | |
7c5c5bf4 | 309 | m_persistedConfiguration.logicalAddresses.primary = address; |
c8b0c13a | 310 | } |
7c5c5bf4 | 311 | |
a75e3a5a LOK |
312 | return bReturn; |
313 | } | |
314 | ||
315 | bool CUSBCECAdapterCommands::SetSettingLogicalAddressMask(uint16_t iMask) | |
316 | { | |
2b44051c | 317 | bool bReturn(false); |
7c5c5bf4 LOK |
318 | |
319 | /* check whether this value was changed */ | |
c8b0c13a LOK |
320 | { |
321 | CLockObject lock(m_mutex); | |
322 | if (m_iSettingLAMask == iMask) | |
323 | return bReturn; | |
324 | m_bNeedsWrite = true; | |
325 | } | |
7c5c5bf4 | 326 | |
004b8382 | 327 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the logical address mask to %2X (previous: %2X)", iMask, m_iSettingLAMask); |
a75e3a5a LOK |
328 | |
329 | CCECAdapterMessage params; | |
330 | params.PushEscaped(iMask >> 8); | |
331 | params.PushEscaped((uint8_t)iMask); | |
332 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_LOGICAL_ADDRESS_MASK, params); | |
7c5c5bf4 | 333 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 334 | delete message; |
7c5c5bf4 LOK |
335 | |
336 | if (bReturn) | |
c8b0c13a LOK |
337 | { |
338 | CLockObject lock(m_mutex); | |
7c5c5bf4 | 339 | m_iSettingLAMask = iMask; |
c8b0c13a | 340 | } |
7c5c5bf4 | 341 | |
a75e3a5a LOK |
342 | return bReturn; |
343 | } | |
344 | ||
345 | bool CUSBCECAdapterCommands::SetSettingPhysicalAddress(uint16_t iPhysicalAddress) | |
346 | { | |
2b44051c | 347 | bool bReturn(false); |
7c5c5bf4 LOK |
348 | |
349 | /* check whether this value was changed */ | |
c8b0c13a LOK |
350 | { |
351 | CLockObject lock(m_mutex); | |
352 | if (m_persistedConfiguration.iPhysicalAddress == iPhysicalAddress) | |
353 | return bReturn; | |
354 | m_bNeedsWrite = true; | |
355 | } | |
7c5c5bf4 | 356 | |
004b8382 | 357 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the physical address to %04X (previous: %04X)", iPhysicalAddress, m_persistedConfiguration.iPhysicalAddress); |
a75e3a5a LOK |
358 | |
359 | CCECAdapterMessage params; | |
360 | params.PushEscaped(iPhysicalAddress >> 8); | |
361 | params.PushEscaped((uint8_t)iPhysicalAddress); | |
362 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_PHYSICAL_ADDRESS, params); | |
7c5c5bf4 | 363 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 364 | delete message; |
7c5c5bf4 LOK |
365 | |
366 | if (bReturn) | |
c8b0c13a LOK |
367 | { |
368 | CLockObject lock(m_mutex); | |
7c5c5bf4 | 369 | m_persistedConfiguration.iPhysicalAddress = iPhysicalAddress; |
c8b0c13a | 370 | } |
7c5c5bf4 | 371 | |
a75e3a5a LOK |
372 | return bReturn; |
373 | } | |
374 | ||
375 | bool CUSBCECAdapterCommands::SetSettingCECVersion(cec_version version) | |
376 | { | |
2b44051c | 377 | bool bReturn(false); |
7c5c5bf4 LOK |
378 | |
379 | /* check whether this value was changed */ | |
c8b0c13a LOK |
380 | { |
381 | CLockObject lock(m_mutex); | |
382 | if (m_settingCecVersion == version) | |
383 | return bReturn; | |
384 | m_bNeedsWrite = true; | |
385 | } | |
7c5c5bf4 | 386 | |
004b8382 | 387 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the CEC version to %s (previous: %s)", ToString(version), ToString(m_settingCecVersion)); |
a75e3a5a LOK |
388 | |
389 | CCECAdapterMessage params; | |
390 | params.PushEscaped((uint8_t)version); | |
391 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_HDMI_VERSION, params); | |
7c5c5bf4 | 392 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 393 | delete message; |
7c5c5bf4 LOK |
394 | |
395 | if (bReturn) | |
c8b0c13a LOK |
396 | { |
397 | CLockObject lock(m_mutex); | |
7c5c5bf4 | 398 | m_settingCecVersion = version; |
c8b0c13a | 399 | } |
7c5c5bf4 | 400 | |
a75e3a5a LOK |
401 | return bReturn; |
402 | } | |
403 | ||
404 | bool CUSBCECAdapterCommands::SetSettingOSDName(const char *strOSDName) | |
405 | { | |
2b44051c | 406 | bool bReturn(false); |
7c5c5bf4 LOK |
407 | |
408 | /* check whether this value was changed */ | |
409 | if (!strcmp(m_persistedConfiguration.strDeviceName, strOSDName)) | |
7c5c5bf4 | 410 | return bReturn; |
7c5c5bf4 | 411 | |
004b8382 | 412 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the OSD name to %s (previous: %s)", strOSDName, m_persistedConfiguration.strDeviceName); |
a75e3a5a LOK |
413 | |
414 | CCECAdapterMessage params; | |
415 | for (size_t iPtr = 0; iPtr < strlen(strOSDName); iPtr++) | |
416 | params.PushEscaped(strOSDName[iPtr]); | |
417 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_OSD_NAME, params); | |
7c5c5bf4 | 418 | bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 419 | delete message; |
7c5c5bf4 LOK |
420 | |
421 | if (bReturn) | |
422 | snprintf(m_persistedConfiguration.strDeviceName, 13, "%s", strOSDName); | |
423 | ||
a75e3a5a LOK |
424 | return bReturn; |
425 | } | |
426 | ||
427 | bool CUSBCECAdapterCommands::WriteEEPROM(void) | |
428 | { | |
c8b0c13a LOK |
429 | { |
430 | CLockObject lock(m_mutex); | |
431 | if (!m_bNeedsWrite) | |
432 | return true; | |
433 | } | |
7c5c5bf4 | 434 | |
004b8382 | 435 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "writing settings in the EEPROM"); |
a75e3a5a LOK |
436 | |
437 | CCECAdapterMessage params; | |
438 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_WRITE_EEPROM, params); | |
c8b0c13a | 439 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; |
a75e3a5a | 440 | delete message; |
c8b0c13a LOK |
441 | |
442 | if (bReturn) | |
443 | { | |
444 | CLockObject lock(m_mutex); | |
445 | m_bNeedsWrite = false; | |
446 | } | |
447 | ||
448 | return bReturn; | |
a75e3a5a LOK |
449 | } |
450 | ||
c0152c09 | 451 | bool CUSBCECAdapterCommands::PersistConfiguration(const libcec_configuration &configuration) |
a75e3a5a | 452 | { |
2b44051c | 453 | bool bReturn(false); |
7c5c5bf4 | 454 | if (m_persistedConfiguration.iFirmwareVersion < 2) |
2b44051c | 455 | return bReturn; |
7c5c5bf4 LOK |
456 | |
457 | if (!RequestSettings()) | |
2b44051c LOK |
458 | return bReturn; |
459 | ||
460 | bReturn |= SetSettingAutoEnabled(true); | |
461 | bReturn |= SetSettingDeviceType(CLibCEC::GetType(configuration.logicalAddresses.primary)); | |
462 | bReturn |= SetSettingDefaultLogicalAddress(configuration.logicalAddresses.primary); | |
463 | bReturn |= SetSettingLogicalAddressMask(CLibCEC::GetMaskForType(configuration.logicalAddresses.primary)); | |
464 | bReturn |= SetSettingPhysicalAddress(configuration.iPhysicalAddress); | |
465 | bReturn |= SetSettingCECVersion(configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_0 ? configuration.cecVersion : CEC_VERSION_1_4); | |
466 | bReturn |= SetSettingOSDName(configuration.strDeviceName); | |
a75e3a5a | 467 | |
a75e3a5a LOK |
468 | return bReturn; |
469 | } | |
470 | ||
7c5c5bf4 | 471 | bool CUSBCECAdapterCommands::RequestSettings(void) |
a75e3a5a | 472 | { |
7c5c5bf4 | 473 | if (m_persistedConfiguration.iFirmwareVersion < 2) |
a75e3a5a | 474 | { |
004b8382 | 475 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - firmware version %d does not have any eeprom settings", __FUNCTION__, m_persistedConfiguration.iFirmwareVersion); |
7c5c5bf4 LOK |
476 | // settings can only be persisted with firmware v2+ |
477 | return false; | |
a75e3a5a LOK |
478 | } |
479 | ||
4c70b3b6 | 480 | if (m_bSettingsRetrieved) |
7c5c5bf4 | 481 | return true; |
a75e3a5a | 482 | |
7c5c5bf4 LOK |
483 | bool bReturn(true); |
484 | bReturn &= RequestSettingAutoEnabled(); | |
485 | bReturn &= RequestSettingCECVersion(); | |
486 | bReturn &= RequestSettingDefaultLogicalAddress(); | |
487 | bReturn &= RequestSettingDeviceType(); | |
488 | bReturn &= RequestSettingLogicalAddressMask(); | |
489 | bReturn &= RequestSettingOSDName(); | |
490 | bReturn &= RequestSettingPhysicalAddress(); | |
a75e3a5a LOK |
491 | |
492 | // don't read the following settings: | |
493 | // - auto enabled (always enabled) | |
494 | // - default logical address (autodetected) | |
495 | // - logical address mask (autodetected) | |
496 | // - CEC version (1.3a) | |
497 | ||
498 | // TODO to be added to the firmware: | |
499 | // - base device (4 bits) | |
500 | // - HDMI port number (4 bits) | |
501 | // - TV vendor id (12 bits) | |
502 | // - wake devices (8 bits) | |
503 | // - standby devices (8 bits) | |
504 | // - use TV menu language (1 bit) | |
505 | // - activate source (1 bit) | |
506 | // - power off screensaver (1 bit) | |
507 | // - power off on standby (1 bit) | |
508 | // - send inactive source (1 bit) | |
7c5c5bf4 LOK |
509 | |
510 | m_bSettingsRetrieved = true; | |
511 | ||
a75e3a5a LOK |
512 | return bReturn; |
513 | } | |
514 | ||
c0152c09 | 515 | bool CUSBCECAdapterCommands::GetConfiguration(libcec_configuration &configuration) |
7c5c5bf4 LOK |
516 | { |
517 | // get the settings from the eeprom if needed | |
518 | if (!RequestSettings()) | |
519 | return false; | |
520 | ||
521 | // copy the settings | |
c0152c09 LOK |
522 | configuration.iFirmwareVersion = m_persistedConfiguration.iFirmwareVersion; |
523 | configuration.deviceTypes = m_persistedConfiguration.deviceTypes; | |
524 | configuration.iPhysicalAddress = m_persistedConfiguration.iPhysicalAddress; | |
525 | snprintf(configuration.strDeviceName, 13, "%s", m_persistedConfiguration.strDeviceName); | |
7c5c5bf4 LOK |
526 | |
527 | return true; | |
528 | } | |
529 | ||
a75e3a5a LOK |
530 | bool CUSBCECAdapterCommands::PingAdapter(void) |
531 | { | |
004b8382 | 532 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending ping"); |
a75e3a5a LOK |
533 | |
534 | CCECAdapterMessage params; | |
535 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_PING, params); | |
536 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; | |
537 | delete message; | |
538 | return bReturn; | |
539 | } | |
540 | ||
541 | bool CUSBCECAdapterCommands::SetAckMask(uint16_t iMask) | |
542 | { | |
004b8382 | 543 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting ackmask to %2x", iMask); |
a75e3a5a LOK |
544 | |
545 | CCECAdapterMessage params; | |
546 | params.PushEscaped(iMask >> 8); | |
547 | params.PushEscaped((uint8_t)iMask); | |
548 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_ACK_MASK, params); | |
549 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; | |
550 | delete message; | |
551 | return bReturn; | |
552 | } | |
553 | ||
554 | bool CUSBCECAdapterCommands::StartBootloader(void) | |
555 | { | |
004b8382 | 556 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "starting the bootloader"); |
a75e3a5a LOK |
557 | |
558 | CCECAdapterMessage params; | |
559 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_START_BOOTLOADER, params); | |
560 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; | |
561 | delete message; | |
562 | return bReturn; | |
563 | } | |
564 | ||
565 | bool CUSBCECAdapterCommands::SetLineTimeout(uint8_t iTimeout) | |
566 | { | |
004b8382 | 567 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the line timeout to %d", iTimeout); |
a75e3a5a LOK |
568 | CCECAdapterMessage params; |
569 | params.PushEscaped(iTimeout); | |
570 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_TRANSMIT_IDLETIME, params); | |
571 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; | |
572 | delete message; | |
573 | return bReturn; | |
574 | } | |
575 | ||
576 | bool CUSBCECAdapterCommands::SetControlledMode(bool controlled) | |
577 | { | |
004b8382 | 578 | LIB_CEC->AddLog(CEC_LOG_DEBUG, "turning controlled mode %s", controlled ? "on" : "off"); |
a75e3a5a LOK |
579 | |
580 | CCECAdapterMessage params; | |
581 | params.PushEscaped(controlled ? 1 : 0); | |
582 | CCECAdapterMessage *message = m_comm->SendCommand(MSGCODE_SET_CONTROLLED, params); | |
583 | bool bReturn = message->state == ADAPTER_MESSAGE_STATE_SENT_ACKED; | |
584 | delete message; | |
585 | return bReturn; | |
586 | } |