Close();
}
-bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */)
+bool CUSBCECAdapterCommunication::Open(IAdapterCommunicationCallback *cb, uint32_t iTimeoutMs /* = 10000 */)
{
uint64_t iNow = GetTimeMs();
uint64_t iTimeout = iNow + iTimeoutMs;
return true;
}
+ m_callback = cb;
CStdString strError;
bool bConnected(false);
while (!bConnected && iNow < iTimeout)
void *CUSBCECAdapterCommunication::Process(void)
{
+ cec_command command;
while (!IsStopped())
{
ReadFromDevice(50);
+
+ /* push the next command to the callback method if there is one */
+ if (m_callback && Read(command, 0))
+ m_callback->OnCommandReceived(command);
+
Sleep(5);
WriteNextCommand();
}
bool CUSBCECAdapterCommunication::Write(CCECAdapterMessage *data)
{
- bool bReturn(false);
-
CLockObject lock(data->mutex);
data->state = ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT;
m_outBuffer.Push(data);
data->condition.Wait(data->mutex);
- if (data->state != ADAPTER_MESSAGE_STATE_SENT)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "command was not sent");
- }
- else if (data->expectControllerAck)
- {
- bReturn = WaitForAck(*data);
- if (bReturn)
- {
- if (data->isTransmission)
- data->state = ADAPTER_MESSAGE_STATE_SENT_ACKED;
- }
- else
- {
- data->state = ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED;
- CLibCEC::AddLog(CEC_LOG_DEBUG, "did not receive ack");
- }
- }
- else
+ if ((data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT_ACKED) ||
+ (!data->expectControllerAck && data->state != ADAPTER_MESSAGE_STATE_SENT))
{
- bReturn = true;
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "command was not %s", data->state == ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED ? "acked" : "sent");
+ return false;
}
- return bReturn;
+ return true;
}
bool CUSBCECAdapterCommunication::Read(cec_command &command, uint32_t iTimeout)
if (!m_inBuffer.Pop(buf))
{
- if (!m_rcvCondition.Wait(m_mutex, iTimeout))
+ if (iTimeout == 0 || !m_rcvCondition.Wait(m_mutex, iTimeout))
return false;
m_inBuffer.Pop(buf);
}
output->isTransmission = false;
output->expectControllerAck = false;
- SendMessageToAdapter(output);
+ bool bWriteOk = Write(output);
delete output;
-
- CCECAdapterMessage input;
- if (!Read(input, CEC_DEFAULT_TRANSMIT_WAIT) || input.Message() != MSGCODE_FIRMWARE_VERSION || input.Size() != 3)
- CLibCEC::AddLog(CEC_LOG_ERROR, "no or invalid firmware version (size = %d, message = %d)", input.Size(), input.Message());
+ if (!bWriteOk)
+ {
+ CLibCEC::AddLog(CEC_LOG_ERROR, "could not request the firmware version");
+ }
else
{
- m_iFirmwareVersion = (input[1] << 8 | input[2]);
- iReturn = m_iFirmwareVersion;
+ ReadFromDevice(CEC_DEFAULT_TRANSMIT_WAIT, 5 /* start + msgcode + 2 bytes for fw version + end */);
+ CCECAdapterMessage input;
+ if (!Read(input, 0) || input.Message() != MSGCODE_FIRMWARE_VERSION || input.Size() != 3)
+ CLibCEC::AddLog(CEC_LOG_ERROR, "no or invalid firmware version (size = %d, message = %d)", input.Size(), input.Message());
+ else
+ {
+ m_iFirmwareVersion = (input[1] << 8 | input[2]);
+ iReturn = m_iFirmwareVersion;
+ }
}
}
uint8_t iPacketsLeft(message.Size() / 4);
int64_t iNow = GetTimeMs();
- int64_t iTargetTime = iNow + message.transmit_timeout;
+ int64_t iTargetTime = iNow + (message.transmit_timeout <= 5 ? CEC_DEFAULT_TRANSMIT_WAIT : message.transmit_timeout);
- while (!bTransmitSucceeded && !bError && (message.transmit_timeout == 0 || iNow < iTargetTime))
+ while (!bTransmitSucceeded && !bError && iNow < iTargetTime)
{
+ ReadFromDevice(50);
CCECAdapterMessage msg;
- int32_t iWait = (int32_t)(iTargetTime - iNow);
- if (iWait <= 5 || message.transmit_timeout <= 5)
- iWait = CEC_DEFAULT_TRANSMIT_WAIT;
-
- if (!Read(msg, iWait))
+ if (!Read(msg, 0))
{
iNow = GetTimeMs();
continue;
}
}
+ message.state = bTransmitSucceeded && !bError ?
+ ADAPTER_MESSAGE_STATE_SENT_ACKED :
+ ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED;
+
return bTransmitSucceeded && !bError;
}
}
}
-bool CUSBCECAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
+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(buff), iTimeout);
+ 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());
{
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->condition.Signal();
}