m_messageProcessor(NULL),
m_bInitialised(false)
{
- m_port = new PLATFORM::CSerialPort(strPort, iBaudRate);
+ m_port = new CSerialPort(strPort, iBaudRate);
}
CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void)
return bReturn;
CLibCEC::AddLog(CEC_LOG_DEBUG, "starting the bootloader");
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_START_BOOTLOADER);
- output->PushBack(MSGEND);
- output->isTransmission = false;
- output->expectControllerAck = false;
-
- if ((bReturn = Write(output)) == false)
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not start the bootloader");
- delete output;
- return bReturn;
+ CCECAdapterMessage params;
+ return SendCommand(MSGCODE_START_BOOTLOADER, params, false);
}
bool CUSBCECAdapterCommunication::PingAdapter(void)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "sending ping");
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_PING);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not ping the adapter");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ return SendCommand(MSGCODE_PING, params);
}
bool CUSBCECAdapterCommunication::ParseMessage(const CCECAdapterMessage &msg)
{
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "requesting the firmware version");
- CCECAdapterMessage *output = new CCECAdapterMessage;
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_FIRMWARE_VERSION);
- output->PushBack(MSGEND);
- output->isTransmission = false;
- output->expectControllerAck = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT;
- delete output;
- if (!bWriteOk)
+ CCECAdapterMessage params;
+ if (!SendCommand(MSGCODE_FIRMWARE_VERSION, params, false))
{
CLibCEC::AddLog(CEC_LOG_ERROR, "could not request the firmware version");
return iReturn;
{
m_iFirmwareVersion = (input[1] << 8 | input[2]);
iReturn = m_iFirmwareVersion;
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "firmware version %d", m_iFirmwareVersion);
}
}
else
bool CUSBCECAdapterCommunication::SetLineTimeout(uint8_t iTimeout)
{
m_iLineTimeout = iTimeout;
- return true;
- //TODO
-// bool bReturn(m_iLineTimeout != iTimeout);
-//
-// if (!bReturn)
-// {
-// CCECAdapterMessage *output = new CCECAdapterMessage;
-//
-// output->PushBack(MSGSTART);
-// output->PushEscaped(MSGCODE_TRANSMIT_IDLETIME);
-// output->PushEscaped(iTimeout);
-// output->PushBack(MSGEND);
-// output->isTransmission = false;
-//
-// if ((bReturn = Write(output)) == false)
-// CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the idletime");
-// delete output;
-// }
-//
-// return bReturn;
+ bool bReturn(m_iLineTimeout != iTimeout);
+
+ if (!bReturn)
+ {
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the line timeout to %d", iTimeout);
+ CCECAdapterMessage params;
+ params.PushEscaped(iTimeout);
+ bReturn = SendCommand(MSGCODE_TRANSMIT_IDLETIME, params);
+ }
+
+ return bReturn;
}
bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask)
{
- return SetAckMaskInternal(iMask, false);
+ return SetAckMaskInternal(iMask, IsRunning());
}
bool CUSBCECAdapterCommunication::SetAckMaskInternal(uint16_t iMask, bool bWriteDirectly /* = false */)
{
- bool bReturn(false);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting ackmask to %2x", iMask);
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_ACK_MASK);
- output->PushEscaped(iMask >> 8);
- output->PushEscaped((uint8_t)iMask);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- if (bWriteDirectly)
- SendMessageToAdapter(output);
- else if ((bReturn = Write(output)) == false)
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the ackmask");
- delete output;
-
- return bReturn;
+ CCECAdapterMessage params;
+ params.PushEscaped(iMask >> 8);
+ params.PushEscaped((uint8_t)iMask);
+ return SendCommand(MSGCODE_SET_ACK_MASK, params, true, false, bWriteDirectly);
}
bool CUSBCECAdapterCommunication::PersistConfiguration(libcec_configuration *configuration)
if (m_iFirmwareVersion < 2)
return false;
- return SetAutoEnabled(true) &&
- SetDefaultLogicalAddress(configuration->logicalAddresses.primary) &&
- SetLogicalAddressMask(configuration->logicalAddresses.AckMask()) &&
- SetPhysicalAddress(configuration->iPhysicalAddress) &&
- SetCECVersion(CEC_VERSION_1_3A) &&
- SetOSDName(configuration->strDeviceName) &&
- WriteEEPROM();
+ bool bReturn(true);
+ bReturn &= SetAutoEnabled(true);
+ bReturn &= SetDeviceType(CLibCEC::GetType(configuration->logicalAddresses.primary));
+ bReturn &= SetDefaultLogicalAddress(configuration->logicalAddresses.primary);
+ bReturn &= SetLogicalAddressMask(CLibCEC::GetMaskForType(configuration->logicalAddresses.primary));
+ bReturn &= SetPhysicalAddress(configuration->iPhysicalAddress);
+ bReturn &= SetCECVersion(CEC_VERSION_1_3A);
+ bReturn &= SetOSDName(configuration->strDeviceName);
+ if (bReturn)
+ bReturn = WriteEEPROM();
+ return bReturn;
}
bool CUSBCECAdapterCommunication::SetControlledMode(bool controlled)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "turning controlled mode %s", controlled ? "on" : "off");
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_CONTROLLED);
- output->PushEscaped(controlled);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set controlled mode");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped(controlled ? 1 : 0);
+ return SendCommand(MSGCODE_SET_CONTROLLED, params);
}
bool CUSBCECAdapterCommunication::SetAutoEnabled(bool enabled)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "turning autonomous mode %s", enabled ? "on" : "off");
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_AUTO_ENABLED);
- output->PushEscaped(enabled);
- output->PushBack(MSGEND);
- output->isTransmission = false;
+ CCECAdapterMessage params;
+ params.PushEscaped(enabled ? 1 : 0);
+ return SendCommand(MSGCODE_SET_AUTO_ENABLED, params);
+}
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set autonomous mode");
- return false;
- }
+bool CUSBCECAdapterCommunication::SetDeviceType(cec_device_type type)
+{
+ CLockObject lock(m_mutex);
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the device type to %1X", (uint8_t)type);
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped((uint8_t)type);
+ return SendCommand(MSGCODE_SET_DEVICE_TYPE, params);
}
bool CUSBCECAdapterCommunication::SetDefaultLogicalAddress(cec_logical_address address)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the default logical address to %1X", address);
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS);
- output->PushEscaped((uint8_t) address);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the default logical address");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped((uint8_t)address);
+ return SendCommand(MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS, params);
}
bool CUSBCECAdapterCommunication::SetLogicalAddressMask(uint16_t iMask)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the logical address mask to %2X", iMask);
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_LOGICAL_ADDRESS_MASK);
- output->PushEscaped(iMask >> 8);
- output->PushEscaped((uint8_t)iMask);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the logical address mask");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped(iMask >> 8);
+ params.PushEscaped((uint8_t)iMask);
+ return SendCommand(MSGCODE_SET_LOGICAL_ADDRESS_MASK, params);
}
bool CUSBCECAdapterCommunication::SetPhysicalAddress(uint16_t iPhysicalAddress)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the physical address to %2X", iPhysicalAddress);
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_PHYSICAL_ADDRESS);
- output->PushEscaped(iPhysicalAddress >> 8);
- output->PushEscaped((uint8_t)iPhysicalAddress);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the physical address");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped(iPhysicalAddress >> 8);
+ params.PushEscaped((uint8_t)iPhysicalAddress);
+ return SendCommand(MSGCODE_SET_PHYSICAL_ADDRESS, params);
}
bool CUSBCECAdapterCommunication::SetCECVersion(cec_version version)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the CEC version to %s", CLibCEC::GetInstance()->ToString(version));
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_HDMI_VERSION);
- output->PushEscaped((uint8_t)version);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the CEC version");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ params.PushEscaped((uint8_t)version);
+ return SendCommand(MSGCODE_SET_HDMI_VERSION, params);
}
bool CUSBCECAdapterCommunication::SetOSDName(const char *strOSDName)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting the OSD name to %s", strOSDName);
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_SET_OSD_NAME);
+ CCECAdapterMessage params;
for (size_t iPtr = 0; iPtr < strlen(strOSDName); iPtr++)
- output->PushEscaped(strOSDName[iPtr]);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not set the OSD name");
- return false;
- }
-
- return true;
+ params.PushEscaped(strOSDName[iPtr]);
+ return SendCommand(MSGCODE_SET_OSD_NAME, params);
}
bool CUSBCECAdapterCommunication::WriteEEPROM(void)
CLockObject lock(m_mutex);
CLibCEC::AddLog(CEC_LOG_DEBUG, "writing settings in the EEPROM");
- CCECAdapterMessage *output = new CCECAdapterMessage;
-
- output->PushBack(MSGSTART);
- output->PushEscaped(MSGCODE_WRITE_EEPROM);
- output->PushBack(MSGEND);
- output->isTransmission = false;
-
- SendMessageToAdapter(output);
- bool bWriteOk = output->state == ADAPTER_MESSAGE_STATE_SENT_ACKED;
- delete output;
- if (!bWriteOk)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "could not write the settings in the EEPROM");
- return false;
- }
-
- return true;
+ CCECAdapterMessage params;
+ return SendCommand(MSGCODE_WRITE_EEPROM, params);
}
bool CUSBCECAdapterCommunication::IsOpen(void)
{
bool bError(false);
bool bTransmitSucceeded(false);
- uint8_t iPacketsLeft(message.Size() / 4);
+ uint8_t iPacketsLeft(message.isTransmission ? message.Size() / 4 : 1);
int64_t iNow = GetTimeMs();
int64_t iTargetTime = iNow + (message.transmit_timeout <= 5 ? CEC_DEFAULT_TRANSMIT_WAIT : message.transmit_timeout);
return;
}
- if (msg->tries == 1)
- SetLineTimeout(msg->lineTimeout);
- else
- SetLineTimeout(msg->retryTimeout);
+ 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())
{
strName = m_port->GetName();
return strName;
}
+
+bool CUSBCECAdapterCommunication::SendCommand(cec_adapter_messagecode msgCode, CCECAdapterMessage ¶ms, bool bExpectAck /* = true */, bool bIsTransmission /* = false */, bool bSendDirectly /* = true */)
+{
+ CLockObject lock(m_mutex);
+
+ CCECAdapterMessage *output = new CCECAdapterMessage;
+
+ output->PushBack(MSGSTART);
+ output->PushEscaped(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;
+ return false;
+ }
+
+ delete output;
+ return true;
+}