+
+bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, CCECAdapterMessage ¶ms, bool bExpectAck /* = true */, bool bIsTransmission /* = false */, bool bSendDirectly /* = true */, bool bIsRetry /* = false */)
+{
+ CLockObject lock(m_mutex);
+
+ CCECAdapterMessage *output = new CCECAdapterMessage;
+
+ output->PushBack(MSGSTART);
+ output->PushEscaped((uint8_t)msgCode);
+ output->Append(params);
+ output->PushBack(MSGEND);
+ output->isTransmission = bIsTransmission;
+ output->expectControllerAck = bExpectAck;
+
+ if (bSendDirectly)
+ SendMessageToAdapter(output);
+ else
+ Write(output);
+
+ bool bWriteOk = output->state == (output->expectControllerAck ? ADAPTER_MESSAGE_STATE_SENT_ACKED : ADAPTER_MESSAGE_STATE_SENT);
+ if (!bWriteOk)
+ {
+ CLibCEC::AddLog(CEC_LOG_ERROR, "'%s' failed", CCECAdapterMessage::ToString(msgCode));
+ delete output;
+
+ if (!bIsRetry && output->reply == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
+ {
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "setting controlled mode and retrying");
+ if (SetControlledMode(true))
+ return SendCommand(msgCode, params, bExpectAck, bIsTransmission, bSendDirectly, true);
+ }
+ return false;
+ }
+
+ delete output;
+ return true;
+}
+
+cec_datapacket CUSBCECAdapterCommunication::GetSetting(cec_adapter_messagecode msgCode, uint8_t iResponseLength)
+{
+ cec_datapacket retVal;
+ retVal.Clear();
+
+ CCECAdapterMessage params;
+ if (!SendCommand(msgCode, params, false))
+ {
+ CLibCEC::AddLog(CEC_LOG_ERROR, "%s failed", CCECAdapterMessage::ToString(msgCode));
+ return retVal;
+ }
+
+ Sleep(250); // TODO ReadFromDevice() isn't waiting for the timeout to pass on win32
+ ReadFromDevice(CEC_DEFAULT_TRANSMIT_WAIT, iResponseLength + 3 /* start + msgcode + iResponseLength + end */);
+ CCECAdapterMessage input;
+ if (Read(input, 0))
+ {
+ if (input.Message() != msgCode)
+ CLibCEC::AddLog(CEC_LOG_ERROR, "invalid response to %s received (%s)", CCECAdapterMessage::ToString(msgCode), CCECAdapterMessage::ToString(input.Message()));
+ else
+ {
+ for (uint8_t iPtr = 1; iPtr < input.Size(); iPtr++)
+ retVal.PushBack(input[iPtr]);
+ }
+ }
+ else
+ {
+ CLibCEC::AddLog(CEC_LOG_ERROR, "no response to %s received", CCECAdapterMessage::ToString(msgCode));
+ }
+
+ return retVal;
+}