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