cec: display an alert message when the firmware of the adapter can be upgraded. bugzi...
[deb_libcec.git] / src / lib / adapter / USBCECAdapterCommunication.cpp
index 828ea24cac2aaecb4bf5a40e85df6b52691243b5..6c548b00ad2eab495083b57ed76295c290b1d71d 100644 (file)
@@ -44,7 +44,12 @@ using namespace PLATFORM;
 
 #define CEC_ADAPTER_PING_TIMEOUT 15000
 
-CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = 38400 */) :
+// firmware version 2
+#define CEC_LATEST_ADAPTER_FW_VERSION 2
+// firmware date Thu Apr 26 20:14:49 2012 +0000
+#define CEC_LATEST_ADAPTER_FW_DATE    0x4F99ACB9
+
+CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate /* = CEC_SERIAL_DEFAULT_BAUDRATE */) :
     IAdapterCommunication(callback),
     m_port(NULL),
     m_iLineTimeout(0),
@@ -54,7 +59,7 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCa
     m_commands(NULL),
     m_adapterMessageQueue(NULL)
 {
-  for (unsigned int iPtr = 0; iPtr < 15; iPtr++)
+  for (unsigned int iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++)
     m_bWaitingForAck[iPtr] = false;
   m_port = new CSerialPort(strPort, iBaudRate);
 }
@@ -67,7 +72,7 @@ CUSBCECAdapterCommunication::~CUSBCECAdapterCommunication(void)
   delete m_port;
 }
 
-bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */, bool bSkipChecks /* = false */, bool bStartListening /* = true */)
+bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */, bool bSkipChecks /* = false */, bool bStartListening /* = true */)
 {
   bool bConnectionOpened(false);
   {
@@ -266,7 +271,7 @@ void CUSBCECAdapterCommunication::MarkAsWaiting(const cec_logical_address dest)
   }
 }
 
-void CUSBCECAdapterCommunication::ClearInputBytes(uint32_t iTimeout /* = 1000 */)
+void CUSBCECAdapterCommunication::ClearInputBytes(uint32_t iTimeout /* = CEC_CLEAR_INPUT_DEFAULT_WAIT */)
 {
   CTimeout timeout(iTimeout);
   uint8_t buff[1024];
@@ -380,7 +385,8 @@ CCECAdapterMessage *CUSBCECAdapterCommunication::SendCommand(cec_adapter_message
   }
   else
   {
-    if (!bIsRetry && output->Reply() == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED)
+    if (!bIsRetry && output->Reply() == MSGCODE_COMMAND_REJECTED && msgCode != MSGCODE_SET_CONTROLLED &&
+        msgCode != MSGCODE_GET_BUILDDATE /* same messagecode value had a different meaning in older fw builds */)
     {
       /* if the controller reported that the command was rejected, and we didn't send the command
          to set controlled mode, then the controller probably switched to auto mode. set controlled
@@ -395,7 +401,7 @@ CCECAdapterMessage *CUSBCECAdapterCommunication::SendCommand(cec_adapter_message
   return output;
 }
 
-bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = 10000 */)
+bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
 {
   bool bReturn(false);
   CTimeout timeout(iTimeoutMs > 0 ? iTimeoutMs : CEC_DEFAULT_TRANSMIT_WAIT);
@@ -425,6 +431,9 @@ bool CUSBCECAdapterCommunication::CheckAdapter(uint32_t iTimeoutMs /* = 10000 */
   else
     bReturn = true;
 
+  /* try to read the build date */
+  m_commands->RequestBuildDate();
+
   SetInitialised(bReturn);
   return bReturn;
 }
@@ -454,7 +463,12 @@ bool CUSBCECAdapterCommunication::IsInitialised(void)
 
 bool CUSBCECAdapterCommunication::StartBootloader(void)
 {
-  return m_port->IsOpen() ? m_commands->StartBootloader() : false;
+  if (m_port->IsOpen() && m_commands->StartBootloader())
+  {
+    Close();
+    return true;
+  }
+  return false;
 }
 
 bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask)
@@ -472,6 +486,17 @@ uint16_t CUSBCECAdapterCommunication::GetFirmwareVersion(void)
   return m_commands->GetFirmwareVersion();
 }
 
+uint32_t CUSBCECAdapterCommunication::GetFirmwareBuildDate(void)
+{
+  return m_commands->RequestBuildDate();
+}
+
+bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void)
+{
+  return GetFirmwareVersion() >= CEC_LATEST_ADAPTER_FW_VERSION &&
+      GetFirmwareBuildDate() >= CEC_LATEST_ADAPTER_FW_DATE;
+}
+
 bool CUSBCECAdapterCommunication::PersistConfiguration(libcec_configuration *configuration)
 {
   return m_port->IsOpen() ? m_commands->PersistConfiguration(configuration) : false;
@@ -508,8 +533,8 @@ void *CAdapterPingThread::Process(void)
       {
         if (!m_com->PingAdapter())
         {
-          /* sleep 1 second and retry */
-          Sleep(1000);
+          /* sleep and retry */
+          Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
           ++iFailedCounter;
         }
         else