[SCM] kodi-pvr-hts/master: [API 5.0.0] Added support for connection state change callback

tiber-guest at users.alioth.debian.org tiber-guest at users.alioth.debian.org
Fri Nov 4 23:23:37 UTC 2016


The following commit has been merged in the master branch:
commit b0979ef2634a4b01f8283c9ae44281efdd17e7b5
Author: Kai Sommerfeld <kai.sommerfeld at gmx.com>
Date:   Wed Nov 18 16:59:21 2015 +0100

    [API 5.0.0] Added support for connection state change callback

diff --git a/src/HTSPConnection.cpp b/src/HTSPConnection.cpp
index 920cb02..440c7e4 100644
--- a/src/HTSPConnection.cpp
+++ b/src/HTSPConnection.cpp
@@ -93,7 +93,8 @@ void *CHTSPRegister::Process ( void )
 CHTSPConnection::CHTSPConnection ()
   : m_socket(NULL), m_regThread(this), m_ready(false), m_seq(0),
     m_serverName(""), m_serverVersion(""), m_htspVersion(0),
-    m_webRoot(""), m_challenge(NULL), m_challengeLen(0), m_suspended(false)
+    m_webRoot(""), m_challenge(NULL), m_challengeLen(0), m_suspended(false),
+    m_state(PVR_CONNECTION_STATE_UNKNOWN)
 {
 }
 
@@ -108,7 +109,7 @@ CHTSPConnection::~CHTSPConnection()
  * Info
  */
 
