Projet

Général

Profil

PARTIE LOGICIELLE » Historique » Version 2

Anonyme, 30/03/2021 14:00

1 1 Anonyme
___________________________________________________
2
3
p=. "ACCUEIL":https://forge.clermont-universite.fr/projects/p18b03/wiki/Wiki | [[INTRODUCTION]] | [[I) L’ORIGINE DU PROJET]] | [[II) LE BESOIN DU CLIENT]] | [[III) L’ORGANISATION DU TRAVAIL]] | [[IV) LA SOLUTION TECHNIQUE]] | *IV.1) PARTIE LOGICIELLE* | IV.2) [[PARTIE MATERIELLE]] | [[BILAN]] *||* [[BIBLIOGRAPHIE]] | [[DOCUMENTS]] | [[NOTES D'APPLICATION]]
4
5
_______________________________
6
7
h1. PARTIE LOGICIELLE
8
9
La partie logicielle est composée de *trois phases* :
10
11
# *Envoi du fichier* depuis le PC sur le Port Série USB.
12
# *Transmission/Sécurisation* à travers les cartes électroniques avec l'embrouillage filaire.
13
# *Réception du fichier* sur le serveur grâce au Port Série USB.
14
15 2 Anonyme
p=. !https://forge.clermont-universite.fr/attachments/download/11954/Syst%C3%A8me_complet.jpg!
16 1 Anonyme
*Figure 10 - Système complet*
17
18
_____________
19
20
h2. PHASE 1 : ENVOI
21
22
La phase d'envoi est exécutée par un programme rédigé en langage C. 
23
Dans un premier temps, ce dernier va générer le répertoire principal qui permettra à l'utilisateur de réaliser ses transferts de données. Ainsi, l’arborescence suivante; qui peut être complètement modifiée par l'utilisateur; est créée : *"D:/Répertoire/Transfert/"* et *"D:/Répertoire/Archive/"*. L'utilisateur n'a plus qu'à déposer ses fichiers dans le dossier *"Transfert"* et le programme va s'occuper de l'envoyer sur le port série de l’ordinateur. Une fois le fichier transféré au serveur, il est automatiquement supprimé du dossier "Transfert". C'est pourquoi, une sauvegarde est créée dans le dossier *"Archive"* pour éviter toutes pertes. En outre, un fichier *"Journal_de_Transfert.txt"* dont la fonction est de dresser l'historique des fichiers transférés est également créé et mis à jour. A chaque transfert sera donc renseigné, *la date et l'heure* à laquelle le fichier a été transféré ainsi que *son nom* et *sa taille*.
24
L'ensemble de ces étapes est illustré sur la figure 11 ci-dessous.
25
26 2 Anonyme
p=. !https://forge.clermont-universite.fr/attachments/download/11824/Application_C.JPG!
27 1 Anonyme
*Figure 11 - Application en langage C*
28
29
Par la suite, le fichier déposé dans le dossier "Transfert" est envoyé sur le Port Série USB de l'ordinateur. Le programme génère donc une *trame*, et c'est cette trame qui est envoyée. Cette dernière est composée de *cinq parties* différentes. En effet, comme nous pouvons le voir sur la figure 8, la première information à être envoyée est le nom du fichier. Pour cela, la *taille de la chaîne de caractère* est envoyée en premier pour indiquer au programme de réception quelle est la longueur exacte du nom qu'il doit s'attendre à acquérir. Puis le *nom du fichier* est transmis. Le même procédé est ensuite utilisé pour envoyer le contenu du fichier. La *taille du fichier* est transmise, puis le *contenu du fichier*. Pour finir, un *checksum*, calculé préalablement, est envoyé. Ce dernier permettra à la réception de vérifier qu'il n'y ait aucunes altérations entre les données envoyées et les données reçues. 
30
Le calcul du checksum utilisé consiste à appliquer un *OU-Exclusif* sur la valeur de chacun des caractères composant le fichier (voir le programme ci-dessous). 
31
32
<pre><code class="ruby">
33
unsigned long checksum(char* nom_fichier)
34
{
35
    FILE* file;
36
    unsigned char buffer[4096];
37
    unsigned int code = 0;
38
    size_t longueur;
39
    size_t i;
40
41
    if (NULL == (file = fopen(nom_fichier, "rb")))
42
    {
43
        printf("Impossible d'ouvrir le fichier %s.\n", nom_fichier);
44
        return -1;
45
    }
46
47
    longueur = fread(buffer, sizeof(char), sizeof(buffer), file);
48
    
49
    for (i = 0 ; i < longueur ; i++)
50
    {
51
        code ^= (unsigned int)(buffer[i]);
52
    }
53
54
    return code;
55
}</code></pre>
56
57 2 Anonyme
p=. !https://forge.clermont-universite.fr/attachments/download/11837/Principe_de_Fonctionnement_du_Programme.JPG!
58 1 Anonyme
*Figure 12 - Principe de Fonctionnement du Programme*
59
60
Pour envoyer les différentes informations sur le port série de l'ordinateur, le programme utilise la fonction "WriteFile" de la librairie "Windows.h". Voici ci-dessous un exemple avec l'envoi de la taille du nom du fichier.
61
62
<pre><code class="ruby">
63
taille_nom_fichier = (unsigned long)strlen(nom_fichier);
64
WriteFile(serial_port, (void *)&taille_nom_fichier, sizeof(unsigned long), &nb_octets, NULL);
65
if (nb_octets != sizeof(unsigned long))
66
{
67
	fprintf(stderr, "Erreur : La taille du nom de fichier a ete perdue.\n");
68
	CloseHandle(serial_port);
69
	exit(0);
70
}
71
</code></pre>
72
73
La fonction prend en compte les paramètres suivants :
74
- *serial_port* : du type HANDLE, il permet de définir le numéro du port USB vers lequel le programme va envoyer les données (exemple : "COM4").
75
- *taille_nom_fichier* : il s'agit d'un entier et ici, il contient le nombre de caractères composant le nom du fichier. C'est donc la donnée qui va être envoyé sur "serial_port".
76
- *sizeof(unsigned long)* : il s'agit d'un entier et il indique le nombre d'octets qui vont être écrits sur "serial_port".
77
- *nb_octets* : il s'agit d'un entier et il indique le nombre d'octets qui ont été effectivement écrits sur "serial_port".
78
- *NULL* : Valeur NULL car le fichier n'est pas ouvert avec "FILE_FLAG_OVERLAPPED". Il n'y a donc pas besoin d'utiliser un pointeur sur une structure "OVERLAPPED".
79
80
______________________________________________
81
82
h2. PHASE 2 : TRANSMISSION/SÉCURISATION
83
84
h3. > TRANSMISSION
85
86
Tout d'abord, avant de réaliser l'envoi de la donnée, *il est primordial de configurer le micro-contrôleur*. Il faut donc débuter par la partie entrée/sortie du bus parallèle, puis par la partie USB qui s'occupe de la réception de la donnée à envoyer.
87
Une partie du code de configuration est exposée ci-dessous.
88
89
<pre><code class="c">
90
void config_PIC(void){
91
    TRIS_LED_USB_DEVICE_STATUS=0;   // Set LED_USB_DEVICE_STATUS as output
92
    TRIS_PULSE =0;                  // Set PULSE as output	
93
    TRIS_DATA = 0x00;               // Set DATA as output
94
       
95
    DATA = 0x00;                    // Init the DATA bus
96
    PULSE = 0;                      // Init the PULSE
97
		
98
#if defined _18F45K50
99
	
100
    ANSELD = 0x00;                  // Set all pin in portD in digital mode
101
    ANSELC = 0;                     // Set RC0 pin in portC in digital mode
102
#endif
103
}
104
</code></pre>
105
106
<pre><code class="c">
107
void APP_DeviceCDCBasicDemoInitialize(){	
108
    CDCInitEP();
109
110
    line_coding.bCharFormat = 0;
111
    line_coding.bDataBits = 8;
112
    line_coding.bParityType = 0;
113
    line_coding.dwDTERate = 19200;	
114
}
115
</code></pre>
116
117
Une fois que la communication USB a été configurée, l'envoi des données peut débuter. Le protocole créé à ces fins est présenté ci-dessous.
118
119
Le principe de *transmission* est le suivant :
120
- *écoute sur le port USB* : si une donnée est reçue, elle est envoyée à un *buffer* grâce à la fonction *"readBuffer"*. 
121
- *envoie d'un "pulse"* : permet d'indiquer à quel moment le micro-contrôleur de réception doit lire la donnée. 
122
- *incrémentation d'une variable* : permet de vérifier que la donnée a bien été envoyée.
123
- *vérification de l'état de la communication USB* : si cette dernière est prête pour l'envoi de donnée, *le caractère "#"* est affiché sur le terminal. 
124
125
<pre><code class="c">
126
void APP_DeviceCDCBasicDemoTasks(){
127
        uint8_t i;
128
        uint8_t numBytesRead;
129
        
130
        /* 
131
         * getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT
132
           endpoint to a user's specified location. It is a non-blocking function.
133
           It does not wait for data if there is no data available. Instead it
134
           returns '0' to notify the caller that there is no data available.
135
         */
136
        
137
        numBytesRead = getsUSBUSART(readBuffer, sizeof(readBuffer));
138
        if(numBytesRead > 0){
139
            for(i=0; i<numBytesRead; i++){
140
                /* Send data*/
141
                DATA = readBuffer[i];
142
                
143
                /* Pulse's start */
144
                __delay_us(63);
145
                PULSE = 1;
146
                __delay_us(63);
147
                PULSE = 0;
148
                /* Pulse's end */                   
149
            }
150
            numBuffSend++;
151
        }
152
        if (USBUSARTIsTxTrfReady()){
153
            if(numBuffSend){
154
                putrsUSBUSART("#");         //validate the transmission by printing this symbole into the terminal
155
                numBuffSend--;
156
            }
157
        }	
158
    /*
159
     CDCTxService handles device-to-host transaction(s). This function
160
     should be called once per Main Program loop after the device reaches
161
     the configured state.	
162
     */
163
    CDCTxService();
164
}
165
</code></pre>
166
167
La donnée a été envoyée depuis l'ordinateur (*réseau externe*), sur le micro-contrôleur d’émission. Il faut ensuite s'assurer que cette dernière soit bien reçue sur le micro-contrôleur de réception, après passage du bus parallèle. Ici, *la configuration des ports du micro-contrôleur ainsi que la configuration de la communication USB doivent être obligatoirement réalisées*.
168
Une fois que la partie réception est prête, la donnée est envoyée à l'ordinateur (*réseau interne*).
169
170
<pre><code class="c">
171
void config_PIC(void){
172
    TRIS_LED_USB_DEVICE_STATUS=0;   // Set LED_USB_DEVICE_STATUS as output
173
    TRIS_LED_ROUGE = 0;             // Set LED_ROUGE as output
174
    TRIS_PULSE = 1;                 // Set PULSE as input	
175
    TRIS_DATA = 0xFF;               // Set DATA as input
176
 
177
    ANSELD = 0X00;                  //Set all pin in portD in digital mode
178
    ANSELC = 0;                     //Set all pin in portC in digital mode	
179
}
180
</code></pre>
181
182
<pre><code class="c">
183
void APP_DeviceCDCBasicDemoInitialize(){
184
    CDCInitEP();
185
    line_coding.bCharFormat = 0;
186
    line_coding.bDataBits = 8;
187
    line_coding.bParityType = 0;
188
    line_coding.dwDTERate = 19200;	
189
}
190
</code></pre>
191
192
Une fois que les configurations sont réalisées, la donnée est prête à être acquise. Pour cela, le programme va avoir recourt à un *double buffer*.
193
194 2 Anonyme
p=. !https://forge.clermont-universite.fr/attachments/download/11948/reception.jpg!
195 1 Anonyme
*Figure 13 - Méthode du double buffer*
196
197
*La méthode du double buffer* se décompose ainsi :
198
- le nombre d'octets est initialisé à 0 et la taille des paquets à recevoir à 63.
199
- dans l'état *"R0"*, il y a *deux configurations* :
200
* *réception des données  à chaque coup d'horloge ou lors d'une interruption*. Dans ce cas, la donnée est stockée dans le buffer1 et est incrémentée du nombre d'octets.
201
* *deux situations possibles* :
202
  -> *le buffer est plein* : *Buffer1* est envoyé et le nombre d'octets est réinitialisé.
