Go to the documentation of this file.
5 #include <QNetworkInterface>
6 #include <QCoreApplication>
7 #include <QtAlgorithms>
22 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
28 #define LOC QString("RAOP Device: ")
37 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Aborting startup - no key found.");
46 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RAOP device thread.");
55 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RAOP device object.");
72 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created RAOP device objects.");
78 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Cleaning up.");
94 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
95 :
m_lock(
new QMutex(QMutex::Recursive))
97 :
m_lock(
new QRecursiveMutex())
111 QMutexLocker locker(
m_lock);
126 QMutexLocker locker(
m_lock);
141 LOG(VB_GENERAL, LOG_ERR,
LOC +
142 "Failed to find a port for incoming connections.");
146 LOG(VB_GENERAL, LOG_INFO,
LOC +
147 QString(
"Listening for connections on port %1").arg(
m_setupPort));
151 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to register service.");
172 m_name += QString::number(multiple);
176 name.append(
m_name.toUtf8());
179 QByteArray
type =
"_raop._tcp";
181 txt.append(6); txt.append(
"tp=UDP");
182 txt.append(8); txt.append(
"sm=false");
183 txt.append(8); txt.append(
"sv=false");
184 txt.append(4); txt.append(
"ek=1");
185 txt.append(6); txt.append(
"et=0,1");
186 txt.append(6); txt.append(
"cn=0,1");
187 txt.append(4); txt.append(
"ch=2");
188 txt.append(5); txt.append(
"ss=16");
189 txt.append(8); txt.append(
"sr=44100");
192 txt.append(7); txt.append(
"pw=true");
196 txt.append(8); txt.append(
"pw=false");
198 txt.append(4); txt.append(
"vn=3");
199 txt.append(9); txt.append(
"txtvers=1");
200 txt.append(8); txt.append(
"md=0,1,2");
201 txt.append(8); txt.append(
"vs=115.2");
202 txt.append(7); txt.append(
"da=true");
203 txt.append(11); txt.append(
"am=MythTV,1");
205 LOG(VB_GENERAL, LOG_INFO, QString(
"Registering service %1.%2 port %3 TXT %4")
206 .arg(QString(name), QString(
type), QString::number(
m_setupPort), QString(txt)));
212 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Receiving new playback message"));
218 QMutexLocker locker(
m_lock);
219 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"New connection from %1:%2")
220 .arg(client->peerAddress().toString()).arg(client->peerPort()));
224 tr(
"from %1:%2").arg(client->peerAddress().toString()).arg(client->peerPort()));
239 LOG(VB_GENERAL, LOG_ERR,
LOC +
240 "Failed to initialise client connection - closing.");
242 client->disconnectFromHost();
248 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Entering DeleteClient.");
249 QMutexLocker locker(
m_lock);
250 QList<MythRAOPConnection *>::iterator it =
m_clients.begin();
260 if ((*it)->GetSocket()->state() == QTcpSocket::UnconnectedState)
262 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Removing client connection.");
269 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Exiting DeleteClient.");
274 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Entering DeleteAllClients.");
275 QMutexLocker locker(
m_lock);
277 QList<MythRAOPConnection*>::iterator it =
m_clients.begin();
287 LOG(VB_GENERAL, LOG_INFO,
LOC +
288 QString(
"Removing client connection %1:%2")
289 .arg(client->
GetSocket()->peerAddress().toString())
294 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Exiting DeleteAllClients.");
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
void newRaopConnection(QTcpSocket *client)
BonjourRegister * m_bonjour
bool RegisterForBonjour(void)
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
bool Register(uint16_t port, const QByteArray &type, const QByteArray &name, const QByteArray &txt)
int tryListeningPort(int baseport, int range=1)
tryListeningPort
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void SetVisibility(VNMask nVisibility)
Define a bitmask of Visibility.
void newConnection(QTcpSocket *)
static bool LoadKey(void)
LoadKey.
void SendSystemEvent(const QString &msg)
QString AirPlayHardwareId()
static QRecursiveMutex * gMythRAOPDeviceMutex
static MythRAOPDevice * gMythRAOPDevice
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
void RegisterForPlayback(QObject *sender, PlaybackStartCb method)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QList< MythRAOPConnection * > m_clients
static constexpr int RAOP_PORT_RANGE
bool GetBoolSetting(const QString &key, bool defaultval=false)
void DeleteAllClients(MythRAOPConnection *keep)
static void Cleanup(void)
MythNotificationCenter * GetNotificationCenter(void)
This is a wrapper around QThread that does several additional things.
void exit(int retcode=0)
Use this to exit from the thread if you are using a Qt event loop.
bool isRunning(void) const
void TVPlaybackStarting(void)
QString GetHostName(void)
~MythRAOPDevice(void) override
static MThread * gMythRAOPDeviceThread
VNMask GetVisibility() const
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.