Go to the documentation of this file.
5 #include <QNetworkInterface>
6 #include <QCoreApplication>
7 #include <QtAlgorithms>
24 #define LOC QString("RAOP Device: ")
33 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Aborting startup - no key found.");
42 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RAOP device thread.");
51 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create RAOP device object.");
68 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created RAOP device objects.");
74 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Cleaning up.");
90 :
m_lock(new QRecursiveMutex())
103 QMutexLocker locker(
m_lock);
118 QMutexLocker locker(
m_lock);
133 LOG(VB_GENERAL, LOG_ERR,
LOC +
134 "Failed to find a port for incoming connections.");
138 LOG(VB_GENERAL, LOG_INFO,
LOC +
139 QString(
"Listening for connections on port %1").arg(
m_setupPort));
143 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to register service.");
164 m_name += QString::number(multiple);
168 name.append(
m_name.toUtf8());
171 QByteArray
type =
"_raop._tcp";
173 txt.append(6); txt.append(
"tp=UDP");
174 txt.append(8); txt.append(
"sm=false");
175 txt.append(8); txt.append(
"sv=false");
176 txt.append(4); txt.append(
"ek=1");
177 txt.append(6); txt.append(
"et=0,1");
178 txt.append(6); txt.append(
"cn=0,1");
179 txt.append(4); txt.append(
"ch=2");
180 txt.append(5); txt.append(
"ss=16");
181 txt.append(8); txt.append(
"sr=44100");
184 txt.append(7); txt.append(
"pw=true");
188 txt.append(8); txt.append(
"pw=false");
190 txt.append(4); txt.append(
"vn=3");
191 txt.append(9); txt.append(
"txtvers=1");
192 txt.append(8); txt.append(
"md=0,1,2");
193 txt.append(8); txt.append(
"vs=115.2");
194 txt.append(7); txt.append(
"da=true");
195 txt.append(11); txt.append(
"am=MythTV,1");
197 LOG(VB_GENERAL, LOG_INFO, QString(
"Registering service %1.%2 port %3 TXT %4")
198 .arg(QString(name), QString(
type), QString::number(
m_setupPort), QString(txt)));
204 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Receiving new playback message"));
210 QMutexLocker locker(
m_lock);
211 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"New connection from %1:%2")
212 .arg(client->peerAddress().toString()).arg(client->peerPort()));
216 tr(
"from %1:%2").arg(client->peerAddress().toString()).arg(client->peerPort()));
231 LOG(VB_GENERAL, LOG_ERR,
LOC +
232 "Failed to initialise client connection - closing.");
234 client->disconnectFromHost();
240 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Entering DeleteClient.");
241 QMutexLocker locker(
m_lock);
242 QList<MythRAOPConnection *>::iterator it =
m_clients.begin();
252 if ((*it)->GetSocket()->state() == QTcpSocket::UnconnectedState)
254 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Removing client connection.");
261 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Exiting DeleteClient.");
266 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
"Entering DeleteAllClients.");
267 QMutexLocker locker(
m_lock);
269 QList<MythRAOPConnection*>::iterator it =
m_clients.begin();
279 LOG(VB_GENERAL, LOG_INFO,
LOC +
280 QString(
"Removing client connection %1:%2")
281 .arg(client->
GetSocket()->peerAddress().toString())
286 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.