Ecran-DARTS  1.1
BTS SNIR LaSalle Avignon 2021
communication.cpp
Aller à la documentation de ce fichier.
1 #include "communication.h"
2 #include <QDebug>
3 #include <unistd.h> // pour usleep
4 
23 Communication::Communication(QObject *parent) : QObject(parent), serveur(nullptr), socket(nullptr), etatPartie(ETAT_PARTIE_ATTENTE)
24 {
25  qDebug() << Q_FUNC_INFO;
26 
27  configurer();
28 }
29 
36 {
37  qDebug() << Q_FUNC_INFO;
38 
39  arreter();
40 }
41 
48 {
49  // vérifier la présence du Bluetooth
50  if (localDevice.isValid())
51  {
52  // activer le bluetooth
53  localDevice.powerOn();
54 
55  // récupérer le nom du périphérique local
57  qDebug() << Q_FUNC_INFO << localDeviceName;
58 
59  // rendre le périphérique local découvrable et jumelable
60  localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
61 
62  // connecter les signaux et les slots
63  connect(&localDevice, SIGNAL(deviceConnected(QBluetoothAddress)), this, SLOT(deviceConnected(QBluetoothAddress)));
64  connect(&localDevice, SIGNAL(deviceDisconnected(QBluetoothAddress)), this, SLOT(deviceDisconnected(QBluetoothAddress)));
65  connect(&localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)), this, SLOT(error(QBluetoothLocalDevice::Error)));
66 
67  QList<QBluetoothAddress> remotes;
68  remotes = localDevice.connectedDevices();
69  if(remotes.size() > 0)
70  qDebug() << Q_FUNC_INFO << remotes;
71  }
72  else
73  qDebug() << Q_FUNC_INFO << "Pas de Bluetooth !!!";
74 }
75 
82 {
83  // vérifier la présence du Bluetooth
84  if (!localDevice.isValid())
85  return;
86 
87  if (serveur == nullptr)
88  {
89  // créer une socket serveur
90  serveur = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
91 
92  connect(serveur, SIGNAL(newConnection()), this, SLOT(connecter()));
93 
94  // placer le serveur en écoute
95  QBluetoothUuid uuid = QBluetoothUuid(serviceUuid);
96  serviceInfo = serveur->listen(uuid, serviceNom);
97  qDebug() << Q_FUNC_INFO << "Serveur en attente de connexion";
98  }
99 }
100 
107 {
108  if (!localDevice.isValid())
109  return;
110 
111  if (serveur == nullptr)
112  return;
113 
114  qDebug() << Q_FUNC_INFO << "Arrête le serveur Bluetooth";
115 
116  serviceInfo.unregisterService();
117 
118  if (socket != nullptr)
119  {
120  deconnecter();
121  delete socket;
122  socket = nullptr;
123  }
124 
125  delete serveur;
126  serveur = nullptr;
127 }
128 
135 {
136  // on récupère la socket
137  socket = serveur->nextPendingConnection();
138  if (socket == nullptr)
139  return;
140 
141  qDebug() << Q_FUNC_INFO;
142  connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
143  connect(socket, SIGNAL(readyRead()), this, SLOT(recevoir()));
144 
145  emit connexionMobileDarts();
146 }
147 
154 {
155  if (socket->isOpen())
156  {
157  qDebug() << Q_FUNC_INFO;
158  socket->close();
159  }
160 }
161 
168 {
169  if (socket == nullptr)
170  return false;
171 
172  qDebug() << Q_FUNC_INFO << socket->isOpen();
173  return socket->isOpen();
174 }
175 
182 {
183  qDebug() << Q_FUNC_INFO << "Déconnexion socket";
184  emit deconnexionMobileDarts();
185 }
186 
192 void Communication::envoyer(QString trame)
193 {
194  if (socket == nullptr || !socket->isOpen())
195  return;
196 
197  qDebug() << Q_FUNC_INFO << trame;
198  socket->write(trame.toLatin1());
199 }
200 
207 {
208  QByteArray donnees;
209  donnees = socket->readAll();
210  qDebug() << Q_FUNC_INFO << donnees;
211 
212  trame += QString(donnees);
213 
214  if(!trame.isEmpty())
215  {
216  traiterTrame();
217  }
218 }
219 
226 {
227  trame.clear();
228 }
229 
236 {
237  // Protocole
238  const QString DEBUT_TRAME = "$";
239  const QString ENTETE_TRAME = "DARTS";
240  const QString DELIMITEUR_CHAMP = ";";
241  const QString DELIMITEUR_FIN = "\r\n";
242  const QString TRAME_PARTIE = "START";
243  const QString TRAME_TOUCHE = "HIT";
244  const QString TRAME_ACQUITTEMENT = "OK";
245  const QString TRAME_REINITIALISATION = "RESET";
246  const QString TRAME_FIN = "FIN";
247  bool trameTraitee = false;
248 
249  //qDebug() << Q_FUNC_INFO << trame;
250 
251  // au moins une trame complète reçue ?
252  if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME) && trame.endsWith(DELIMITEUR_FIN))
253  {
254  //qDebug() << Q_FUNC_INFO << trame << "ok";
255  trame.remove(DELIMITEUR_FIN);
256 
257  if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_PARTIE))
258  {
261 
262  // Trame de début
263  // Format : $DARTS;START;TYPE_PARTIE;NB_JOUEURS;NOMS\r\n
264  qDebug() << Q_FUNC_INFO << trame << "trame de début";
265  QStringList champs = trame.split(";");
266  qDebug() << Q_FUNC_INFO << champs;
267  int nbJoueurs = (champs.at(CHAMP_NB_JOUEURS)).toInt();
268  emit tramePartieRecue(champs.at(CHAMP_TYPE_PARTIE), nbJoueurs);
269  QStringList nomsJoueur;
270  for(int i = 0; i < nbJoueurs; ++i)
271  {
272  nomsJoueur << (champs.at(CHAMP_DEBUT_NOM_JOUEUR+i));
273  }
274  emit listeJoueurs(nomsJoueur);
275  // Acquitte la trame
276  envoyer(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_ACQUITTEMENT + DELIMITEUR_FIN);
277  trameTraitee = true;
278  }
279  else if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_TOUCHE))
280  {
281  // Trame de touche
282  // Format : $DARTS;HIT;valeurTouche;multiplicateurTouche;ID\r\n
283  qDebug() << Q_FUNC_INFO << trame << "trame de touche";
284  QStringList champs = trame.split(";");
285  qDebug() << Q_FUNC_INFO << champs;
286  int idTouche = (champs.at(CHAMP_ID)).toInt();
287  int valeurTouche = (champs.at(CHAMP_TOUCHE)).toInt();
288  int multiplicateurTouche = (champs.at(CHAMP_MULTIPLICATEUR)).toInt();
289  emit trameToucheRecue(idTouche, valeurTouche, multiplicateurTouche);
290  // Acquitte la trame
291  envoyer(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_ACQUITTEMENT + DELIMITEUR_FIN);
292  trameTraitee = true;
293  }
294  /*else if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_ACQUITTEMENT))
295  {
296  // @warning Le protocole ne précise pas que l'on reçoit des trames d'acquittement
297  // Trame d'acquittement
298  // Format : $DARTS;OK\r\n
299  qDebug() << Q_FUNC_INFO << trame << "trame d'acquittement";
300  emit trameAcquittementRecue();
301  trameTraitee = true;
302  }*/
303  else if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_REINITIALISATION))
304  {
305  // Trame de réinitialisation
306  // Format : $DARTS;RESET\r\n
307  qDebug() << Q_FUNC_INFO << trame << "trame réinitialisation";
309  // Acquitte la trame
310  envoyer(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_ACQUITTEMENT + DELIMITEUR_FIN);
311  trameTraitee = true;
312  }
313  else if(trame.startsWith(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_FIN))
314  {
316  emit partieFini(etatPartie);
317  QStringList champs = trame.split(";");
318  QString leGagnant;
319  leGagnant = (champs.at(CHAMP_LE_GAGNANT));
320  // Trame de Fin
321  // Format : $DARTS;FIN;LE_GAGNANT\r\n
322  qDebug() << Q_FUNC_INFO << trame << "trame de fin";
323  emit tramePartieFinRecue(leGagnant);
324  // Acquitte la trame
325  envoyer(DEBUT_TRAME + ENTETE_TRAME + DELIMITEUR_CHAMP + TRAME_ACQUITTEMENT + DELIMITEUR_FIN);
326  trameTraitee = true;
327  }
328  else
329  {
330  qDebug() << Q_FUNC_INFO << trame << "inconnue !";
331  trameTraitee = false;
332  }
333 
334  // Pour la prochaine trame
335  effacerTrame();
336  }
337  else
338  {
339  qDebug() << Q_FUNC_INFO << trame << "incomplète !";
340  trameTraitee = false;
341  trame.clear();
342  }
343 
344  return trameTraitee;
345 }
346 
352 void Communication::deviceConnected(const QBluetoothAddress &adresse)
353 {
354  if (localDevice.pairingStatus(adresse) == QBluetoothLocalDevice::Paired || localDevice.pairingStatus(adresse) == QBluetoothLocalDevice::AuthorizedPaired)
355  {
356  qDebug() << Q_FUNC_INFO << adresse.toString() << "appairé";
357  emit connexionAppareil();
358  }
359  else
360  qDebug() << Q_FUNC_INFO << adresse.toString() << "non appairé";
361 }
362 
368 void Communication::deviceDisconnected(const QBluetoothAddress &adresse)
369 {
370  qDebug() << Q_FUNC_INFO << adresse;
371  emit deconnexionAppareil();
372 }
373 
379 void Communication::error(QBluetoothLocalDevice::Error erreur)
380 {
381  qDebug() << Q_FUNC_INFO << erreur;
382 }
Communication::error
void error(QBluetoothLocalDevice::Error erreur)
Renvoie une erreur.
Definition: communication.cpp:379
CHAMP_LE_GAGNANT
#define CHAMP_LE_GAGNANT
Definition: communication.h:69
Communication::etatPartie
int etatPartie
Défini les états de la partie.
Definition: communication.h:85
Communication::tramePartieFinRecue
void tramePartieFinRecue(QString leGagnant)
Signal qui est envoyer quand la trame de fin et reçu.
Communication::connexionMobileDarts
void connexionMobileDarts()
Signal qui est envoyer lors de la connection Bluetooth.
Communication::localDevice
QBluetoothLocalDevice localDevice
L'interface add Widjet Bluetooth de la Raspberry Pi.
Definition: communication.h:81
Communication::deviceConnected
void deviceConnected(const QBluetoothAddress &adresse)
Vérifie si l'appreille est connecter.
Definition: communication.cpp:352
serviceNom
static const QString serviceNom(QStringLiteral("ecran-darts"))
ETAT_PARTIE_ATTENTE
#define ETAT_PARTIE_ATTENTE
Quand la partie est en attente.
Definition: communication.h:24
Communication::~Communication
~Communication()
Déstruteur de la classe Communication.
Definition: communication.cpp:35
Communication::connexionAppareil
void connexionAppareil()
Signal qui est envoyer quand l'appareil est connecter.
CHAMP_MULTIPLICATEUR
#define CHAMP_MULTIPLICATEUR
Le champ qui contient le valeur du multiplicateur.
Definition: communication.h:62
Communication::recevoir
void recevoir()
Recoit les trames envoyer.
Definition: communication.cpp:206
Communication::partieEnCours
void partieEnCours(int etatPartie)
Signal qui change l'état de la partie et qui la met en cours.
Communication::envoyer
void envoyer(QString trame)
Envoie la trame.
Definition: communication.cpp:192
Communication::traiterTrame
bool traiterTrame()
Méthode qui traite la trame.
Definition: communication.cpp:235
Communication::localDeviceName
QString localDeviceName
Le nom de l'appareil.
Definition: communication.h:82
ETAT_PARTIE_FIN
#define ETAT_PARTIE_FIN
Quand la partie est fini.
Definition: communication.h:34
Communication::serviceInfo
QBluetoothServiceInfo serviceInfo
Informations sur le service bluetooth.
Definition: communication.h:83
Communication::serveur
QBluetoothServer * serveur
Le serveur Bluetooth.
Definition: communication.h:79
CHAMP_DEBUT_NOM_JOUEUR
#define CHAMP_DEBUT_NOM_JOUEUR
Le champ qui contient le nom des joueurs.
Definition: communication.h:51
Communication::connecter
void connecter()
Connecte la socket de communication Bluetooth.
Definition: communication.cpp:134
CHAMP_ID
#define CHAMP_ID
Le champ qui contient l'identifiant de la touche.
Definition: communication.h:67
Communication::deconnexionAppareil
void deconnexionAppareil()
Signal qui est envoyer quand l'appareil est déconnecter.
Communication::tramePartieRecue
void tramePartieRecue(QString typePartie, int nbJoueurs)
Signal qui contient le type de partie et le nombres de joueurs.
Communication::socket
QBluetoothSocket * socket
La socket de communication Bluetooth.
Definition: communication.h:80
Communication::deconnecter
void deconnecter()
Méthode qui déconnect le bluetooth.
Definition: communication.cpp:153
ETAT_PARTIE_EN_COURS
#define ETAT_PARTIE_EN_COURS
Quand la partie est en cours.
Definition: communication.h:29
Communication::socketDisconnected
void socketDisconnected()
Déconnecte la socket de communication Bluetooth.
Definition: communication.cpp:181
Communication::listeJoueurs
void listeJoueurs(QStringList nomsJoueur)
Signal qui contient la liste de nom des joueurs.
CHAMP_TYPE_PARTIE
#define CHAMP_TYPE_PARTIE
Le champ qui définie le type de partie.
Definition: communication.h:41
Communication::deviceDisconnected
void deviceDisconnected(const QBluetoothAddress &adresse)
Emet le signal deconnexionAppareil()
Definition: communication.cpp:368
serviceUuid
static const QString serviceUuid(QStringLiteral("0000110a-0000-1000-8000-00805f9b34fb"))
Communication::configurer
void configurer()
Méthode qui configure la connexion Bluetooth en mode serveur.
Definition: communication.cpp:47
Communication::partieFini
void partieFini(int etatPartie)
Signal qui change l'état de la partie et qui la met en attente.
Communication::estConnecte
bool estConnecte()
Méthode qui vérifie la connection Bluetooth.
Definition: communication.cpp:167
Communication::deconnexionMobileDarts
void deconnexionMobileDarts()
Signal qui est envoyer lors de la déconnection Bluetooth.
communication.h
Déclaration de la classe Communication.
CHAMP_NB_JOUEURS
#define CHAMP_NB_JOUEURS
Le champ qui contient le nombre de joueurs.
Definition: communication.h:46
Communication::Communication
Communication(QObject *parent=nullptr)
Constructeur de la classe Communication.
Definition: communication.cpp:23
QObject
Communication::trameReinitialisationRecue
void trameReinitialisationRecue()
Signal qui est envoyer quand la trame de reinitialisation et reçu.
Communication::arreter
void arreter()
Méthode qui arrête le serveur Bluetooth
Definition: communication.cpp:106
Communication::trame
QString trame
Attribut qui contient la trame.
Definition: communication.h:84
CHAMP_TOUCHE
#define CHAMP_TOUCHE
Le champ qui contient le valeur de la touche.
Definition: communication.h:57
Communication::trameToucheRecue
void trameToucheRecue(int id, int touche, int multiplicateur)
Signal qui contient l'identifiant de la touche, la valeur de la touche et le multiplcateur de touche.
Communication::effacerTrame
void effacerTrame()
Méthode qui efface la trame.
Definition: communication.cpp:225
Communication::demarrer
void demarrer()
Méthode qui démarre le serveur Bluetooth.
Definition: communication.cpp:81