-std::string CHTSPConnection::GetWebURL ( const char *fmt, ... )
+std::string CHTSPConnection::GetWebURL ( const char *fmt, ... ) const
 {
   va_list va;
   const Settings &settings = Settings::GetInstance();
@@ -133,32 +134,38 @@ std::string CHTSPConnection::GetWebURL ( const char *fmt, ... )
 
 bool CHTSPConnection::WaitForConnection ( void )
 {
-  if (!m_ready) {
+  if (!m_ready)
+  {
     Logger::Log(LogLevel::LEVEL_TRACE, "waiting for registration...");
     m_regCond.Wait(m_mutex, m_ready, Settings::GetInstance().GetConnectTimeout());
   }
   return m_ready;
 }
 
-std::string CHTSPConnection::GetServerName ( void )
+int  CHTSPConnection::GetProtocol ( void ) const
+{
+  CLockObject lock(m_mutex);
+  return m_htspVersion;
+}
+
+std::string CHTSPConnection::GetServerName ( void ) const
 {
   CLockObject lock(m_mutex);
   return m_serverName;
 }
 
-std::string CHTSPConnection::GetServerVersion ( void )
+std::string CHTSPConnection::GetServerVersion ( void ) const
 {
   CLockObject lock(m_mutex);
   return StringUtils::Format("%s (HTSP v%d)", m_serverVersion.c_str(), m_htspVersion);
 }
 
-std::string CHTSPConnection::GetServerString ( void )
+std::string CHTSPConnection::GetServerString ( void ) const
 {
   const Settings &settings = Settings::GetInstance();
 
   CLockObject lock(m_mutex);
-  return StringUtils::Format("%s:%d [%s]", settings.GetHostname().c_str(), settings.GetPortHTSP(),
-             m_ready ? "connected" : "disconnected");
+  return StringUtils::Format("%s:%d", settings.GetHostname().c_str(), settings.GetPortHTSP());
 }
 
 bool CHTSPConnection::HasCapability(const std::string &capability) const
@@ -187,6 +194,32 @@ void CHTSPConnection::OnWake ( void )
   m_suspended = false;
 }
 
+void CHTSPConnection::SetState ( PVR_CONNECTION_STATE state )
+{
+  PVR_CONNECTION_STATE prevState(PVR_CONNECTION_STATE_UNKNOWN);
+  PVR_CONNECTION_STATE newState(PVR_CONNECTION_STATE_UNKNOWN);
+
+  {
+    CLockObject lock(m_mutex);
+
+    /* No notification if no state change or while suspended. */
+    if (m_state != state && !m_suspended)
+    {
+      prevState = m_state;
+      newState  = state;
+      m_state   = newState;
+
+      Logger::Log(LogLevel::LEVEL_DEBUG, "connection state change (%d -> %d)", prevState, newState);
+    }
+  }
+
+  if (prevState != newState)
+  {
+    /* Notify connection state change (callback!) */
+    PVR->ConnectionStateChange(GetServerString().c_str(), newState, NULL);
+  }
+}
+
 /*
  * Close the connection
  */
@@ -350,7 +383,6 @@ htsmsg_t *CHTSPConnection::SendAndWait0 ( const char *method, htsmsg_t *msg, int
   m_messages.erase(seq);
   if (!msg)
   {
-    //XBMC->QueueNotification(QUEUE_ERROR, "Command %s failed: No response received", method);
     Logger::Log(LogLevel::LEVEL_ERROR, "Command %s failed: No response received", method);
     if (!m_suspended)
       Disconnect();
@@ -362,7 +394,6 @@ htsmsg_t *CHTSPConnection::SendAndWait0 ( const char *method, htsmsg_t *msg, int
   if (!htsmsg_get_u32(msg, "noaccess", &noaccess) && noaccess)
   {
     // access denied
-    //XBMC->QueueNotification(QUEUE_ERROR, "Command %s failed: Access denied", method);
     Logger::Log(LogLevel::LEVEL_ERROR, "Command %s failed: Access denied", method);
     htsmsg_destroy(msg);
     return NULL;
@@ -372,7 +403,6 @@ htsmsg_t *CHTSPConnection::SendAndWait0 ( const char *method, htsmsg_t *msg, int
     const char* strError;
     if((strError = htsmsg_get_str(msg, "error")) != NULL)
     {
-      //XBMC->QueueNotification(QUEUE_ERROR, "Command %s failed: %s", method, strError);
       Logger::Log(LogLevel::LEVEL_ERROR, "Command %s failed: %s", method, strError);
       htsmsg_destroy(msg);
       return NULL;
@@ -483,8 +513,10 @@ void CHTSPConnection::Register ( void )
 
     /* Send Greeting */
     Logger::Log(LogLevel::LEVEL_DEBUG, "sending hello");
-    if (!SendHello()) {
+    if (!SendHello())
+    {
       Logger::Log(LogLevel::LEVEL_ERROR, "failed to send hello");
+      SetState(PVR_CONNECTION_STATE_SERVER_MISMATCH);
       goto fail;
     }
 
@@ -492,17 +524,18 @@ void CHTSPConnection::Register ( void )
     if (m_htspVersion < HTSP_MIN_SERVER_VERSION)
     {
       Logger::Log(LogLevel::LEVEL_ERROR, "server htsp version (v%d) does not match minimum htsp version required by client (v%d)", m_htspVersion, HTSP_MIN_SERVER_VERSION);
-      Disconnect();
-      m_ready = false;
-      m_regCond.Broadcast();
-      return;
+      SetState(PVR_CONNECTION_STATE_VERSION_MISMATCH);
+      goto fail;
     }
 
     /* Send Auth */
     Logger::Log(LogLevel::LEVEL_DEBUG, "sending auth");
     
     if (!SendAuth(user, pass))
+    {
+      SetState(PVR_CONNECTION_STATE_ACCESS_DENIED);
       goto fail;
+    }
 
     /* Rebuild state */
     Logger::Log(LogLevel::LEVEL_DEBUG, "rebuilding state");
@@ -510,6 +543,7 @@ void CHTSPConnection::Register ( void )
       goto fail;
 
     Logger::Log(LogLevel::LEVEL_DEBUG, "registered");
+    SetState(PVR_CONNECTION_STATE_CONNECTED);
     m_ready = true;
     m_regCond.Broadcast();
     return;
@@ -577,13 +611,14 @@ void* CHTSPConnection::Process ( void )
     {
       /* Unable to connect */
       Logger::Log(LogLevel::LEVEL_ERROR, "unable to connect to %s:%d", host.c_str(), port);
-      
+      SetState(PVR_CONNECTION_STATE_SERVER_UNREACHABLE);
+
       // Retry a few times with a short interval, after that with the default timeout
       if (++retryAttempt <= FAST_RECONNECT_ATTEMPTS)
         Sleep(FAST_RECONNECT_INTERVAL);
       else
         Sleep(timeout);
-      
+
       continue;
     }
     Logger::Log(LogLevel::LEVEL_DEBUG, "connected");
diff --git a/src/Tvheadend.cpp b/src/Tvheadend.cpp
index c65fb22..728c46a 100644
--- a/src/Tvheadend.cpp
+++ b/src/Tvheadend.cpp
@@ -658,26 +658,24 @@ PVR_ERROR CTvheadend::GetTimerTypes ( PVR_TIMER_TYPE types[], int *size )
   }
 
   /* PVR_Timer.iLifetime values and presentation.*/
-  static std::vector< std::pair<int, std::string> > lifetimeValues;
-  if (lifetimeValues.size() == 0)
-  {
-    lifetimeValues.push_back(std::make_pair(DVR_RET_1DAY,    XBMC->GetLocalizedString(30365)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_3DAY,    StringUtils::Format(XBMC->GetLocalizedString(30366), 3)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_5DAY,    StringUtils::Format(XBMC->GetLocalizedString(30366), 5)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_1WEEK,   XBMC->GetLocalizedString(30367)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_2WEEK,   StringUtils::Format(XBMC->GetLocalizedString(30368), 2)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_3WEEK,   StringUtils::Format(XBMC->GetLocalizedString(30368), 3)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_1MONTH,  XBMC->GetLocalizedString(30369)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_2MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 2)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_3MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 3)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_6MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 6)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_1YEAR,   XBMC->GetLocalizedString(30371)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_2YEARS,  StringUtils::Format(XBMC->GetLocalizedString(30372), 2)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_3YEARS,  StringUtils::Format(XBMC->GetLocalizedString(30372), 3)));
-    if (m_conn.GetProtocol() >= 25)
-      lifetimeValues.push_back(std::make_pair(DVR_RET_SPACE,   XBMC->GetLocalizedString(30373)));
-    lifetimeValues.push_back(std::make_pair(DVR_RET_FOREVER, XBMC->GetLocalizedString(30374)));
-  }
+  std::vector< std::pair<int, std::string> > lifetimeValues;
+
+  lifetimeValues.push_back(std::make_pair(DVR_RET_1DAY,    XBMC->GetLocalizedString(30365)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_3DAY,    StringUtils::Format(XBMC->GetLocalizedString(30366), 3)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_5DAY,    StringUtils::Format(XBMC->GetLocalizedString(30366), 5)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_1WEEK,   XBMC->GetLocalizedString(30367)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_2WEEK,   StringUtils::Format(XBMC->GetLocalizedString(30368), 2)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_3WEEK,   StringUtils::Format(XBMC->GetLocalizedString(30368), 3)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_1MONTH,  XBMC->GetLocalizedString(30369)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_2MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 2)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_3MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 3)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_6MONTH,  StringUtils::Format(XBMC->GetLocalizedString(30370), 6)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_1YEAR,   XBMC->GetLocalizedString(30371)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_2YEARS,  StringUtils::Format(XBMC->GetLocalizedString(30372), 2)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_3YEARS,  StringUtils::Format(XBMC->GetLocalizedString(30372), 3)));
+  if (m_conn.GetProtocol() >= 25)
+    lifetimeValues.push_back(std::make_pair(DVR_RET_SPACE,   XBMC->GetLocalizedString(30373)));
+  lifetimeValues.push_back(std::make_pair(DVR_RET_FOREVER, XBMC->GetLocalizedString(30374)));
 
   unsigned int TIMER_ONCE_MANUAL_ATTRIBS
     = PVR_TIMER_TYPE_IS_MANUAL           |
@@ -703,134 +701,132 @@ PVR_ERROR CTvheadend::GetTimerTypes ( PVR_TIMER_TYPE types[], int *size )
   }
 
   /* Timer types definition. */
-  static std::vector< std::unique_ptr<TimerType> > timerTypes;
-  if (timerTypes.size() == 0)
-  {
-    timerTypes.push_back(
-      /* One-shot manual (time and channel based) */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_ONCE_MANUAL,
-        /* Attributes. */
-        TIMER_ONCE_MANUAL_ATTRIBS,
-        /* Let Kodi generate the description. */
-        "",
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues)));
-
-    timerTypes.push_back(
-      /* One-shot epg based */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_ONCE_EPG,
-        /* Attributes. */
-        TIMER_ONCE_EPG_ATTRIBS,
-        /* Let Kodi generate the description. */
-        "",
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues)));
-
-    timerTypes.push_back(
-      /* Read-only one-shot for timers generated by timerec */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_ONCE_CREATED_BY_TIMEREC,
-        /* Attributes. */
-        TIMER_ONCE_MANUAL_ATTRIBS  |
-        PVR_TIMER_TYPE_IS_READONLY |
-        PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES,
-        /* Description. */
-        XBMC->GetLocalizedString(30350), // "One Time (Scheduled by repeating timer)"
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues)));
-
-    timerTypes.push_back(
-      /* Read-only one-shot for timers generated by autorec */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_ONCE_CREATED_BY_AUTOREC,
-        /* Attributes. */
-        TIMER_ONCE_EPG_ATTRIBS     |
-        PVR_TIMER_TYPE_IS_READONLY |
-        PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES,
-        /* Description. */
-        XBMC->GetLocalizedString(30350), // "One Time (Scheduled by repeating timer)"
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues)));
-
-    timerTypes.push_back(
-      /* Repeating manual (time and channel based) - timerec */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_REPEATING_MANUAL,
-        /* Attributes. */
-        PVR_TIMER_TYPE_IS_MANUAL                  |
-        PVR_TIMER_TYPE_IS_REPEATING               |
-        PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE    |
-        PVR_TIMER_TYPE_SUPPORTS_CHANNELS          |
-        PVR_TIMER_TYPE_SUPPORTS_START_TIME        |
-        PVR_TIMER_TYPE_SUPPORTS_END_TIME          |
-        PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS          |
-        PVR_TIMER_TYPE_SUPPORTS_PRIORITY          |
-        PVR_TIMER_TYPE_SUPPORTS_LIFETIME          |
-        PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS,
-        /* Let Kodi generate the description. */
-        "",
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues)));
-
-    unsigned int TIMER_REPEATING_EPG_ATTRIBS
-      = PVR_TIMER_TYPE_IS_REPEATING                |
-        PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE     |
-        PVR_TIMER_TYPE_SUPPORTS_TITLE_EPG_MATCH    |
-        PVR_TIMER_TYPE_SUPPORTS_CHANNELS           |
-        PVR_TIMER_TYPE_SUPPORTS_START_TIME         |
-        PVR_TIMER_TYPE_SUPPORTS_START_ANYTIME      |
-        PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS           |
-        PVR_TIMER_TYPE_SUPPORTS_START_END_MARGIN   |
-        PVR_TIMER_TYPE_SUPPORTS_PRIORITY           |
-        PVR_TIMER_TYPE_SUPPORTS_LIFETIME           |
-        PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS;
-
-    if (m_conn.GetProtocol() >= 20)
-    {
-      TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_FULLTEXT_EPG_MATCH;
-      TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_RECORD_ONLY_NEW_EPISODES;
-    }
-
-    if (!Settings::GetInstance().GetAutorecApproxTime())
-    {
-      /* We need the end time to represent the end of the tvh starting window */
-      TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_END_TIME;
-      TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_END_ANYTIME;
-    }
-
-    timerTypes.push_back(
-      /* Repeating epg based - autorec */
-      std::unique_ptr<TimerType>(new TimerType(
-        /* Type id. */
-        TIMER_REPEATING_EPG,
-        /* Attributes. */
-        TIMER_REPEATING_EPG_ATTRIBS,
-        /* Let Kodi generate the description. */
-        "",
-        /* Values definitions for priorities. */
-        priorityValues,
-        /* Values definitions for lifetime. */
-        lifetimeValues,
-        /* Values definitions for prevent duplicate episodes. */
-        deDupValues)));
-  }
+  std::vector< std::unique_ptr<TimerType> > timerTypes;
+
+  timerTypes.push_back(
+    /* One-shot manual (time and channel based) */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_ONCE_MANUAL,
+      /* Attributes. */
+      TIMER_ONCE_MANUAL_ATTRIBS,
+      /* Let Kodi generate the description. */
+      "",
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues)));
+
+  timerTypes.push_back(
+    /* One-shot epg based */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_ONCE_EPG,
+      /* Attributes. */
+      TIMER_ONCE_EPG_ATTRIBS,
+      /* Let Kodi generate the description. */
+      "",
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues)));
+
+  timerTypes.push_back(
+    /* Read-only one-shot for timers generated by timerec */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_ONCE_CREATED_BY_TIMEREC,
+      /* Attributes. */
+      TIMER_ONCE_MANUAL_ATTRIBS  |
+      PVR_TIMER_TYPE_IS_READONLY |
+      PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES,
+      /* Description. */
+      XBMC->GetLocalizedString(30350), // "One Time (Scheduled by repeating timer)"
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues)));
+
+  timerTypes.push_back(
+    /* Read-only one-shot for timers generated by autorec */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_ONCE_CREATED_BY_AUTOREC,
+      /* Attributes. */
+      TIMER_ONCE_EPG_ATTRIBS     |
+      PVR_TIMER_TYPE_IS_READONLY |
+      PVR_TIMER_TYPE_FORBIDS_NEW_INSTANCES,
+      /* Description. */
+      XBMC->GetLocalizedString(30350), // "One Time (Scheduled by repeating timer)"
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues)));
+
+  timerTypes.push_back(
+    /* Repeating manual (time and channel based) - timerec */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_REPEATING_MANUAL,
+      /* Attributes. */
+      PVR_TIMER_TYPE_IS_MANUAL                  |
+      PVR_TIMER_TYPE_IS_REPEATING               |
+      PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE    |
+      PVR_TIMER_TYPE_SUPPORTS_CHANNELS          |
+      PVR_TIMER_TYPE_SUPPORTS_START_TIME        |
+      PVR_TIMER_TYPE_SUPPORTS_END_TIME          |
+      PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS          |
+      PVR_TIMER_TYPE_SUPPORTS_PRIORITY          |
+      PVR_TIMER_TYPE_SUPPORTS_LIFETIME          |
+      PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS,
+      /* Let Kodi generate the description. */
+      "",
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues)));
+
+  unsigned int TIMER_REPEATING_EPG_ATTRIBS
+    = PVR_TIMER_TYPE_IS_REPEATING                |
+      PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE     |
+      PVR_TIMER_TYPE_SUPPORTS_TITLE_EPG_MATCH    |
+      PVR_TIMER_TYPE_SUPPORTS_CHANNELS           |
+      PVR_TIMER_TYPE_SUPPORTS_START_TIME         |
+      PVR_TIMER_TYPE_SUPPORTS_START_ANYTIME      |
+      PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS           |
+      PVR_TIMER_TYPE_SUPPORTS_START_END_MARGIN   |
+      PVR_TIMER_TYPE_SUPPORTS_PRIORITY           |
+      PVR_TIMER_TYPE_SUPPORTS_LIFETIME           |
+      PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS;
+
+  if (m_conn.GetProtocol() >= 20)
+  {
+    TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_FULLTEXT_EPG_MATCH;
+    TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_RECORD_ONLY_NEW_EPISODES;
+  }
+
+  if (!Settings::GetInstance().GetAutorecApproxTime())
+  {
+    /* We need the end time to represent the end of the tvh starting window */
+    TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_END_TIME;
+    TIMER_REPEATING_EPG_ATTRIBS |= PVR_TIMER_TYPE_SUPPORTS_END_ANYTIME;
+  }
+
+  timerTypes.push_back(
+    /* Repeating epg based - autorec */
+    std::unique_ptr<TimerType>(new TimerType(
+      /* Type id. */
+      TIMER_REPEATING_EPG,
+      /* Attributes. */
+      TIMER_REPEATING_EPG_ATTRIBS,
+      /* Let Kodi generate the description. */
+      "",
+      /* Values definitions for priorities. */
+      priorityValues,
+      /* Values definitions for lifetime. */
+      lifetimeValues,
+      /* Values definitions for prevent duplicate episodes. */
+      deDupValues)));
 
   /* Copy data to target array. */
   int i = 0;
