- return bTransmitSucceeded && !bError;
-}
-
-void CUSBCECAdapterCommunication::AddData(uint8_t *data, size_t iLen)
-{
- CLockObject lock(m_mutex);
- for (size_t iPtr = 0; iPtr < iLen; iPtr++)
- {
- if (!m_bGotStart)
- {
- if (data[iPtr] == MSGSTART)
- m_bGotStart = true;
- }
- else if (data[iPtr] == MSGSTART) //we found a msgstart before msgend, this is not right, remove
- {
- if (m_currentAdapterMessage.Size() > 0)
- CLibCEC::AddLog(CEC_LOG_WARNING, "received MSGSTART before MSGEND, removing previous buffer contents");
- m_currentAdapterMessage.Clear();
- m_bGotStart = true;
- }
- else if (data[iPtr] == MSGEND)
- {
- CCECAdapterMessage *newMessage = new CCECAdapterMessage;
- newMessage->packet = m_currentAdapterMessage.packet;
- m_inBuffer.Push(newMessage);
- m_currentAdapterMessage.Clear();
- m_bGotStart = false;
- m_bNextIsEscaped = false;
- m_bHasData = true;
- m_rcvCondition.Broadcast();
- }
- else if (m_bNextIsEscaped)
- {
- m_currentAdapterMessage.PushBack(data[iPtr] + (uint8_t)ESCOFFSET);
- m_bNextIsEscaped = false;
- }
- else if (data[iPtr] == MSGESC)
- {
- m_bNextIsEscaped = true;
- }
- else
- {
- m_currentAdapterMessage.PushBack(data[iPtr]);
- }
- }
-}
-
-bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout, size_t iSize /* = 256 */)
-{
- ssize_t iBytesRead;
- uint8_t buff[256];
- if (!m_port)
- return false;
- if (iSize > 256)
- iSize = 256;
-
- CLockObject lock(m_mutex);
- iBytesRead = m_port->Read(buff, sizeof(uint8_t) * iSize, iTimeout);
- if (iBytesRead < 0 || iBytesRead > 256)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "error reading from serial port: %s", m_port->GetError().c_str());
- StopThread(false);
- return false;
- }
- else if (iBytesRead > 0)
- {
- AddData(buff, iBytesRead);
- }
-
- return iBytesRead > 0;
-}
-
-void CUSBCECAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
-{
- CLockObject adapterLock(m_mutex);
- if (!m_port->IsOpen())
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "error writing to serial port: the connection is closed");
- msg->state = ADAPTER_MESSAGE_STATE_ERROR;
- return;
- }
-
- if (msg->isTransmission && (msg->Size() < 2 || msg->At(1) != MSGCODE_TRANSMIT_IDLETIME))
- {
- if (msg->tries == 1)
- SetLineTimeout(msg->lineTimeout);
- else
- SetLineTimeout(msg->retryTimeout);
- }
-
- if (m_port->Write(msg->packet.data, msg->Size()) != (ssize_t) msg->Size())
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "error writing to serial port: %s", m_port->GetError().c_str());
- msg->state = ADAPTER_MESSAGE_STATE_ERROR;
- }
- else
- {
- CLibCEC::AddLog(CEC_LOG_DEBUG, "command sent");
- msg->state = ADAPTER_MESSAGE_STATE_SENT;
-
- if (msg->expectControllerAck)
- {
- if (!WaitForAck(*msg))
- CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack");
- }
- }
- msg->event.Signal();
-}
-
-CStdString CUSBCECAdapterCommunication::GetPortName(void)
-{
- CStdString strName;
- strName = m_port->GetName();
- return strName;
-}
-
-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);
- cec_adapter_messagecode reply = output->reply;
- delete output;
-
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "'%s' failed", CCECAdapterMessage::ToString(msgCode));
-
- if (!bIsRetry && 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;
- }
-
- 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;
- }
-
- 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]);
- }