defuze.me
Client
|
00001 /************************************************************************** 00002 ** defuze.me Epitech Innovative Project 00003 ** 00004 ** Copyright 2010 00005 ** Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard 00006 ** Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier 00007 ** 00008 ** All rights reserved. 00009 **************************************************************************/ 00010 00011 #include <QHostInfo> 00012 #include "guicore.hpp" 00013 #include "networkcore.hpp" 00014 #include "exception.hpp" 00015 #include "parser.hpp" 00016 #include "logger.hpp" 00017 #include "loginview.hpp" 00018 #include "authview.hpp" 00019 #include "status.hpp" 00020 00021 using namespace Network; 00022 00023 NetworkCore::NetworkCore(QStringList &) 00024 { 00025 webManager = new QNetworkAccessManager(); 00026 rcServer = new QTcpServer(); 00027 adServer = new QUdpSocket(); 00028 authenticator = NULL; 00029 doorman = NULL; 00030 } 00031 00032 NetworkCore::~NetworkCore() 00033 { 00034 delete rcServer; 00035 delete webManager; 00036 delete adServer; 00037 } 00038 00039 void NetworkCore::init(Cores *c) 00040 { 00041 JsonParser::test(); 00042 00043 cores = c; 00044 00045 // Web service 00046 authenticator = new Authenticator(*this); 00047 authenticator->setParamsBackEnd(cores->db()); 00048 authenticator->registerToParamsCore(cores->params()); 00049 connect(authenticator, SIGNAL(needCredentials(const QString&)), SLOT(giveCredentials(const QString&))); 00050 connect(authenticator, SIGNAL(authenticated()), SIGNAL(APIAuthenticated())); 00051 authenticator->getToken(); 00052 00053 // Remote control 00054 initRCServer(gl_RC_PORT); 00055 00056 // Auto discovery 00057 adServer->bind(gl_AD_ASK_PORT, QUdpSocket::ShareAddress); 00058 connect(adServer, SIGNAL(readyRead()), this, SLOT(discoveryRequest())); 00059 } 00060 00061 void NetworkCore::aboutToQuit() 00062 { 00063 if (authenticator) 00064 delete authenticator; 00065 if (doorman) 00066 delete doorman; 00067 } 00068 00069 void NetworkCore::initRCServer(unsigned short port) 00070 { 00071 if (!rcServer->listen(QHostAddress::Any, port)) 00072 { 00073 Logger::log(QString("Network: RCServer could not listen port %1").arg(port)); 00074 Notification::Status::gMessage(tr("Could not listen TCP port %1, launched twice or firewall?").arg(port), Notification::ERR); 00075 } 00076 00077 if (!doorman) 00078 { 00079 doorman = new Doorman(rcServer); 00080 doorman->setParamsBackEnd(cores->db()); 00081 doorman->registerToParamsCore(cores->params()); 00082 connect(doorman, SIGNAL(authenticatedRemote(RemoteSock*)), SIGNAL(newRemoteClient(RemoteSock*))); 00083 connect(doorman, SIGNAL(needAuthorization(const RemoteEvent&)), SLOT(giveAuthorization(const RemoteEvent&))); 00084 } 00085 } 00086 00087 00088 void NetworkCore::discoveryRequest() 00089 { 00090 while (adServer->hasPendingDatagrams()) 00091 { 00092 QByteArray datagram; 00093 QHostAddress sender; 00094 quint16 senderPort; 00095 00096 datagram.resize(adServer->pendingDatagramSize()); 00097 adServer->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); 00098 if (datagram == "\"defuze.me:discovery\"") 00099 { 00100 Logger::log("Network: new discovery request from " + sender.toString()); 00101 QUdpSocket().writeDatagram(JsonParser().serialize(discoveryAddresses()), QHostAddress::Broadcast, gl_AD_REPLY_PORT); 00102 } 00103 else 00104 { 00105 Logger::log("Network: bad udp request from " + sender.toString()); 00106 } 00107 } 00108 } 00109 00110 QVariantList NetworkCore::discoveryAddresses() const 00111 { 00112 QVariantList list; 00113 QString host = QHostInfo::localHostName(); 00114 QVariantMap address; 00115 00116 address["host"] = host; 00117 address["port"] = gl_RC_PORT; 00118 QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses(); 00119 for (int i = 0; i < ipAddressesList.size(); ++i) 00120 if (ipAddressesList.at(i) != QHostAddress::LocalHost && 00121 ipAddressesList.at(i) != QHostAddress::LocalHostIPv6) 00122 { 00123 address["ip"] = ipAddressesList.at(i).toString(); 00124 address["protocol"] = (ipAddressesList.at(i).protocol() ? "IPv6" : "IPv4"); 00125 list << address; 00126 } 00127 if (list.isEmpty()) 00128 { 00129 address["ip"] = QHostAddress(QHostAddress::LocalHost).toString(); 00130 list << address; 00131 } 00132 return list; 00133 } 00134 00135 00136 void NetworkCore::invalidateWebToken() 00137 { 00138 authenticator->invalidate(); 00139 } 00140 00141 QVariantMap NetworkCore::getRadioInfo() const 00142 { 00143 if (authenticator) 00144 return authenticator->getRadioInfo(); 00145 else 00146 return QVariantMap(); 00147 } 00148 00149 void NetworkCore::giveCredentials(const QString& login) 00150 { 00151 LoginView *lv = new LoginView(login); 00152 00153 // This slot is called when the authenticator ask for credentials, 00154 // it displays a window. 00155 authenticator->connect(lv, SIGNAL(authenticate(QString, QString)), SLOT(authenticate(QString, QString))); 00156 authenticator->connect(lv, SIGNAL(cancelled()), SLOT(cancel())); 00157 lv->connect(authenticator, SIGNAL(failed(QString)), SLOT(login_failed(QString))); 00158 lv->connect(authenticator, SIGNAL(authenticated()), SLOT(login_sucess())); 00159 cores->gui()->popup(lv); 00160 } 00161 00162 void NetworkCore::giveAuthorization(const RemoteEvent& event) 00163 { 00164 AuthView *av = new AuthView(event); 00165 00166 // This slot is called when the doorman ask for authorization, 00167 // it displays a window. 00168 doorman->connect(av, SIGNAL(answered(RemoteSock*, unsigned, bool, bool)), SLOT(answered(RemoteSock*, unsigned, bool, bool))); 00169 cores->gui()->popup(av); 00170 } 00171 00172 const QString NetworkCore::name() 00173 { 00174 return "Network"; 00175 } 00176 00177 QNetworkAccessManager& NetworkCore::web() 00178 { 00179 return *webManager; 00180 } 00181 00182 QTcpServer& NetworkCore::remoteControl() 00183 { 00184 return *rcServer; 00185 } 00186 00187 QUdpSocket& NetworkCore::autoDiscovery() 00188 { 00189 return *adServer; 00190 } 00191 00192 // This is our default API parser, all parsing & serialization must be done using this method 00193 // This way we can easily switch our entire application API format. 00194 const Parser& NetworkCore::apiParser() const 00195 { 00196 return defaultApiParser; 00197 } 00198 00199 QNetworkRequest NetworkCore::apiRequest(const QString& url) const 00200 { 00201 QNetworkRequest request; 00202 QUrl fullUrl("http://" + gl_API_HOSTNAME + "/" + url); 00203 00204 request.setUrl(fullUrl); 00205 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); 00206 request.setRawHeader("Accept", "application/json"); 00207 request.setRawHeader("Connection", "Close"); 00208 request.setRawHeader("User-Agent", QString("%1 client %2").arg(gl_APPLICATION_NAME, gl_APPLICATION_VERSION).toUtf8()); 00209 request.setRawHeader("Client-Version", gl_APPLICATION_VERSION.toUtf8()); 00210 request.setRawHeader("API-Token", authenticator->getToken().toUtf8()); 00211 00212 Logger::log(QString("Network: new API request on %1").arg(fullUrl.toString())); 00213 00214 return request; 00215 }