diff --git a/src/Tvheadend.h b/src/Tvheadend.h
index 8ea7374..724bcd7 100644
--- a/src/Tvheadend.h
+++ b/src/Tvheadend.h
@@ -178,19 +178,16 @@ public:
   htsmsg_t *SendAndWait0    ( const char *method, htsmsg_t *m, int iResponseTimeout = -1);
   htsmsg_t *SendAndWait     ( const char *method, htsmsg_t *m, int iResponseTimeout = -1 );
 
-  inline int  GetProtocol      ( void ) const { return m_htspVersion; }
+  int  GetProtocol             ( void ) const;
 
-  std::string GetWebURL        ( const char *fmt, ... );
+  std::string GetWebURL        ( const char *fmt, ... ) const;
 
-  std::string GetServerName    ( void );
-  std::string GetServerVersion ( void );
-  std::string GetServerString  ( void );
+  std::string GetServerName    ( void ) const;
+  std::string GetServerVersion ( void ) const;
+  std::string GetServerString  ( void ) const;
   
   bool        HasCapability(const std::string &capability) const;
 
-  inline bool IsConnected       ( void ) const { return m_ready; }
-  bool        WaitForConnection ( void );
-
   inline P8PLATFORM::CMutex& Mutex ( void ) { return m_mutex; }
 
   void        OnSleep ( void );
