using namespace PLATFORM;
CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) :
- m_bStarted(false),
m_bInitialised(false),
m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
}
CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types) :
- m_bStarted(false),
m_bInitialised(false),
m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
CCECProcessor::~CCECProcessor(void)
{
- m_bStarted = false;
- m_startCondition.Broadcast();
StopThread();
delete m_communication;
CLockObject lock(m_mutex);
if (m_communication)
{
- CLibCEC::AddLog(CEC_LOG_ERROR, "existing connection handler found");
- return bReturn;
+ CLibCEC::AddLog(CEC_LOG_WARNING, "existing connection handler found, deleting it");
+ m_communication->Close();
+ delete m_communication;
}
m_communication = new CUSBCECAdapterCommunication(this, strPort, iBaudRate);
uint64_t iNow = GetTimeMs();
uint64_t iTarget = iTimeoutMs > 0 ? iNow + iTimeoutMs : iNow + CEC_DEFAULT_TRANSMIT_WAIT;
- unsigned iConnectTry(0), iPingTry(0), iFwVersionTry(0), iControlledTry(0);
- bool bConnected(false), bPinged(false), bControlled(false);
/* open a new connection */
- while (iNow < iTarget && (bConnected = m_communication->Open(iTimeoutMs)) == false)
+ unsigned iConnectTry(0);
+ while (iNow < iTarget && (bReturn = m_communication->Open(this, iTimeoutMs)) == false)
{
CLibCEC::AddLog(CEC_LOG_ERROR, "could not open a connection (try %d)", ++iConnectTry);
Sleep(500);
iNow = GetTimeMs();
}
- /* try to ping the adapter */
- while (bConnected && iNow < iTarget && (bPinged = m_communication->PingAdapter()) == false)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond correctly to a ping (try %d)", ++iPingTry);
- Sleep(500);
- iNow = GetTimeMs();
- }
-
- /* try to read the firmware version */
- uint16_t iFirmwareVersion(CEC_FW_VERSION_UNKNOWN);
- while (bPinged && iNow < iTarget && (iFirmwareVersion = m_communication->GetFirmwareVersion()) == CEC_FW_VERSION_UNKNOWN)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond with a correct firmware version (try %d)", ++iFwVersionTry);
- Sleep(500);
- iNow = GetTimeMs();
- }
-
- if (iFirmwareVersion >= 2)
- {
- /* try to set controlled mode */
- while (bConnected && iNow < iTarget && (bControlled = m_communication->SetControlledMode(true)) == false)
- {
- CLibCEC::AddLog(CEC_LOG_ERROR, "the adapter did not respond correctly to setting controlled mode (try %d)", ++iControlledTry);
- Sleep(500);
- iNow = GetTimeMs();
- }
- }
-
- if ((bReturn = iFirmwareVersion != CEC_FW_VERSION_UNKNOWN) == true)
- CLibCEC::AddLog(CEC_LOG_NOTICE, "connected to the CEC adapter. firmware version = %d", iFirmwareVersion);
+ if (bReturn)
+ CLibCEC::AddLog(CEC_LOG_NOTICE, "connected to the CEC adapter. firmware version = %d", m_communication->GetFirmwareVersion());
return bReturn;
}
+bool CCECProcessor::IsInitialised(void)
+{
+ CLockObject lock(m_mutex);
+ return m_bInitialised;
+}
+
void CCECProcessor::SetInitialised(bool bSetTo /* = true */)
{
CLockObject lock(m_mutex);
return bReturn;
/* create the processor thread */
- if (!CreateThread() || !m_startCondition.Wait(m_mutex) || !m_bStarted)
+ if (!CreateThread())
{
CLibCEC::AddLog(CEC_LOG_ERROR, "could not create a processor thread");
return bReturn;
void CCECProcessor::ReplaceHandlers(void)
{
+ CLockObject lock(m_mutex);
+ if (!IsInitialised())
+ return;
for (uint8_t iPtr = 0; iPtr <= CECDEVICE_PLAYBACKDEVICE3; iPtr++)
m_busDevices[iPtr]->ReplaceHandler(m_bInitialised);
}
-void *CCECProcessor::Process(void)
+bool CCECProcessor::OnCommandReceived(const cec_command &command)
{
- bool bParseFrame(false);
- cec_command command;
- CCECAdapterMessage msg;
+ m_commandBuffer.Push(command);
+ return true;
+}
- {
- CLockObject lock(m_mutex);
- m_bStarted = true;
- CLibCEC::AddLog(CEC_LOG_DEBUG, "processor thread started");
- m_startCondition.Signal();
- }
+void *CCECProcessor::Process(void)
+{
+ cec_command command;
+ CLibCEC::AddLog(CEC_LOG_DEBUG, "processor thread started");
- while (!IsStopped())
+ while (!IsStopped() && m_communication->IsOpen())
{
ReplaceHandlers();
- command.Clear();
-
- {
- CLockObject lock(m_mutex);
- if (m_commandBuffer.Pop(command))
- bParseFrame = true;
- else if (m_communication->IsOpen() && m_communication->Read(command, 50))
- bParseFrame = true;
- }
-
- if (bParseFrame)
+ if (m_commandBuffer.Pop(command))
ParseCommand(command);
- bParseFrame = false;
-
- Sleep(5);
m_controller->CheckKeypressTimeout();
+ Sleep(5);
}
if (m_communication)
+ {
m_communication->Close();
+ delete m_communication;
+ m_communication = NULL;
+ }
return NULL;
}
m_iBaseDevice = iBaseDevice;
m_iHDMIPort = iPort;
- if (!m_bStarted && !bForce)
+ if (!IsRunning() && !bForce)
return true;
CLibCEC::AddLog(CEC_LOG_DEBUG, "setting HDMI port to %d on device %s (%d)", iPort, ToString(iBaseDevice), (int)iBaseDevice);
bool bSendActiveView(false);
bool bReturn(false);
cec_logical_addresses sendUpdatesTo;
+ sendUpdatesTo.Clear();
{
CLockObject lock(m_mutex);
Transmit(command);
}
-void CCECProcessor::ParseCommand(cec_command &command)
+void CCECProcessor::ParseCommand(const cec_command &command)
{
CStdString dataStr;
dataStr.Format(">> %1x%1x:%02x", command.initiator, command.destination, command.opcode);
void CCECProcessor::HandlePoll(cec_logical_address initiator, cec_logical_address destination)
{
- m_busDevices[initiator]->GetHandler()->HandlePoll(initiator, destination);
+ m_busDevices[initiator]->HandlePoll(destination);
}
bool CCECProcessor::HandleReceiveFailed(cec_logical_address initiator)
{
- return !m_busDevices[initiator]->GetHandler()->HandleReceiveFailed();
+ return !m_busDevices[initiator]->HandleReceiveFailed();
+}
+
+bool CCECProcessor::SetStreamPath(uint16_t iPhysicalAddress)
+{
+ // stream path changes are sent by the TV
+ return m_busDevices[CECDEVICE_TV]->GetHandler()->TransmitSetStreamPath(iPhysicalAddress);
}