203
  -> *le buffer n'est pas plein et un timeout est reçu* : Buffer1 envoyé et le nombre d'octets est réinitialisé.
204
Après avoir envoyé le Buffer1, le nombre d'octets est mis à zéro et l'état du système passe à *"R1"*. Cet état permet de recevoir les données dans le *Buffer2*. Ce dernier sera ensuite envoyé en suivant le même principe que Buffer1.
205
206
La phase de transmission ayant été réalisée, il reste à étudier l'aspect sécurité des données envoyées.
207
208
h3. > SÉCURISATION (CÂBLAGE EMBROUILLÉ)
209
210
L'une des demandes du client était de réaliser un système de sécurisation par câblage embrouillé, capable de "crypter" les données, et dont la combinaison pouvait être modifiable.
211
La solution consiste donc à connecter les ports de données de chacun des micro-contrôleurs entre eux, de façon prédéfinie. La donnée reçue sur le micro-contrôleur de réception est ensuite reconstruite grâce à une table de correspondance.
212
Par exemple, si l'utilisateur décide d'envoyer "010", il recevra "001" dans cette configuration.
213
214 2 Anonyme
p=. !https://forge.clermont-universite.fr/attachments/download/11949/MaillageFilaire.jpg!
215 1 Anonyme
*Figure 14 - Maillage Filaire*
216
217
Voici un exemple d'embrouillage filaire sur trois fils du bus parallèle (figure 14).
218
De cette façon, si la table de correspondance n'est pas connue, la donnée ne peut être décryptée.
219
220
221
___________________
222
223
h2. PHASE 3 : RÉCEPTION
224
225
La phase de réception est également exécutée par un programme rédigé en langage C. 
226
Dans un premier temps, ce dernier va générer *le dossier de réception* dans lequel les fichiers transférés par le programme d'envoi seront stockés. Ainsi, l’arborescence suivante; qui peut être complètement modifiée par l'utilisateur; est créée : *"D:/Réception/"*. De ce côté de l'application, l'utilisateur n'a aucune action à réaliser. Le programme s'occupe du transfert de données. En effet, ce dernier va créer un *fichier temporaire vide* qui sera renommé en fonction de l'avancement du transfert. Par exemple, pour le fichier "test.txt", le programme va créer dans le dossier de réception le fichier *"test.txt_xx%"*. Ici, "xx" représente l'avancement du transfert et sa valeur est un entier compris entre 0 et 100. Une fois le transfert effectué à 100%, le fichier temporaire va être supprimé. A noter que le fichier transféré va apparaître dans le dossier de réception au début du transfert mais ce dernier ne pourra être ouvert qu'une fois le transfert terminé.
227
228
En outre, comme présenté sur la figure 12, la trame envoyé par le programme d'envoi est composée de cinq parties.
229
Comme pour la partie d'émission, le programme de réception va acquérir chaque partie une par une. Pour se faire, le programme utilise la fonction "ReadFile" de la libraire "Windows.h". Voici ci-dessous un exemple avec la réception de la taille du nom du fichier.
230
231
<pre><code class="ruby">
232
ReadFile(serial_port, (void *)&taille_nom_fichier, sizeof(unsigned long), &octets_recus, NULL);
233
if (octets_recus != sizeof(unsigned long))
234
{
235
	fprintf(stderr, "Erreur : Impossible d'obtenir la taille du nom de fichier.\n");
236
        CloseHandle(serial_port);
237
	exit(0);
238
}</code></pre>La fonction prend en compte les paramètres suivants :
239
- *serial_port* : du type HANDLE, il permet de définir le numéro du port USB sur lequel le programme va recevoir les données (exemple : "COM3").
240
- *taille_nom_fichier* : il s'agit d'un entier et ici, il contient le nombre de caractères composant le nom du fichier. Cette variable reçoit donc la valeur envoyée sur serial_port.
241
- *sizeof(unsigned long)* : il s'agit d'un entier et il indique le nombre d'octets qui vont être reçus sur "serial_port".
242
- *octets_recus* : il s'agit d'un entier et il indique le nombre d'octets qui ont été effectivement reçus sur "serial_port".
243
- *NULL* : Valeur NULL car le fichier n'est pas ouvert avec "FILE_FLAG_OVERLAPPED". Il n'y a donc pas besoin d'utiliser un pointeur sur une structure "OVERLAPPED".
244
245
Par la suite, une fois que le transfert du fichier c'est parfaitement déroulé, le programme va calculer le *checksum* de ce dernier. La méthode de calcul est exactement la même que pour le programme d'envoi.
246
Une fois calculé, ce checksum va être comparé à celui calculé par le programme d'envoi et qui a été envoyé au programme de réception. Si il n'y a pas correspondance, alors le fichier a été altéré ou corrompu lors du transfert. Il est donc automatiquement effacé. 
247
248
_________________________
249
250
p=. << Revenir à [[IV) LA SOLUTION TECHNIQUE]] | Chapitre Suivant : IV.2) [[PARTIE MATERIELLE]] >>
251 2 Anonyme
252
253
"Application_C.JPG":https://forge.clermont-universite.fr/attachments/download/11824/Application_C.JPG 
254
255
"Principe_de_Fonctionnement_du_Programme.JPG":https://forge.clermont-universite.fr/attachments/download/11837/Principe_de_Fonctionnement_du_Programme.JPG
256
257
"reception.jpg":https://forge.clermont-universite.fr/attachments/download/11948/reception.jpg 
258
259
"MaillageFilaire.jpg":https://forge.clermont-universite.fr/attachments/download/11949/MaillageFilaire.jpg 
260
261
"Système_complet.jpg":https://forge.clermont-universite.fr/attachments/download/11954/Syst%C3%A8me_complet.jpg 
262
263 1 Anonyme
264
__________________________________________________________________________________________________________________________________________