@@ -203,8 +200,11 @@ private:
   bool        SendHello        ( void );
   bool        SendAuth         ( const std::string &u, const std::string &p );
 
-  P8PLATFORM::CTcpSocket               *m_socket;
-  P8PLATFORM::CMutex                    m_mutex;
+  void        SetState         ( PVR_CONNECTION_STATE state );
+  bool        WaitForConnection( void );
+
+  P8PLATFORM::CTcpSocket              *m_socket;
+  mutable P8PLATFORM::CMutex          m_mutex;
   CHTSPRegister                       m_regThread;
   P8PLATFORM::CCondition<volatile bool> m_regCond;
   bool                                m_ready;
@@ -220,6 +220,7 @@ private:
   std::vector<std::string>            m_capabilities;
 
   bool                                m_suspended;
+  PVR_CONNECTION_STATE                m_state;
 };
 
 /*
@@ -494,20 +495,15 @@ public:
   /*
    * Connection (pass-thru)
    */
-  bool WaitForConnection ( void )
-  {
-    P8PLATFORM::CLockObject lock(m_conn.Mutex());
-    return m_conn.WaitForConnection();
-  }
-  std::string GetServerName    ( void )
+  std::string GetServerName    ( void ) const
   {
     return m_conn.GetServerName();
   }
