5#include <QCoreApplication>
12#include <QWaitCondition>
13#include <QAbstractSocket>
14#include <QHostAddress>
16#include <QNetworkInterface>
17#include <QNetworkAddressEntry>
20#include <QRegularExpression>
46#include "mythversion.h"
55#define LOC QString("MythCoreContext::%1(): ").arg(__func__)
66 bool WaitForWOL(std::chrono::milliseconds
timeout = std::chrono::milliseconds::max());
132 m_guiContext(guicontext),
133 m_appBinaryVersion(
std::move(binversion)),
135 m_uiThread(QThread::currentThread())
141#
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
142 QMutexLocker &locker,
144 QMutexLocker<QMutex> &locker,
189 GetMythDB()->GetDBManager()->CloseDatabases();
204 std::chrono::milliseconds timeout_remaining =
timeout;
207 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Wake-On-LAN in progress, waiting...");
209 std::chrono::milliseconds max_wait = std::min(1000ms, timeout_remaining);
211 timeout_remaining -= max_wait;
227 LOG(VB_GENERAL, LOG_EMERG,
LOC +
"Out-of-memory");
233 LOG(VB_GENERAL, LOG_CRIT,
234 QString(
"Application binary version (%1) does not "
235 "match libraries (%2)")
238 QString warning = tr(
"This application is not compatible with the "
239 "installed MythTV libraries. Please recompile "
240 "after a make distclean");
241 LOG(VB_GENERAL, LOG_WARNING, warning);
247 static const QRegularExpression utf8
248 {
"utf-?8", QRegularExpression::CaseInsensitiveOption };
249 QString lang_variables(
"");
250 QString lc_value = setlocale(LC_CTYPE,
nullptr);
251 if (lc_value.isEmpty())
255 lc_value = qEnvironmentVariable(
"LC_ALL");
256 if (lc_value.isEmpty())
257 lc_value = qEnvironmentVariable(
"LC_CTYPE");
259 if (!lc_value.contains(utf8))
260 lang_variables.append(
"LC_ALL or LC_CTYPE");
261 lc_value = qEnvironmentVariable(
"LANG");
262 if (!lc_value.contains(utf8))
264 if (!lang_variables.isEmpty())
265 lang_variables.append(
", and ");
266 lang_variables.append(
"LANG");
268 LOG(VB_GENERAL, LOG_INFO, QString(
"Assumed character encoding: %1")
270 if (!lang_variables.isEmpty())
272 LOG(VB_GENERAL, LOG_WARNING, QString(
"This application expects to "
273 "be running a locale that specifies a UTF-8 codeset, and many "
274 "features may behave improperly with your current language "
275 "settings. Please set the %1 variable(s) in the environment "
276 "in which this program is executed to include a UTF-8 codeset "
277 "(such as 'en_US.UTF-8').").arg(lang_variables));
306 const QString &announcement,
307 [[maybe_unused]] std::chrono::milliseconds
timeout,
308 bool &proto_mismatch)
310 proto_mismatch =
false;
312#ifndef IGNORE_PROTO_VER_MISMATCH
315 proto_mismatch =
true;
320 QStringList strlist(announcement);
324 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Connecting server socket to "
325 "master backend, socket write failed");
330 strlist.empty() || (strlist[0] ==
"ERROR"))
332 if (!strlist.empty())
334 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Problem connecting "
335 "server socket to master backend");
339 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timeout connecting "
340 "server socket to master backend");
350 bool openEventSocket)
361 bool openEventSocket)
367 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ERROR: Master backend tried to connect back "
375 if (server.isEmpty())
379 bool proto_mismatch =
false;
389 QString
type {
"Monitor" };
392 else if (blockingClient)
394 QString ann = QString(
"ANN %1 %2 %3")
397 server, port, ann, &proto_mismatch);
405 if (!openEventSocket)
424 QCoreApplication::postEvent(
435 const QString &
hostname,
int port,
const QString &announce,
436 bool *p_proto_mismatch,
int maxConnTry, std::chrono::milliseconds setup_timeout)
450 maxConnTry = std::max(
GetNumSetting(
"BackendConnectRetry", 1), 1);
452 std::chrono::seconds WOLsleepTime = 0s;
453 int WOLmaxConnTry = 0;
454 if (!WOLcmd.isEmpty())
456 WOLsleepTime = GetDurSetting<std::chrono::seconds>(
"WOLbackendReconnectWaitTime", 0s);
457 WOLmaxConnTry = std::max(
GetNumSetting(
"WOLbackendConnectRetry", 1), 1);
458 maxConnTry = std::max(maxConnTry, WOLmaxConnTry);
461 bool we_attempted_wol =
false;
463 if (setup_timeout <= 0ms)
466 bool proto_mismatch =
false;
467 for (
int cnt = 1; cnt <= maxConnTry; cnt++)
469 LOG(VB_GENERAL, LOG_INFO,
LOC +
470 QString(
"Connecting to backend server: %1:%2 (try %3 of %4)")
471 .arg(
hostname).arg(port).arg(cnt).arg(maxConnTry));
475 std::chrono::microseconds sleepus = 0us;
479 serverSock, announce, setup_timeout, proto_mismatch))
486 if (p_proto_mismatch)
487 *p_proto_mismatch =
true;
490 serverSock =
nullptr;
494 setup_timeout += setup_timeout / 2;
496 else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
498 if (!we_attempted_wol)
512 sleepus = WOLsleepTime;
516 serverSock =
nullptr;
520 QCoreApplication::postEvent(
525 usleep(sleepus.count());
528 if (we_attempted_wol)
535 if (!serverSock && !proto_mismatch)
537 LOG(VB_GENERAL, LOG_ERR,
538 "Connection to master server timed out.\n\t\t\t"
539 "Either the server is down or the master server settings"
541 "in mythtv-settings does not contain the proper IP address\n");
545 QCoreApplication::postEvent(
559 if (!eventSock->ConnectToHost(
hostname, port))
561 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to connect event "
562 "socket to master backend");
563 eventSock->DecrRef();
567 QString str = QString(
"ANN Monitor %1 %2")
569 QStringList strlist(str);
570 eventSock->WriteStringList(strlist);
572 if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
573 (strlist[0] ==
"ERROR"))
575 if (!strlist.empty())
577 LOG(VB_GENERAL, LOG_ERR,
LOC +
578 "Problem connecting event socket to master backend");
582 LOG(VB_GENERAL, LOG_ERR,
LOC +
583 "Timeout connecting event socket to master backend");
590 eventSock->DecrRef();
611 strlist <<
"BLOCK_SHUTDOWN";
625 strlist <<
"ALLOW_SHUTDOWN";
687 if (addr.toLower() == host.toLower())
689 QHostAddress addrfix(addr);
690 addrfix.setScopeId(QString());
691 QString addrstr = addrfix.toString();
692 if (addrfix.isNull())
696 return !addrstr.isEmpty()
697 && ((addrstr == thisip) || (addrstr == thisip6));
699 return GetSetting(
"MasterServerName") == host;
709#if defined(Q_OS_DARWIN) || defined(__FreeBSD__) || defined(__OpenBSD__)
710 const char *command =
"ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
712 const char *command =
"%systemroot%\\system32\\tasklist.exe "
713 " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
715 const char *command =
"ps ch -C mythbackend -o pid > /dev/null";
735 if (addr.toLower() == host.toLower())
738 QHostAddress addrfix(addr);
739 addrfix.setScopeId(QString());
740 QString addrstr = addrfix.toString();
742 if (addrfix.isNull())
749 return !addrstr.isEmpty() && ((addrstr == thisip));
755 bool backendOnLocalhost =
false;
757 QStringList strlist(
"QUERY_IS_ACTIVE_BACKEND");
762 backendOnLocalhost = strlist[0] !=
"FALSE";
764 return !backendOnLocalhost;
773 QHostAddress addr(host);
776 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"(%1/%2): Given "
777 "IP address instead of hostname "
778 "(ID). This is invalid.").arg(host, path));
784 if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
785 m_host =
"[" + addr.toString().toLower() +
"]";
787 ret.setScheme(
"myth");
788 if (!storageGroup.isEmpty())
789 ret.setUserName(storageGroup);
791 if (port > 0 && port != 6543)
793 if (!path.startsWith(
"/"))
794 path = QString(
"/") + path;
798 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
799 QString(
"GenMythURL returning %1").arg(ret.toString()));
802 return ret.toString();
825 QStringList strlist(
"QUERY_HOSTNAME");
857 int &width,
int &height,
858 double &forced_aspect,
859 double &refresh_rate,
862 d->
m_database->GetResolutionSetting(
type, width, height, forced_aspect,
863 refresh_rate, index);
899 const QString &newValue,
902 return d->
m_database->SaveSettingOnHost(key, newValue, host);
906 const QString &defaultval)
915 int result =
GetNumSetting(key,
static_cast<int>(defaultval));
923 return d->
m_database->GetNumSetting(key, defaultval);
930 return d->
m_database->GetFloatSetting(key, defaultval);
935 const QString &defaultval)
939 return d->
m_database->GetSettingOnHost(key, host, defaultval);
956 return d->
m_database->GetNumSettingOnHost(key, host, defaultval);
965 return d->
m_database->GetFloatSettingOnHost(key, host, defaultval);
990 (
"MasterServerName");
992 (
"BackendServerPort", masterserver, 6543);
1118 QHostAddress addr1 = addr;
1119 addr1.setScopeId(QString());
1120 QString addrstr = addr1.toString();
1138 QHostAddress addr1 = addr;
1139 addr1.setScopeId(QString());
1142 d->
m_scopes.insert(addr1.toString(), addr.scopeId());
1152 QHostAddress addr1 = addr;
1153 addr1.setScopeId(QString());
1156 d->
m_scopes.insert(addr1.toString(), QString::number(scope));
1171 const QString &host,
1202 QHostAddress addr(host);
1204 if (!host.isEmpty() && addr.isNull())
1207 QHostInfo
info = QHostInfo::fromName(host);
1208 QList<QHostAddress> list =
info.addresses();
1212 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1213 QString(
"Can't resolve hostname:'%1', using localhost").arg(host));
1220 for (
const auto& item : std::as_const(list))
1223 QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1225 if (prot == QAbstractSocket::IPv4Protocol)
1231 else if (prot == QAbstractSocket::IPv6Protocol)
1241 addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1244 addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1249 else if (!v4.isNull())
1252 addr = QHostAddress::LocalHostIPv6;
1256 else if (host.isEmpty())
1263 addr.setScopeId(QString());
1265 return addr.toString();
1281 QHostAddress peer = socket->peerAddress();
1313 static const QHostAddress
kLinkLocal(
"fe80::");
1321 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1322 QString(
"Repeat denied connection from ip address: %1")
1323 .arg(peer.toString()));
1335 QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1336 for (
const auto & qni : std::as_const(IFs))
1338 if ((qni.flags() & QNetworkInterface::IsRunning) == 0)
1341 QList<QNetworkAddressEntry> IPs = qni.addressEntries();
1342 for (
const auto & qnai : std::as_const(IPs))
1344 int pfxlen = qnai.prefixLength();
1349 if (peer.isInSubnet(qnai.ip(),pfxlen))
1358 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1359 QString(
"Denied connection from ip address: %1")
1360 .arg(peer.toString()));
1366 const QString &value)
1368 d->
m_database->OverrideSettingForSession(key, value);
1373 d->
m_database->ClearOverrideSettingForSession(key);
1400 QStringList &strlist,
bool quickTimeout,
bool block)
1405 msg =
"SendReceiveStringList(";
1406 for (
uint i=0; i<(
uint)strlist.size() && i<2; i++)
1407 msg += (i?
",":
"") + strlist[i];
1408 msg += (strlist.size() > 2) ?
"...)" :
")";
1409 LOG(VB_GENERAL, LOG_DEBUG,
LOC + msg +
" called from UI thread");
1412 QString query_type =
"UNKNOWN";
1414 if (!strlist.isEmpty())
1415 query_type = strlist[0];
1429 std::chrono::milliseconds
timeout = quickTimeout ?
1435 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
1436 QString(
"Connection to backend server lost"));
1459 while (ok && strlist[0] ==
"BACKEND_MESSAGE")
1462 LOG(VB_GENERAL, LOG_EMERG,
LOC +
"SRSL you shouldn't see this!!");
1463 QString message = strlist[1];
1464 strlist.pop_front(); strlist.pop_front();
1480 LOG(VB_GENERAL, LOG_CRIT,
LOC +
1481 QString(
"Reconnection to backend server failed"));
1484 new MythEvent(
"PERSISTENT_CONNECTION_FAILURE"));
1490 if (strlist.isEmpty())
1492 else if (strlist[0] ==
"ERROR")
1494 if (strlist.size() == 2)
1496 LOG(VB_GENERAL, LOG_INFO,
LOC +
1497 QString(
"Protocol query '%1' responded with the error '%2'")
1498 .arg(query_type, strlist[1]));
1502 LOG(VB_GENERAL, LOG_INFO,
LOC +
1503 QString(
"Protocol query '%1' responded with an error, but "
1504 "no error message.") .arg(query_type));
1509 else if (strlist[0] ==
"UNKNOWN_COMMAND")
1511 LOG(VB_GENERAL, LOG_ERR,
LOC +
1512 QString(
"Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1534 QStringList strlist(
"MESSAGE");
1583 const QString &
args)
1593 QStringList strlist;
1597 if (strlist.size() < 2)
1600 QString
prefix = strlist[0];
1601 QString message = strlist[1];
1602 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
1607 else if (
prefix !=
"BACKEND_MESSAGE")
1609 LOG(VB_NETWORK, LOG_ERR,
LOC +
1610 QString(
"Received a: %1 message from the backend "
1611 "but I don't know what to do with it.")
1614 else if (message ==
"CLEAR_SETTINGS_CACHE")
1617 LOG(VB_NETWORK, LOG_INFO,
LOC +
"Received remote 'Clear Cache' request");
1620 else if (message.startsWith(
"FILE_WRITTEN"))
1626 if (tokens.size() == NUMTOKENS)
1629 size = tokens[2].toULongLong();
1633 LOG(VB_NETWORK, LOG_ERR,
LOC +
1634 QString(
"FILE_WRITTEN event received "
1635 "with invalid number of arguments, "
1636 "%1 expected, %2 actual")
1638 .arg(tokens.size()-1));
1642 LOG(VB_NETWORK, LOG_INFO,
LOC +
1643 QString(
"Received remote 'FILE_WRITTEN %1' request").arg(
file));
1646 else if (message.startsWith(
"FILE_CLOSED"))
1651 if (tokens.size() == NUMTOKENS)
1657 LOG(VB_NETWORK, LOG_ERR,
LOC +
1658 QString(
"FILE_CLOSED event received "
1659 "with invalid number of arguments, "
1660 "%1 expected, %2 actual")
1662 .arg(tokens.size()-1));
1666 LOG(VB_NETWORK, LOG_INFO,
LOC +
1667 QString(
"Received remote 'FILE_CLOSED %1' request").arg(
file));
1672 strlist.pop_front();
1673 strlist.pop_front();
1682 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
1683 "Event socket closed. No connection to the backend.");
1689 std::chrono::milliseconds
timeout,
1690 bool error_dialog_desired)
1695 QStringList strlist(QString(
"MYTH_PROTO_VERSION %1 %2")
1696 .arg(MYTH_PROTO_VERSION,
1697 QString::fromUtf8(MYTH_PROTO_TOKEN)));
1702 LOG(VB_GENERAL, LOG_CRIT,
"Protocol version check failure.\n\t\t\t"
1703 "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1704 "This happens when the backend is too busy to respond,\n\t\t\t"
1705 "or has deadlocked due to bugs or hardware failure.");
1709 if (strlist[0] ==
"REJECT" && strlist.size() >= 2)
1711 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Protocol version or token mismatch "
1712 "(frontend=%1/%2,backend=%3/\?\?)\n")
1713 .arg(MYTH_PROTO_VERSION,
1714 QString::fromUtf8(MYTH_PROTO_TOKEN),
1719 QStringList list(strlist[1]);
1720 QCoreApplication::postEvent(
1726 if (strlist[0] ==
"ACCEPT")
1731 LOG(VB_GENERAL, LOG_INFO,
LOC +
1732 QString(
"Using protocol version %1 %2")
1733 .arg(MYTH_PROTO_VERSION,
1734 QString::fromUtf8(MYTH_PROTO_TOKEN)));
1740 LOG(VB_GENERAL, LOG_ERR,
LOC +
1741 QString(
"Unexpected response to MYTH_PROTO_VERSION: %1")
1748 LOG(VB_NETWORK, LOG_INFO,
LOC + QString(
"MythEvent: %1").arg(event.
Message()));
1842 LOG(VB_AUDIO, LOG_DEBUG,
LOC + QString(
"audio language:%1 menu language:%2")
1856 LOG(VB_GENERAL, LOG_INFO,
"Restarting Backend Connections");
1883 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Setting QT default locale to %1")
1896 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Setting QT default locale to %1")
1916 LOG(VB_GENERAL, LOG_INFO,
1923 LOG(VB_GENERAL, LOG_ERR,
LOC +
1924 "No locale defined! We weren't able to set locale defaults.");
1946 QEventLoop eventLoop;
1947 for (
const auto& s : sigs)
1949 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1950 QString(
"Waiting for signal %1")
1955 eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1966 if (!sender || !method)
1976 Qt::BlockingQueuedConnection);
2012 QThread *currentThread = QThread::currentThread();
2017 if (it.key() == sender)
2020 QThread *thread = it.key()->thread();
2022 if (thread != currentThread)
2044 Qt::BlockingQueuedConnection);
2049 if (it.key() == sender)
2052 QThread *thread = it.key()->thread();
2054 if (thread != currentThread)
2058 it.key(), it.value());
2060 it.key(), it.value(), Qt::BlockingQueuedConnection);
2095 return intvplayback;
2111 const QString &libversion,
2112 const QString &pluginversion)
2114 if (libversion == pluginversion)
2117 LOG(VB_GENERAL, LOG_EMERG,
LOC +
2118 QString(
"Plugin %1 (%2) binary version does not "
2119 "match libraries (%3)")
2120 .arg(name, pluginversion, libversion));
2157 QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2162 QString message = QString(
"FILE_WRITTEN %1 %2").arg(
file).arg(size);
2167 LOG(VB_FILE, LOG_DEBUG,
LOC +
2168 QString(
"%1").arg(
file));
2179 QString message = QString(
"FILE_CLOSED %1").arg(
file);
2184 LOG(VB_FILE, LOG_DEBUG,
LOC +
2185 QString(
"%1").arg(
file));
DB connection pool, used by MSqlQuery. Do not use directly.
static void StopAllPools(void)
static MThreadPool * globalInstance(void)
void start(QRunnable *runnable, const QString &debugName, int priority=0)
static void ShutdownAllPools(void)
static void Cleanup(void)
This will print out all the running threads, call exit(1) on each and then wait up to 5 seconds total...
static void ThreadSetup(const QString &name)
This is to be called on startup in those few threads that haven't been ported to MThread.
MythSocket * m_eventSock
socket events arrive on
~MythCoreContextPrivate() override
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
MythCoreContext * m_parent
QMutex m_sockLock
protects both m_serverSock and m_eventSock
MythSocket * m_serverSock
socket for sending MythProto requests
QMap< QObject *, MythCoreContext::PlaybackStartCb > m_playbackClients
QString m_masterHostname
master backend hostname
QString m_localHostname
hostname from config.xml or gethostname()
QWaitCondition m_wolInProgressWaitCondition
MythSessionManager * m_sessionManager
MythPluginManager * m_pluginmanager
bool WaitForWOL(std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
If another thread has already started WOL process, wait on them...
QMutex m_wolInProgressLock
QMutex m_masterHostLock
Locking for m_masterHostname.
MythScheduler * m_scheduler
QMutex m_scopesLock
Locking for m_masterHostname.
QMutex m_localHostLock
Locking for m_localHostname.
QString m_appBinaryVersion
QMap< QString, QPair< int64_t, uint64_t > > m_fileswritten
QList< QHostAddress > m_deniedIps
QMap< QString, QString > m_scopes
Scope Id cache for Link-Local addresses.
QList< QHostAddress > m_approvedIps
This class contains the runtime context for MythTV.
void TVPlaybackAboutToStart(void)
bool IsFrontend(void) const
is this process a frontend process
void ResetAudioLanguage(void)
void UnregisterForPlayback(QObject *sender)
Unregister sender from being called when TVPlaybackAboutToStart signal is emitted.
bool IsConnectedToMaster(void)
void setTestIntSettings(QMap< QString, int > &overrides)
void ClearSettingsCache(const QString &myKey=QString(""))
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
QString resolveSettingAddress(const QString &name, const QString &host=QString(), ResolveType type=ResolveAny, bool keepscope=false)
Retrieve IP setting "name" for "host".
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
QMap< QString, QString > m_testOverrideStrings
void readyRead(MythSocket *sock) override
QMap< QString, double > m_testOverrideFloats
void ActivateSettingsCache(bool activate=true)
bool IsLocalSubnet(const QHostAddress &peer, bool log)
Check if peer is on local subnet.
void SetWOLAllowed(bool allow)
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
QString GetHostName(void)
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
MythCoreContextPrivate * d
static bool BackendIsRunning(void)
a backend process is running on this host
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
void ClearOverrideSettingForSession(const QString &key)
static QHash< QString, int > s_serverPortCache
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
void connectionClosed(MythSocket *sock) override
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
void SaveSetting(const QString &key, int newValue)
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, std::chrono::milliseconds setup_timeout=-1ms)
void setTestFloatSettings(QMap< QString, double > &overrides)
void SetLocalHostname(const QString &hostname)
void SetExiting(bool exiting=true)
static QString resolveAddress(const QString &host, ResolveType type=ResolveAny, bool keepscope=false)
if host is an IP address, it will be returned or resolved otherwise.
void SetAsBackend(bool backend)
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
Register sender for TVPlaybackAboutToStart signal.
bool IsThisHost(const QString &addr)
is this address mapped to this host
MythScheduler * GetScheduler(void)
MythCoreContext(const QString &binversion, QObject *guiContext)
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
MythSessionManager * GetSessionManager(void)
QString GetSetting(const QString &key, const QString &defaultval="")
void SendSystemEvent(const QString &msg)
QString GetAudioLanguageAndVariant(void)
Returns the user-set audio language and variant.
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
bool IsRegisteredFileForWrite(const QString &file)
bool CheckProtoVersion(MythSocket *socket, std::chrono::milliseconds timeout=kMythSocketLongTimeout, bool error_dialog_desired=false)
QString GetAudioLanguage(void)
Returns two character ISO-639 language descriptor for audio language.
QObject * GetGUIContext(void)
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
void setTestStringSettings(QMap< QString, QString > &overrides)
MythPluginManager * GetPluginManager(void)
bool InWantingPlayback(void)
Returns true if a client has requested playback.
int GetBackendServerPort(void)
Returns the locally defined backend control port.
void OverrideSettingForSession(const QString &key, const QString &value)
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
QObject * GetGUIObject(void)
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
bool IsBackend(void) const
is this process a backend process
double GetFloatSetting(const QString &key, double defaultval=0.0)
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
~MythCoreContext() override
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
void SetScheduler(MythScheduler *sched)
QString GetFilePrefix(void)
void dispatch(const MythEvent &event)
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
void SendMessage(const QString &message)
bool SetupCommandSocket(MythSocket *serverSock, const QString &announcement, std::chrono::milliseconds timeout, bool &proto_mismatch)
bool IsMasterHost(void)
is this the same host as the master
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
void SetPluginManager(MythPluginManager *pmanager)
bool IsWOLAllowed() const
void SetGUIObject(QObject *gui)
void SaveLocaleDefaults(void)
int GetNumSetting(const QString &key, int defaultval=0)
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
void(QObject::*)(void) PlaybackStartCb
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
void SetAsFrontend(bool frontend)
QString GetMasterHostName(void)
QMap< QString, int > m_testOverrideInts
bool IsMasterBackend(void)
is this the actual MBE process
MythSocket * ConnectEventSocket(const QString &hostname, int port)
static void ClearBackendServerPortCache()
void UnregisterFileForWrite(const QString &file)
bool IsBlockingClient(void) const
is this client blocking shutdown
MDBManager * GetDBManager(void)
void InitPower(bool Create=true)
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
void WaitUntilSignals(std::vector< CoreWaitInfo > &sigs) const
Wait until any of the provided signals have been received.
void SendEvent(const MythEvent &event)
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
bool GetBoolSetting(const QString &key, bool defaultval=false)
MythLocale * GetLocale(void) const
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
This class is used as a container for messages.
const QString & Message() const
const QStringList & ExtraDataList() const
QLocale ToQLocale() const
QString GetLocaleCode() const
Name of language in that language.
void SaveLocaleDefaults(bool overwrite=false)
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
This is an generic interface to a program scheduler.
We use digest authentication because it protects the password over unprotected networks.
static void UnlockSessions()
static void LockSessions()
Class for communcating between myth backends and frontends.
static constexpr std::chrono::milliseconds kLongTimeout
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
bool IsConnected(void) const
bool IsDataAvailable(void)
static constexpr std::chrono::milliseconds kShortTimeout
void DisconnectFromHost(void)
bool WriteStringList(const QStringList &list)
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
SendAsyncMessage(QString msg)
SendAsyncMessage(QString msg, QStringList extra)
@ GENERIC_EXIT_OK
Exited with no error.
void loggingDeregisterThread(void)
Deregister the current thread's name.
void logStop(void)
Entry point for stopping logging for an application.
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
static constexpr const char * MYTH_APPNAME_MYTHTV_SETUP
static void delete_sock(QMutexLocker< QMutex > &locker, MythSocket **s)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
@ kMSProcessEvents
process events while waiting
@ kMSDontDisableDrawing
avoid disabling UI drawing
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
None log(str msg, int level=LOGDEBUG)
static QPair< QHostAddress, int > kLinkLocal