Merge branch 'master' of https://code.google.com/r/asfa194-clementineremote into remote
This commit is contained in:
commit
22322593aa
|
@ -16,6 +16,7 @@ enum MsgType {
|
||||||
STOP = 23;
|
STOP = 23;
|
||||||
NEXT = 24;
|
NEXT = 24;
|
||||||
PREV = 25;
|
PREV = 25;
|
||||||
|
TOOGLE_SHUFFLE = 26;
|
||||||
|
|
||||||
// Messages send from server to client
|
// Messages send from server to client
|
||||||
INFOS = 40;
|
INFOS = 40;
|
||||||
|
@ -33,13 +34,14 @@ enum EngineState {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Message {
|
message Message {
|
||||||
required MsgType msgType = 1;
|
required int32 version = 1;
|
||||||
|
required MsgType msgType = 2;
|
||||||
|
|
||||||
optional EngineState state = 2;
|
optional EngineState state = 3;
|
||||||
optional ClementineInfos infos = 3;
|
optional ClementineInfos infos = 4;
|
||||||
optional SongMetadata currentSong = 4;
|
optional SongMetadata currentSong = 5;
|
||||||
optional int32 volume = 5;
|
optional int32 volume = 6;
|
||||||
repeated Playlist playlists = 6;
|
repeated Playlist playlists = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ClementineInfos {
|
message ClementineInfos {
|
||||||
|
|
|
@ -218,6 +218,7 @@ set(SOURCES
|
||||||
networkremote/networkremote.cpp
|
networkremote/networkremote.cpp
|
||||||
networkremote/incomingdataparser.cpp
|
networkremote/incomingdataparser.cpp
|
||||||
networkremote/outgoingdatacreator.cpp
|
networkremote/outgoingdatacreator.cpp
|
||||||
|
networkremote/remoteclient.cpp
|
||||||
|
|
||||||
playlist/dynamicplaylistcontrols.cpp
|
playlist/dynamicplaylistcontrols.cpp
|
||||||
playlist/playlist.cpp
|
playlist/playlist.cpp
|
||||||
|
@ -496,6 +497,7 @@ set(HEADERS
|
||||||
networkremote/networkremote.h
|
networkremote/networkremote.h
|
||||||
networkremote/incomingdataparser.h
|
networkremote/incomingdataparser.h
|
||||||
networkremote/outgoingdatacreator.h
|
networkremote/outgoingdatacreator.h
|
||||||
|
networkremote/remoteclient.h
|
||||||
|
|
||||||
playlist/dynamicplaylistcontrols.h
|
playlist/dynamicplaylistcontrols.h
|
||||||
playlist/playlist.h
|
playlist/playlist.h
|
||||||
|
|
|
@ -43,6 +43,8 @@ IncomingDataParser::IncomingDataParser(Application* app)
|
||||||
app_->player(), SLOT(PlayAt(int,Engine::TrackChangeFlags,bool)));
|
app_->player(), SLOT(PlayAt(int,Engine::TrackChangeFlags,bool)));
|
||||||
connect(this, SIGNAL(SetActivePlaylist(int)),
|
connect(this, SIGNAL(SetActivePlaylist(int)),
|
||||||
app_->playlist_manager(), SLOT(SetActivePlaylist(int)));
|
app_->playlist_manager(), SLOT(SetActivePlaylist(int)));
|
||||||
|
connect(this, SIGNAL(ShuffleCurrent()),
|
||||||
|
app_->playlist_manager(), SLOT(ShuffleCurrent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
IncomingDataParser::~IncomingDataParser() {
|
IncomingDataParser::~IncomingDataParser() {
|
||||||
|
@ -52,13 +54,12 @@ bool IncomingDataParser::close_connection() {
|
||||||
return close_connection_;
|
return close_connection_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncomingDataParser::Parse(const QByteArray& b64_data) {
|
void IncomingDataParser::Parse(const QByteArray& data) {
|
||||||
close_connection_ = false;
|
close_connection_ = false;
|
||||||
QByteArray pb_data = QByteArray::fromBase64(b64_data);
|
|
||||||
|
|
||||||
// Parse the incoming data
|
// Parse the incoming data
|
||||||
pb::remote::Message msg;
|
pb::remote::Message msg;
|
||||||
if (!msg.ParseFromArray(pb_data.constData(), pb_data.size())) {
|
if (!msg.ParseFromArray(data.constData(), data.size())) {
|
||||||
qLog(Info) << "Couldn't parse data";
|
qLog(Info) << "Couldn't parse data";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +91,8 @@ void IncomingDataParser::Parse(const QByteArray& b64_data) {
|
||||||
break;
|
break;
|
||||||
case pb::remote::CHANGE_SONG: ChangeSong(&msg);
|
case pb::remote::CHANGE_SONG: ChangeSong(&msg);
|
||||||
break;
|
break;
|
||||||
|
case pb::remote::TOOGLE_SHUFFLE: emit ShuffleCurrent();
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,11 @@ public:
|
||||||
IncomingDataParser(Application* app);
|
IncomingDataParser(Application* app);
|
||||||
~IncomingDataParser();
|
~IncomingDataParser();
|
||||||
|
|
||||||
void Parse(const QByteArray& pb_data);
|
|
||||||
bool close_connection();
|
bool close_connection();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void Parse(const QByteArray& pb_data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void SendClementineInfos();
|
void SendClementineInfos();
|
||||||
void SendFirstData();
|
void SendFirstData();
|
||||||
|
@ -29,6 +31,7 @@ signals:
|
||||||
void SetVolume(int volume);
|
void SetVolume(int volume);
|
||||||
void PlayAt(int i, Engine::TrackChangeFlags change, bool reshuffle);
|
void PlayAt(int i, Engine::TrackChangeFlags change, bool reshuffle);
|
||||||
void SetActivePlaylist(int id);
|
void SetActivePlaylist(int id);
|
||||||
|
void ShuffleCurrent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
|
|
|
@ -26,15 +26,17 @@
|
||||||
|
|
||||||
const char* NetworkRemote::kSettingsGroup = "NetworkRemote";
|
const char* NetworkRemote::kSettingsGroup = "NetworkRemote";
|
||||||
const int NetworkRemote::kDefaultServerPort = 5500;
|
const int NetworkRemote::kDefaultServerPort = 5500;
|
||||||
|
const int NetworkRemote::kProtocolBufferVersion = 1;
|
||||||
|
|
||||||
NetworkRemote::NetworkRemote(Application* app)
|
NetworkRemote::NetworkRemote(Application* app)
|
||||||
: app_(app)
|
: app_(app)
|
||||||
{
|
{
|
||||||
|
signals_connected_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetworkRemote::~NetworkRemote() {
|
NetworkRemote::~NetworkRemote() {
|
||||||
server_->close();
|
StopServer();
|
||||||
delete incoming_data_parser_;
|
delete incoming_data_parser_;
|
||||||
delete outgoing_data_creator_;
|
delete outgoing_data_creator_;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +47,14 @@ void NetworkRemote::ReadSettings() {
|
||||||
s.beginGroup(NetworkRemote::kSettingsGroup);
|
s.beginGroup(NetworkRemote::kSettingsGroup);
|
||||||
use_remote_ = s.value("use_remote").toBool();
|
use_remote_ = s.value("use_remote").toBool();
|
||||||
port_ = s.value("port").toInt();
|
port_ = s.value("port").toInt();
|
||||||
|
|
||||||
|
// Use only non public ips must be true be default
|
||||||
|
if (s.contains("only_non_public_ip")) {
|
||||||
|
only_non_public_ip_ = s.value("only_non_public_ip").toBool();
|
||||||
|
} else {
|
||||||
|
only_non_public_ip_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (port_ == 0) {
|
if (port_ == 0) {
|
||||||
port_ = kDefaultServerPort;
|
port_ = kDefaultServerPort;
|
||||||
}
|
}
|
||||||
|
@ -53,9 +63,12 @@ void NetworkRemote::ReadSettings() {
|
||||||
|
|
||||||
void NetworkRemote::SetupServer() {
|
void NetworkRemote::SetupServer() {
|
||||||
server_ = new QTcpServer();
|
server_ = new QTcpServer();
|
||||||
|
server_ipv6_ = new QTcpServer();
|
||||||
incoming_data_parser_ = new IncomingDataParser(app_);
|
incoming_data_parser_ = new IncomingDataParser(app_);
|
||||||
outgoing_data_creator_ = new OutgoingDataCreator(app_);
|
outgoing_data_creator_ = new OutgoingDataCreator(app_);
|
||||||
|
|
||||||
|
outgoing_data_creator_->SetClients(&clients_);
|
||||||
|
|
||||||
connect(app_->current_art_loader(),
|
connect(app_->current_art_loader(),
|
||||||
SIGNAL(ArtLoaded(const Song&, const QString&, const QImage&)),
|
SIGNAL(ArtLoaded(const Song&, const QString&, const QImage&)),
|
||||||
outgoing_data_creator_,
|
outgoing_data_creator_,
|
||||||
|
@ -76,11 +89,11 @@ void NetworkRemote::StartServer() {
|
||||||
|
|
||||||
qLog(Info) << "Starting network remote";
|
qLog(Info) << "Starting network remote";
|
||||||
|
|
||||||
clients_ = NULL;
|
|
||||||
|
|
||||||
connect(server_, SIGNAL(newConnection()), this, SLOT(AcceptConnection()));
|
connect(server_, SIGNAL(newConnection()), this, SLOT(AcceptConnection()));
|
||||||
|
connect(server_ipv6_, SIGNAL(newConnection()), this, SLOT(AcceptConnection()));
|
||||||
|
|
||||||
server_->listen(QHostAddress::Any, port_);
|
server_->listen(QHostAddress::Any, port_);
|
||||||
|
server_ipv6_->listen(QHostAddress::AnyIPv6, port_);
|
||||||
|
|
||||||
qLog(Info) << "Listening on port " << port_;
|
qLog(Info) << "Listening on port " << port_;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +101,8 @@ void NetworkRemote::StartServer() {
|
||||||
void NetworkRemote::StopServer() {
|
void NetworkRemote::StopServer() {
|
||||||
if (server_->isListening()) {
|
if (server_->isListening()) {
|
||||||
server_->close();
|
server_->close();
|
||||||
|
server_ipv6_->close();
|
||||||
|
clients_.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +112,8 @@ void NetworkRemote::ReloadSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkRemote::AcceptConnection() {
|
void NetworkRemote::AcceptConnection() {
|
||||||
if (!clients_) {
|
if (!signals_connected_) {
|
||||||
// Create a new QList with clients
|
signals_connected_ = true;
|
||||||
clients_ = new QList<QTcpSocket*>();
|
|
||||||
outgoing_data_creator_->SetClients(clients_);
|
|
||||||
|
|
||||||
// Setting up the signals, but only once
|
// Setting up the signals, but only once
|
||||||
connect(incoming_data_parser_, SIGNAL(SendClementineInfos()),
|
connect(incoming_data_parser_, SIGNAL(SendClementineInfos()),
|
||||||
|
@ -122,23 +135,50 @@ void NetworkRemote::AcceptConnection() {
|
||||||
connect(app_->player()->engine(), SIGNAL(StateChanged(Engine::State)),
|
connect(app_->player()->engine(), SIGNAL(StateChanged(Engine::State)),
|
||||||
outgoing_data_creator_, SLOT(StateChanged(Engine::State)));
|
outgoing_data_creator_, SLOT(StateChanged(Engine::State)));
|
||||||
}
|
}
|
||||||
QTcpSocket* client = server_->nextPendingConnection();
|
|
||||||
|
|
||||||
clients_->push_back(client);
|
if (server_->hasPendingConnections()) {
|
||||||
|
QTcpSocket* client_socket = server_->nextPendingConnection();
|
||||||
|
// Check if our ip is in private scope
|
||||||
|
if (only_non_public_ip_
|
||||||
|
&& !IpIsPrivate(client_socket->peerAddress().toIPv4Address())) {
|
||||||
|
qLog(Info) << "Got a connection from public ip" <<
|
||||||
|
client_socket->peerAddress().toString();
|
||||||
|
} else {
|
||||||
|
CreateRemoteClient(client_socket);
|
||||||
|
// TODO: Check private ips for ipv6
|
||||||
|
}
|
||||||
|
|
||||||
// Connect to the slot IncomingData when receiving data
|
} else {
|
||||||
connect(client, SIGNAL(readyRead()), this, SLOT(IncomingData()));
|
// No checks on ipv6
|
||||||
}
|
CreateRemoteClient(server_ipv6_->nextPendingConnection());
|
||||||
|
}
|
||||||
void NetworkRemote::IncomingData() {
|
}
|
||||||
QTcpSocket* client = static_cast<QTcpSocket*>(QObject::sender());
|
|
||||||
|
bool NetworkRemote::IpIsPrivate(int ip) {
|
||||||
// Now read all the data from the socket
|
int private_local = QHostAddress("127.0.0.1").toIPv4Address();
|
||||||
QByteArray data;
|
int private_a = QHostAddress("10.0.0.0").toIPv4Address();
|
||||||
data = client->readAll();
|
int private_b = QHostAddress("172.16.0.0").toIPv4Address();
|
||||||
incoming_data_parser_->Parse(data);
|
int private_c = QHostAddress("192.168.0.0").toIPv4Address();
|
||||||
|
|
||||||
if (incoming_data_parser_->close_connection()) {
|
// Check if we have a private ip address
|
||||||
client->close();
|
if (ip == private_local
|
||||||
|
|| (ip >= private_a && ip < private_a + 16777216)
|
||||||
|
|| (ip >= private_b && ip < private_b + 1048576)
|
||||||
|
|| (ip >= private_c && ip < private_c + 65536)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkRemote::CreateRemoteClient(QTcpSocket *client_socket) {
|
||||||
|
if (client_socket) {
|
||||||
|
// Add the client to the list
|
||||||
|
RemoteClient* client = new RemoteClient(app_, client_socket);
|
||||||
|
clients_.push_back(client);
|
||||||
|
|
||||||
|
// Connect the signal to parse data
|
||||||
|
connect(client, SIGNAL(Parse(QByteArray)),
|
||||||
|
incoming_data_parser_, SLOT(Parse(QByteArray)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef NETWORKREMOTE_H
|
#ifndef NETWORKREMOTE_H
|
||||||
#define NETWORKREMOTE_H
|
#define NETWORKREMOTE_H
|
||||||
|
|
||||||
#include <QtNetwork>
|
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
@ -9,12 +8,14 @@
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "incomingdataparser.h"
|
#include "incomingdataparser.h"
|
||||||
#include "outgoingdatacreator.h"
|
#include "outgoingdatacreator.h"
|
||||||
|
#include "remoteclient.h"
|
||||||
|
|
||||||
class NetworkRemote : public QThread {
|
class NetworkRemote : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static const char* kSettingsGroup;
|
static const char* kSettingsGroup;
|
||||||
static const int kDefaultServerPort;
|
static const int kDefaultServerPort;
|
||||||
|
static const int kProtocolBufferVersion;
|
||||||
|
|
||||||
NetworkRemote(Application* app);
|
NetworkRemote(Application* app);
|
||||||
~NetworkRemote();
|
~NetworkRemote();
|
||||||
|
@ -24,19 +25,24 @@ public slots:
|
||||||
void StartServer();
|
void StartServer();
|
||||||
void ReloadSettings();
|
void ReloadSettings();
|
||||||
void AcceptConnection();
|
void AcceptConnection();
|
||||||
void IncomingData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTcpServer* server_;
|
QTcpServer* server_;
|
||||||
QList<QTcpSocket*>* clients_;
|
QTcpServer* server_ipv6_;
|
||||||
IncomingDataParser* incoming_data_parser_;
|
IncomingDataParser* incoming_data_parser_;
|
||||||
OutgoingDataCreator* outgoing_data_creator_;
|
OutgoingDataCreator* outgoing_data_creator_;
|
||||||
int port_;
|
int port_;
|
||||||
bool use_remote_;
|
bool use_remote_;
|
||||||
|
bool only_non_public_ip_;
|
||||||
|
bool signals_connected_;
|
||||||
Application* app_;
|
Application* app_;
|
||||||
|
|
||||||
|
QList<RemoteClient*> clients_;
|
||||||
|
|
||||||
void StopServer();
|
void StopServer();
|
||||||
void ReadSettings();
|
void ReadSettings();
|
||||||
|
void CreateRemoteClient(QTcpSocket* client_socket);
|
||||||
|
bool IpIsPrivate(int ip);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETWORKREMOTE_H
|
#endif // NETWORKREMOTE_H
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "outgoingdatacreator.h"
|
#include "outgoingdatacreator.h"
|
||||||
|
#include "networkremote.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
|
|
||||||
OutgoingDataCreator::OutgoingDataCreator(Application* app)
|
OutgoingDataCreator::OutgoingDataCreator(Application* app)
|
||||||
: app_(app),
|
: app_(app)
|
||||||
clients_(NULL)
|
|
||||||
{
|
{
|
||||||
// Create Keep Alive Timer
|
// Create Keep Alive Timer
|
||||||
keep_alive_timer_ = new QTimer(this);
|
keep_alive_timer_ = new QTimer(this);
|
||||||
|
@ -31,7 +31,7 @@ OutgoingDataCreator::OutgoingDataCreator(Application* app)
|
||||||
OutgoingDataCreator::~OutgoingDataCreator() {
|
OutgoingDataCreator::~OutgoingDataCreator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutgoingDataCreator::SetClients(QList<QTcpSocket*>* clients) {
|
void OutgoingDataCreator::SetClients(QList<RemoteClient*>* clients) {
|
||||||
clients_ = clients;
|
clients_ = clients;
|
||||||
// After we got some clients, start the keep alive timer
|
// After we got some clients, start the keep alive timer
|
||||||
// Default: every 10 seconds
|
// Default: every 10 seconds
|
||||||
|
@ -40,21 +40,21 @@ void OutgoingDataCreator::SetClients(QList<QTcpSocket*>* clients) {
|
||||||
|
|
||||||
void OutgoingDataCreator::SendDataToClients(pb::remote::Message* msg) {
|
void OutgoingDataCreator::SendDataToClients(pb::remote::Message* msg) {
|
||||||
// Check if we have clients to send data to
|
// Check if we have clients to send data to
|
||||||
if (!clients_ || clients_->size() == 0) {
|
if (clients_->empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTcpSocket* sock;
|
// Add the Version number
|
||||||
foreach(sock, *clients_) {
|
msg->set_version(NetworkRemote::kProtocolBufferVersion);
|
||||||
|
|
||||||
|
RemoteClient* client;
|
||||||
|
foreach(client, *clients_) {
|
||||||
// Check if the client is still active
|
// Check if the client is still active
|
||||||
if (sock->state() == QTcpSocket::ConnectedState) {
|
if (client->State() == QTcpSocket::ConnectedState) {
|
||||||
std::string data = msg->SerializeAsString();
|
client->SendData(msg);
|
||||||
QByteArray b64_data = QByteArray::fromRawData(data.data(), data.length());
|
|
||||||
sock->write(b64_data.toBase64());
|
|
||||||
sock->write("\n");
|
|
||||||
sock->flush();
|
|
||||||
} else {
|
} else {
|
||||||
clients_->removeAt(clients_->indexOf(sock));
|
clients_->removeAt(clients_->indexOf(client));
|
||||||
|
delete client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ void OutgoingDataCreator::CurrentSongChanged(const Song& song, const QString& ur
|
||||||
current_uri_ = uri;
|
current_uri_ = uri;
|
||||||
current_image_ = img;
|
current_image_ = img;
|
||||||
|
|
||||||
if (clients_) {
|
if (!clients_->empty()) {
|
||||||
// Create the message
|
// Create the message
|
||||||
pb::remote::Message msg;
|
pb::remote::Message msg;
|
||||||
msg.set_msgtype(pb::remote::CURRENT_METAINFOS);
|
msg.set_msgtype(pb::remote::CURRENT_METAINFOS);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "playlist/playlist.h"
|
#include "playlist/playlist.h"
|
||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
#include "remotecontrolmessages.pb.h"
|
#include "remotecontrolmessages.pb.h"
|
||||||
|
#include "remoteclient.h"
|
||||||
|
|
||||||
class OutgoingDataCreator : public QObject {
|
class OutgoingDataCreator : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -20,7 +21,7 @@ public:
|
||||||
OutgoingDataCreator(Application* app);
|
OutgoingDataCreator(Application* app);
|
||||||
~OutgoingDataCreator();
|
~OutgoingDataCreator();
|
||||||
|
|
||||||
void SetClients(QList<QTcpSocket*>* clients);
|
void SetClients(QList<RemoteClient*>* clients);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void SendClementineInfos();
|
void SendClementineInfos();
|
||||||
|
@ -36,7 +37,7 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
QList<QTcpSocket*>* clients_;
|
QList<RemoteClient*>* clients_;
|
||||||
Song current_song_;
|
Song current_song_;
|
||||||
QString current_uri_;
|
QString current_uri_;
|
||||||
QImage current_image_;
|
QImage current_image_;
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* This file is part of Clementine.
|
||||||
|
Copyright 2013, Andreas Muttscheller <asfa194@gmail.com>
|
||||||
|
|
||||||
|
Clementine is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Clementine is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "core/logging.h"
|
||||||
|
|
||||||
|
#include "remoteclient.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
RemoteClient::RemoteClient(Application* app, QTcpSocket* client)
|
||||||
|
: app_(app),
|
||||||
|
client_(client)
|
||||||
|
{
|
||||||
|
// Open the buffer
|
||||||
|
buffer_.setData(QByteArray());
|
||||||
|
buffer_.open(QIODevice::ReadWrite);
|
||||||
|
reading_protobuf_ = false;
|
||||||
|
|
||||||
|
// Connect to the slot IncomingData when receiving data
|
||||||
|
connect(client, SIGNAL(readyRead()), this, SLOT(IncomingData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RemoteClient::~RemoteClient() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::IncomingData() {
|
||||||
|
while (client_->bytesAvailable()) {
|
||||||
|
if (!reading_protobuf_) {
|
||||||
|
// Read the length of the next message
|
||||||
|
QDataStream s(client_);
|
||||||
|
s >> expected_length_;
|
||||||
|
reading_protobuf_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read some of the message
|
||||||
|
buffer_.write(
|
||||||
|
client_->read(expected_length_ - buffer_.size()));
|
||||||
|
|
||||||
|
// Did we get everything?
|
||||||
|
if (buffer_.size() == expected_length_) {
|
||||||
|
// Parse the message
|
||||||
|
emit Parse(buffer_.data());
|
||||||
|
|
||||||
|
// Clear the buffer
|
||||||
|
buffer_.close();
|
||||||
|
buffer_.setData(QByteArray());
|
||||||
|
buffer_.open(QIODevice::ReadWrite);
|
||||||
|
reading_protobuf_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::SendData(pb::remote::Message *msg) {
|
||||||
|
// Serialize the message
|
||||||
|
std::string data = msg->SerializeAsString();
|
||||||
|
|
||||||
|
// write the length of the data first
|
||||||
|
QDataStream s(client_);
|
||||||
|
s << qint32(data.length());
|
||||||
|
s.writeRawData(data.data(), data.length());
|
||||||
|
|
||||||
|
// Flush data
|
||||||
|
client_->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketState RemoteClient::State() {
|
||||||
|
return client_->state();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef REMOTECLIENT_H
|
||||||
|
#define REMOTECLIENT_H
|
||||||
|
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
|
#include "core/application.h"
|
||||||
|
#include "incomingdataparser.h"
|
||||||
|
|
||||||
|
class RemoteClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
RemoteClient(Application* app, QTcpSocket* client);
|
||||||
|
~RemoteClient();
|
||||||
|
|
||||||
|
void SendData(pb::remote::Message* msg);
|
||||||
|
QAbstractSocket::SocketState State();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void IncomingData();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void Parse(const QByteArray& pb_data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Application* app_;
|
||||||
|
|
||||||
|
QTcpSocket* client_;
|
||||||
|
bool reading_protobuf_;
|
||||||
|
quint32 expected_length_;
|
||||||
|
QBuffer buffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // REMOTECLIENT_H
|
|
@ -51,6 +51,13 @@ void NetworkRemoteSettingsPage::Load() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_->use_remote->setChecked(s.value("use_remote").toBool());
|
ui_->use_remote->setChecked(s.value("use_remote").toBool());
|
||||||
|
if (s.contains("only_non_public_ip")) {
|
||||||
|
ui_->only_non_public_ip->setChecked(s.value("only_non_public_ip").toBool());
|
||||||
|
} else {
|
||||||
|
// Default yes
|
||||||
|
ui_->only_non_public_ip->setChecked(true);
|
||||||
|
s.setValue("only_non_public_ip", true);
|
||||||
|
}
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
}
|
}
|
||||||
|
@ -61,6 +68,7 @@ void NetworkRemoteSettingsPage::Save() {
|
||||||
s.beginGroup(NetworkRemote::kSettingsGroup);
|
s.beginGroup(NetworkRemote::kSettingsGroup);
|
||||||
s.setValue("port", ui_->remote_port->value());
|
s.setValue("port", ui_->remote_port->value());
|
||||||
s.setValue("use_remote", ui_->use_remote->isChecked());
|
s.setValue("use_remote", ui_->use_remote->isChecked());
|
||||||
|
s.setValue("only_non_public_ip", ui_->only_non_public_ip->isChecked());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>475</width>
|
||||||
<height>300</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_15">
|
<widget class="QLabel" name="label_remote_port">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>171</width>
|
<width>171</width>
|
||||||
|
@ -63,6 +63,26 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="only_non_public_ip">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Only accept connections from clients within the ip ranges:
|
||||||
|
10.x.x.x
|
||||||
|
172.16.0.0 - 172.31.255.255
|
||||||
|
192.168.x.x</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Accept non public clients only</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in New Issue