Go to the documentation of this file.
3 #include <QCoreApplication>
10 #include <QWaitCondition>
11 #include <QNetworkInterface>
12 #include <QAbstractSocket>
13 #include <QHostAddress>
15 #include <QNetworkInterface>
16 #include <QNetworkAddressEntry>
55 #define LOC QString("MythCoreContext::%1(): ").arg(__func__)
57 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
58 #define qEnvironmentVariable getenv
71 bool WaitForWOL(std::chrono::milliseconds
timeout = std::chrono::milliseconds::max());
135 m_guiContext(guicontext),
136 m_guiObject(nullptr),
137 m_appBinaryVersion(
std::move(binversion)),
138 m_serverSock(nullptr),
139 m_eventSock(nullptr),
140 m_wolInProgress(
false),
141 m_isWOLAllowed(
true),
145 m_uiThread(QThread::currentThread()),
147 m_scheduler(nullptr),
148 m_blockingClient(
true),
150 m_intvwanting(
false),
151 m_announcedProtocol(
false),
152 m_pluginmanager(nullptr),
154 m_sessionManager(nullptr),
161 #
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
162 QMutexLocker &locker,
164 QMutexLocker<QMutex> &locker,
209 GetMythDB()->GetDBManager()->CloseDatabases();
224 std::chrono::milliseconds timeout_remaining =
timeout;
227 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Wake-On-LAN in progress, waiting...");
229 std::chrono::milliseconds max_wait = std::min(1000ms, timeout_remaining);
231 timeout_remaining -= max_wait;
247 LOG(VB_GENERAL, LOG_EMERG,
LOC +
"Out-of-memory");
253 LOG(VB_GENERAL, LOG_CRIT,
254 QString(
"Application binary version (%1) does not "
255 "match libraries (%2)")
258 QString warning = tr(
"This application is not compatible with the "
259 "installed MythTV libraries. Please recompile "
260 "after a make distclean");
261 LOG(VB_GENERAL, LOG_WARNING, warning);
267 QString lang_variables(
"");
268 QString lc_value = setlocale(LC_CTYPE,
nullptr);
269 if (lc_value.isEmpty())
273 lc_value = qEnvironmentVariable(
"LC_ALL");
274 if (lc_value.isEmpty())
275 lc_value = qEnvironmentVariable(
"LC_CTYPE");
277 if (!lc_value.contains(
"UTF-8", Qt::CaseInsensitive))
278 lang_variables.append(
"LC_ALL or LC_CTYPE");
279 lc_value = qEnvironmentVariable(
"LANG");
280 if (!lc_value.contains(
"UTF-8", Qt::CaseInsensitive))
282 if (!lang_variables.isEmpty())
283 lang_variables.append(
", and ");
284 lang_variables.append(
"LANG");
286 LOG(VB_GENERAL, LOG_INFO, QString(
"Assumed character encoding: %1")
288 if (!lang_variables.isEmpty())
290 LOG(VB_GENERAL, LOG_WARNING, QString(
"This application expects to "
291 "be running a locale that specifies a UTF-8 codeset, and many "
292 "features may behave improperly with your current language "
293 "settings. Please set the %1 variable(s) in the environment "
294 "in which this program is executed to include a UTF-8 codeset "
295 "(such as 'en_US.UTF-8').").arg(lang_variables));
324 const QString &announcement,
325 std::chrono::milliseconds
timeout,
326 bool &proto_mismatch)
328 proto_mismatch =
false;
330 #ifndef IGNORE_PROTO_VER_MISMATCH
333 proto_mismatch =
true;
340 QStringList strlist(announcement);
344 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Connecting server socket to "
345 "master backend, socket write failed");
350 strlist.empty() || (strlist[0] ==
"ERROR"))
352 if (!strlist.empty())
354 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Problem connecting "
355 "server socket to master backend");
359 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Timeout connecting "
360 "server socket to master backend");
370 bool openEventSocket)
381 bool openEventSocket)
387 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ERROR: Master backend tried to connect back "
395 if (server.isEmpty())
399 bool proto_mismatch =
false;
409 QString
type =
IsFrontend() ?
"Frontend" : (blockingClient ?
"Playback" :
"Monitor");
410 QString ann = QString(
"ANN %1 %2 %3")
413 server, port, ann, &proto_mismatch);
421 if (!openEventSocket)
440 QCoreApplication::postEvent(
451 const QString &
hostname,
int port,
const QString &announce,
452 bool *p_proto_mismatch,
int maxConnTry, std::chrono::milliseconds setup_timeout)
466 maxConnTry = std::max(
GetNumSetting(
"BackendConnectRetry", 1), 1);
468 std::chrono::seconds WOLsleepTime = 0s;
469 int WOLmaxConnTry = 0;
470 if (!WOLcmd.isEmpty())
472 WOLsleepTime = GetDurSetting<std::chrono::seconds>(
"WOLbackendReconnectWaitTime", 0s);
473 WOLmaxConnTry = std::max(
GetNumSetting(
"WOLbackendConnectRetry", 1), 1);
474 maxConnTry = std::max(maxConnTry, WOLmaxConnTry);
477 bool we_attempted_wol =
false;
479 if (setup_timeout <= 0ms)
482 bool proto_mismatch =
false;
483 for (
int cnt = 1; cnt <= maxConnTry; cnt++)
485 LOG(VB_GENERAL, LOG_INFO,
LOC +
486 QString(
"Connecting to backend server: %1:%2 (try %3 of %4)")
487 .arg(
hostname).arg(port).arg(cnt).arg(maxConnTry));
491 std::chrono::microseconds sleepus = 0us;
495 serverSock, announce, setup_timeout, proto_mismatch))
502 if (p_proto_mismatch)
503 *p_proto_mismatch =
true;
506 serverSock =
nullptr;
510 setup_timeout += setup_timeout / 2;
512 else if (!WOLcmd.isEmpty() && (cnt < maxConnTry))
514 if (!we_attempted_wol)
528 sleepus = WOLsleepTime;
532 serverSock =
nullptr;
536 QCoreApplication::postEvent(
541 usleep(sleepus.count());
544 if (we_attempted_wol)
551 if (!serverSock && !proto_mismatch)
553 LOG(VB_GENERAL, LOG_ERR,
554 "Connection to master server timed out.\n\t\t\t"
555 "Either the server is down or the master server settings"
557 "in mythtv-settings does not contain the proper IP address\n");
561 QCoreApplication::postEvent(
575 if (!eventSock->ConnectToHost(
hostname, port))
577 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to connect event "
578 "socket to master backend");
579 eventSock->DecrRef();
583 QString str = QString(
"ANN Monitor %1 %2")
585 QStringList strlist(str);
586 eventSock->WriteStringList(strlist);
588 if (!eventSock->ReadStringList(strlist) || strlist.empty() ||
589 (strlist[0] ==
"ERROR"))
591 if (!strlist.empty())
593 LOG(VB_GENERAL, LOG_ERR,
LOC +
594 "Problem connecting event socket to master backend");
598 LOG(VB_GENERAL, LOG_ERR,
LOC +
599 "Timeout connecting event socket to master backend");
606 eventSock->DecrRef();
627 strlist <<
"BLOCK_SHUTDOWN";
641 strlist <<
"ALLOW_SHUTDOWN";
703 if (addr.toLower() == host.toLower())
705 QHostAddress addrfix(addr);
706 addrfix.setScopeId(QString());
707 QString addrstr = addrfix.toString();
708 if (addrfix.isNull())
712 return !addrstr.isEmpty()
713 && ((addrstr == thisip) || (addrstr == thisip6));
715 return GetSetting(
"MasterServerName") == host;
725 #if defined(Q_OS_DARWIN) || defined(__FreeBSD__) || defined(__OpenBSD__)
726 const char *command =
"ps -axc | grep -i mythbackend | grep -v grep > /dev/null";
728 const char *command =
"%systemroot%\\system32\\tasklist.exe "
729 " | %systemroot%\\system32\\find.exe /i \"mythbackend.exe\" ";
731 const char *command =
"ps ch -C mythbackend -o pid > /dev/null";
751 if (addr.toLower() == host.toLower())
754 QHostAddress addrfix(addr);
755 addrfix.setScopeId(QString());
756 QString addrstr = addrfix.toString();
758 if (addrfix.isNull())
765 return !addrstr.isEmpty() && ((addrstr == thisip));
771 bool backendOnLocalhost =
false;
773 QStringList strlist(
"QUERY_IS_ACTIVE_BACKEND");
778 backendOnLocalhost = strlist[0] !=
"FALSE";
780 return !backendOnLocalhost;
789 QHostAddress addr(host);
792 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"(%1/%2): Given "
793 "IP address instead of hostname "
794 "(ID). This is invalid.").arg(host, path));
800 if (!addr.isNull() && addr.protocol() == QAbstractSocket::IPv6Protocol)
801 m_host =
"[" + addr.toString().toLower() +
"]";
803 ret.setScheme(
"myth");
804 if (!storageGroup.isEmpty())
805 ret.setUserName(storageGroup);
807 if (port > 0 && port != 6543)
809 if (!path.startsWith(
"/"))
810 path = QString(
"/") + path;
814 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
815 QString(
"GenMythURL returning %1").arg(ret.toString()));
818 return ret.toString();
841 QStringList strlist(
"QUERY_HOSTNAME");
873 int &width,
int &height,
874 double &forced_aspect,
875 double &refresh_rate,
878 d->
m_database->GetResolutionSetting(
type, width, height, forced_aspect,
879 refresh_rate, index);
915 const QString &newValue,
918 return d->
m_database->SaveSettingOnHost(key, newValue, host);
922 const QString &defaultval)
931 int result =
GetNumSetting(key,
static_cast<int>(defaultval));
939 return d->
m_database->GetNumSetting(key, defaultval);
946 return d->
m_database->GetFloatSetting(key, defaultval);
951 const QString &defaultval)
955 return d->
m_database->GetSettingOnHost(key, host, defaultval);
972 return d->
m_database->GetNumSettingOnHost(key, host, defaultval);
981 return d->
m_database->GetFloatSettingOnHost(key, host, defaultval);
1006 (
"MasterServerName");
1008 (
"BackendServerPort", masterserver, 6543);
1134 QHostAddress addr1 = addr;
1135 addr1.setScopeId(QString());
1136 QString addrstr = addr1.toString();
1154 QHostAddress addr1 = addr;
1155 addr1.setScopeId(QString());
1158 d->
m_scopes.insert(addr1.toString(), addr.scopeId());
1168 QHostAddress addr1 = addr;
1169 addr1.setScopeId(QString());
1172 d->
m_scopes.insert(addr1.toString(), QString::number(scope));
1187 const QString &host,
1218 QHostAddress addr(host);
1220 if (!host.isEmpty() && addr.isNull())
1223 QHostInfo info = QHostInfo::fromName(host);
1224 QList<QHostAddress> list = info.addresses();
1228 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1229 QString(
"Can't resolve hostname:'%1', using localhost").arg(host));
1236 for (
const auto& item : qAsConst(list))
1239 QAbstractSocket::NetworkLayerProtocol prot = addr.protocol();
1241 if (prot == QAbstractSocket::IPv4Protocol)
1247 else if (prot == QAbstractSocket::IPv6Protocol)
1257 addr = v4.isNull() ? QHostAddress::LocalHost : v4;
1260 addr = v6.isNull() ? QHostAddress::LocalHostIPv6 : v6;
1263 addr = v6.isNull() ?
1264 (v4.isNull() ? QHostAddress::LocalHostIPv6 : v4) : v6;
1268 else if (host.isEmpty())
1275 addr.setScopeId(QString());
1277 return addr.toString();
1293 QHostAddress peer = socket->peerAddress();
1310 static const QHostAddress
kLinkLocal(
"fe80::");
1317 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1318 QString(
"Repeat denied connection from ip address: %1")
1319 .arg(peer.toString()));
1331 QList<QNetworkInterface> IFs = QNetworkInterface::allInterfaces();
1332 for (
const auto & qni : qAsConst(IFs))
1334 if ((qni.flags() & QNetworkInterface::IsRunning) == 0)
1337 QList<QNetworkAddressEntry> IPs = qni.addressEntries();
1338 for (
const auto & qnai : qAsConst(IPs))
1340 int pfxlen = qnai.prefixLength();
1345 if (peer.isInSubnet(qnai.ip(),pfxlen))
1353 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1354 QString(
"Denied connection from ip address: %1")
1355 .arg(peer.toString()));
1361 const QString &value)
1363 d->
m_database->OverrideSettingForSession(key, value);
1368 d->
m_database->ClearOverrideSettingForSession(key);
1395 QStringList &strlist,
bool quickTimeout,
bool block)
1400 msg =
"SendReceiveStringList(";
1401 for (
uint i=0; i<(
uint)strlist.size() && i<2; i++)
1402 msg += (i?
",":
"") + strlist[i];
1403 msg += (strlist.size() > 2) ?
"...)" :
")";
1404 LOG(VB_GENERAL, LOG_DEBUG,
LOC + msg +
" called from UI thread");
1407 QString query_type =
"UNKNOWN";
1409 if (!strlist.isEmpty())
1410 query_type = strlist[0];
1424 std::chrono::milliseconds
timeout = quickTimeout ?
1430 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
1431 QString(
"Connection to backend server lost"));
1454 while (ok && strlist[0] ==
"BACKEND_MESSAGE")
1457 LOG(VB_GENERAL, LOG_EMERG,
LOC +
"SRSL you shouldn't see this!!");
1458 QString message = strlist[1];
1459 strlist.pop_front(); strlist.pop_front();
1475 LOG(VB_GENERAL, LOG_CRIT,
LOC +
1476 QString(
"Reconnection to backend server failed"));
1479 new MythEvent(
"PERSISTENT_CONNECTION_FAILURE"));
1485 if (strlist.isEmpty())
1487 else if (strlist[0] ==
"ERROR")
1489 if (strlist.size() == 2)
1491 LOG(VB_GENERAL, LOG_INFO,
LOC +
1492 QString(
"Protocol query '%1' responded with the error '%2'")
1493 .arg(query_type, strlist[1]));
1497 LOG(VB_GENERAL, LOG_INFO,
LOC +
1498 QString(
"Protocol query '%1' responded with an error, but "
1499 "no error message.") .arg(query_type));
1504 else if (strlist[0] ==
"UNKNOWN_COMMAND")
1506 LOG(VB_GENERAL, LOG_ERR,
LOC +
1507 QString(
"Protocol query '%1' responded with the error 'UNKNOWN_COMMAND'")
1529 QStringList strlist(
"MESSAGE");
1578 const QString &
args)
1588 QStringList strlist;
1592 if (strlist.size() < 2)
1595 QString
prefix = strlist[0];
1596 QString message = strlist[1];
1597 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
1598 QStringList tokens = message.split(
" ", QString::SkipEmptyParts);
1600 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
1606 else if (
prefix !=
"BACKEND_MESSAGE")
1608 LOG(VB_NETWORK, LOG_ERR,
LOC +
1609 QString(
"Received a: %1 message from the backend "
1610 "but I don't know what to do with it.")
1613 else if (message ==
"CLEAR_SETTINGS_CACHE")
1616 LOG(VB_NETWORK, LOG_INFO,
LOC +
"Received remote 'Clear Cache' request");
1619 else if (message.startsWith(
"FILE_WRITTEN"))
1625 if (tokens.size() == NUMTOKENS)
1628 size = tokens[2].toULongLong();
1632 LOG(VB_NETWORK, LOG_ERR,
LOC +
1633 QString(
"FILE_WRITTEN event received "
1634 "with invalid number of arguments, "
1635 "%1 expected, %2 actual")
1637 .arg(tokens.size()-1));
1641 LOG(VB_NETWORK, LOG_INFO,
LOC +
1642 QString(
"Received remote 'FILE_WRITTEN %1' request").arg(
file));
1645 else if (message.startsWith(
"FILE_CLOSED"))
1650 if (tokens.size() == NUMTOKENS)
1656 LOG(VB_NETWORK, LOG_ERR,
LOC +
1657 QString(
"FILE_CLOSED event received "
1658 "with invalid number of arguments, "
1659 "%1 expected, %2 actual")
1661 .arg(tokens.size()-1));
1665 LOG(VB_NETWORK, LOG_INFO,
LOC +
1666 QString(
"Received remote 'FILE_CLOSED %1' request").arg(
file));
1671 strlist.pop_front();
1672 strlist.pop_front();
1684 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
1685 "Event socket closed. No connection to the backend.");
1691 std::chrono::milliseconds
timeout,
1692 bool error_dialog_desired)
1697 QStringList strlist(QString(
"MYTH_PROTO_VERSION %1 %2")
1704 LOG(VB_GENERAL, LOG_CRIT,
"Protocol version check failure.\n\t\t\t"
1705 "The response to MYTH_PROTO_VERSION was empty.\n\t\t\t"
1706 "This happens when the backend is too busy to respond,\n\t\t\t"
1707 "or has deadlocked due to bugs or hardware failure.");
1711 if (strlist[0] ==
"REJECT" && strlist.size() >= 2)
1713 LOG(VB_GENERAL, LOG_CRIT,
LOC + QString(
"Protocol version or token mismatch "
1714 "(frontend=%1/%2,backend=%3/\?\?)\n")
1721 QStringList list(strlist[1]);
1722 QCoreApplication::postEvent(
1728 if (strlist[0] ==
"ACCEPT")
1733 LOG(VB_GENERAL, LOG_INFO,
LOC +
1734 QString(
"Using protocol version %1 %2")
1742 LOG(VB_GENERAL, LOG_ERR,
LOC +
1743 QString(
"Unexpected response to MYTH_PROTO_VERSION: %1")
1750 LOG(VB_NETWORK, LOG_INFO,
LOC + QString(
"MythEvent: %1").arg(event.
Message()));
1824 LOG(VB_GENERAL, LOG_INFO,
"Restarting Backend Connections");
1868 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Setting QT default locale to %1")
1881 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Setting QT default locale to %1")
1901 LOG(VB_GENERAL, LOG_INFO,
1908 LOG(VB_GENERAL, LOG_ERR,
LOC +
1909 "No locale defined! We weren't able to set locale defaults.");
1931 QEventLoop eventLoop;
1934 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1935 QString(
"Waiting for signal %1")
1940 eventLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
1951 if (!sender || !method)
1961 Qt::BlockingQueuedConnection);
1997 QThread *currentThread = QThread::currentThread();
2002 if (it.key() == sender)
2005 QThread *thread = it.key()->thread();
2007 if (thread != currentThread)
2029 Qt::BlockingQueuedConnection);
2034 if (it.key() == sender)
2037 QThread *thread = it.key()->thread();
2039 if (thread != currentThread)
2043 it.key(), it.value());
2045 it.key(), it.value(), Qt::BlockingQueuedConnection);
2080 return intvplayback;
2092 const QString &libversion,
2093 const QString &pluginversion)
2095 if (libversion == pluginversion)
2098 LOG(VB_GENERAL, LOG_EMERG,
LOC +
2099 QString(
"Plugin %1 (%2) binary version does not "
2100 "match libraries (%3)")
2101 .arg(name, pluginversion, libversion));
2138 QPair<int64_t, uint64_t> pair(QDateTime::currentMSecsSinceEpoch(), size);
2143 QString message = QString(
"FILE_WRITTEN %1 %2").arg(
file).arg(size);
2148 LOG(VB_FILE, LOG_DEBUG,
LOC +
2149 QString(
"%1").arg(
file));
2160 QString message = QString(
"FILE_CLOSED %1").arg(
file);
2165 LOG(VB_FILE, LOG_DEBUG,
LOC +
2166 QString(
"%1").arg(
file));
QString resolveSettingAddress(const QString &name, const QString &host=QString(), ResolveType type=ResolveAny, bool keepscope=false)
Retrieve IP setting "name" for "host".
void SetPluginManager(MythPluginManager *pmanager)
void loggingDeregisterThread(void)
Deregister the current thread's name.
void SetWOLAllowed(bool allow)
bool WaitForWOL(std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
If another thread has already started WOL process, wait on them...
void SendMessage(const QString &message)
QString GetMasterHostName(void)
#define GENERIC_EXIT_OK
Exited with no error.
QMap< QString, QPair< int64_t, uint64_t > > m_fileswritten
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
This is an generic interface to a program scheduler.
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
MythScheduler * GetScheduler(void)
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
bool IsBlockingClient(void) const
is this client blocking shutdown
bool IsFrontendOnly(void)
is there a frontend, but no backend, running on this host
QMutex m_masterHostLock
Locking for m_masterHostname.
MDBManager * GetDBManager(void)
void UnregisterFileForWrite(const QString &file)
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
MythSocket * m_eventSock
socket events arrive on
MythLocale * GetLocale(void) const
~MythCoreContext() override
void ShutdownMythDownloadManager(void)
Deletes the running MythDownloadManager at program exit.
void SetScheduler(MythScheduler *sched)
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
void OverrideSettingForSession(const QString &key, const QString &value)
DB connection pool, used by MSqlQuery. Do not use directly.
QLocale ToQLocale() const
static QHash< QString, int > s_serverPortCache
This class is used as a container for messages.
#define MYTH_APPNAME_MYTHTV_SETUP
QString m_appBinaryVersion
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
bool IsDatabaseIgnored(void) const
/brief Returns true if database is being ignored.
QObject * GetGUIObject(void)
QString GetFilePrefix(void)
void connectionClosed(MythSocket *sock) override
void DisconnectFromHost(void)
bool CheckProtoVersion(MythSocket *socket, std::chrono::milliseconds timeout=kMythSocketLongTimeout, bool error_dialog_desired=false)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
static bool TestPluginVersion(const QString &name, const QString &libversion, const QString &pluginversion)
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
bool GetScopeForAddress(QHostAddress &addr) const
Return the cached scope Id for the given address.
bool ConnectToHost(const QString &hostname, quint16 port)
connect to host
void setTestStringSettings(QMap< QString, QString > &overrides)
void InitPower(bool Create=true)
bool SafeConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
const QString & Message() const
bool IsConnected(void) const
QWaitCondition m_wolInProgressWaitCondition
VERBOSE_PREAMBLE Most true
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
QMutex m_scopesLock
Locking for m_masterHostname.
SendAsyncMessage(QString msg, QStringList extra)
void SendHostSystemEvent(const QString &msg, const QString &hostname, const QString &args)
MythPluginManager * m_pluginmanager
Class for communcating between myth backends and frontends.
void ClearOverrideSettingForSession(const QString &key)
bool IsConnectedToMaster(void)
MythCoreContext(const QString &binversion, QObject *guiContext)
static void ShutdownAllPools(void)
void UnregisterForPlayback(QObject *sender)
bool IsRegisteredFileForWrite(const QString &file)
bool IsMasterBackend(void)
is this the actual MBE process
QString m_localHostname
hostname from config.xml or gethostname()
static void SetConfiguration(Configuration *pConfig)
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
QObject * GetGUIContext(void)
static bool BackendIsRunning(void)
a backend process is running on this host
bool WriteStringList(const QStringList &list)
void SetAsFrontend(bool frontend)
static void StopAllPools(void)
int GetBackendServerPort(void)
Returns the locally defined backend control port.
void SendSystemEvent(const QString &msg)
void SendEvent(const MythEvent &event)
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
void WaitUntilSignals(std::vector< CoreWaitInfo > &sigs) const
Wait until any of the provided signals have been received.
MythCoreContext * m_parent
static MythPower * AcquireRelease(void *Reference, bool Acquire, std::chrono::seconds MinimumDelay=0s)
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
MythSessionManager * m_sessionManager
bool IsFrontend(void) const
is this process a frontend process
void readyRead(MythSocket *sock) override
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
QList< QHostAddress > m_approvedIps
QMutex m_wolInProgressLock
void GetResolutionSetting(const QString &type, int &width, int &height, double &forced_aspect, double &refresh_rate, int index=-1)
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
QString GetBackendServerIP4(void)
Returns the IPv4 address defined for the current host see GetBackendServerIP4(host)
QMap< QString, QString > m_testOverrideStrings
void TVPlaybackAboutToStart(void)
static constexpr std::chrono::milliseconds kShortTimeout
MythSocket * ConnectCommandSocket(const QString &hostname, int port, const QString &announcement, bool *proto_mismatch=nullptr, int maxConnTry=-1, std::chrono::milliseconds setup_timeout=-1ms)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
~MythCoreContextPrivate() override
MythSocket * ConnectEventSocket(const QString &hostname, int port)
QString GetLanguage(void)
Returns two character ISO-639 language descriptor for UI language.
int GetNumSetting(const QString &key, int defaultval=0)
void logStop(void)
Entry point for stopping logging for an application.
void SaveLocaleDefaults(bool overwrite=false)
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 SetLocalHostname(const QString &hostname)
bool GetBoolSetting(const QString &key, bool defaultval=false)
const QStringList & ExtraDataList() const
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
QMap< QObject *, MythCoreContext::PlaybackStartCb > m_playbackClients
bool InWantingPlayback(void)
Returns true if a client has requested playback.
This class contains the runtime context for MythTV.
void setTestIntSettings(QMap< QString, int > &overrides)
QMap< QString, double > m_testOverrideFloats
bool IsBackend(void) const
is this process a backend process
static QPair< QHostAddress, int > kLinkLocal
QString m_masterHostname
master backend hostname
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
QMap< QString, QString > m_scopes
Scope Id cache for Link-Local addresses.
@ kMSProcessEvents
process events while waiting
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
MythSocket * m_serverSock
socket for sending MythProto requests
bool IsDataAvailable(void)
static void ClearBackendServerPortCache()
void TVInWantingPlayback(bool b)
Let the TV class tell us if we was interrupted following a call to WantingPlayback().
MythCoreContextPrivate * d
SendAsyncMessage(QString msg)
void ActivateSettingsCache(bool activate=true)
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...
QMutex m_sockLock
protects both m_serverSock and m_eventSock
QString GetLocaleCode() const
Name of language in that language.
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
QString GetHostName(void)
MythScheduler * m_scheduler
static void ThreadSetup(const QString &name)
This is to be called on startup in those few threads that haven't been ported to MThread.
QList< QHostAddress > m_deniedIps
bool GetBoolSettingOnHost(const QString &key, const QString &host, bool defaultval=false)
void ClearSettingsCache(const QString &myKey=QString(""))
static Configuration * g_pConfig
bool IsThisHost(const QString &addr)
is this address mapped to this host
bool IsMasterHost(void)
is this the same host as the master
QMutex m_localHostLock
Locking for m_localHostname.
bool IsWOLAllowed() const
double GetFloatSetting(const QString &key, double defaultval=0.0)
@ kMSDontDisableDrawing
avoid disabling UI drawing
void SaveSetting(const QString &key, int newValue)
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
MythSessionManager * GetSessionManager(void)
QString GetBackendServerIP6(void)
Returns the IPv6 address defined for the current host see GetBackendServerIP6(host)
static void delete_sock(QMutexLocker< QMutex > &locker, MythSocket **s)
static MThreadPool * globalInstance(void)
MythPluginManager * GetPluginManager(void)
void SetScopeForAddress(const QHostAddress &addr)
Record the scope Id of the given IP address.
static constexpr std::chrono::milliseconds kLongTimeout
bool SetupCommandSocket(MythSocket *serverSock, const QString &announcement, std::chrono::milliseconds timeout, bool &proto_mismatch)
bool CheckSubnet(const QAbstractSocket *socket)
Check if a socket is connected to an approved peer.
void SaveLocaleDefaults(void)
void dispatch(const MythEvent &event)
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
bool ReadStringList(QStringList &list, std::chrono::milliseconds timeoutMS=kShortTimeout)
void SetAsBackend(bool backend)
QMap< QString, int > m_testOverrideInts
void(QObject::*)(void) PlaybackStartCb
bool IsThisBackend(const QString &addr)
is this address mapped to this backend host
void setTestFloatSettings(QMap< QString, double > &overrides)
double GetFloatSettingOnHost(const QString &key, const QString &host, double defaultval=0.0)
void start(QRunnable *runnable, const QString &debugName, int priority=0)
void SetExiting(bool exiting=true)
void SetGUIObject(QObject *gui)
bool SendReceiveStringList(QStringList &list, uint min_reply_length=0, std::chrono::milliseconds timeoutMS=kLongTimeout)
MythCoreContextPrivate(MythCoreContext *lparent, QString binversion, QObject *guicontext)
QString GetSetting(const QString &key, const QString &defaultval="")
static Configuration * GetConfiguration()