Projet Darts  0.2
BTS SNIR LaSalle Avignon 2020
communication.cpp
Aller à la documentation de ce fichier.
1 #include "communication.h"
2 #include <QDebug>
3 
22 Communication::Communication(Darts *darts, QObject *parent) : QObject(parent), darts(darts), serveur(nullptr), socket(nullptr), localDeviceName("Ecran-Darts"), trame("")
23 {
24  qDebug() << Q_FUNC_INFO;
25 
27 
29 }
30 
37 {
38  arreter();
39  localDevice.setHostMode(QBluetoothLocalDevice::HostPoweredOff);
40  qDebug() << Q_FUNC_INFO;
41 }
42 
50 {
51  return etatPartie;
52 }
53 
60 {
61  if (!localDevice.isValid())
62  {
63  qDebug() << Q_FUNC_INFO << "Communication Bluetooth locale valide : " << localDevice.isValid();
64  emit erreurBluetooth("Communication Bluetooth locale valide : " + QString::number(localDevice.isValid()));
65 
66  return;
67  }
68  else
69  {
70  // active le bluetooth
71  localDevice.powerOn();
72 
73  // lire le nom de l'appareil local
75 
76 
77  //localDevice.setHostMode(QBluetoothLocalDevice::HostConnectable);
78 
79  //ou
80 
81  //les appareil qui ne sont pas jumelé peuvent decouvrir ecran-DARTS
82  localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
83 
84  QList<QBluetoothAddress> remotes;
85  remotes = localDevice.connectedDevices();
86 
87  connect(&localDevice, SIGNAL(deviceConnected(QBluetoothAddress)), this, SLOT(deviceConnected(QBluetoothAddress)));
88  connect(&localDevice, SIGNAL(deviceDisconnected(QBluetoothAddress)), this, SLOT(deviceDisconnected(QBluetoothAddress)));
89  connect(&localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)), this, SLOT(error(QBluetoothLocalDevice::Error)));
90 
91  connect(darts, SIGNAL(etatPartieFini()), this , SLOT(miseAJourEtatPartieFin()));
92  connect(darts, SIGNAL(etatPartieTournois()), this , SLOT(miseAJourEtatPartieTournois()));
93  connect(darts, SIGNAL(changerEtatPartie()), this , SLOT(miseAJourEtatPartieEnCours()));
94  connect(darts, SIGNAL(etatPartieAttenteTournois()), this, SLOT(miseAJourEtatPartieAttenteTournois()));
95  }
96 }
97 
104 {
105  if (!localDevice.isValid())
106  return;
107 
108  if (!serveur) //Démarre le serveur s'il n'est pas déjà démarré
109  {
110  serveur = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
111  connect(serveur, SIGNAL(newConnection()), this, SLOT(nouveauClient()));
112 
113  QBluetoothUuid uuid = QBluetoothUuid(serviceUuid);
114  serviceInfo = serveur->listen(uuid, serviceNom);
115  }
116 }
117 
124 {
125  if (!localDevice.isValid())
126  return;
127 
128  if (!serveur)
129  return;
130 
131  serviceInfo.unregisterService();
132 
133  if (socket)
134  {
135  if (socket->isOpen())
136  {
137  socket->close();
138  }
139  delete socket;
140  socket = nullptr;
141  }
142 
143  delete serveur;
144  serveur = nullptr;
145 }
146 
153 {
154  // on récupère la socket
155  socket = serveur->nextPendingConnection();
156  if (!socket)
157  return;
158 
159  connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
160  connect(socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
161 }
162 
169 {
170  QByteArray donnees;
171 
172  while (socket->bytesAvailable())
173  {
174  donnees += socket->readAll();
175  usleep(150000); // cf. timeout
176  }
177 
178  trame = QString(donnees);
179 
180  qDebug() << Q_FUNC_INFO << QString::fromUtf8("Trame reçues : ") << QString(donnees);
181 
182  decomposerTrame();
183 }
184 
191 {
192  if(estValide()) //test si la trame est valide
193  {
194  trame.remove(DELIMITEUR_FIN);
195  if(trame.contains("START") && (etatPartie == EtatPartie::Attente || etatPartie == EtatPartie::Fin))
196  {
197  emit resetPartie();
199 
200  QString modeJeu;
201  QStringList joueurs;
202 
203  extraireParametresTrameStart(joueurs, modeJeu);
204  }
205  else if(trame.contains("GAME") && etatPartie == EtatPartie::EnCours)
206  {
207  darts->receptionnerImpact(trame.section(";",2,2).toInt(), trame.section(";",3,3).toInt());
208  }
209  else if(trame.contains("GAME") && etatPartie == EtatPartie::Tournois)
210  {
211  darts->receptionnerImpactTournois(trame.section(";",2,2).toInt(), trame.section(";",3,3).toInt());
212  }
213  else if(trame.contains("REGLE")&& etatPartie != EtatPartie::Regle)
214  {
216  }
217  else if(trame.contains("PAUSE") && (etatPartie == EtatPartie::EnCours || etatPartie == EtatPartie::Tournois))
218  {
220  emit pause();
222  }
223  else if(trame.contains("PLAY") && etatPartie == EtatPartie::Pause)
224  {
225  emit play();
226  relancerPartie();
227  }
228  else if(trame.contains("SON"))
229  {
230  emit jouerSon(trame.section(";",2,2));
231  }
232  else if(trame.contains("TOURNOIS"))
233  {
235  }
236  else if(trame.contains("RESET")) // quelque soit l'état de la partie /** $DART;RESET */
237  {
238  reamorcerPartie();
239  }
240  else if(trame.contains("STOP") && (etatPartie == EtatPartie::EnCours || etatPartie == EtatPartie::Pause))
241  {
242  darts->arreterPartie();
243  }
244  else if(trame.contains("STOP") && (etatPartie == EtatPartie::Regle)) //permet l'arret des regles en cours de lecture
245  {
246  emit stopperRegle();
247  }
248  else
249  {
250  qDebug() << Q_FUNC_INFO << "Trame non Traité: " << trame;
251  }
252  }
253 }
254 
262 {
263  if(trame.startsWith(TYPE_TRAME) && trame.endsWith(DELIMITEUR_FIN) && trame.contains(";"))
264  {
265  return true;
266  }
267  else
268  {
269  qDebug() << Q_FUNC_INFO << "Trame non Valide: " << trame;
270  return false;
271  }
272 }
273 
281 void Communication::extraireParametresTrameStart(QStringList &joueurs, QString &modeJeu)
282 {
283  modeJeu = trame.section(";",2,2);
284 
285  if(trame.section(";",4,4).toInt() == 0) //test effectuer pour verifier que la trame n'est pas une trame de la version du protocol DARTS 0.2
286  return;
287 
288  for(int i = 0;i <= trame.section(";",4,4).toInt();i++) //boucle qui recuperer les noms des differents joueurs
289  {
290  if(trame.section(";",4+i,4+i) == "") //test si le joueur a un nom
291  {
292  joueurs.push_back("Joueur[" + QString::number(i) + "]");
293  }
294  else
295  {
296  joueurs.push_back(trame.section(";",4+i,4+i));
297  }
298  }
299 
300  darts->initialiserPartie(joueurs, modeJeu);
301 
302  if(trame.section(";",3,3) == "1")
303  {
304  if(etatPartie != EtatPartie::Pause)
305  emit pause();
306 
308  }
309 
310 }
311 
318 {
319  QString modeJeu;
320  QString nomTournois;
321  QStringList joueurs;
322 
323  if(trame.contains("CONFIG") && (etatPartie == EtatPartie::Attente || etatPartie == EtatPartie::Fin))
324  {
325  modeJeu = trame.section(";",3,3);
326 
327  if(trame.section(";",5,5).toInt()%2 !=0)
328  {
329  qDebug() << "Nombre de joueur insuffissant";
330  return;
331  }
332 
334 
335  for(int i = 0;i <= trame.section(";",5,5).toInt();i++) //boucle qui recuperer les noms des differents joueurs
336  {
337  if(trame.section(";",5+i,5+i) == "") //test si le joueur a un nom
338  {
339  joueurs.push_back("Joueur[" + QString::number(i) + "]");
340  }
341  else
342  {
343  joueurs.push_back(trame.section(";",5+i,5+i));
344  }
345  }
346  nomTournois = trame.section(";",4,4);
347  darts->configurationTournois(joueurs, modeJeu, nomTournois);
348 
349  }
350  else if(trame.contains("PLAY") && (etatPartie == EtatPartie::AttenteTournois))
351  {
353  }
354  else
355  {
356  qDebug() << Q_FUNC_INFO << "Trame non Traité: " << trame;
357  }
358 }
359 
366 {
367  QString regle ="";
368 
369  if(etatPartie != EtatPartie::Pause)
370  emit pause();
371 
372  if(trame.section(";",2,2).contains("DOUBLE_OUT"))
373  {
374  emit afficherRegle("DOUBLE_OUT");
375  }
376  else if(trame.section(";",2,2) == "" && (etatPartie == EtatPartie::EnCours || etatPartie == EtatPartie::Pause))
377  {
379  }
380  else
381  {
382  emit afficherRegle("SANS_DOUBLE_OUT");
383  }
384 }
385 
392 {
393  emit resetPartie();
396 }
397 
404 {
405  QString message = QString::fromUtf8("Périphérique déconnecté ");
406  qDebug() << Q_FUNC_INFO << message;
407 }
408 
415 void Communication::deviceConnected(const QBluetoothAddress &adresse)
416 {
417  qDebug() << Q_FUNC_INFO << adresse << localDevice.pairingStatus(adresse);
418  QString message = QString::fromUtf8("Demande connexion du client ") + adresse.toString();
419  emit appareilConnecter();
420  if (localDevice.pairingStatus(adresse) == QBluetoothLocalDevice::Paired || localDevice.pairingStatus(adresse) == QBluetoothLocalDevice::AuthorizedPaired)
421  message += " [" + QString::fromUtf8("appairé") + "]";
422  else
423  message += " [" + QString::fromUtf8("non appairé") + "]" ;
424  qDebug() << message << endl;
425 
426  if(etatPartie == EtatPartie::Pause) // si l'appareil est reconnecte, la partie reprend
427  {
428  emit play();
429  relancerPartie();
430  }
431 }
432 
439 void Communication::deviceDisconnected(const QBluetoothAddress &adresse)
440 {
441  qDebug() << Q_FUNC_INFO << adresse;
443 
444  if(etatPartie == EtatPartie::EnCours || etatPartie == EtatPartie::Tournois) // si l'appareil se deconnecte pendant la partie, il la met donc en pause
445  {
447  emit pause();
449  }
450 }
451 
458 void Communication::error(QBluetoothLocalDevice::Error erreur)
459 {
460  qDebug() << Q_FUNC_INFO << erreur;
461 }
462 
469 {
470  qDebug() << Q_FUNC_INFO << "EtatPartie::Attente";
471  etatPartie = EtatPartie::Attente;
472 }
473 
480 {
481  qDebug() << Q_FUNC_INFO << "EtatPartie::Pause";
482  etatPartie = EtatPartie::Pause;
483 }
484 
491 {
492  qDebug() << Q_FUNC_INFO << "EtatPartie::Fin";
493  etatPartie = EtatPartie::Fin;
494 }
495 
502 {
503  qDebug() << Q_FUNC_INFO << "EtatPartie::EnCours";
504  etatPartie = EtatPartie::EnCours;
505 }
506 
513 {
514  qDebug() << Q_FUNC_INFO << "EtatPartie::Regle";
515  etatPartie = EtatPartie::Regle;
516 }
517 
524 {
525  qDebug() << Q_FUNC_INFO << "EtatPartie::Tournois";
526  etatPartie = EtatPartie::Tournois;
527 }
528 
529 
536 {
537  qDebug() << Q_FUNC_INFO << "EtatPartie::AttenteTournois";
538  etatPartie = EtatPartie::AttenteTournois;
539 }
540 
547 {
548  if(etatPrecedent == EtatPartie::EnCours)
549  {
551  }
552  else
553  {
555  }
556 }
QString trame
La trame recue.
void miseAJourEtatPartieAttente()
Méthode appelé pour mettre à jour l&#39;état de la partie à Attente.
#define DELIMITEUR_FIN
Définit le délimiteur de fin de trame du protocole DARTS.
Definition: communication.h:30
Déclaration de la classe Communication (Module Ecran-DARTS)
void decomposerTrame()
Méthode qui decompose la trame reçue.
void stopperRegle()
signal emit pour stopper la lecture des regles
void extraireParametresTrameStart(QStringList &joueurs, QString &modeJeu)
Méthode qui extrait les paramètres de la trame START.
void socketReadyRead()
Slot appelé quand une nouvelle trame est disponible.
void configurationTournois(QStringList joueurList, QString modeJeu, QString nomTournois)
methode utiliser pour configurer le tournois
Definition: darts.cpp:570
~Communication()
destructeur de la classe Communication
static const QString serviceNom(QStringLiteral("Ecran-Darts"))
void parametrerBluetooth()
Méthode qui configure la connexion Bluetooth en mode serveur.
QBluetoothLocalDevice localDevice
L&#39;interface Bluetooth de la Raspberry Pi.
void socketDisconnected()
Slot appelé quand la communication est deconnectée.
void play()
signal qui relancera le chronometrage de la partie la partie
void error(QBluetoothLocalDevice::Error erreur)
Slot appelé quand il y a une erreur avec l&#39;appareil bluetooth.
void reamorcerPartie()
Méthode qui relance la partie.
void jouerSon(QString)
void relancerPartie()
Méthode qui gere l&#39;initialisation d&#39;une partie de flechette.
void demarrerTournois()
methode appelé pour demarrer le tournois
Definition: darts.cpp:614
EtatPartie etatPartie
L&#39;état de la partie.
Communication(Darts *darts, QObject *parent=nullptr)
constructeur de la classe Communication
void miseAJourEtatPartiePause()
Méthode appelé pour mettre à jour l&#39;état de la partie à Pause.
void demarrer()
Méthode qui démarre le serveur.
QBluetoothServiceInfo serviceInfo
Informations sur le service bluetooth.
QBluetoothServer * serveur
Le serveur Bluetooth.
static const QString serviceUuid(QStringLiteral("0000110a-0000-1000-8000-00805f9b34fb"))
void nouveauClient()
Slot appelé quand un nouveau client veut se connecter.
void resetPartie()
signal qui reinitialisera la partie en cours
void deviceConnected(const QBluetoothAddress &adresse)
Slot appelé quand un nouvel appareil est connecté
int etatPrecedent
Contient l&#39;etat dans lequel se trouver l&#39;application.
Déclaration de la classe Darts (Module Ecran-DARTS)
Definition: darts.h:33
void afficherRegle(QString regle)
signal emit pour afficher les regles
QBluetoothSocket * socket
La socket de communication Bluetooth.
void receptionnerImpact(int typePoint, int point)
Permets de traiter la réception d&#39;impact.
Definition: darts.cpp:261
void arreterPartie()
arrête la partie
Definition: darts.cpp:462
void extraireParametresTrameRegle()
Méthode qui extrait les paramètres de la trame REGLE.
void receptionnerImpactTournois(int typePoint, int point)
methode qui gere le deroulement de la partie tournois
Definition: darts.cpp:629
void appareilConnecter()
signal émis quand un nouvel appareil est connecté
QString localDeviceName
Nom du peripherique local.
void initialiserPartie(QStringList joueurList, QString modeJeu)
Initialise la partie.
Definition: darts.cpp:177
void miseAJourEtatPartieAttenteTournois()
Slot appelé pour mettre à jour l&#39;état de la partie à attenteTournois.
int getEtatPartie()
Méthode qui permet de recuperer l&#39;etat de la partie.
void miseAJourEtatPartieTournois()
Slot appelé pour mettre à jour l&#39;état de la partie à tournois.
QString testerModeDeJeu()
Méthode qui teste le mode de jeu.
Definition: darts.cpp:547
bool estValide()
Méthode qui test si la trame est valide.
void miseAJourEtatPartieFin()
Slot appelé pour mettre à jour l&#39;état de la partie à Fin.
void miseAJourEtatPartieEnCours()
Slot appelé pour mettre à jour l&#39;état de la partie à EnCours.
La classe QObject est la classe de base de tous les objets Qt. Elle permet à ces objets Qt de dispose...
void erreurBluetooth(QString erreur)
signal emit quand un probleme de configuration bluetooth est detecté
void deviceDisconnected(const QBluetoothAddress &adresse)
Slot appelé quand un appareil est déconnecté
void pause()
signal qui mettra en pause la partie
void arreter()
Méthode qui arrête le serveur.
void decomposerTrameTournois()
Méthode qui extrait les paramètres de la trame TOURNOIS.
void reinitialiserPartie()
Méthode qui permet de remettre a zero les differents attribut et conteneur pour une nouvelle partie...
Definition: darts.cpp:217
Darts * darts
Association avec l&#39;objet darts.
Definition: communication.h:99
void miseAJourEtatPartieRegle()
Méthode appelé pour mettre à jour l&#39;état de la partie à regle.
void afficherAttenteConnexion()
signal émis quand un appareil se déconnecte
#define TYPE_TRAME
Définit le type de trame du protocole DARTS.
Definition: communication.h:24