-  std::string GetServerVersion ( void )
+  std::string GetServerVersion ( void ) const
   {
     return m_conn.GetServerVersion();
   }
-  std::string GetServerString  ( void )
+  std::string GetServerString  ( void ) const
   {
     return m_conn.GetServerString();
   }
@@ -519,10 +515,6 @@ public:
   {
     return m_conn.HasCapability(capability);
   }
-  inline bool IsConnected ( void ) const
-  {
-    return m_conn.IsConnected();
-  }
   inline void OnSleep ( void )
   {
     m_conn.OnSleep();
diff --git a/src/client.cpp b/src/client.cpp
index 1ce08b3..3826c0b 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -41,7 +41,6 @@ using namespace tvheadend::utilities;
  * Client state
  */
 ADDON_STATUS m_CurStatus = ADDON_STATUS_UNKNOWN;
-bool         m_bAlertHtspVersionMismatch = true;
 
 /*
  * Globals
@@ -80,7 +79,8 @@ ADDON_STATUS ADDON_Create(void* hdl, void* _unused(props))
     SAFE_DELETE(PVR);
     SAFE_DELETE(CODEC);
     SAFE_DELETE(XBMC);
-    return ADDON_STATUS_PERMANENT_FAILURE;
+    m_CurStatus = ADDON_STATUS_PERMANENT_FAILURE;
+    return m_CurStatus;
   }
 
   /* Configure the logger */
@@ -117,41 +117,13 @@ ADDON_STATUS ADDON_Create(void* hdl, void* _unused(props))
   tvh = new CTvheadend();
   tvh->Start();
 
-  /* Wait for connection */
-  if (!tvh->WaitForConnection())
-  {
-    if (m_bAlertHtspVersionMismatch &&
-        (tvh->GetProtocol() > 0) && // 0 => tvh server down
-        (tvh->GetProtocol() < HTSP_MIN_SERVER_VERSION))
-    {
-      m_bAlertHtspVersionMismatch = false; // alert max once during addon lifetime
-
-      /* client/server API version mismatch */
-      XBMC->QueueNotification(
-        QUEUE_ERROR,
-        XBMC->GetLocalizedString(30300), tvh->GetProtocol(), HTSP_MIN_SERVER_VERSION);
-    }
-
-    SAFE_DELETE(tvh);
-    SAFE_DELETE(PVR);
-    SAFE_DELETE(CODEC);
-    SAFE_DELETE(XBMC);
-
-    return ADDON_STATUS_LOST_CONNECTION;
-  }
-
-  m_CurStatus     = ADDON_STATUS_OK;
+  m_CurStatus = ADDON_STATUS_OK;
   return m_CurStatus;
 }
 
 ADDON_STATUS ADDON_GetStatus()
 {
   CLockObject lock(g_mutex);
-
-  // Check that we're still connected
-  if (m_CurStatus == ADDON_STATUS_OK && !tvh->IsConnected())
-    m_CurStatus = ADDON_STATUS_LOST_CONNECTION;
-
   return m_CurStatus;
 }
 
@@ -180,7 +152,9 @@ unsigned int ADDON_GetSettings
 ADDON_STATUS ADDON_SetSetting
   (const char *settingName, const void *settingValue)
 {
-  return Settings::GetInstance().SetSetting(settingName, settingValue);
+  CLockObject lock(g_mutex);
+  m_CurStatus = Settings::GetInstance().SetSetting(settingName, settingValue);
+  return m_CurStatus;
 }
 
 void ADDON_Stop()
@@ -245,19 +219,25 @@ PVR_ERROR GetAddonCapabilities(PVR_ADDON_CAPABILITIES* pCapabilities)
 
 const char *GetBackendName(void)
 {
-  static std::string serverName = tvh->GetServerName();
+  static std::string serverName;
+
+  serverName = tvh->GetServerName();
   return serverName.c_str();
 }
 
 const char *GetBackendVersion(void)
 {
-  static std::string serverVersion = tvh->GetServerVersion();
+  static std::string serverVersion;
+
+  serverVersion = tvh->GetServerVersion();
   return serverVersion.c_str();
 }
 
 const char *GetConnectionString(void)
 {
-  static std::string serverString = tvh->GetServerString();
+  static std::string serverString;
+
+  serverString = tvh->GetServerString();
   return serverString.c_str();
 }
 

-- 
kodi-pvr-hts packaging



More information about the pkg-multimedia-commits mailing list